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 | |
16 | |
17 | #ifndef Foundation_StreamUtil_INCLUDED |
18 | #define Foundation_StreamUtil_INCLUDED |
19 | |
20 | |
21 | #include "Poco/Foundation.h" |
22 | |
23 | |
24 | // poco_ios_init |
25 | // |
26 | // This is a workaround for a bug in the Dinkumware |
27 | // implementation of iostreams. |
28 | // |
29 | // Calling basic_ios::init() multiple times for the |
30 | // same basic_ios instance results in a memory leak |
31 | // caused by the ios' locale being allocated more than |
32 | // once, each time overwriting the old pointer. |
33 | // This usually occurs in the following scenario: |
34 | // |
35 | // class MyStreamBuf: public std::streambuf |
36 | // { |
37 | // ... |
38 | // }; |
39 | // |
40 | // class MyIOS: public virtual std::ios |
41 | // { |
42 | // public: |
43 | // MyIOS() |
44 | // { |
45 | // init(&_buf); |
46 | // } |
47 | // protected: |
48 | // MyStreamBuf _buf; |
49 | // }; |
50 | // |
51 | // class MyIStream: public MyIOS, public std::istream |
52 | // { |
53 | // ... |
54 | // }; |
55 | // |
56 | // In this scenario, std::ios::init() is called twice |
57 | // (the first time by the MyIOS constructor, the second |
58 | // time by the std::istream constructor), resulting in |
59 | // two locale objects being allocated, the pointer second |
60 | // one overwriting the pointer to the first one and thus |
61 | // causing a memory leak. |
62 | // |
63 | // The workaround is to call init() only once for each |
64 | // stream object - by the istream, ostream or iostream |
65 | // constructor, and not calling init() in ios-derived |
66 | // base classes. |
67 | // |
68 | // Some stream implementations, however, require that |
69 | // init() is called in the MyIOS constructor. |
70 | // Therefore we replace each call to init() with |
71 | // the poco_ios_init macro defined below. |
72 | |
73 | |
74 | #if !defined(POCO_IOS_INIT_HACK) |
75 | // Microsoft Visual Studio with Dinkumware STL (but not STLport) |
76 | # if defined(_MSC_VER) && (!defined(_STLP_MSVC) || defined(_STLP_NO_OWN_IOSTREAMS)) |
77 | # define POCO_IOS_INIT_HACK 1 |
78 | // QNX with Dinkumware but not GNU C++ Library |
79 | # elif defined(__QNX__) && !defined(__GLIBCPP__) |
80 | # define POCO_IOS_INIT_HACK 1 |
81 | # endif |
82 | #endif |
83 | |
84 | |
85 | #if defined(POCO_IOS_INIT_HACK) |
86 | # define poco_ios_init(buf) |
87 | #else |
88 | # define poco_ios_init(buf) init(buf) |
89 | #endif |
90 | |
91 | |
92 | #endif // Foundation_StreamUtil_INCLUDED |
93 | |