os/ossrv/genericopenlibs/cppstdlib/stl/src/stdio_streambuf.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
 * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
sl@0
     3
 *
sl@0
     4
 * Copyright (c) 1999
sl@0
     5
 * Silicon Graphics Computer Systems, Inc.
sl@0
     6
 *
sl@0
     7
 * Copyright (c) 1999
sl@0
     8
 * Boris Fomitchev
sl@0
     9
 *
sl@0
    10
 * This material is provided "as is", with absolutely no warranty expressed
sl@0
    11
 * or implied. Any use is at your own risk.
sl@0
    12
 *
sl@0
    13
 * Permission to use or copy this software for any purpose is hereby granted
sl@0
    14
 * without fee, provided the above notices are retained on all copies.
sl@0
    15
 * Permission to modify the code and to distribute modified code is granted,
sl@0
    16
 * provided the above notices are retained, and a notice that the code was
sl@0
    17
 * modified is included with the above copyright notice.
sl@0
    18
 *
sl@0
    19
 */
sl@0
    20
sl@0
    21
#include "stlport_prefix.h"
sl@0
    22
#include "stdio_streambuf.h"
sl@0
    23
// #include "file_streambuf.h"
sl@0
    24
sl@0
    25
#ifdef _STLP_UNIX
sl@0
    26
#  include <sys/types.h>
sl@0
    27
#  include <sys/stat.h>
sl@0
    28
#endif /* __unix */
sl@0
    29
sl@0
    30
#include <fstream>
sl@0
    31
#include <limits>
sl@0
    32
#include "fstream_impl.h"
sl@0
    33
sl@0
    34
#if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
sl@0
    35
#  if defined (__BORLANDC__)
sl@0
    36
// #  include <cio.h>
sl@0
    37
#    include <cfcntl.h>
sl@0
    38
#  else
sl@0
    39
#    include <io.h>
sl@0
    40
#    include <fcntl.h>
sl@0
    41
#  endif
sl@0
    42
#  include <sys/stat.h>
sl@0
    43
#endif
sl@0
    44
sl@0
    45
_STLP_BEGIN_NAMESPACE
sl@0
    46
_STLP_MOVE_TO_PRIV_NAMESPACE
sl@0
    47
sl@0
    48
// Compare with streamoff definition in stl/char_traits.h!
sl@0
    49
sl@0
    50
#ifdef _STLP_USE_DEFAULT_FILE_OFFSET
sl@0
    51
#  define FSEEK fseek
sl@0
    52
#  define FTELL ftell
sl@0
    53
#  define FSTAT fstat
sl@0
    54
#  define STAT  stat
sl@0
    55
#  define FSETPOS  fsetpos
sl@0
    56
#  define FGETPOS  fgetpos
sl@0
    57
#  define FPOS_T   fpos_t
sl@0
    58
#elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
sl@0
    59
     /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
sl@0
    60
#  define FSEEK fseeko64
sl@0
    61
#  define FTELL ftello64
sl@0
    62
#  define FSTAT fstat64
sl@0
    63
#  define STAT  stat64
sl@0
    64
#  define FSETPOS  fsetpos64
sl@0
    65
#  define FGETPOS  fgetpos64
sl@0
    66
#  define FPOS_T   fpos64_t
sl@0
    67
#else
sl@0
    68
#  define FSEEK fseek
sl@0
    69
#  define FTELL ftell
sl@0
    70
#  define FSTAT fstat
sl@0
    71
#  define STAT  stat
sl@0
    72
#  define FSETPOS  fsetpos
sl@0
    73
#  define FGETPOS  fgetpos
sl@0
    74
#  define FPOS_T   fpos_t
sl@0
    75
#endif
sl@0
    76
sl@0
    77
//----------------------------------------------------------------------
sl@0
    78
// Class stdio_streambuf_base
sl@0
    79
sl@0
    80
stdio_streambuf_base::stdio_streambuf_base(FILE* file)
sl@0
    81
    : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
sl@0
    82
    _M_file(file)
sl@0
    83
{}
sl@0
    84
sl@0
    85
stdio_streambuf_base::~stdio_streambuf_base() {
sl@0
    86
  _STLP_VENDOR_CSTD::fflush(_M_file);
sl@0
    87
}
sl@0
    88
sl@0
    89
_STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
sl@0
    90
#ifdef _STLP_WCE
sl@0
    91
  // no buffering in windows ce .NET
sl@0
    92
#else
sl@0
    93
  size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
sl@0
    94
                                                            : __STATIC_CAST(size_t, n);
sl@0
    95
  _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
sl@0
    96
#endif
sl@0
    97
  return this;
sl@0
    98
}
sl@0
    99
sl@0
   100
stdio_streambuf_base::pos_type
sl@0
   101
stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
sl@0
   102
                              ios_base::openmode /* mode */) {
sl@0
   103
  int whence;
sl@0
   104
  switch (dir) {
sl@0
   105
  case ios_base::beg:
sl@0
   106
    whence = SEEK_SET;
sl@0
   107
    break;
sl@0
   108
  case ios_base::cur:
sl@0
   109
    whence = SEEK_CUR;
sl@0
   110
    break;
sl@0
   111
  case ios_base::end:
sl@0
   112
    whence = SEEK_END;
sl@0
   113
    break;
sl@0
   114
  default:
sl@0
   115
    return pos_type(-1);
sl@0
   116
  }
sl@0
   117
sl@0
   118
  if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
sl@0
   119
    FPOS_T pos;
sl@0
   120
    FGETPOS(_M_file, &pos);
sl@0
   121
    // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
sl@0
   122
    // of a primitive type
sl@0
   123
#if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
sl@0
   124
    return pos_type((streamoff)pos.__pos);
sl@0
   125
#elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
sl@0
   126
    return pos_type(pos.__fpos_elem[ 0 ]);
sl@0
   127
#elif defined (__EMX__)
sl@0
   128
    return pos_type((streamoff)pos._pos);
sl@0
   129
#else
sl@0
   130
    return pos_type(pos);
sl@0
   131
#endif
sl@0
   132
  }
sl@0
   133
  else
sl@0
   134
    return pos_type(-1);
sl@0
   135
}
sl@0
   136
sl@0
   137
sl@0
   138
stdio_streambuf_base::pos_type
sl@0
   139
stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
sl@0
   140
  // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
sl@0
   141
  // of a primitive type
sl@0
   142
#if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
sl@0
   143
  FPOS_T p;
sl@0
   144
  p.__pos = pos;
sl@0
   145
#  ifdef _STLP_USE_UCLIBC
sl@0
   146
#    ifdef __STDIO_MBSTATE
sl@0
   147
  memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
sl@0
   148
#    endif
sl@0
   149
#    ifdef __STDIO_WIDE
sl@0
   150
  p.mblen_pending = 0;
sl@0
   151
#    endif
sl@0
   152
#  else
sl@0
   153
  memset( &(p.__state), 0, sizeof(p.__state) );
sl@0
   154
#  endif
sl@0
   155
#elif defined (__MVS__) || defined (__OS400__)
sl@0
   156
  FPOS_T p;
sl@0
   157
  p.__fpos_elem[0] = pos;
sl@0
   158
#elif defined(__EMX__)
sl@0
   159
  FPOS_T p;
sl@0
   160
  p._pos = pos;
sl@0
   161
  memset( &(p._mbstate), 0, sizeof(p._mbstate) );
sl@0
   162
#else
sl@0
   163
  FPOS_T p(pos);
sl@0
   164
#endif
sl@0
   165
sl@0
   166
  return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
sl@0
   167
}
sl@0
   168
sl@0
   169
int stdio_streambuf_base::sync() {
sl@0
   170
  return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
sl@0
   171
}
sl@0
   172
sl@0
   173
//----------------------------------------------------------------------
sl@0
   174
// Class stdio_istreambuf
sl@0
   175
sl@0
   176
stdio_istreambuf::~stdio_istreambuf() {}
sl@0
   177
sl@0
   178
streamsize stdio_istreambuf::showmanyc() {
sl@0
   179
  if (feof(_M_file))
sl@0
   180
    return -1;
sl@0
   181
  else {
sl@0
   182
#ifdef __SYMBIAN32__
sl@0
   183
	  int fd = fileno(_M_file);
sl@0
   184
#else
sl@0
   185
    int fd = _FILE_fd(_M_file);
sl@0
   186
#endif
sl@0
   187
#ifdef _STLP_WCE
sl@0
   188
   (fd); // prevent warning about unused variable
sl@0
   189
// not sure if i can mix win32 io mode with ftell but time will show
sl@0
   190
// cannot use WIN32_IO implementation since missing stat
sl@0
   191
    streamsize tmp = FTELL(_M_file);
sl@0
   192
    FSEEK(_M_file, 0, SEEK_END);
sl@0
   193
    streamoff size= FTELL(_M_file)-tmp;
sl@0
   194
    FSEEK(_M_file, tmp, SEEK_SET);
sl@0
   195
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   196
    // in this case, __file_size works with Win32 fh , not libc one
sl@0
   197
    streamoff size;
sl@0
   198
    struct stat buf;
sl@0
   199
    if(FSTAT(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
sl@0
   200
      size = ( buf.st_size > 0  ? buf.st_size : 0);
sl@0
   201
    else
sl@0
   202
      size = 0;
sl@0
   203
#else
sl@0
   204
    streamoff size = __file_size(fd);
sl@0
   205
#endif
sl@0
   206
    // fbp : we can use ftell as this flavour always use stdio.
sl@0
   207
    streamsize pos = FTELL(_M_file);
sl@0
   208
    return pos >= 0 && size > pos ? size - pos : 0;
sl@0
   209
  }
sl@0
   210
}
sl@0
   211
sl@0
   212
stdio_istreambuf::int_type stdio_istreambuf::underflow()
sl@0
   213
{
sl@0
   214
#ifdef _STLP_WCE
sl@0
   215
  int c = fgetc(_M_file);
sl@0
   216
#else
sl@0
   217
  int c = getc(_M_file);
sl@0
   218
#endif
sl@0
   219
  if (c != EOF) {
sl@0
   220
    _STLP_VENDOR_CSTD::ungetc(c, _M_file);
sl@0
   221
    return c;
sl@0
   222
  }
sl@0
   223
  else
sl@0
   224
    return traits_type::eof();
sl@0
   225
}
sl@0
   226
sl@0
   227
stdio_istreambuf::int_type stdio_istreambuf::uflow() {
sl@0
   228
#ifdef _STLP_WCE
sl@0
   229
  int c = fgetc(_M_file);
sl@0
   230
#else
sl@0
   231
  int c = getc(_M_file);
sl@0
   232
#endif
sl@0
   233
  return c != EOF ? c : traits_type::eof();
sl@0
   234
}
sl@0
   235
sl@0
   236
stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
sl@0
   237
  if (c != traits_type::eof()) {
sl@0
   238
    int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
sl@0
   239
    return result != EOF ? result : traits_type::eof();
sl@0
   240
  }
sl@0
   241
  else{
sl@0
   242
    if (this->eback() < this->gptr()) {
sl@0
   243
      this->gbump(-1);
sl@0
   244
      return traits_type::not_eof(c);
sl@0
   245
    }
sl@0
   246
    else
sl@0
   247
      return traits_type::eof();
sl@0
   248
  }
sl@0
   249
}
sl@0
   250
sl@0
   251
//----------------------------------------------------------------------
sl@0
   252
// Class stdio_ostreambuf
sl@0
   253
sl@0
   254
stdio_ostreambuf::~stdio_ostreambuf() {}
sl@0
   255
sl@0
   256
streamsize stdio_ostreambuf::showmanyc() {
sl@0
   257
  return -1;
sl@0
   258
}
sl@0
   259
sl@0
   260
stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
sl@0
   261
  // Write the existing buffer, without writing any additional character.
sl@0
   262
  if (c == traits_type::eof()) {
sl@0
   263
    // Do we have a buffer to write?
sl@0
   264
    ptrdiff_t unwritten = this->pptr() - this->pbase();
sl@0
   265
    if (unwritten != 0) {
sl@0
   266
      _STLP_VENDOR_CSTD::fflush(_M_file);
sl@0
   267
      // Test if the write succeeded.
sl@0
   268
      if (this->pptr() - this->pbase() < unwritten)
sl@0
   269
        return traits_type::not_eof(c);
sl@0
   270
      else
sl@0
   271
        return traits_type::eof();
sl@0
   272
    }
sl@0
   273
sl@0
   274
    // We always succeed if we don't have to do anything.
sl@0
   275
    else
sl@0
   276
      return traits_type::not_eof(c);
sl@0
   277
  }
sl@0
   278
sl@0
   279
  // Write the character c, and whatever else might be in the buffer.
sl@0
   280
  else {
sl@0
   281
#ifdef _STLP_WCE
sl@0
   282
    int result = fputc(c, _M_file);
sl@0
   283
#else
sl@0
   284
    int result = putc(c, _M_file);
sl@0
   285
#endif
sl@0
   286
    return result != EOF ? result : traits_type::eof();
sl@0
   287
  }
sl@0
   288
}
sl@0
   289
sl@0
   290
_STLP_MOVE_TO_STD_NAMESPACE
sl@0
   291
_STLP_END_NAMESPACE
sl@0
   292
sl@0
   293
// Local Variables:
sl@0
   294
// mode:C++
sl@0
   295
// End:
sl@0
   296