Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (c) 1999 |
michael@0 | 3 | * Silicon Graphics Computer Systems, Inc. |
michael@0 | 4 | * |
michael@0 | 5 | * Copyright (c) 1999 |
michael@0 | 6 | * Boris Fomitchev |
michael@0 | 7 | * |
michael@0 | 8 | * This material is provided "as is", with absolutely no warranty expressed |
michael@0 | 9 | * or implied. Any use is at your own risk. |
michael@0 | 10 | * |
michael@0 | 11 | * Permission to use or copy this software for any purpose is hereby granted |
michael@0 | 12 | * without fee, provided the above notices are retained on all copies. |
michael@0 | 13 | * Permission to modify the code and to distribute modified code is granted, |
michael@0 | 14 | * provided the above notices are retained, and a notice that the code was |
michael@0 | 15 | * modified is included with the above copyright notice. |
michael@0 | 16 | * |
michael@0 | 17 | */ |
michael@0 | 18 | |
michael@0 | 19 | #include "stlport_prefix.h" |
michael@0 | 20 | #include "stdio_streambuf.h" |
michael@0 | 21 | |
michael@0 | 22 | #ifdef _STLP_UNIX |
michael@0 | 23 | # include <sys/types.h> |
michael@0 | 24 | # include <sys/stat.h> |
michael@0 | 25 | #endif |
michael@0 | 26 | |
michael@0 | 27 | #include <fstream> |
michael@0 | 28 | #include <limits> |
michael@0 | 29 | |
michael@0 | 30 | _STLP_BEGIN_NAMESPACE |
michael@0 | 31 | _STLP_MOVE_TO_PRIV_NAMESPACE |
michael@0 | 32 | |
michael@0 | 33 | // Compare with streamoff definition in stl/char_traits.h! |
michael@0 | 34 | |
michael@0 | 35 | #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \ |
michael@0 | 36 | (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE)) |
michael@0 | 37 | # if !defined (_STLP_MSVC) || (_STLP_MSVC < 1400) || defined(_STLP_WCE) |
michael@0 | 38 | # define FSEEK fseek |
michael@0 | 39 | # else |
michael@0 | 40 | # define FSEEK _fseeki64 |
michael@0 | 41 | # endif |
michael@0 | 42 | # define FSETPOS fsetpos |
michael@0 | 43 | # define FGETPOS fgetpos |
michael@0 | 44 | # define FPOS_T fpos_t |
michael@0 | 45 | #else |
michael@0 | 46 | # define FSEEK fseeko64 |
michael@0 | 47 | # define FSETPOS fsetpos64 |
michael@0 | 48 | # define FGETPOS fgetpos64 |
michael@0 | 49 | # define FPOS_T fpos64_t |
michael@0 | 50 | #endif |
michael@0 | 51 | |
michael@0 | 52 | //---------------------------------------------------------------------- |
michael@0 | 53 | // Class stdio_streambuf_base |
michael@0 | 54 | |
michael@0 | 55 | stdio_streambuf_base::stdio_streambuf_base(FILE* file) |
michael@0 | 56 | : /* _STLP_STD::FILE_basic_streambuf(file, 0), */ |
michael@0 | 57 | _M_file(file) |
michael@0 | 58 | {} |
michael@0 | 59 | |
michael@0 | 60 | stdio_streambuf_base::~stdio_streambuf_base() { |
michael@0 | 61 | _STLP_VENDOR_CSTD::fflush(_M_file); |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) { |
michael@0 | 65 | #ifdef _STLP_WCE |
michael@0 | 66 | // no buffering in windows ce .NET |
michael@0 | 67 | #else |
michael@0 | 68 | size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n)) |
michael@0 | 69 | : __STATIC_CAST(size_t, n); |
michael@0 | 70 | _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t); |
michael@0 | 71 | #endif |
michael@0 | 72 | return this; |
michael@0 | 73 | } |
michael@0 | 74 | |
michael@0 | 75 | stdio_streambuf_base::pos_type |
michael@0 | 76 | stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir, |
michael@0 | 77 | ios_base::openmode /* mode */) { |
michael@0 | 78 | int whence; |
michael@0 | 79 | switch (dir) { |
michael@0 | 80 | case ios_base::beg: |
michael@0 | 81 | whence = SEEK_SET; |
michael@0 | 82 | break; |
michael@0 | 83 | case ios_base::cur: |
michael@0 | 84 | whence = SEEK_CUR; |
michael@0 | 85 | break; |
michael@0 | 86 | case ios_base::end: |
michael@0 | 87 | whence = SEEK_END; |
michael@0 | 88 | break; |
michael@0 | 89 | default: |
michael@0 | 90 | return pos_type(-1); |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) { |
michael@0 | 94 | FPOS_T pos; |
michael@0 | 95 | FGETPOS(_M_file, &pos); |
michael@0 | 96 | // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead |
michael@0 | 97 | // of a primitive type |
michael@0 | 98 | #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)))) |
michael@0 | 99 | return pos_type((streamoff)pos.__pos); |
michael@0 | 100 | #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__) |
michael@0 | 101 | return pos_type(pos.__fpos_elem[ 0 ]); |
michael@0 | 102 | #elif defined (__EMX__) |
michael@0 | 103 | return pos_type((streamoff)pos._pos); |
michael@0 | 104 | #else |
michael@0 | 105 | return pos_type(pos); |
michael@0 | 106 | #endif |
michael@0 | 107 | } |
michael@0 | 108 | else |
michael@0 | 109 | return pos_type(-1); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | |
michael@0 | 113 | stdio_streambuf_base::pos_type |
michael@0 | 114 | stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) { |
michael@0 | 115 | // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead |
michael@0 | 116 | // of a primitive type |
michael@0 | 117 | #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) ) |
michael@0 | 118 | FPOS_T p; |
michael@0 | 119 | p.__pos = pos; |
michael@0 | 120 | # ifdef _STLP_USE_UCLIBC |
michael@0 | 121 | # ifdef __STDIO_MBSTATE |
michael@0 | 122 | memset( &(p.__mbstate), 0, sizeof(p.__mbstate) ); |
michael@0 | 123 | # endif |
michael@0 | 124 | # ifdef __STDIO_WIDE |
michael@0 | 125 | p.mblen_pending = 0; |
michael@0 | 126 | # endif |
michael@0 | 127 | # else |
michael@0 | 128 | memset( &(p.__state), 0, sizeof(p.__state) ); |
michael@0 | 129 | # endif |
michael@0 | 130 | #elif defined (__MVS__) || defined (__OS400__) |
michael@0 | 131 | FPOS_T p; |
michael@0 | 132 | p.__fpos_elem[0] = pos; |
michael@0 | 133 | #elif defined (__EMX__) |
michael@0 | 134 | FPOS_T p; |
michael@0 | 135 | p._pos = pos; |
michael@0 | 136 | memset( &(p._mbstate), 0, sizeof(p._mbstate) ); |
michael@0 | 137 | #else |
michael@0 | 138 | FPOS_T p(pos); |
michael@0 | 139 | #endif |
michael@0 | 140 | |
michael@0 | 141 | return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1); |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | int stdio_streambuf_base::sync() { |
michael@0 | 145 | return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1; |
michael@0 | 146 | } |
michael@0 | 147 | |
michael@0 | 148 | //---------------------------------------------------------------------- |
michael@0 | 149 | // Class stdio_istreambuf |
michael@0 | 150 | |
michael@0 | 151 | stdio_istreambuf::~stdio_istreambuf() {} |
michael@0 | 152 | |
michael@0 | 153 | streamsize stdio_istreambuf::showmanyc() |
michael@0 | 154 | { return 0; } |
michael@0 | 155 | |
michael@0 | 156 | stdio_istreambuf::int_type stdio_istreambuf::underflow() |
michael@0 | 157 | { |
michael@0 | 158 | #ifdef _STLP_WCE |
michael@0 | 159 | int c = fgetc(_M_file); |
michael@0 | 160 | #else |
michael@0 | 161 | int c = getc(_M_file); |
michael@0 | 162 | #endif |
michael@0 | 163 | if (c != EOF) { |
michael@0 | 164 | _STLP_VENDOR_CSTD::ungetc(c, _M_file); |
michael@0 | 165 | return c; |
michael@0 | 166 | } |
michael@0 | 167 | else |
michael@0 | 168 | return traits_type::eof(); |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | stdio_istreambuf::int_type stdio_istreambuf::uflow() { |
michael@0 | 172 | #ifdef _STLP_WCE |
michael@0 | 173 | int c = fgetc(_M_file); |
michael@0 | 174 | #else |
michael@0 | 175 | int c = getc(_M_file); |
michael@0 | 176 | #endif |
michael@0 | 177 | return c != EOF ? c : traits_type::eof(); |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) { |
michael@0 | 181 | if (c != traits_type::eof()) { |
michael@0 | 182 | int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file); |
michael@0 | 183 | return result != EOF ? result : traits_type::eof(); |
michael@0 | 184 | } |
michael@0 | 185 | else{ |
michael@0 | 186 | if (this->eback() < this->gptr()) { |
michael@0 | 187 | this->gbump(-1); |
michael@0 | 188 | return traits_type::not_eof(c); |
michael@0 | 189 | } |
michael@0 | 190 | else |
michael@0 | 191 | return traits_type::eof(); |
michael@0 | 192 | } |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | //---------------------------------------------------------------------- |
michael@0 | 196 | // Class stdio_ostreambuf |
michael@0 | 197 | |
michael@0 | 198 | stdio_ostreambuf::~stdio_ostreambuf() {} |
michael@0 | 199 | |
michael@0 | 200 | streamsize stdio_ostreambuf::showmanyc() |
michael@0 | 201 | { return -1; } |
michael@0 | 202 | |
michael@0 | 203 | stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) { |
michael@0 | 204 | // Write the existing buffer, without writing any additional character. |
michael@0 | 205 | if (c == traits_type::eof()) { |
michael@0 | 206 | // Do we have a buffer to write? |
michael@0 | 207 | ptrdiff_t unwritten = this->pptr() - this->pbase(); |
michael@0 | 208 | if (unwritten != 0) { |
michael@0 | 209 | _STLP_VENDOR_CSTD::fflush(_M_file); |
michael@0 | 210 | // Test if the write succeeded. |
michael@0 | 211 | if (this->pptr() - this->pbase() < unwritten) |
michael@0 | 212 | return traits_type::not_eof(c); |
michael@0 | 213 | else |
michael@0 | 214 | return traits_type::eof(); |
michael@0 | 215 | } |
michael@0 | 216 | |
michael@0 | 217 | // We always succeed if we don't have to do anything. |
michael@0 | 218 | else |
michael@0 | 219 | return traits_type::not_eof(c); |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | // Write the character c, and whatever else might be in the buffer. |
michael@0 | 223 | else { |
michael@0 | 224 | #ifdef _STLP_WCE |
michael@0 | 225 | int result = fputc(c, _M_file); |
michael@0 | 226 | #else |
michael@0 | 227 | int result = putc(c, _M_file); |
michael@0 | 228 | #endif |
michael@0 | 229 | return result != EOF ? result : traits_type::eof(); |
michael@0 | 230 | } |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | _STLP_MOVE_TO_STD_NAMESPACE |
michael@0 | 234 | _STLP_END_NAMESPACE |
michael@0 | 235 | |
michael@0 | 236 | // Local Variables: |
michael@0 | 237 | // mode:C++ |
michael@0 | 238 | // End: |
michael@0 | 239 |