BDE 4.39.x 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 otherwise.
472 ///
473 /// \note Note that `\n`s in the specified `buffer` will be
474 /// translated to `\r\n` sequences on output. Also note that this
475 /// method does not exist and is not called except on Windows.
476 int windowsWriteText(const char *buffer, int numChars);
477#endif
478
479 private:
480 // NOT IMPLEMENTED
483
484 public:
485 // CLASS METHODS
486
487 /// Return the operating system's page size.
488 static bsl::size_t pageSize();
489
490 // CREATORS
491
492 /// Create a file handler that is not associated with any file descriptor.
493 ///
494 /// \note Note that `isOpened` will be `false` on the newly created object.
496
497 /// Destroy this file handler. If `willCloseOnReset` is `true`, close any
498 /// file descriptor associated with this object.
500
501 // MANIPULATORS
502
503 /// Associate this object with the specified `fileDescriptor`, and record
504 /// the state of the specified `writableFlag` which, if `true`, indicates
505 /// that the `fileDescriptor` is writable, otherwise it is not. Before
506 /// making this association, if, prior to this call, `willCloseOnReset` is
507 /// true, close any file descriptor previously associated with this object,
508 /// otherwise leave it open but disassociate this object from it. The
509 /// optionally specified `willCloseOnResetFlag` will set
510 /// `willCloseOnReset`, which, if `true`, indicates that `fileDescriptor`
511 /// is to be closed when this object is cleared, reset, or destroyed,
512 /// otherwise no action will be taken on `fileDescriptor` at that time.
513 /// Optionally specify a `binaryModeFlag`, which is ignored on Unix; if
514 /// `false` on Windows, it indicates that `\n`s internally are to be
515 /// translated to and from `\r\n` sequences on the device; on Unix or if
516 /// `binaryModeFlag` is `true` no such translation is to occur. Return 0 on success, and a non-zero value otherwise.
517 ///
518 /// \note Note that if
519 /// `FilesystemUtil::k_INVALID_FD` is passed as `fileDescriptor`, no file
520 /// descriptor is to be associated with this object. Also note that the
521 /// state of `fileDescriptor` is unchanged by this call, there is no
522 /// implicit seek.
523 int reset(FilesystemUtil::FileDescriptor fileDescriptor,
524 bool writableFlag,
525 bool willCloseOnResetFlag = true,
526 bool binaryModeFlag = false);
527
528 /// Disassociate this file handler from any file descriptor with which it
529 /// may be associated without closing that file descriptor. This method
530 /// succeeds with no effect if `isOpened` was `false`.
531 ///
532 /// \note Note that `fileDescriptor` is `FilesystemUtil::k_INVALID_FD` after this call.
533 void release();
534
535 /// Release any file descriptor that may be associated with this file
536 /// handler. If `isOpened` and `willCloseOnReset` are both `true`, the
537 /// file descriptor will be closed, otherwise it will be left unchanged.
538 /// Return 0 on success and a non-zero value if the close fails. This
539 /// method succeeds with no effect if `isOpened` was `false`.
540 ///
541 /// \note Note that `fileDescriptor` is always `FilesystemUtil::k_INVALID_FD` after this
542 /// call.
543 int clear();
544
545 /// Read the specified `numBytes` bytes from the current position of the
546 /// file descriptor into the specified `buffer`. Return the number of characters successfully read.
547 ///
548 /// \pre The behavior is undefined unless
549 /// `0 <= numBytes` and `buffer` is at least `numBytes` long.
550 ///
551 /// \note Note that on Windows in text mode, `\r\n` is read as a single character and
552 /// stored in the buffer as `\n`.
553 int read(char *buffer, int numBytes);
554
555 /// Write the specified `buffer`, containing the specified `numBytes`, to
556 /// the file descriptor starting at the current position. Return 0 on
557 /// success, and a non-zero value otherwise.
558 ///
559 /// \pre The behavior is undefined unless `0 <= numBytes`.
560 /// \note Note that on Windows in text mode, a `\n` is
561 /// written as `\r\n` and counts as one character.
562 int write(const char *buffer, int numBytes);
563
564 /// Set the file position associated with this object according to the
565 /// specified `offset` and `dir` behavior.
566 ///
567 /// * If 'dir' is 'FilesystemUtil::e_SEEK_FROM_BEGINNING', set the
568 /// position to 'offset' bytes from the beginning of the file.
569 /// * If 'dir' is 'FilesystemUtil::e_SEEK_FROM_CURRENT', advance the
570 /// position by 'offset' bytes
571 /// * If 'dir' is 'FilesystemUtil::e_SEEK_FROM_END', set the position
572 /// to 'offset' bytes beyond the end of the file.
573 ///
574 /// Return the new location of the file position, in bytes from the
575 /// beginning of the file on success; and `FilesystemUtil::k_INVALID_FD`
576 /// otherwise. The effect on the file position is undefined unless the
577 /// file descriptor represents a device capable of seeking.
578 ///
579 /// \note Note that `seek` does not change the size of the file if the position advances
580 /// beyond the end of the file; instead, the next write at the pointer
581 /// will increase the file size. Also note that on Windows in text
582 /// mode, `offset` will be the number of bytes on disk passed over,
583 /// including `\r`s in `\r\n` sequences.
584 bsl::streampos seek(bsl::streamoff offset, FilesystemUtil::Whence dir);
585
586 /// Map to memory a section of the file starting at the specified
587 /// `offset` from the start of the file and return a pointer to that
588 /// memory. The section mapped is to be of the specified `length`.
589 ///
590 /// \pre The behavior is undefined unless `offset` is a multiple of `pageSize`.
591 ///
592 /// \note Note that the memory is mapped for readonly access.
593 void *mmap(bsl::streamoff offset, bsl::streamoff length);
594
595 /// Unmap the section of memory beginning at the specified
596 /// `mappedMemory`, having the specified `length`.
597 ///
598 /// \pre The behavior is undefined unless `mappedMemory` is an address returned by a previous
599 /// call to the `mmap` method and `length` was the `length` specified in
600 /// that call.
601 void unmap(void *mappedMemory, bsl::streamoff length);
602
603 /// Set `willCloseOnReset` (the flag determining whether this file
604 /// handler will close the file descriptor on the next reset, clear, or
605 /// destruction) to the specified `booleanValue`. If `willCloseOnReset`
606 /// is `true`, the next reset, clear, or destruction will result in the
607 /// file descriptor being closed, otherwise, it will remain open.
608 void setWillCloseOnReset(bool booleanValue);
609
610 // ACCESSORS
611
612 /// Return the file descriptor associated with this object, if `isOpened`
613 /// is `true`, and -1 otherwise.
614 FilesystemUtil::FileDescriptor fileDescriptor() const;
615
616 /// Return the size of the file associated with this file handler, or 0 if
617 /// it is associated with a device other than a regular file (e.g., a
618 /// device or directory).
619 bsl::streamoff fileSize() const;
620
621 /// Return the number of bytes that the data in the range specified by
622 /// `[first, last)` will fill when written to the file descriptor.
623 ///
624 /// \note Note that on Unix, or for a binary file on Windows, this value will be
625 /// `last - first`, but for on Windows in text mode, extra bytes are
626 /// added when `\n` would be written to the file descriptor as `\r\n`.
627 bsl::streamoff getOffset(char *first, char *last) const;
628
629 /// Return `false` if on Windows and the file is opened in text mode, and
630 /// `true` otherwise.
631 bool isInBinaryMode() const;
632
633 /// Return `true` if this file handler is currently associated with a file
634 /// descriptor, and `false` otherwise.
635 bool isOpened() const;
636
637 /// Return `true` if the file descriptor associated with this file handler
638 /// is associated with a regular file and `false` otherwise.
639 ///
640 /// \note Note that directories and pipes are not regular files.
641 bool isRegularFile() const;
642
643 /// Return the `bsl::ios_base` mode bits corresponding to this file handler.
644 ///
645 /// \note Note that this will be a union (bitwise-OR) of a subset of
646 /// the `bsl::ios_base` constants `in`, `out`, and `binary`.
647 int openMode() const;
648
649 /// Return `true` if the associated file descriptor will be closed the next
650 /// time this file handler is reset, cleared, or destroyed, and `false` otherwise.
651 ///
652 /// \note Note that this value is determined by the value of
653 /// `willCloseOnResetFlag` that was passed to the most recent call to
654 /// `reset` or `setWillCloseOnReset`.
655 bool willCloseOnReset() const;
656};
657
658 // =================
659 // class FdStreamBuf
660 // =================
661
662/// This class, derived from the C++ standard library class `bsl::streambuf`,
663/// is a mechanism that can be associated with an opened file descriptor, and,
664/// except for changing the locale, enables the caller to invoke all the
665/// standard `bsl::streambuf` operations on that file descriptor.
666///
667/// \note Note that objects of this class are always in exactly one of the 5 modes outlined in
668/// the enum `FdStreamBuf::FdStreamBufMode`.
669///
670/// See @ref bdls_fdstreambuf
671class FdStreamBuf : public bsl::streambuf {
672
673 private:
674 // PRIVATE TYPES
675 enum { k_PBACK_BUF_SIZE = 8 }; // size of d_pBackBuf
676
677 enum FdStreamBufMode {
678 e_NULL_MODE = 0, // empty state, when not in any other mode;
679 // the object is constructed in this state
680
681 e_INPUT_MODE = 1, // doing input
682
683 e_INPUT_PUTBACK_MODE = 2, // input putback mode is a form of input
684 // mode where chars that have been stuffed
685 // back into the input buffer are kept in
686 // `d_pBackBuf`.
687
688 e_OUTPUT_MODE = 3, // doing output
689
690 e_ERROR_MODE = 4 // An error has occurred. Note that error
691 // mode is sticky -- subsequent I/O won't
692 // work until error mode is cleared by a
693 // `reset` or a seek.
694 };
695
696 private:
697 // DATA
698 // data members used in all modes
699
701 d_fileHandler; // file handler, holds the file
702 // descriptor, used for doing low
703 // level operations on the file
704 // descriptor
705
706 // mode information
707
708 FdStreamBufMode d_mode;
709
710 bool d_dynamicBufferFlag;// `true` if the buffer `d_buf_p` is
711 // heap allocated, `false` if it was
712 // supplied by the user.
713
714 // putback buffer
715
716 char d_pBackBuf[k_PBACK_BUF_SIZE];
717 // for putback mode (see above)
718
719 // input/output buffer
720
721 char *d_buf_p; // buffer
722 char *d_bufEOS_p; // end of buffer space, allocated or
723 // otherwise
724 char *d_bufEnd_p; // end of data that's been read in
725 // input mode, not used in output
726 // mode.
727
728 // data members saved when entering putback mode --
729 // these elements are for saving fields from the base
730 // class while we are in putback mode
731
732 char *d_savedEback_p; // saved value of `eback`
733 char *d_savedGptr_p; // saved value of `gptr`
734 char *d_savedEgptr_p; // saved value of `egptr`
735
736 // fields relevant to mapping the file while in input
737 // mode
738
739 char *d_mmapBase_p; // pointer to the `mmap`ed input
740 // area, 0 if we are not in `mmap`
741 // input mode
742
743 bsl::streamoff d_mmapLen; // length of mapped area
744
745 // memory allocator
746
747 bslma::Allocator *d_allocator_p; // allocator (held, not owned)
748
749 private:
750 // PRIVATE MANIPULATORS
751
752 /// Exit putback mode (leaving this object in input mode) and restore the
753 /// get buffer to the state it was in just prior to entering putback mode.
754 ///
755 /// \pre The behavior is undefined unless this object is in putback mode.
756 void exitPutbackMode();
757
758 /// Switch this object to input mode. Return 0 on success, and a non-zero
759 /// value otherwise. If this method is called while in input putback mode, exit input putback mode.
760 ///
761 /// \note Note that this function is called when doing
762 /// the first input, after a seek, or after writing. Also note that this
763 /// method has no effect if called when this object is in input mode.
764 int switchToInputMode();
765
766 /// Change from input mode to null mode. If the specified `correctSeek` is
767 /// `true`, seek to position the file pointer at the point from which the
768 /// next input would have come; otherwise don't do the seek. If the input
769 /// file is currently mapped, unmap it. Return 0 on success, and non-zero otherwise.
770 ///
771 /// \pre The behavior is undefined unless this object is in input or input_putback mode.
772 ///
773 /// \note Note that performing a corrective seek corrects
774 /// the discrepancy between the client's perception of the file pointer
775 /// location and the actual file pointer location, caused by buffering.
776 int exitInputMode(bool correctSeek);
777
778 /// Switch this object to output mode. Return 0 on success, and a non-zero value otherwise.
779 ///
780 /// \note Note that this method has no effect if this object is
781 /// already in output mode. Also note that this method is called when
782 /// performing the first output, or when performing the first output after
783 /// a seek or read.
784 int switchToOutputMode();
785
786 /// Use `read` to get some data from the file descriptor, and add it to the input buffer. Return the first character of input.
787 ///
788 /// \note Note that this
789 /// method is called only by `underflow`, and only as a last resort, when
790 /// additional data can't be provided by mapping.
791 int underflowRead();
792
793 /// Put this object into error mode, clearing the get area. Always return `traits_type::eof()`.
794 ///
795 /// \note Note that error mode is sticky and is cleared
796 /// only by a `reset`, `clear` or seek.
797 int inputError();
798
799 /// Put this object into error mode, clearing the put area. Always return `traits_type::eof()`.
800 ///
801 /// \note Note that error mode is sticky and is cleared
802 /// only by a `reset`, `clear`, `seekoff`, or `seekpos`.
803 int outputError();
804
805 /// Set the buffer to be used by this object. If the specified `buffer` is
806 /// 0, dynamically allocate a buffer of specified `numBytes` length, or if
807 /// `buffer` is a non-zero value, use the first `numBytes` bytes of
808 /// `buffer`. Return 0 on success, and a non-zero value otherwise.
809 ///
810 /// \pre The behavior is undefined unless `1 <= numBytes`, `buffer` (if non-zero) is
811 /// at least `numBytes` long, a buffer has not previously been allocated or
812 /// provided, and no I/O has occurred prior to this call.
813 int allocateBuffer(char *buffer, int numBytes);
814
815 /// Dynamically allocate an input/output buffer of a default size. Return
816 /// 0 on success, and a non-zero value otherwise.
817 ///
818 /// \pre The behavior is undefined unless no buffer has previously been allocated or provided,
819 /// and no I/O has occurred prior to this call.
820 int allocateBuffer();
821
822 /// If the buffer is dynamically allocated by `allocateBuffer`, free it.
823 ///
824 /// \pre The behavior is undefined unless the buffer was previously allocated or
825 /// provided.
826 void deallocateBuffer();
827
828 /// Prepare this `FdStreamBuf` for a subsequent seek operation by setting
829 /// various mode information into an appropriate state. If in output mode,
830 /// flush the buffer. If in putback input mode or error mode, exit that
831 /// mode. If in regular input mode, leave that mode unaffected. Return 0
832 /// on success, and a non-zero value otherwise.
833 int seekInit();
834
835 /// Finish a seek by putting this object into null mode and nulling out
836 /// pointers to the buffer to reflect the fact that a seek has occurred.
837 /// Return the specified `offset` on success, and a negative value
838 /// otherwise.
839 pos_type seekReturn(pos_type offset);
840
841 /// Flush any output data to the file descriptor, and reset the state of
842 /// this object. Return 0 on success, and a non-zero value otherwise.
843 int flush();
844
845 protected:
846 // PROTECTED MEMBER FUNCTIONS
847
848 // The following member functions override protected virtual functions
849 // inherited from the base class, and are specified to be protected as part
850 // of the standard library 'bsl::streambuf' interface.
851
852 // PROTECTED MANIPULATORS
853
854 /// Replenish the input buffer with data obtained from the file descriptor,
855 /// and return the next character of input (or eof if no input is available).
856 ///
857 /// \note Note that in windows text mode, `\r\n` sequences on the
858 /// device will be translated to `\n`s.
860
861 /// If the optionally specified `c` is not given, move the current input
862 /// position back one character and return the character at that
863 /// position. Otherwise specify a value for `c` other than
864 /// `traits_type::eof`. If `c` is equal to the previous character in
865 /// the read buffer, the behavior is the same as if `eof()` was passed.
866 /// If `c` is not eof and is not equal to the previous character in the
867 /// putback buffer push the character `c` is back into the input buffer,
868 /// if possible. Return the backed up character on success and
869 /// `traits_type::eof()` otherwise. If the input buffer is readonly, or
870 /// `gptr()` is already at the beginning of the input buffer, this
871 /// object enters `INPUT_PUTBACK_MODE` and `c` is stuffed back into the putback buffer.
872 ///
873 /// \note Note that only `PBACK_BUF_SIZE` characters can be
874 /// backed up into the putback buffer, if this limit is exceeded,
875 /// `traits_type::eof()` will be returned. Also note that this method
876 /// is called by public methods `sputbackc` or `sungetc` in the base
877 /// class, and only when simply decrementing the current position in the
878 /// input buffer won't satisfy the request, either because `c` doesn't
879 /// match the previously input character, or because the input position
880 /// is already at the beginning of the input buffer.
881 int_type pbackfail(int_type c = traits_type::eof()) BSLS_KEYWORD_OVERRIDE;
882
883 /// If in output mode, write the contents of the buffer to output. Return
884 /// `traits_type::eof()` on failure, and any other value on success.
885 /// Optionally specify a character `c` to be appended to the buffer prior
886 /// to the flush. If no character is specified, no character is appended
887 /// to the buffer. If not in output mode, switch to output mode.
888 ///
889 /// \note Note that the write will translate `\n`s to `\r\n`s.
890 int_type overflow(int_type c = traits_type::eof()) BSLS_KEYWORD_OVERRIDE;
891
892 /// Use the specified `buffer` of the specified `numBytes` capacity as
893 /// the input/output buffer for this `streambuf`. If `buffer == 0`, the
894 /// buffer is dynamically allocated with a default size. If both
895 /// `buffer` and `numBytes` are zero a 1-byte buffer is dynamically allocated.
896 ///
897 /// \pre The behavior is undefined if any I/O has preceded this
898 /// call, and unless the buffer is uninitialized before this call.
899 FdStreamBuf *setbuf(char_type *buffer, bsl::streamsize numBytes)
901
902 /// Set the file pointer associated with the file descriptor according
903 /// to the specified `offset` and `whence`:
904 ///
905 /// * If 'whence' is 'bsl::ios_base::beg', set the pointer to 'offset'
906 /// bytes from the beginning of the file.
907 /// * If 'whence' is 'bsl::ios_base::cur', advance the pointer by
908 /// 'offset' bytes
909 /// * If 'whence' is 'bsl::ios_base::end', set the pointer to 'offset'
910 /// bytes beyond the end of the file.
911 ///
912 /// Optionally specify `mode`, which is ignored. Return the new location
913 /// of the file position, in bytes from the beginning of the file, on success, and -1 otherwise.
914 ///
915 /// \pre The behavior is undefined unless the file descriptor is on a device capable of seeking.
916 ///
917 /// \note Note that seeking does
918 /// not change the size of the file if the pointer advances beyond the end
919 /// of the file; instead, the next write at the pointer will increase the
920 /// file size. Also note that seeks are always in terms of bytes on the
921 /// device, meaning that in Windows text mode, seeking past a `\n`
922 /// perceived by the caller will count as 2 bytes since it has to seek over
923 /// a `\r\n` sequence on the device.
924 pos_type seekoff(
925 off_type offset,
926 bsl::ios_base::seekdir whence,
927 bsl::ios_base::openmode mode = bsl::ios_base::in | bsl::ios_base::out)
929
930 /// Seek to the specified `offset` relative to the beginning of the file.
931 /// Return the resulting absolute position in the file relative to the
932 /// beginning. Optionally specify `mode` which is ignored. Also note that
933 /// seeks are always in terms of bytes on the device, meaning that on a
934 /// Windows text file, seeking past a `\r\n` sequence on the disk will
935 /// count as two bytes, though if it is read in it will be a single `\n`
936 /// byte.
937 pos_type seekpos(
938 pos_type offset,
939 bsl::ios_base::openmode mode = bsl::ios_base::in | bsl::ios_base::out)
941
942 /// If in output mode, flush the buffer to the associated file descriptor;
943 /// otherwise do nothing. Return 0 on success, -1 otherwise.
945
946 /// Set the locale for this object. This method has no effect.
947 ///
948 /// \pre The behavior is undefined unless the specified `locale` is the same as
949 /// `bsl::locale()`.
950 void imbue(const bsl::locale& locale) BSLS_KEYWORD_OVERRIDE;
951
952 /// If this object is in putback mode, return the number of characters
953 /// remaining to be read in the putback buffer, and otherwise the
954 /// number of characters remaining in the file to be read. Return a
955 /// non-negative number of characters on success and a negative value otherwise.
956 ///
957 /// \pre The behavior is undefined unless this object is in input
958 /// mode and the file descriptor is associated with a regular file.
960
961 /// Read up to the specified `numBytes` characters from the file
962 /// descriptor into the specified `buffer` and return the number of characters successfully read.
963 ///
964 /// \pre The behavior is undefined unless `buffer` is at least `numBytes` bytes long.
965 ///
966 /// \note Note that on a Windows
967 /// text file, a `\r\n` in the file will be read as `\n` (counting as a
968 /// single character).
969 bsl::streamsize xsgetn(char *buffer, bsl::streamsize numBytes)
971
972 /// Write up to the specified `numBytes` characters from the specified
973 /// `buffer` and return the number of characters successfully written.
974 ///
975 /// \note Note that this method does not necessarily modify the file: this method
976 /// may simply write the characters to a buffer to be flushed to the file
977 /// at a later time. Also note that on a Windows text file, a `\n` will be
978 /// written to the file as `\r\n` (counted as a single character).
979 bsl::streamsize xsputn(const char *buffer,
980 bsl::streamsize numBytes) BSLS_KEYWORD_OVERRIDE;
981
982 private:
983 // NOT IMPLEMENTED
984 FdStreamBuf( const FdStreamBuf&);
985 FdStreamBuf& operator=(const FdStreamBuf&);
986
987 public:
988 // CREATORS
989
990 /// Create a `FdStreamBuf` associated with the specified `fileDescriptor`
991 /// that refers to an already opened file or device, and specify
992 /// `writableFlag` which, if `true`, indicates that `fileDescriptor` is
993 /// writable, otherwise it is not. The optionally specified
994 /// `willCloseOnResetFlag`, if `true`, indicates that `fileDescriptor` is
995 /// to be closed the next time this object is reset, cleared or destroyed,
996 /// or if `false` the file descriptor is to be left open. Optionally
997 /// specify a `binaryModeFlag` which is ignored on Unix; if `false` on
998 /// Windows, it indicates that `\n`s are to be translated to and from
999 /// `\r\n` sequences on the device. Optionally specify a `basicAllocator`
1000 /// used to supply memory. If `basicAllocator` is 0, the currently
1001 /// installed default allocator is used. The supplied file descriptor, if
1002 /// valid, should remain open until the next call to either `reset` or the destructor.
1003 ///
1004 /// \note Note that if `FilesystemUtil::k_INVALID_FD` is passed to
1005 /// `fileDescriptor`, no file descriptor is to be associated with this
1006 /// object. Also note that the state of the `fileDescriptor` is unchanged
1007 /// by this call (i.e., there is no implicit seek).
1008 explicit FdStreamBuf(
1009 FilesystemUtil::FileDescriptor fileDescriptor,
1010 bool writableFlag,
1011 bool willCloseOnResetFlag = true,
1012 bool binaryModeFlag = false,
1013 bslma::Allocator *basicAllocator = 0);
1014
1015 /// Destroy this object and, if `willCloseOnReset` is `true`, close the
1016 /// file descriptor associated with this object, if any.
1018
1019 // MANIPULATORS
1020
1021 /// Associate this object with the specified `fileDescriptor`, and record
1022 /// the state of the specified `writableFlag` which, if `true`, indicates
1023 /// that `fileDescriptor` is writable, otherwise it is not. If, in the
1024 /// call to the constructor or `reset` prior to this call,
1025 /// `willCloseOnReset` was true, close any file descriptor previously
1026 /// associated with this object, otherwise leave it open but disassociate
1027 /// this object from it. The Optionally specified `willCloseOnResetFlag`
1028 /// which will set `willCloseOnReset`, which, if `true`, indicates that the
1029 /// specified file descriptor is to be closed when this object is later
1030 /// cleared, reset, or destroyed, otherwise no action will be taken on
1031 /// `fileDescriptor` at that time. The supplied file descriptor, if valid,
1032 /// should remain open until the next call to either `reset` or the
1033 /// destructor, regardless of the value of `willCloseOnResetFlag`.
1034 /// Optionally specify a `binaryModeFlag`, which is ignored on Unix; if
1035 /// `false` on Windows, it indicates that `\n`s internally are to be
1036 /// translated to and from `\r\n` sequences on the device; on Unix or if
1037 /// `binaryModeFlag` is `true` no such translation is to occur. Return 0 on success, and a non-zero value otherwise.
1038 ///
1039 /// \note Note that if
1040 /// `FilesystemUtil::k_INVALID_FD` is passed as `fileDescriptor`, no file
1041 /// descriptor is to be associated with this object. Also note that the
1042 /// state of the `fileDescriptor` is unchanged by this call, there is no
1043 /// implicit seek.
1044 int reset(FilesystemUtil::FileDescriptor fileDescriptor,
1045 bool writableFlag,
1046 bool willCloseOnResetFlag = true,
1047 bool binaryModeFlag = false);
1048
1049 /// Disassociate this file handler from any file descriptor with which
1050 /// it may be associated without closing that file descriptor. This
1051 /// method succeeds with no effect is `isOpened` was false.
1052 ///
1053 /// \note Note that `fileDescriptor` is `FilesystemUtil::k_INVALID_FD` after this call.
1054 void release();
1055
1056 /// Release any file descriptor that may be associated with this file
1057 /// handler. If `isOpened` and `willCloseOnReset` are both `true`, the
1058 /// file descriptor will be closed, otherwise it will not. Return 0 on
1059 /// success, and a non-zero value if the close fails. This method
1060 /// succeeds with no effect if `isOpened` was false.
1061 ///
1062 /// \note Note that `fileDescriptor` is `FilesystemUtil::k_INVALID_FD` after this call.
1063 int clear();
1064
1065 // ACCESSORS
1066
1067 /// Return the file descriptor associated with this object, or
1068 /// `FilesystemUtil::k_INVALID_FD` if this object is not currently
1069 /// associated with a file descriptor.
1070 FilesystemUtil::FileDescriptor fileDescriptor() const;
1071
1072 /// Return `true` if this object is currently associated with a file
1073 /// descriptor, and `false` otherwise.
1074 bool isOpened() const;
1075
1076 /// Return `true` if this object will close the associated file descriptor
1077 /// the next time it is reset, cleared, or destroyed, and `false`
1078 /// otherwise.
1079 bool willCloseOnReset() const;
1080};
1081
1082// ============================================================================
1083// INLINE DEFINITIONS
1084// ============================================================================
1085
1086 // -----------------------------
1087 // class FdStreamBuf_FileHandler
1088 // -----------------------------
1089
1090// CLASS METHODS
1091inline
1092size_t FdStreamBuf_FileHandler::pageSize()
1093{
1094 return bsls::AtomicOperations::getIntRelaxed(&s_pageSize);
1095}
1096
1097// MANIPULATORS
1098inline
1100{
1101 d_willCloseOnResetFlag = false;
1103}
1104
1105inline
1110
1111inline
1113{
1114 d_willCloseOnResetFlag = booleanValue;
1115}
1116
1117inline
1118bsl::streamoff
1119FdStreamBuf_FileHandler::getOffset(char *first, char *last) const
1120{
1121 BSLS_ASSERT(first <= last);
1122
1123 return d_openModeFlags & bsl::ios_base::binary
1124 ? last - first
1125 : bsl::count(first, last, '\n') + last - first;
1126}
1127
1128inline
1130{
1131#if defined(BSLS_PLATFORM_OS_UNIX)
1132 return true;
1133# else
1134 // Windows
1135
1136 return (d_openModeFlags & bsl::ios_base::binary) != 0;
1137# endif
1138}
1139
1140inline
1142{
1143 return d_openedFlag;
1144}
1145
1146inline
1148{
1149 return d_regularFileFlag;
1150}
1151
1152inline
1154{
1155 return (int) d_openModeFlags;
1156}
1157
1158inline
1160{
1161 return d_willCloseOnResetFlag;
1162}
1163
1164inline
1165FilesystemUtil::FileDescriptor
1167{
1168 return d_fileId;
1169}
1170
1171 // -----------------
1172 // class FdStreamBuf
1173 // -----------------
1174
1175// PRIVATE MANIPULATORS
1176inline
1177void FdStreamBuf::exitPutbackMode()
1178{
1179 setg(d_savedEback_p, d_savedGptr_p, d_savedEgptr_p);
1180 d_mode = e_INPUT_MODE;
1181}
1182
1183/// Only called by `seekoff` and `seekpos`, returns the value about to be
1184/// returned by the calling routine.
1185inline
1186FdStreamBuf::pos_type
1187FdStreamBuf::seekReturn(pos_type offset)
1188{
1189 if (e_INPUT_MODE == d_mode || e_INPUT_PUTBACK_MODE == d_mode) {
1190 if (0 != exitInputMode(false)) {
1191 // error
1192
1193 return (pos_type) - 1; // RETURN
1194 }
1195 }
1196 setg(0, 0, 0);
1197 setp(0, 0);
1198
1199 d_mode = e_NULL_MODE;
1200
1201 return offset;
1202}
1203
1204// MANIPULATORS
1205inline
1206int FdStreamBuf::reset(FilesystemUtil::FileDescriptor fileDescriptor,
1207 bool writableFlag,
1208 bool willCloseOnResetFlag,
1209 bool binaryModeFlag)
1210{
1211 bool ok = 0 == flush();
1212
1214 // note we reset() whether flush succeeded or not
1215
1216 ok &= (0 == d_fileHandler.reset(fileDescriptor,
1217 writableFlag,
1218 willCloseOnResetFlag,
1219 binaryModeFlag));
1220 }
1221
1222 return ok ? 0 : -1;
1223}
1224
1225inline
1227{
1228 d_fileHandler.setWillCloseOnReset(false);
1230}
1231
1232inline
1234{
1235 return reset(FilesystemUtil::k_INVALID_FD, false);
1236}
1237
1238// ACCESSORS
1239inline
1240FilesystemUtil::FileDescriptor FdStreamBuf::fileDescriptor() const
1241{
1242 return d_fileHandler.fileDescriptor();
1243}
1244
1245inline
1247{
1248 return d_fileHandler.isOpened();
1249}
1250
1251inline
1253{
1254 return d_fileHandler.willCloseOnReset();
1255}
1256
1257} // close package namespace
1258
1259
1260#endif
1261
1262// ----------------------------------------------------------------------------
1263// Copyright 2015 Bloomberg Finance L.P.
1264//
1265// Licensed under the Apache License, Version 2.0 (the "License");
1266// you may not use this file except in compliance with the License.
1267// You may obtain a copy of the License at
1268//
1269// http://www.apache.org/licenses/LICENSE-2.0
1270//
1271// Unless required by applicable law or agreed to in writing, software
1272// distributed under the License is distributed on an "AS IS" BASIS,
1273// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1274// See the License for the specific language governing permissions and
1275// limitations under the License.
1276// ----------------------------- END-OF-FILE ----------------------------------
1277
1278/** @} */
1279/** @} */
1280/** @} */
Definition bdls_fdstreambuf.h:427
FilesystemUtil::FileDescriptor fileDescriptor() const
Definition bdls_fdstreambuf.h:1166
static bsl::size_t pageSize()
Return the operating system's page size.
Definition bdls_fdstreambuf.h:1092
bool isInBinaryMode() const
Definition bdls_fdstreambuf.h:1129
int openMode() const
Definition bdls_fdstreambuf.h:1153
void setWillCloseOnReset(bool booleanValue)
Definition bdls_fdstreambuf.h:1112
int reset(FilesystemUtil::FileDescriptor fileDescriptor, bool writableFlag, bool willCloseOnResetFlag=true, bool binaryModeFlag=false)
bool isRegularFile() const
Definition bdls_fdstreambuf.h:1147
int write(const char *buffer, int numBytes)
void unmap(void *mappedMemory, bsl::streamoff length)
bsl::streamoff fileSize() const
void release()
Definition bdls_fdstreambuf.h:1099
void * mmap(bsl::streamoff offset, bsl::streamoff length)
bsl::streamoff getOffset(char *first, char *last) const
Definition bdls_fdstreambuf.h:1119
int clear()
Definition bdls_fdstreambuf.h:1106
bsl::streampos seek(bsl::streamoff offset, FilesystemUtil::Whence dir)
int read(char *buffer, int numBytes)
bool willCloseOnReset() const
Definition bdls_fdstreambuf.h:1159
bool isOpened() const
Definition bdls_fdstreambuf.h:1141
Definition bdls_fdstreambuf.h:671
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:1252
int_type pbackfail(int_type c=traits_type::eof()) BSLS_KEYWORD_OVERRIDE
int sync() BSLS_KEYWORD_OVERRIDE
int clear()
Definition bdls_fdstreambuf.h:1233
bool isOpened() const
Definition bdls_fdstreambuf.h:1246
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:1206
bsl::streamsize xsgetn(char *buffer, bsl::streamsize numBytes) BSLS_KEYWORD_OVERRIDE
FilesystemUtil::FileDescriptor fileDescriptor() const
Definition bdls_fdstreambuf.h:1240
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:1226
Definition bslma_allocator.h:545
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition bdls_fdstreambuf.h:412
Definition bdlat_valuetypefunctions.h:939
Definition baljsn_encoder_testtypes.h:76
Definition bdls_filesystemutil.h:364
Whence
Definition bdls_filesystemutil.h:413
static const FileDescriptor k_INVALID_FD
Definition bdls_filesystemutil.h:484
static int getIntRelaxed(AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations.h:1536