StreamUtil.h 2.3 KB

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