]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/interprocess/include/boost/interprocess/streams/bufferstream.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / interprocess / include / boost / interprocess / streams / bufferstream.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 //
11 // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
12 // Changed internal SGI string to a buffer. Added efficient
13 // internal buffer get/set/swap functions, so that we can obtain/establish the
14 // internal buffer without any reallocation or copy. Kill those temporaries!
15 ///////////////////////////////////////////////////////////////////////////////
16 /*
17 * Copyright (c) 1998
18 * Silicon Graphics Computer Systems, Inc.
19 *
20 * Permission to use, copy, modify, distribute and sell this software
21 * and its documentation for any purpose is hereby granted without fee,
22 * provided that the above copyright notice appear in all copies and
23 * that both that copyright notice and this permission notice appear
24 * in supporting documentation. Silicon Graphics makes no
25 * representations about the suitability of this software for any
26 * purpose. It is provided "as is" without express or implied warranty.
27 */
28
29 //!\file
30 //!This file defines basic_bufferbuf, basic_ibufferstream,
31 //!basic_obufferstream, and basic_bufferstream classes. These classes
32 //!represent streamsbufs and streams whose sources or destinations
33 //!are fixed size character buffers.
34
35 #ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP
36 #define BOOST_INTERPROCESS_BUFFERSTREAM_HPP
37
38 #ifndef BOOST_CONFIG_HPP
39 # include <boost/config.hpp>
40 #endif
41 #
42 #if defined(BOOST_HAS_PRAGMA_ONCE)
43 # pragma once
44 #endif
45
46 #include <boost/interprocess/detail/config_begin.hpp>
47 #include <boost/interprocess/detail/workaround.hpp>
48
49 #include <iosfwd>
50 #include <ios>
51 #include <istream>
52 #include <ostream>
53 #include <string> // char traits
54 #include <cstddef> // ptrdiff_t
55 #include <boost/assert.hpp>
56 #include <boost/interprocess/interprocess_fwd.hpp>
57
58 namespace boost { namespace interprocess {
59
60 //!A streambuf class that controls the transmission of elements to and from
61 //!a basic_xbufferstream. The elements are transmitted from a to a fixed
62 //!size buffer
63 template <class CharT, class CharTraits>
64 class basic_bufferbuf
65 : public std::basic_streambuf<CharT, CharTraits>
66 {
67 public:
68 typedef CharT char_type;
69 typedef typename CharTraits::int_type int_type;
70 typedef typename CharTraits::pos_type pos_type;
71 typedef typename CharTraits::off_type off_type;
72 typedef CharTraits traits_type;
73 typedef std::basic_streambuf<char_type, traits_type> base_t;
74
75 public:
76 //!Constructor.
77 //!Does not throw.
78 explicit basic_bufferbuf(std::ios_base::openmode mode
79 = std::ios_base::in | std::ios_base::out)
80 : base_t(), m_mode(mode), m_buffer(0), m_length(0)
81 {}
82
83 //!Constructor. Assigns formatting buffer.
84 //!Does not throw.
85 explicit basic_bufferbuf(CharT *buf, std::size_t length,
86 std::ios_base::openmode mode
87 = std::ios_base::in | std::ios_base::out)
88 : base_t(), m_mode(mode), m_buffer(buf), m_length(length)
89 { this->set_pointers(); }
90
91 virtual ~basic_bufferbuf(){}
92
93 public:
94 //!Returns the pointer and size of the internal buffer.
95 //!Does not throw.
96 std::pair<CharT *, std::size_t> buffer() const
97 { return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
98
99 //!Sets the underlying buffer to a new value
100 //!Does not throw.
101 void buffer(CharT *buf, std::size_t length)
102 { m_buffer = buf; m_length = length; this->set_pointers(); }
103
104 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
105 private:
106 void set_pointers()
107 {
108 // The initial read position is the beginning of the buffer.
109 if(m_mode & std::ios_base::in)
110 this->setg(m_buffer, m_buffer, m_buffer + m_length);
111
112 // The initial write position is the beginning of the buffer.
113 if(m_mode & std::ios_base::out)
114 this->setp(m_buffer, m_buffer + m_length);
115 }
116
117 protected:
118 virtual int_type underflow()
119 {
120 // Precondition: gptr() >= egptr(). Returns a character, if available.
121 return this->gptr() != this->egptr() ?
122 CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
123 }
124
125 virtual int_type pbackfail(int_type c = CharTraits::eof())
126 {
127 if(this->gptr() != this->eback()) {
128 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
129 if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
130 this->gbump(-1);
131 return c;
132 }
133 else if(m_mode & std::ios_base::out) {
134 this->gbump(-1);
135 *this->gptr() = c;
136 return c;
137 }
138 else
139 return CharTraits::eof();
140 }
141 else {
142 this->gbump(-1);
143 return CharTraits::not_eof(c);
144 }
145 }
146 else
147 return CharTraits::eof();
148 }
149
150 virtual int_type overflow(int_type c = CharTraits::eof())
151 {
152 if(m_mode & std::ios_base::out) {
153 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
154 // if(!(m_mode & std::ios_base::in)) {
155 // if(this->pptr() != this->epptr()) {
156 // *this->pptr() = CharTraits::to_char_type(c);
157 // this->pbump(1);
158 // return c;
159 // }
160 // else
161 // return CharTraits::eof();
162 // }
163 // else {
164 if(this->pptr() == this->epptr()) {
165 //We can't append to a static buffer
166 return CharTraits::eof();
167 }
168 else {
169 *this->pptr() = CharTraits::to_char_type(c);
170 this->pbump(1);
171 return c;
172 }
173 // }
174 }
175 else // c is EOF, so we don't have to do anything
176 return CharTraits::not_eof(c);
177 }
178 else // Overflow always fails if it's read-only.
179 return CharTraits::eof();
180 }
181
182 virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
183 std::ios_base::openmode mode
184 = std::ios_base::in | std::ios_base::out)
185 {
186 bool in = false;
187 bool out = false;
188
189 const std::ios_base::openmode inout =
190 std::ios_base::in | std::ios_base::out;
191
192 if((mode & inout) == inout) {
193 if(dir == std::ios_base::beg || dir == std::ios_base::end)
194 in = out = true;
195 }
196 else if(mode & std::ios_base::in)
197 in = true;
198 else if(mode & std::ios_base::out)
199 out = true;
200
201 if(!in && !out)
202 return pos_type(off_type(-1));
203 else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
204 (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
205 return pos_type(off_type(-1));
206
207 std::streamoff newoff;
208 switch(dir) {
209 case std::ios_base::beg:
210 newoff = 0;
211 break;
212 case std::ios_base::end:
213 newoff = static_cast<std::streamoff>(m_length);
214 break;
215 case std::ios_base::cur:
216 newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
217 : static_cast<std::streamoff>(this->pptr() - this->pbase());
218 break;
219 default:
220 return pos_type(off_type(-1));
221 }
222
223 off += newoff;
224
225 if(in) {
226 std::ptrdiff_t n = this->egptr() - this->eback();
227
228 if(off < 0 || off > n)
229 return pos_type(off_type(-1));
230 else
231 this->setg(this->eback(), this->eback() + off, this->eback() + n);
232 }
233
234 if(out) {
235 std::ptrdiff_t n = this->epptr() - this->pbase();
236
237 if(off < 0 || off > n)
238 return pos_type(off_type(-1));
239 else {
240 this->setp(this->pbase(), this->pbase() + n);
241 this->pbump(off);
242 }
243 }
244
245 return pos_type(off);
246 }
247
248 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
249 = std::ios_base::in | std::ios_base::out)
250 { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
251
252 private:
253 std::ios_base::openmode m_mode;
254 CharT * m_buffer;
255 std::size_t m_length;
256 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
257 };
258
259 //!A basic_istream class that uses a fixed size character buffer
260 //!as its formatting buffer.
261 template <class CharT, class CharTraits>
262 class basic_ibufferstream :
263 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
264 private basic_bufferbuf<CharT, CharTraits>,
265 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
266 public std::basic_istream<CharT, CharTraits>
267 {
268 public: // Typedefs
269 typedef typename std::basic_ios
270 <CharT, CharTraits>::char_type char_type;
271 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
272 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
273 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
274 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
275
276 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
277 private:
278 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
279 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
280 typedef std::basic_istream<char_type, CharTraits> base_t;
281 bufferbuf_t & get_buf() { return *this; }
282 const bufferbuf_t & get_buf() const{ return *this; }
283 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
284
285 public:
286 //!Constructor.
287 //!Does not throw.
288 basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
289 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
290 //virtual base of basic_istream. The class will be initialized when
291 //basic_istream is constructed calling basic_ios_t::init().
292 //As bufferbuf_t's constructor does not throw there is no risk of
293 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
294 bufferbuf_t(mode | std::ios_base::in)
295 , base_t(&get_buf())
296 {}
297
298 //!Constructor. Assigns formatting buffer.
299 //!Does not throw.
300 basic_ibufferstream(const CharT *buf, std::size_t length,
301 std::ios_base::openmode mode = std::ios_base::in)
302 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
303 //virtual base of basic_istream. The class will be initialized when
304 //basic_istream is constructed calling basic_ios_t::init().
305 //As bufferbuf_t's constructor does not throw there is no risk of
306 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
307 bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
308 , base_t(&get_buf())
309 {}
310
311 ~basic_ibufferstream(){};
312
313 public:
314 //!Returns the address of the stored
315 //!stream buffer.
316 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
317 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
318
319 //!Returns the pointer and size of the internal buffer.
320 //!Does not throw.
321 std::pair<const CharT *, std::size_t> buffer() const
322 { return get_buf().buffer(); }
323
324 //!Sets the underlying buffer to a new value. Resets
325 //!stream position. Does not throw.
326 void buffer(const CharT *buf, std::size_t length)
327 { get_buf().buffer(const_cast<CharT*>(buf), length); }
328 };
329
330 //!A basic_ostream class that uses a fixed size character buffer
331 //!as its formatting buffer.
332 template <class CharT, class CharTraits>
333 class basic_obufferstream :
334 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
335 private basic_bufferbuf<CharT, CharTraits>,
336 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
337 public std::basic_ostream<CharT, CharTraits>
338 {
339 public:
340 typedef typename std::basic_ios
341 <CharT, CharTraits>::char_type char_type;
342 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
343 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
344 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
345 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
346
347 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
348 private:
349 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
350 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
351 typedef std::basic_ostream<char_type, CharTraits> base_t;
352 bufferbuf_t & get_buf() { return *this; }
353 const bufferbuf_t & get_buf() const{ return *this; }
354 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
355
356 public:
357 //!Constructor.
358 //!Does not throw.
359 basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
360 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
361 //virtual base of basic_istream. The class will be initialized when
362 //basic_istream is constructed calling basic_ios_t::init().
363 //As bufferbuf_t's constructor does not throw there is no risk of
364 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
365 bufferbuf_t(mode | std::ios_base::out)
366 , base_t(&get_buf())
367 {}
368
369 //!Constructor. Assigns formatting buffer.
370 //!Does not throw.
371 basic_obufferstream(CharT *buf, std::size_t length,
372 std::ios_base::openmode mode = std::ios_base::out)
373 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
374 //virtual base of basic_istream. The class will be initialized when
375 //basic_istream is constructed calling basic_ios_t::init().
376 //As bufferbuf_t's constructor does not throw there is no risk of
377 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
378 bufferbuf_t(buf, length, mode | std::ios_base::out)
379 , base_t(&get_buf())
380 {}
381
382 ~basic_obufferstream(){}
383
384 public:
385 //!Returns the address of the stored
386 //!stream buffer.
387 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
388 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
389
390 //!Returns the pointer and size of the internal buffer.
391 //!Does not throw.
392 std::pair<CharT *, std::size_t> buffer() const
393 { return get_buf().buffer(); }
394
395 //!Sets the underlying buffer to a new value. Resets
396 //!stream position. Does not throw.
397 void buffer(CharT *buf, std::size_t length)
398 { get_buf().buffer(buf, length); }
399 };
400
401
402 //!A basic_iostream class that uses a fixed size character buffer
403 //!as its formatting buffer.
404 template <class CharT, class CharTraits>
405 class basic_bufferstream :
406 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
407 private basic_bufferbuf<CharT, CharTraits>,
408 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
409 public std::basic_iostream<CharT, CharTraits>
410 {
411 public: // Typedefs
412 typedef typename std::basic_ios
413 <CharT, CharTraits>::char_type char_type;
414 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
415 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
416 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
417 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
418
419 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
420 private:
421 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
422 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
423 typedef std::basic_iostream<char_type, CharTraits> base_t;
424 bufferbuf_t & get_buf() { return *this; }
425 const bufferbuf_t & get_buf() const{ return *this; }
426 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
427
428 public:
429 //!Constructor.
430 //!Does not throw.
431 basic_bufferstream(std::ios_base::openmode mode
432 = std::ios_base::in | std::ios_base::out)
433 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
434 //virtual base of basic_istream. The class will be initialized when
435 //basic_istream is constructed calling basic_ios_t::init().
436 //As bufferbuf_t's constructor does not throw there is no risk of
437 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
438 bufferbuf_t(mode)
439 , base_t(&get_buf())
440 {}
441
442 //!Constructor. Assigns formatting buffer.
443 //!Does not throw.
444 basic_bufferstream(CharT *buf, std::size_t length,
445 std::ios_base::openmode mode
446 = std::ios_base::in | std::ios_base::out)
447 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
448 //virtual base of basic_istream. The class will be initialized when
449 //basic_istream is constructed calling basic_ios_t::init().
450 //As bufferbuf_t's constructor does not throw there is no risk of
451 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
452 bufferbuf_t(buf, length, mode)
453 , base_t(&get_buf())
454 {}
455
456 ~basic_bufferstream(){}
457
458 public:
459 //!Returns the address of the stored
460 //!stream buffer.
461 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
462 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
463
464 //!Returns the pointer and size of the internal buffer.
465 //!Does not throw.
466 std::pair<CharT *, std::size_t> buffer() const
467 { return get_buf().buffer(); }
468
469 //!Sets the underlying buffer to a new value. Resets
470 //!stream position. Does not throw.
471 void buffer(CharT *buf, std::size_t length)
472 { get_buf().buffer(buf, length); }
473 };
474
475 //Some typedefs to simplify usage
476 typedef basic_bufferbuf<char> bufferbuf;
477 typedef basic_bufferstream<char> bufferstream;
478 typedef basic_ibufferstream<char> ibufferstream;
479 typedef basic_obufferstream<char> obufferstream;
480
481 typedef basic_bufferbuf<wchar_t> wbufferbuf;
482 typedef basic_bufferstream<wchar_t> wbufferstream;
483 typedef basic_ibufferstream<wchar_t> wibufferstream;
484 typedef basic_obufferstream<wchar_t> wobufferstream;
485
486
487 }} //namespace boost { namespace interprocess {
488
489 #include <boost/interprocess/detail/config_end.hpp>
490
491 #endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */