BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdls_fdstreambuf.h
Go to the documentation of this file.
1/// @file bdls_fdstreambuf.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdls_fdstreambuf.h -*-C++-*-
8#ifndef INCLUDED_BDLS_FDSTREAMBUF
9#define INCLUDED_BDLS_FDSTREAMBUF
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdls_fdstreambuf bdls_fdstreambuf
15/// @brief Provide a stream buffer initialized with a file descriptor.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdls
19/// @{
20/// @addtogroup bdls_fdstreambuf
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdls_fdstreambuf-purpose"> Purpose</a>
25/// * <a href="#bdls_fdstreambuf-classes"> Classes </a>
26/// * <a href="#bdls_fdstreambuf-description"> Description </a>
27/// * <a href="#bdls_fdstreambuf-usage"> Usage </a>
28/// * <a href="#bdls_fdstreambuf-example-1-stream-initialization"> Example 1: Stream Initialization </a>
29/// * <a href="#bdls_fdstreambuf-example-2-streambuf"> Example 2: Streambuf </a>
30///
31/// # Purpose {#bdls_fdstreambuf-purpose}
32/// Provide a stream buffer initialized with a file descriptor.
33///
34/// # Classes {#bdls_fdstreambuf-classes}
35///
36/// - bdls::FdStreamBuf: stream buffer constructed with file descriptor
37///
38/// @see bsl::streambuf
39///
40/// # Description {#bdls_fdstreambuf-description}
41/// This component implements a class, `bdls::FdStreamBuf`, derived
42/// from the C++ standard library's `bsl::streambuf` that can be associated with
43/// a file descriptor. Except for the `pubimbue` function, all of the actions
44/// that can be performed on an `bsl::streambuf` can be performed on a
45/// `bdls::FdStreamBuf`. An `bsl::streambuf` provides public methods for
46/// reading from and writing to a stream of data, which are implemented in terms
47/// of protected virtual functions. A `bdls::FdStreamBuf` provides an
48/// implementation of these protected virtual members such that they operate on
49/// a given file descriptor. The file descriptor can represent a file, a pipe,
50/// or other device, and it can be associated with the `bdls::FdStreamBuf` at
51/// construction, or by calling the `reset` method. Note that a `bsl::stream`
52/// can be initialized with a `bdls::FdStreamBuf`, making it possible to
53/// associate the stream with a file descriptor.
54///
55/// Note that the `pubimbue` function may be called, but not with any value
56/// other than `bsl::locale()`. Furthermore, when called with this value, it
57/// has no effect.
58///
59/// The file descriptor type `bdls::FilesystemUtil::FileDescriptor` used in this
60/// component is, on Unix, an `int` type returned by `open`, and on Windows, a
61/// `HANDLE` type returned by `CreateFile`. Ideally, a user would open the file
62/// and obtain the platform-independent `bdls::FilesystemUtil::FileDescriptor`
63/// by calling `bdls::FilesystemUtil::open`, which will call the appropriate
64/// routine for the platform and return a
65/// `bdls::FilesystemUtil::FileDescriptor`. A value of
66/// `bdls::FilesystemUtil::k_INVALID_FD` is used to represent an invalid file
67/// handle on both platforms.
68///
69/// On Windows for a file in text mode, the byte `0x1a` (ctrl-Z) is recognized
70/// as an end of file marker. If it is encountered, it is not returned in the
71/// buffer and subsequent reads will indicate that no more input is available.
72/// The behavior is undefined if it is not the last byte in the file. Other
73/// types of files are not required to end with `0x1a`. For files on Unix and
74/// files opened in binary mode on Windows, `0x1a` is treated like any other
75/// byte.
76///
77/// Note that the public methods of the `bsl::streambuf` class used in the usage
78/// example are not described here. See documentation in
79/// "The C++ Programming Language, Third Edition", by Bjarne Stroustrup,
80/// Section 21.6.4, and on the web at:
81/// @code
82/// http://www.cplusplus.com/reference/iostream/streambuf
83/// @endcode
84/// Note that the `bdls::FdStreamBuf` and `bdls::FdStreamBuf_FileHandler`
85/// classes here are based on STLPort's implementation of `filebuf` and
86/// `_Filebuf_Base` respectively, with copyright notice as follows:
87/// @code
88/// ----------------------------------------------------------------------------
89/// Copyright (c) 1999
90/// Silicon Graphics Computer Systems, Inc.
91///
92/// Copyright (c) 1999
93/// Boris Fomitchev
94///
95/// This material is provided "as is", with absolutely no warranty expressed
96/// or implied. Any use is at your own risk.
97///
98/// Permission to use or copy this software for any purpose is hereby granted
99/// without fee, provided the above notices are retained on all copies.
100/// Permission to modify the code and to distribute modified code is granted,
101/// provided the above notices are retained, and a notice that the code was
102/// modified is included with the above copyright notice.
103/// ----------------------------------------------------------------------------
104/// @endcode
105///
106/// ## Usage {#bdls_fdstreambuf-usage}
107///
108///
109/// This section illustrates intended use of this component.
110///
111/// ### Example 1: Stream Initialization {#bdls_fdstreambuf-example-1-stream-initialization}
112///
113///
114/// The most common usage of this component is to initialize a stream. In this
115/// case, the `bdls::FdStreamBuf` will be used for either input or output, but
116/// not both.
117///
118/// First we create a suitable file name, and make sure that no file of that
119/// name already exists:
120/// @code
121/// char fileNameBuffer[100];
122/// bsl::sprintf(fileNameBuffer,
123/// #ifdef BSLS_PLATFORM_OS_UNIX
124/// "/tmp/bdls_FdStreamBuf.usage.1.%d.txt",
125/// #else // windows
126/// "C:\\TEMP\\bdls_FdStreamBuf.usage.1.%d.txt";
127/// #endif
128/// bdls::ProcessUtil::getProcessId());
129///
130/// bdls::FilesystemUtil::remove(fileNameBuffer);
131/// assert(0 == bdls::FilesystemUtil::exists(fileNameBuffer));
132/// @endcode
133/// Then we create the file and open a file descriptor to it; the boolean
134/// flags indicate that the file is to be writable, and not previously existing
135/// (and therefore must be created):
136/// @code
137/// typedef bdls::FilesystemUtil::FileDescriptor FdType;
138///
139/// FdType fd = bdls::FilesystemUtil::open(fileNameBuffer,
140/// bdls::FilesystemUtil::e_CREATE,
141/// bdls::FilesystemUtil::e_READ_WRITE);
142/// assert(bdls::FilesystemUtil::k_INVALID_FD != fd);
143/// @endcode
144/// Next we create a `bdls::FdStreamBuf` associated with file descriptor
145/// `fd`; the `false` argument indicates that `streamBuffer` will not assume
146/// ownership of `fd`, meaning that when `streamBuffer` is destroyed `fd` will
147/// remain open:
148///
149/// Note also that the stream buffer defaults to being in text mode on Windows,
150/// and binary mode on Unix.
151/// @code
152/// {
153/// bdls::FdStreamBuf streamBuffer(fd,
154/// true, // writable
155/// false); // 'fd' won't be closed
156/// // when 'streamBuffer' is
157/// // destroyed
158///
159/// bsl::ostream os(&streamBuffer);
160///
161/// os << "Five times nine point five = " << 5 * 9.5 << bsl::endl;
162/// }
163/// @endcode
164/// Note also that the stream buffer defaults to being in text mode on
165/// Windows, and binary mode on Unix.
166///
167/// Now create a new stream buffer to read the file back, in this case
168/// using binary mode so we can see exactly what was written. The new
169/// stream buf is used to initialize an input stream.
170/// @code
171/// {
172/// // read it in binary mode
173///
174/// bdls::FdStreamBuf streamBuffer(fd,
175/// false, // not writable
176/// false, // 'streamBuffer' does not
177/// // own 'fd'
178/// true); // binary mode
179///
180/// streamBuffer.pubseekpos(0);
181///
182/// char buf[100];
183/// bsl::memset(buf, 0, sizeof(buf));
184///
185/// bsl::istream is(&streamBuffer);
186/// char *pc = buf;
187/// do {
188/// is >> bsl::noskipws >> *pc++;
189/// } while ('\n' != pc[-1]);
190///
191/// #ifdef BSLS_PLATFORM_OS_UNIX
192/// assert(!bsl::strcmp("Five times nine point five = 47.5\n", buf));
193/// #else
194/// //On Windows we see a CRLF ('\r\n') instead of a simple LF '\n'
195/// assert(!bsl::strcmp("Five times nine point five = 47.5\r\n", buf));
196/// #endif
197/// }
198/// @endcode
199/// Finally, read the file back a second time, this time in text mode. Note
200/// how, on Windows, the `\r\n` is translated back to `\n`:
201/// @code
202/// {
203/// // read it back in text mode
204///
205/// bdls::FdStreamBuf streamBuffer(fd,
206/// false); // not writable
207/// // 'fd' will be closed when
208/// // streamBuffer is destroyed.
209/// // Mode will be binary on
210/// // Unix, text on Dos.
211/// streamBuffer.pubseekpos(0);
212///
213/// char buf[100];
214/// bsl::memset(buf, 0, sizeof(buf));
215///
216/// bsl::istream is(&streamBuffer);
217/// char *pc = buf;
218/// do {
219/// is >> bsl::noskipws >> *pc++;
220/// } while ('\n' != pc[-1]);
221///
222/// assert(!bsl::strcmp("Five times nine point five = 47.5\n", buf));
223/// }
224/// @endcode
225/// And finally, we clean up:
226/// @code
227/// bdls::FilesystemUtil::remove(fileNameBuffer);
228/// @endcode
229///
230/// ### Example 2: Streambuf {#bdls_fdstreambuf-example-2-streambuf}
231///
232///
233/// For our second example we will create a `bdls::FdStreamBuf` associated with
234/// a temporary file, and then use the public methods of the base class
235/// interface, including `sputn`, `sgetn` and `pubseekpos`, to do some I/O and
236/// seeking on it.
237/// @code
238/// const char line1[] = "To be or not to be, that is the question.\n";
239/// const char line2[] =
240/// "There are more things in heaven and earth,\n"
241/// "Horatio, than are dreamt of in your philosophy.\n";
242/// const char line3[] = "Wherever you go, there you are. B Banzai\n";
243///
244/// const int lengthLine1 = sizeof(line1) - 1;
245/// const int lengthLine2 = sizeof(line2) - 1;
246/// const int lengthLine3 = sizeof(line3) - 1;
247/// @endcode
248/// We start by selecting a file name for our (temporary) file.
249/// @code
250/// char fileNameBuffer[100];
251/// bsl::sprintf(fileNameBuffer,
252/// #ifdef BSLS_PLATFORM_OS_UNIX
253/// "/tmp/bdls_FdStreamBuf.usage.2.%d.txt",
254/// #else // windows
255/// "C:\\TEMP\\bdls_FdStreamBuf.usage.2.%d.txt",
256/// #endif
257/// bdls::ProcessUtil::getProcessId());
258/// @endcode
259/// Then, make sure the file does not already exist:
260/// @code
261/// bdls::FilesystemUtil::remove(fileNameBuffer);
262/// assert(false == bdls::FilesystemUtil::exists(fileNameBuffer));
263/// @endcode
264/// Next, Create the file and open a file descriptor to it. The boolean
265/// flags indicate that the file is writable, and not previously
266/// existing (and therefore must be created):
267/// @code
268/// typedef bdls::FilesystemUtil::FileDescriptor FdType;
269///
270/// FdType fd = bdls::FilesystemUtil::open(fileNameBuffer,
271/// bdls::FilesystemUtil::e_CREATE,
272/// bdls::FilesystemUtil::e_READ_WRITE);
273/// assert(bdls::FilesystemUtil::k_INVALID_FD != fd);
274/// @endcode
275/// Now, we create a `bdls::FdStreamBuf` object named `streamBuffer`
276/// associated with the file descriptor `fd`. Note that `streamBuffer`
277/// defaults to assuming ownership of `fd`, meaning that when
278/// `streamBuffer` is cleared, reset, or destroyed, `fd` will be closed.
279/// Note that `FdStreamBuf` implements `streambuf`, which provides the
280/// public methods used in this example:
281/// @code
282/// bdls::FdStreamBuf streamBuffer(fd, true);
283///
284/// assert(streamBuffer.fileDescriptor() == fd);
285/// assert(streamBuffer.isOpened());
286/// @endcode
287/// Next we use the `sputn` method to write two lines to the file:
288/// @code
289/// streamBuffer.sputn(line1, lengthLine1);
290/// streamBuffer.sputn(line2, lengthLine2);
291/// @endcode
292/// Then we seek back to the start of the file.
293/// @code
294/// bsl::streamoff status = streamBuffer.pubseekpos(0);
295/// assert(0 == status);
296/// @endcode
297/// Next, we read the first `lengthLine1` characters of the file
298/// into `buf`, with the method `sgetn`.
299/// @code
300/// char buf[1000];
301/// bsl::memset(buf, 0, sizeof(buf));
302/// status = streamBuffer.sgetn(buf, lengthLine1);
303/// assert(lengthLine1 == status);
304/// assert(!bsl::strcmp(line1, buf));
305/// @endcode
306/// Next we try to read `2 * lengthLine2` characters when only
307/// `lengthLine2` characters are available in the file to read, so
308/// the `sgetn` method will stop after reading `lengthLine2` characters.
309/// The `sgetn` method will return the number of chars successfully
310/// read:
311/// @code
312/// bsl::memset(buf, 0, sizeof(buf));
313/// status = streamBuffer.sgetn(buf, 2 * lengthLine2);
314/// assert(lengthLine2 == status);
315/// assert(!bsl::strcmp(line2, buf));
316/// @endcode
317/// Trying to read past the end of the file invalidated the current
318/// cursor position in the file, so we must seek from the end or the
319/// beginning of the file in order to establish a new cursor position.
320/// Note the `pubseekpos` method always seeks relative to the beginning.
321/// We seek back to the start of the file:
322/// @code
323/// status = streamBuffer.pubseekpos(0);
324/// assert(0 == status);
325/// @endcode
326/// Note that line1 and line3 are the same length:
327/// @code
328/// assert(lengthLine1 == lengthLine3);
329/// @endcode
330/// Then we write, replacing `line1` in the file with `line3`:
331/// @code
332/// status = streamBuffer.sputn(line3, lengthLine3);
333/// assert(lengthLine3 == status);
334/// @endcode
335/// Now we seek back to the beginning of the file:
336/// @code
337/// status = streamBuffer.pubseekpos(0);
338/// @endcode
339/// Next we verify we were returned to the start of the file:
340/// @code
341/// assert(0 == status);
342/// @endcode
343/// Then we read and verify the first line, which now contains the text
344/// of `line3`:
345/// @code
346/// bsl::memset(buf, 0, sizeof(buf));
347/// status = streamBuffer.sgetn(buf, lengthLine3);
348/// assert(lengthLine3 == status);
349/// assert(!bsl::strcmp(line3, buf));
350/// @endcode
351/// Now we read and verify the second line, still `line2`:
352/// @code
353/// bsl::memset(buf, 0, sizeof(buf));
354/// status = streamBuffer.sgetn(buf, lengthLine2);
355/// assert(lengthLine2 == status);
356/// assert(!bsl::strcmp(line2, buf));
357/// @endcode
358/// Next we close `fd` and disconnect `streamBuffer` from `fd`:
359/// @code
360/// status = streamBuffer.clear();
361/// assert(0 == status);
362/// @endcode
363/// Note that `streamBuffer` is now no longer open, and is not
364/// associated with a file descriptor:
365/// @code
366/// assert(!streamBuffer.isOpened());
367/// assert(bdls::FilesystemUtil::k_INVALID_FD ==
368/// streamBuffer.fileDescriptor());
369/// @endcode
370/// Finally, we clean up the file:
371/// @code
372/// bdls::FilesystemUtil::remove(fileNameBuffer);
373/// @endcode
374/// @}
375/** @} */
376/** @} */
377
378/** @addtogroup bdl
379 * @{
380 */
381/** @addtogroup bdls
382 * @{
383 */
384/** @addtogroup bdls_fdstreambuf
385 * @{
386 */
387
388#include <bdlscm_version.h>
389
390#include <bdls_filesystemutil.h>
391
392#include <bslma_allocator.h>
393
394#include <bsls_assert.h>
396#include <bsls_keyword.h>
397#include <bsls_platform.h>
398#include <bsls_review.h>
399#include <bsls_types.h>
400
401#include <bsl_algorithm.h>
402#include <bsl_cstddef.h>
403#include <bsl_cstring.h> // 'size_t'
404#include <bsl_ios.h>
405#include <bsl_iosfwd.h>
406#include <bsl_locale.h>
407#include <bsl_streambuf.h> // 'char_type', 'int_type', 'pos_type', 'off_type',
408 // @ref traits_type are within the 'bsl::streambuf'
409 // class
410
411
412namespace bdls {
413
414 // ====================================
415 // helper class FdStreamBuf_FileHandler
416 // ====================================
417
418/// This private helper class isolates direct operations on files from the
419/// `FdStreamBuf` class; it is a thin wrapper around `FilesystemUtil`. One
420/// service this class provides is converting between an in-process `\n` and
421/// its corresponding on-file `\r\n` when writing to or reading from a
422/// Windows text file. On `reset` an object of this type is associated with
423/// a supplied file descriptor, after which it can do simple operations on
424/// that file descriptor in the service of a `FdStreamBuf`.
425///
426/// See @ref bdls_fdstreambuf
428
429 private:
430 // CLASS DATA
431 static bsls::AtomicOperations::AtomicTypes::Int
432 s_pageSize; // page size associated with this operating
433 // system
434
435 // DATA
436 FilesystemUtil::FileDescriptor
437 d_fileId; // file descriptor, which is owned if
438 // `d_willCloseOnResetFlag` is `true`,
439 // otherwise not owned
440
441 bool d_openedFlag; // `true` if this object is associated with
442 // a valid file descriptor, and `false`
443 // otherwise
444
445 bool d_regularFileFlag; // `true` if the file descriptor represents
446 // a plain file (and not a directory or
447 // other device), and `false` otherwise
448
449 bsl::ios_base::openmode
450 d_openModeFlags; // `ios_base`-style flags with which the
451 // file or device was opened
452
453 bool d_willCloseOnResetFlag; // `true` if the file descriptor should be
454 // closed when this file handler is reset,
455 // cleared or destroyed, and `false`
456 // otherwise
457
458 char d_peekBuffer; // buffer used when looking one byte ahead
459 // to complete a `\r\n` in text mode
460
461 bool d_peekBufferFlag; // `true` if peek buffer contains a
462 // character, `false` otherwise. Note this
463 // is never true on Unix or in binary mode
464 // on Windows.
465
466 private:
467 // PRIVATE MANIPULATORS
468#ifdef BSLS_PLATFORM_OS_WINDOWS
469 /// Write the specified `numChars` characters from the specified
470 /// `buffer` to this object's file descriptor. Return the number of
471 /// characters successfully written on success, and a negative value
472 /// otherwise. Note that `\n`s in the specified `buffer` will be
473 /// translated to `\r\n` sequences on output. Also note that this
474 /// method does not exist and is not called except on Windows.
475 int windowsWriteText(const char *buffer, int numChars);
476#endif
477
478 private:
479 // NOT IMPLEMENTED
482
483 public:
484 // CLASS METHODS
485
486 /// Return the operating system's page size.
487 static bsl::size_t pageSize();
488
489 // CREATORS
490
491 /// Create a file handler that is not associated with any file descriptor.
492 /// Note that `isOpened` will be `false` on the newly created object.
494
495 /// Destroy this file handler. If `willCloseOnReset` is `true`, close any
496 /// file descriptor associated with this object.
498
499 // MANIPULATORS
500
501 /// Associate this object with the specified `fileDescriptor`, and record
502 /// the state of the specified `writableFlag` which, if `true`, indicates
503 /// that the `fileDescriptor` is writable, otherwise it is not. Before
504 /// making this association, if, prior to this call, `willCloseOnReset` is
505 /// true, close any file descriptor previously associated with this object,
506 /// otherwise leave it open but disassociate this object from it. The
507 /// optionally specified `willCloseOnResetFlag` will set
508 /// `willCloseOnReset`, which, if `true`, indicates that `fileDescriptor`
509 /// is to be closed when this object is cleared, reset, or destroyed,
510 /// otherwise no action will be taken on `fileDescriptor` at that time.
511 /// Optionally specify a `binaryModeFlag`, which is ignored on Unix; if
512 /// `false` on Windows, it indicates that `\n`s internally are to be
513 /// translated to and from `\r\n` sequences on the device; on Unix or if
514 /// `binaryModeFlag` is `true` no such translation is to occur. Return 0
515 /// on success, and a non-zero value otherwise. Note that if
516 /// `FilesystemUtil::k_INVALID_FD` is passed as `fileDescriptor`, no file
517 /// descriptor is to be associated with this object. Also note that the
518 /// state of `fileDescriptor` is unchanged by this call, there is no
519 /// implicit seek.
520 int reset(FilesystemUtil::FileDescriptor fileDescriptor,
521 bool writableFlag,
522 bool willCloseOnResetFlag = true,
523 bool binaryModeFlag = false);
524
525 /// Disassociate this file handler from any file descriptor with which it
526 /// may be associated without closing that file descriptor. This method
527 /// succeeds with no effect if `isOpened` was `false`. Note that
528 /// `fileDescriptor` is `FilesystemUtil::k_INVALID_FD` after this call.
529 void release();
530
531 /// Release any file descriptor that may be associated with this file
532 /// handler. If `isOpened` and `willCloseOnReset` are both `true`, the
533 /// file descriptor will be closed, otherwise it will be left unchanged.
534 /// Return 0 on success and a non-zero value if the close fails. This
535 /// method succeeds with no effect if `isOpened` was `false`. Note that
536 /// `fileDescriptor` is always `FilesystemUtil::k_INVALID_FD` after this
537 /// call.
538 int clear();
539
540 /// Read the specified `numBytes` bytes from the current position of the
541 /// file descriptor into the specified `buffer`. Return the number of
542 /// characters successfully read. The behavior is undefined unless
543 /// `0 <= numBytes` and `buffer` is at least `numBytes` long. Note that
544 /// on Windows in text mode, `\r\n` is read as a single character and
545 /// stored in the buffer as `\n`.
546 int read(char *buffer, int numBytes);
547
548 /// Write the specified `buffer`, containing the specified `numBytes`, to
549 /// the file descriptor starting at the current position. Return 0 on
550 /// success, and a non-zero value otherwise. The behavior is undefined
551 /// unless `0 <= numBytes`. Note that on Windows in text mode, a `\n` is
552 /// written as `\r\n` and counts as one character.
553 int write(const char *buffer, int numBytes);
554
555 /// Set the file position associated with this object according to the
556 /// specified `offset` and `dir` behavior.
557 ///
558 /// * If 'dir' is 'FilesystemUtil::e_SEEK_FROM_BEGINNING', set the
559 /// position to 'offset' bytes from the beginning of the file.
560 /// * If 'dir' is 'FilesystemUtil::e_SEEK_FROM_CURRENT', advance the
561 /// position by 'offset' bytes
562 /// * If 'dir' is 'FilesystemUtil::e_SEEK_FROM_END', set the position
563 /// to 'offset' bytes beyond the end of the file.
564 ///
565 /// Return the new location of the file position, in bytes from the
566 /// beginning of the file on success; and `FilesystemUtil::k_INVALID_FD`
567 /// otherwise. The effect on the file position is undefined unless the
568 /// file descriptor represents a device capable of seeking. Note that
569 /// `seek` does not change the size of the file if the position advances
570 /// beyond the end of the file; instead, the next write at the pointer
571 /// will increase the file size. Also note that on Windows in text
572 /// mode, `offset` will be the number of bytes on disk passed over,
573 /// including `\r`s in `\r\n` sequences.
574 bsl::streampos seek(bsl::streamoff offset, FilesystemUtil::Whence dir);
575
576 /// Map to memory a section of the file starting at the specified
577 /// `offset` from the start of the file and return a pointer to that
578 /// memory. The section mapped is to be of the specified `length`.
579 /// The behavior is undefined unless `offset` is a multiple of
580 /// `pageSize`. Note that the memory is mapped for readonly access.
581 void *mmap(bsl::streamoff offset, bsl::streamoff length);
582
583 /// Unmap the section of memory beginning at the specified
584 /// `mappedMemory`, having the specified `length`. The behavior is
585 /// undefined unless `mappedMemory` is an address returned by a previous
586 /// call to the `mmap` method and `length` was the `length` specified in
587 /// that call.
588 void unmap(void *mappedMemory, bsl::streamoff length);
589
590 /// Set `willCloseOnReset` (the flag determining whether this file
591 /// handler will close the file descriptor on the next reset, clear, or
592 /// destruction) to the specified `booleanValue`. If `willCloseOnReset`
593 /// is `true`, the next reset, clear, or destruction will result in the
594 /// file descriptor being closed, otherwise, it will remain open.
595 void setWillCloseOnReset(bool booleanValue);
596
597 // ACCESSORS
598
599 /// Return the file descriptor associated with this object, if `isOpened`
600 /// is `true`, and -1 otherwise.
601 FilesystemUtil::FileDescriptor fileDescriptor() const;
602
603 /// Return the size of the file associated with this file handler, or 0 if
604 /// it is associated with a device other than a regular file (e.g., a
605 /// device or directory).
606 bsl::streamoff fileSize() const;
607
608 /// Return the number of bytes that the data in the range specified by
609 /// `[first, last)` will fill when written to the file descriptor. Note
610 /// that on Unix, or for a binary file on Windows, this value will be
611 /// `last - first`, but for on Windows in text mode, extra bytes are
612 /// added when `\n` would be written to the file descriptor as `\r\n`.
613 bsl::streamoff getOffset(char *first, char *last) const;
614
615 /// Return `false` if on Windows and the file is opened in text mode, and
616 /// `true` otherwise.
617 bool isInBinaryMode() const;
618
619 /// Return `true` if this file handler is currently associated with a file
620 /// descriptor, and `false` otherwise.
621 bool isOpened() const;
622
623 /// Return `true` if the file descriptor associated with this file handler
624 /// is associated with a regular file and `false` otherwise. Note that
625 /// directories and pipes are not regular files.
626 bool isRegularFile() const;
627
628 /// Return the `bsl::ios_base` mode bits corresponding to this file
629 /// handler. Note that this will be a union (bitwise-OR) of a subset of
630 /// the `bsl::ios_base` constants `in`, `out`, and `binary`.
631 int openMode() const;
632
633 /// Return `true` if the associated file descriptor will be closed the next
634 /// time this file handler is reset, cleared, or destroyed, and `false`
635 /// otherwise. Note that this value is determined by the value of
636 /// `willCloseOnResetFlag` that was passed to the most recent call to
637 /// `reset` or `setWillCloseOnReset`.
638 bool willCloseOnReset() const;
639};
640
641 // =================
642 // class FdStreamBuf
643 // =================
644
645/// This class, derived from the C++ standard library class `bsl::streambuf`,
646/// is a mechanism that can be associated with an opened file descriptor, and,
647/// except for changing the locale, enables the caller to invoke all the
648/// standard `bsl::streambuf` operations on that file descriptor. Note that
649/// objects of this class are always in exactly one of the 5 modes outlined in
650/// the enum `FdStreamBuf::FdStreamBufMode`.
651///
652/// See @ref bdls_fdstreambuf
653class FdStreamBuf : public bsl::streambuf {
654
655 private:
656 // PRIVATE TYPES
657 enum { k_PBACK_BUF_SIZE = 8 }; // size of d_pBackBuf
658
659 enum FdStreamBufMode {
660 e_NULL_MODE = 0, // empty state, when not in any other mode;
661 // the object is constructed in this state
662
663 e_INPUT_MODE = 1, // doing input
664
665 e_INPUT_PUTBACK_MODE = 2, // input putback mode is a form of input
666 // mode where chars that have been stuffed
667 // back into the input buffer are kept in
668 // `d_pBackBuf`.
669
670 e_OUTPUT_MODE = 3, // doing output
671
672 e_ERROR_MODE = 4 // An error has occurred. Note that error
673 // mode is sticky -- subsequent I/O won't
674 // work until error mode is cleared by a
675 // `reset` or a seek.
676 };
677
678 private:
679 // DATA
680 // data members used in all modes
681
683 d_fileHandler; // file handler, holds the file
684 // descriptor, used for doing low
685 // level operations on the file
686 // descriptor
687
688 // mode information
689
690 FdStreamBufMode d_mode;
691
692 bool d_dynamicBufferFlag;// `true` if the buffer `d_buf_p` is
693 // heap allocated, `false` if it was
694 // supplied by the user.
695
696 // putback buffer
697
698 char d_pBackBuf[k_PBACK_BUF_SIZE];
699 // for putback mode (see above)
700
701 // input/output buffer
702
703 char *d_buf_p; // buffer
704 char *d_bufEOS_p; // end of buffer space, allocated or
705 // otherwise
706 char *d_bufEnd_p; // end of data that's been read in
707 // input mode, not used in output
708 // mode.
709
710 // data members saved when entering putback mode --
711 // these elements are for saving fields from the base
712 // class while we are in putback mode
713
714 char *d_savedEback_p; // saved value of `eback`
715 char *d_savedGptr_p; // saved value of `gptr`
716 char *d_savedEgptr_p; // saved value of `egptr`
717
718 // fields relevant to mapping the file while in input
719 // mode
720
721 char *d_mmapBase_p; // pointer to the `mmap`ed input
722 // area, 0 if we are not in `mmap`
723 // input mode
724
725 bsl::streamoff d_mmapLen; // length of mapped area
726
727 // memory allocator
728
729 bslma::Allocator *d_allocator_p; // allocator (held, not owned)
730
731 private:
732 // PRIVATE MANIPULATORS
733
734 /// Exit putback mode (leaving this object in input mode) and restore the
735 /// get buffer to the state it was in just prior to entering putback mode.
736 /// The behavior is undefined unless this object is in putback mode.
737 void exitPutbackMode();
738
739 /// Switch this object to input mode. Return 0 on success, and a non-zero
740 /// value otherwise. If this method is called while in input putback mode,
741 /// exit input putback mode. Note that this function is called when doing
742 /// the first input, after a seek, or after writing. Also note that this
743 /// method has no effect if called when this object is in input mode.
744 int switchToInputMode();
745
746 /// Change from input mode to null mode. If the specified `correctSeek` is
747 /// `true`, seek to position the file pointer at the point from which the
748 /// next input would have come; otherwise don't do the seek. If the input
749 /// file is currently mapped, unmap it. Return 0 on success, and non-zero
750 /// otherwise. The behavior is undefined unless this object is in input or
751 /// input_putback mode. Note that performing a corrective seek corrects
752 /// the discrepancy between the client's perception of the file pointer
753 /// location and the actual file pointer location, caused by buffering.
754 int exitInputMode(bool correctSeek);
755
756 /// Switch this object to output mode. Return 0 on success, and a non-zero
757 /// value otherwise. Note that this method has no effect if this object is
758 /// already in output mode. Also note that this method is called when
759 /// performing the first output, or when performing the first output after
760 /// a seek or read.
761 int switchToOutputMode();
762
763 /// Use `read` to get some data from the file descriptor, and add it to the
764 /// input buffer. Return the first character of input. Note that this
765 /// method is called only by `underflow`, and only as a last resort, when
766 /// additional data can't be provided by mapping.
767 int underflowRead();
768
769 /// Put this object into error mode, clearing the get area. Always return
770 /// `traits_type::eof()`. Note that error mode is sticky and is cleared
771 /// only by a `reset`, `clear` or seek.
772 int inputError();
773
774 /// Put this object into error mode, clearing the put area. Always return
775 /// `traits_type::eof()`. Note that error mode is sticky and is cleared
776 /// only by a `reset`, `clear`, `seekoff`, or `seekpos`.
777 int outputError();
778
779 /// Set the buffer to be used by this object. If the specified `buffer` is
780 /// 0, dynamically allocate a buffer of specified `numBytes` length, or if
781 /// `buffer` is a non-zero value, use the first `numBytes` bytes of
782 /// `buffer`. Return 0 on success, and a non-zero value otherwise. The
783 /// behavior is undefined unless `1 <= numBytes`, `buffer` (if non-zero) is
784 /// at least `numBytes` long, a buffer has not previously been allocated or
785 /// provided, and no I/O has occurred prior to this call.
786 int allocateBuffer(char *buffer, int numBytes);
787
788 /// Dynamically allocate an input/output buffer of a default size. Return
789 /// 0 on success, and a non-zero value otherwise. The behavior is
790 /// undefined unless no buffer has previously been allocated or provided,
791 /// and no I/O has occurred prior to this call.
792 int allocateBuffer();
793
794 /// If the buffer is dynamically allocated by `allocateBuffer`, free it.
795 /// The behavior is undefined unless the buffer was previously allocated or
796 /// provided.
797 void deallocateBuffer();
798
799 /// Prepare this `FdStreamBuf` for a subsequent seek operation by setting
800 /// various mode information into an appropriate state. If in output mode,
801 /// flush the buffer. If in putback input mode or error mode, exit that
802 /// mode. If in regular input mode, leave that mode unaffected. Return 0
803 /// on success, and a non-zero value otherwise.
804 int seekInit();
805
806 /// Finish a seek by putting this object into null mode and nulling out
807 /// pointers to the buffer to reflect the fact that a seek has occurred.
808 /// Return the specified `offset` on success, and a negative value
809 /// otherwise.
810 pos_type seekReturn(pos_type offset);
811
812 /// Flush any output data to the file descriptor, and reset the state of
813 /// this object. Return 0 on success, and a non-zero value otherwise.
814 int flush();
815
816 protected:
817 // PROTECTED MEMBER FUNCTIONS
818
819 // The following member functions override protected virtual functions
820 // inherited from the base class, and are specified to be protected as part
821 // of the standard library 'bsl::streambuf' interface.
822
823 // PROTECTED MANIPULATORS
824
825 /// Replenish the input buffer with data obtained from the file descriptor,
826 /// and return the next character of input (or eof if no input is
827 /// available). Note that in windows text mode, `\r\n` sequences on the
828 /// device will be translated to `\n`s.
830
831 /// If the optionally specified `c` is not given, move the current input
832 /// position back one character and return the character at that
833 /// position. Otherwise specify a value for `c` other than
834 /// `traits_type::eof`. If `c` is equal to the previous character in
835 /// the read buffer, the behavior is the same as if `eof()` was passed.
836 /// If `c` is not eof and is not equal to the previous character in the
837 /// putback buffer push the character `c` is back into the input buffer,
838 /// if possible. Return the backed up character on success and
839 /// `traits_type::eof()` otherwise. If the input buffer is readonly, or
840 /// `gptr()` is already at the beginning of the input buffer, this
841 /// object enters `INPUT_PUTBACK_MODE` and `c` is stuffed back into the
842 /// putback buffer. Note that only `PBACK_BUF_SIZE` characters can be
843 /// backed up into the putback buffer, if this limit is exceeded,
844 /// `traits_type::eof()` will be returned. Also note that this method
845 /// is called by public methods `sputbackc` or `sungetc` in the base
846 /// class, and only when simply decrementing the current position in the
847 /// input buffer won't satisfy the request, either because `c` doesn't
848 /// match the previously input character, or because the input position
849 /// is already at the beginning of the input buffer.
850 int_type pbackfail(int_type c = traits_type::eof()) BSLS_KEYWORD_OVERRIDE;
851
852 /// If in output mode, write the contents of the buffer to output. Return
853 /// `traits_type::eof()` on failure, and any other value on success.
854 /// Optionally specify a character `c` to be appended to the buffer prior
855 /// to the flush. If no character is specified, no character is appended
856 /// to the buffer. If not in output mode, switch to output mode. Note
857 /// that the write will translate `\n`s to `\r\n`s.
858 int_type overflow(int_type c = traits_type::eof()) BSLS_KEYWORD_OVERRIDE;
859
860 /// Use the specified `buffer` of the specified `numBytes` capacity as
861 /// the input/output buffer for this `streambuf`. If `buffer == 0`, the
862 /// buffer is dynamically allocated with a default size. If both
863 /// `buffer` and `numBytes` are zero a 1-byte buffer is dynamically
864 /// allocated. The behavior is undefined if any I/O has preceded this
865 /// call, and unless the buffer is uninitialized before this call.
866 FdStreamBuf *setbuf(char_type *buffer, bsl::streamsize numBytes)
868
869 /// Set the file pointer associated with the file descriptor according
870 /// to the specified `offset` and `whence`:
871 ///
872 /// * If 'whence' is 'bsl::ios_base::beg', set the pointer to 'offset'
873 /// bytes from the beginning of the file.
874 /// * If 'whence' is 'bsl::ios_base::cur', advance the pointer by
875 /// 'offset' bytes
876 /// * If 'whence' is 'bsl::ios_base::end', set the pointer to 'offset'
877 /// bytes beyond the end of the file.
878 ///
879 /// Optionally specify `mode`, which is ignored. Return the new location
880 /// of the file position, in bytes from the beginning of the file, on
881 /// success, and -1 otherwise. The behavior is undefined unless the file
882 /// descriptor is on a device capable of seeking. Note that seeking does
883 /// not change the size of the file if the pointer advances beyond the end
884 /// of the file; instead, the next write at the pointer will increase the
885 /// file size. Also note that seeks are always in terms of bytes on the
886 /// device, meaning that in Windows text mode, seeking past a `\n`
887 /// perceived by the caller will count as 2 bytes since it has to seek over
888 /// a `\r\n` sequence on the device.
889 pos_type seekoff(
890 off_type offset,
891 bsl::ios_base::seekdir whence,
892 bsl::ios_base::openmode mode = bsl::ios_base::in | bsl::ios_base::out)
894
895 /// Seek to the specified `offset` relative to the beginning of the file.
896 /// Return the resulting absolute position in the file relative to the
897 /// beginning. Optionally specify `mode` which is ignored. Also note that
898 /// seeks are always in terms of bytes on the device, meaning that on a
899 /// Windows text file, seeking past a `\r\n` sequence on the disk will
900 /// count as two bytes, though if it is read in it will be a single `\n`
901 /// byte.
902 pos_type seekpos(
903 pos_type offset,
904 bsl::ios_base::openmode mode = bsl::ios_base::in | bsl::ios_base::out)
906
907 /// If in output mode, flush the buffer to the associated file descriptor;
908 /// otherwise do nothing. Return 0 on success, -1 otherwise.
910
911 /// Set the locale for this object. This method has no effect. The
912 /// behavior is undefined unless the specified `locale` is the same as
913 /// `bsl::locale()`.
914 void imbue(const bsl::locale& locale) BSLS_KEYWORD_OVERRIDE;
915
916 /// If this object is in putback mode, return the number of characters
917 /// remaining to be read in the putback buffer, and otherwise the
918 /// number of characters remaining in the file to be read. Return a
919 /// non-negative number of characters on success and a negative value
920 /// otherwise. The behavior is undefined unless this object is in input
921 /// mode and the file descriptor is associated with a regular file.
923
924 /// Read up to the specified `numBytes` characters from the file
925 /// descriptor into the specified `buffer` and return the number of
926 /// characters successfully read. The behavior is undefined unless
927 /// `buffer` is at least `numBytes` bytes long. Note that on a Windows
928 /// text file, a `\r\n` in the file will be read as `\n` (counting as a
929 /// single character).
930 bsl::streamsize xsgetn(char *buffer, bsl::streamsize numBytes)
932
933 /// Write up to the specified `numBytes` characters from the specified
934 /// `buffer` and return the number of characters successfully written.
935 /// Note that this method does not necessarily modify the file: this method
936 /// may simply write the characters to a buffer to be flushed to the file
937 /// at a later time. Also note that on a Windows text file, a `\n` will be
938 /// written to the file as `\r\n` (counted as a single character).
939 bsl::streamsize xsputn(const char *buffer,
940 bsl::streamsize numBytes) BSLS_KEYWORD_OVERRIDE;
941
942 private:
943 // NOT IMPLEMENTED
944 FdStreamBuf( const FdStreamBuf&);
945 FdStreamBuf& operator=(const FdStreamBuf&);
946
947 public:
948 // CREATORS
949
950 /// Create a `FdStreamBuf` associated with the specified
951 /// `fileDescriptor` that refers to an already opened file or device,
952 /// and specify `writableFlag` which, if `true`, indicates that
953 /// `fileDescriptor` is writable, otherwise it is not. The optionally
954 /// specified `willCloseOnResetFlag`, if `true`, indicates that
955 /// `fileDescriptor` is to be closed the next time this object is reset,
956 /// cleared or destroyed, or if `false` the file descriptor is to be
957 /// left open. Optionally specify a `binaryModeFlag` which is ignored
958 /// on Unix; if `false` on Windows, it indicates that `\n`s are to be
959 /// translated to and from `\r\n` sequences on the device. Optionally
960 /// specify a `basicAllocator` used to supply memory. If
961 /// `basicAllocator` is 0, the currently installed default allocator is
962 /// used. Note that if `FilesystemUtil::k_INVALID_FD` is passed to
963 /// `fileDescriptor`, no file descriptor is to be associated with this
964 /// object. Also note that the state of the `fileDescriptor` is
965 /// unchanged by this call (i.e., there is no implicit seek).
966 explicit FdStreamBuf(
967 FilesystemUtil::FileDescriptor fileDescriptor,
968 bool writableFlag,
969 bool willCloseOnResetFlag = true,
970 bool binaryModeFlag = false,
971 bslma::Allocator *basicAllocator = 0);
972
973 /// Destroy this object and, if `willCloseOnReset` is `true`, close the
974 /// file descriptor associated with this object, if any.
976
977 // MANIPULATORS
978
979 /// Associate this object with the specified `fileDescriptor`, and
980 /// record the state of the specified `writableFlag` which, if `true`,
981 /// indicates that `fileDescriptor` is writable, otherwise it is not.
982 /// Before making this association, if, prior to this call,
983 /// `willCloseOnReset` is true, close any file descriptor previously
984 /// associated with this object, otherwise leave it open but
985 /// disassociate this object from it. The Optionally specified
986 /// `willCloseOnResetFlag` which will set `willCloseOnReset`, which, if
987 /// `true`, indicates that the specified file descriptor is to be closed
988 /// when this object is cleared, reset, or destroyed, otherwise no
989 /// action will be taken on `fileDescriptor` at that time. Optionally
990 /// specify a `binaryModeFlag`, which is ignored on Unix; if `false` on
991 /// Windows, it indicates that `\n`s internally are to be translated to
992 /// and from `\r\n` sequences on the device; on Unix or if
993 /// `binaryModeFlag` is `true` no such translation is to occur. Return
994 /// 0 on success, and a non-zero value otherwise. Note that if
995 /// `FilesystemUtil::k_INVALID_FD` is passed as `fileDescriptor`, no
996 /// file descriptor is to be associated with this object. Also note
997 /// that the state of the `fileDescriptor` is unchanged by this call,
998 /// there is no implicit seek.
999 int reset(FilesystemUtil::FileDescriptor fileDescriptor,
1000 bool writableFlag,
1001 bool willCloseOnResetFlag = true,
1002 bool binaryModeFlag = false);
1003
1004 /// Disassociate this file handler from any file descriptor with which
1005 /// it may be associated without closing that file descriptor. This
1006 /// method succeeds with no effect is `isOpened` was false. Note that
1007 /// `fileDescriptor` is `FilesystemUtil::k_INVALID_FD` after this call.
1008 void release();
1009
1010 /// Release any file descriptor that may be associated with this file
1011 /// handler. If `isOpened` and `willCloseOnReset` are both `true`, the
1012 /// file descriptor will be closed, otherwise it will not. Return 0 on
1013 /// success, and a non-zero value if the close fails. This method
1014 /// succeeds with no effect if `isOpened` was false. Note that
1015 /// `fileDescriptor` is `FilesystemUtil::k_INVALID_FD` after this call.
1016 int clear();
1017
1018 // ACCESSORS
1019
1020 /// Return the file descriptor associated with this object, or
1021 /// `FilesystemUtil::k_INVALID_FD` if this object is not currently
1022 /// associated with a file descriptor.
1023 FilesystemUtil::FileDescriptor fileDescriptor() const;
1024
1025 /// Return `true` if this object is currently associated with a file
1026 /// descriptor, and `false` otherwise.
1027 bool isOpened() const;
1028
1029 /// Return `true` if this object will close the associated file descriptor
1030 /// the next time it is reset, cleared, or destroyed, and `false`
1031 /// otherwise.
1032 bool willCloseOnReset() const;
1033};
1034
1035// ============================================================================
1036// INLINE DEFINITIONS
1037// ============================================================================
1038
1039 // -----------------------------
1040 // class FdStreamBuf_FileHandler
1041 // -----------------------------
1042
1043// CLASS METHODS
1044inline
1045size_t FdStreamBuf_FileHandler::pageSize()
1046{
1047 return bsls::AtomicOperations::getIntRelaxed(&s_pageSize);
1048}
1049
1050// MANIPULATORS
1051inline
1053{
1054 d_willCloseOnResetFlag = false;
1056}
1057
1058inline
1063
1064inline
1066{
1067 d_willCloseOnResetFlag = booleanValue;
1068}
1069
1070inline
1071bsl::streamoff
1072FdStreamBuf_FileHandler::getOffset(char *first, char *last) const
1073{
1074 BSLS_ASSERT(first <= last);
1075
1076 return d_openModeFlags & bsl::ios_base::binary
1077 ? last - first
1078 : bsl::count(first, last, '\n') + last - first;
1079}
1080
1081inline
1083{
1084#if defined(BSLS_PLATFORM_OS_UNIX)
1085 return true;
1086# else
1087 // Windows
1088
1089 return (d_openModeFlags & bsl::ios_base::binary) != 0;
1090# endif
1091}
1092
1093inline
1095{
1096 return d_openedFlag;
1097}
1098
1099inline
1101{
1102 return d_regularFileFlag;
1103}
1104
1105inline
1107{
1108 return (int) d_openModeFlags;
1109}
1110
1111inline
1113{
1114 return d_willCloseOnResetFlag;
1115}
1116
1117inline
1118FilesystemUtil::FileDescriptor
1120{
1121 return d_fileId;
1122}
1123
1124 // -----------------
1125 // class FdStreamBuf
1126 // -----------------
1127
1128// PRIVATE MANIPULATORS
1129inline
1130void FdStreamBuf::exitPutbackMode()
1131{
1132 setg(d_savedEback_p, d_savedGptr_p, d_savedEgptr_p);
1133 d_mode = e_INPUT_MODE;
1134}
1135
1136/// Only called by `seekoff` and `seekpos`, returns the value about to be
1137/// returned by the calling routine.
1138inline
1139FdStreamBuf::pos_type
1140FdStreamBuf::seekReturn(pos_type offset)
1141{
1142 if (e_INPUT_MODE == d_mode || e_INPUT_PUTBACK_MODE == d_mode) {
1143 if (0 != exitInputMode(false)) {
1144 // error
1145
1146 return (pos_type) - 1; // RETURN
1147 }
1148 }
1149 setg(0, 0, 0);
1150 setp(0, 0);
1151
1152 d_mode = e_NULL_MODE;
1153
1154 return offset;
1155}
1156
1157// MANIPULATORS
1158inline
1159int FdStreamBuf::reset(FilesystemUtil::FileDescriptor fileDescriptor,
1160 bool writableFlag,
1161 bool willCloseOnResetFlag,
1162 bool binaryModeFlag)
1163{
1164 bool ok = 0 == flush();
1165
1167 // note we reset() whether flush succeeded or not
1168
1169 ok &= (0 == d_fileHandler.reset(fileDescriptor,
1170 writableFlag,
1171 willCloseOnResetFlag,
1172 binaryModeFlag));
1173 }
1174
1175 return ok ? 0 : -1;
1176}
1177
1178inline
1180{
1181 d_fileHandler.setWillCloseOnReset(false);
1183}
1184
1185inline
1187{
1188 return reset(FilesystemUtil::k_INVALID_FD, false);
1189}
1190
1191// ACCESSORS
1192inline
1193FilesystemUtil::FileDescriptor FdStreamBuf::fileDescriptor() const
1194{
1195 return d_fileHandler.fileDescriptor();
1196}
1197
1198inline
1200{
1201 return d_fileHandler.isOpened();
1202}
1203
1204inline
1206{
1207 return d_fileHandler.willCloseOnReset();
1208}
1209
1210} // close package namespace
1211
1212
1213#endif
1214
1215// ----------------------------------------------------------------------------
1216// Copyright 2015 Bloomberg Finance L.P.
1217//
1218// Licensed under the Apache License, Version 2.0 (the "License");
1219// you may not use this file except in compliance with the License.
1220// You may obtain a copy of the License at
1221//
1222// http://www.apache.org/licenses/LICENSE-2.0
1223//
1224// Unless required by applicable law or agreed to in writing, software
1225// distributed under the License is distributed on an "AS IS" BASIS,
1226// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1227// See the License for the specific language governing permissions and
1228// limitations under the License.
1229// ----------------------------- END-OF-FILE ----------------------------------
1230
1231/** @} */
1232/** @} */
1233/** @} */
Definition bdls_fdstreambuf.h:427
FilesystemUtil::FileDescriptor fileDescriptor() const
Definition bdls_fdstreambuf.h:1119
static bsl::size_t pageSize()
Return the operating system's page size.
Definition bdls_fdstreambuf.h:1045
bool isInBinaryMode() const
Definition bdls_fdstreambuf.h:1082
int openMode() const
Definition bdls_fdstreambuf.h:1106
void setWillCloseOnReset(bool booleanValue)
Definition bdls_fdstreambuf.h:1065
int reset(FilesystemUtil::FileDescriptor fileDescriptor, bool writableFlag, bool willCloseOnResetFlag=true, bool binaryModeFlag=false)
bool isRegularFile() const
Definition bdls_fdstreambuf.h:1100
int write(const char *buffer, int numBytes)
void unmap(void *mappedMemory, bsl::streamoff length)
bsl::streamoff fileSize() const
void release()
Definition bdls_fdstreambuf.h:1052
void * mmap(bsl::streamoff offset, bsl::streamoff length)
bsl::streamoff getOffset(char *first, char *last) const
Definition bdls_fdstreambuf.h:1072
int clear()
Definition bdls_fdstreambuf.h:1059
bsl::streampos seek(bsl::streamoff offset, FilesystemUtil::Whence dir)
int read(char *buffer, int numBytes)
bool willCloseOnReset() const
Definition bdls_fdstreambuf.h:1112
bool isOpened() const
Definition bdls_fdstreambuf.h:1094
Definition bdls_fdstreambuf.h:653
int_type overflow(int_type c=traits_type::eof()) BSLS_KEYWORD_OVERRIDE
bsl::streamsize showmanyc() BSLS_KEYWORD_OVERRIDE
bsl::streamsize xsputn(const char *buffer, bsl::streamsize numBytes) BSLS_KEYWORD_OVERRIDE
bool willCloseOnReset() const
Definition bdls_fdstreambuf.h:1205
int_type pbackfail(int_type c=traits_type::eof()) BSLS_KEYWORD_OVERRIDE
int sync() BSLS_KEYWORD_OVERRIDE
int clear()
Definition bdls_fdstreambuf.h:1186
bool isOpened() const
Definition bdls_fdstreambuf.h:1199
pos_type seekpos(pos_type offset, bsl::ios_base::openmode mode=bsl::ios_base::in|bsl::ios_base::out) BSLS_KEYWORD_OVERRIDE
int_type underflow() BSLS_KEYWORD_OVERRIDE
void imbue(const bsl::locale &locale) BSLS_KEYWORD_OVERRIDE
int reset(FilesystemUtil::FileDescriptor fileDescriptor, bool writableFlag, bool willCloseOnResetFlag=true, bool binaryModeFlag=false)
Definition bdls_fdstreambuf.h:1159
bsl::streamsize xsgetn(char *buffer, bsl::streamsize numBytes) BSLS_KEYWORD_OVERRIDE
FilesystemUtil::FileDescriptor fileDescriptor() const
Definition bdls_fdstreambuf.h:1193
FdStreamBuf * setbuf(char_type *buffer, bsl::streamsize numBytes) BSLS_KEYWORD_OVERRIDE
pos_type seekoff(off_type offset, bsl::ios_base::seekdir whence, bsl::ios_base::openmode mode=bsl::ios_base::in|bsl::ios_base::out) BSLS_KEYWORD_OVERRIDE
void release()
Definition bdls_fdstreambuf.h:1179
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition bdls_fdstreambuf.h:412
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
Definition bdls_filesystemutil.h:362
Whence
Definition bdls_filesystemutil.h:411
static const FileDescriptor k_INVALID_FD
Definition bdls_filesystemutil.h:482
static int getIntRelaxed(AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations.h:1534