StreamUtil.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. //
  2. // StreamUtil.h
  3. //
  4. // Library: Foundation
  5. // Package: Streams
  6. // Module: StreamUtil
  7. //
  8. // Stream implementation support.
  9. //
  10. // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #ifndef Foundation_StreamUtil_INCLUDED
  16. #define Foundation_StreamUtil_INCLUDED
  17. #include "Poco/Foundation.h"
  18. // poco_ios_init
  19. //
  20. // This is a workaround for a bug in the Dinkumware
  21. // implementation of iostreams.
  22. //
  23. // Calling basic_ios::init() multiple times for the
  24. // same basic_ios instance results in a memory leak
  25. // caused by the ios' locale being allocated more than
  26. // once, each time overwriting the old pointer.
  27. // This usually occurs in the following scenario:
  28. //
  29. // class MyStreamBuf: public std::streambuf
  30. // {
  31. // ...
  32. // };
  33. //
  34. // class MyIOS: public virtual std::ios
  35. // {
  36. // public:
  37. // MyIOS()
  38. // {
  39. // init(&_buf);
  40. // }
  41. // protected:
  42. // MyStreamBuf _buf;
  43. // };
  44. //
  45. // class MyIStream: public MyIOS, public std::istream
  46. // {
  47. // ...
  48. // };
  49. //
  50. // In this scenario, std::ios::init() is called twice
  51. // (the first time by the MyIOS constructor, the second
  52. // time by the std::istream constructor), resulting in
  53. // two locale objects being allocated, the pointer second
  54. // one overwriting the pointer to the first one and thus
  55. // causing a memory leak.
  56. //
  57. // The workaround is to call init() only once for each
  58. // stream object - by the istream, ostream or iostream
  59. // constructor, and not calling init() in ios-derived
  60. // base classes.
  61. //
  62. // Some stream implementations, however, require that
  63. // init() is called in the MyIOS constructor.
  64. // Therefore we replace each call to init() with
  65. // the poco_ios_init macro defined below.
  66. #if !defined(POCO_IOS_INIT_HACK)
  67. // Microsoft Visual Studio with Dinkumware STL (but not STLport)
  68. # if defined(_MSC_VER) && (!defined(_STLP_MSVC) || defined(_STLP_NO_OWN_IOSTREAMS))
  69. # define POCO_IOS_INIT_HACK 1
  70. // QNX with Dinkumware but not GNU C++ Library
  71. # elif defined(__QNX__) && !defined(__GLIBCPP__)
  72. # define POCO_IOS_INIT_HACK 1
  73. # endif
  74. #endif
  75. #if defined(POCO_IOS_INIT_HACK)
  76. # define poco_ios_init(buf)
  77. #else
  78. # define poco_ios_init(buf) init(buf)
  79. #endif
  80. #endif // Foundation_StreamUtil_INCLUDED