os/ossrv/genericopenlibs/cppstdlib/stl/src/fstream.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
sl@0
    22
#include "stlport_prefix.h"
sl@0
    23
sl@0
    24
#if defined  (__SUNPPRO_CC)  && !defined (_STLP_NO_NEW_C_HEADERS)
sl@0
    25
#  include <time.h>
sl@0
    26
// For sunpro, it chokes if time.h is included through stat.h
sl@0
    27
#endif
sl@0
    28
sl@0
    29
#include <fstream>
sl@0
    30
sl@0
    31
#ifdef __CYGWIN__
sl@0
    32
#  define __int64 long long
sl@0
    33
#endif
sl@0
    34
sl@0
    35
#if defined (_STLP_USE_UNIX_IO)
sl@0
    36
extern "C" {
sl@0
    37
// open/close/read/write
sl@0
    38
#  include <sys/stat.h>           // For stat
sl@0
    39
#  if !defined (_CRAY) && ! defined (__EMX__)
sl@0
    40
#    include <sys/mman.h>           // For mmap
sl@0
    41
#  endif
sl@0
    42
sl@0
    43
//  on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this
sl@0
    44
#  if defined (__hpux) && defined (__GNUC__)
sl@0
    45
#    undef _INCLUDE_POSIX1C_SOURCE
sl@0
    46
#  endif
sl@0
    47
sl@0
    48
#  include <unistd.h>
sl@0
    49
#  include <fcntl.h>
sl@0
    50
}
sl@0
    51
#  ifdef __APPLE__
sl@0
    52
#    include <sys/sysctl.h>
sl@0
    53
#  endif
sl@0
    54
#elif defined (_STLP_USE_WIN32_IO)
sl@0
    55
#  define WIN32_LEAN_AND_MEAN
sl@0
    56
#  include <windows.h>
sl@0
    57
sl@0
    58
#  ifdef __BORLANDC__
sl@0
    59
#      include <cfcntl.h>            // For _O_RDONLY, etc
sl@0
    60
#    include <sys/stat.h>         // For _fstat
sl@0
    61
#  elif !defined(_STLP_WCE)
sl@0
    62
#    include <io.h>               // For _get_osfhandle
sl@0
    63
#    include <fcntl.h>            // For _O_RDONLY, etc
sl@0
    64
#    include <sys/stat.h>         // For _fstat
sl@0
    65
#  endif
sl@0
    66
#  define _TEXTBUF_SIZE 0x1000
sl@0
    67
#elif defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
    68
#  if defined( __MSL__ )
sl@0
    69
#    include <unistd.h>
sl@0
    70
#  else
sl@0
    71
#    include <io.h>
sl@0
    72
#  endif
sl@0
    73
#  include <fcntl.h>
sl@0
    74
#  include <sys/stat.h>
sl@0
    75
#elif defined (_STLP_USE_STDIO_IO)
sl@0
    76
#  include <cstdio>
sl@0
    77
#  if !(defined(__MRC__) || defined(__SC__) || defined(__ISCPP__) )
sl@0
    78
extern "C" {
sl@0
    79
#    include <sys/stat.h>
sl@0
    80
}
sl@0
    81
#  endif
sl@0
    82
#  if defined( __MSL__ )
sl@0
    83
#    include <unix.h>
sl@0
    84
#  endif
sl@0
    85
#  if defined(__ISCPP__)
sl@0
    86
#    include <c_locale_is/filestat.h>
sl@0
    87
#  endif
sl@0
    88
#  if (defined(__BEOS__) && defined(__INTEL__)) || defined (__SYMBIAN32__)
sl@0
    89
#    include <fcntl.h>
sl@0
    90
#    include <sys/stat.h>         // For _fstat
sl@0
    91
#    define _S_IREAD S_IREAD
sl@0
    92
#    define _S_IWRITE S_IWRITE
sl@0
    93
#    define _S_IFREG S_IFREG
sl@0
    94
#  endif
sl@0
    95
#else
sl@0
    96
#  error "Configure i/o !"
sl@0
    97
#endif
sl@0
    98
sl@0
    99
#if defined (_STLP_USE_WIN32_IO)
sl@0
   100
const _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE;
sl@0
   101
#  if !defined (INVALID_SET_FILE_POINTER)
sl@0
   102
#    define INVALID_SET_FILE_POINTER 0xffffffff
sl@0
   103
#  endif
sl@0
   104
#elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO) || defined (_STLP_USE_UNIX_IO)
sl@0
   105
const _STLP_fd INVALID_STLP_FD = -1;
sl@0
   106
#else
sl@0
   107
#  error "Configure i/o !"
sl@0
   108
#endif
sl@0
   109
sl@0
   110
// map permission masks
sl@0
   111
#if defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
sl@0
   112
#  ifndef S_IRUSR
sl@0
   113
#    define S_IRUSR _S_IREAD
sl@0
   114
#    define S_IWUSR _S_IWRITE
sl@0
   115
#    define S_IRGRP _S_IREAD
sl@0
   116
#    define S_IWGRP _S_IWRITE
sl@0
   117
#    define S_IROTH _S_IREAD
sl@0
   118
#    define S_IWOTH _S_IWRITE
sl@0
   119
#  endif
sl@0
   120
#  ifndef O_RDONLY
sl@0
   121
#    define O_RDONLY _O_RDONLY
sl@0
   122
#    define O_WRONLY _O_WRONLY
sl@0
   123
#    define O_RDWR   _O_RDWR
sl@0
   124
#    define O_APPEND _O_APPEND
sl@0
   125
#    define O_CREAT  _O_CREAT
sl@0
   126
#    define O_TRUNC  _O_TRUNC
sl@0
   127
#    define O_TEXT   _O_TEXT
sl@0
   128
#    define O_BINARY _O_BINARY
sl@0
   129
#  endif
sl@0
   130
sl@0
   131
#  ifdef __MSL__
sl@0
   132
#    define _O_TEXT 0x0
sl@0
   133
#    if !defined( O_TEXT )
sl@0
   134
#      define O_TEXT _O_TEXT
sl@0
   135
#    endif
sl@0
   136
#    define _S_IFREG S_IFREG
sl@0
   137
#    define S_IREAD        S_IRUSR
sl@0
   138
#    define S_IWRITE       S_IWUSR
sl@0
   139
#    define S_IEXEC        S_IXUSR
sl@0
   140
#    define _S_IWRITE S_IWRITE
sl@0
   141
#    define _S_IREAD S_IREAD
sl@0
   142
#    define _open open
sl@0
   143
#    define _lseek lseek
sl@0
   144
#    define _close close
sl@0
   145
#    define _read read
sl@0
   146
#    define _write write
sl@0
   147
#  endif
sl@0
   148
#endif
sl@0
   149
sl@0
   150
#ifndef O_ACCMODE
sl@0
   151
#  define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
sl@0
   152
#endif
sl@0
   153
sl@0
   154
#include "fstream_impl.h"
sl@0
   155
sl@0
   156
#ifdef _STLP_LONG_LONG
sl@0
   157
#  define ULL(x) ((unsigned _STLP_LONG_LONG)x)
sl@0
   158
#elif defined(__MRC__) || defined(__SC__)    //*TY 02/25/2000 - added support for MPW compilers
sl@0
   159
#  include <Math64.h>
sl@0
   160
#  define ULL(x) (U64SetU(x))
sl@0
   161
#elif defined(__ISCPP__)
sl@0
   162
#  include "uint64.h"
sl@0
   163
#elif defined(__SYMBIAN32__)
sl@0
   164
#  include <sys/types.h>
sl@0
   165
#else
sl@0
   166
#  error "there should be some long long type on the system!"
sl@0
   167
#endif
sl@0
   168
sl@0
   169
sl@0
   170
#if defined(__SYMBIAN32__WSD__) 
sl@0
   171
# include "libstdcppwsd.h"
sl@0
   172
sl@0
   173
_STLP_DECLSPEC size_t& get_fstream_Filebuf_Base_GetPageSize()
sl@0
   174
{
sl@0
   175
	return get_libcpp_wsd().fstream_Filebuf_base_M_page_size;
sl@0
   176
}
sl@0
   177
sl@0
   178
void filebuf_page_size_init()
sl@0
   179
{
sl@0
   180
	get_fstream_Filebuf_Base_GetPageSize() = 4096;	
sl@0
   181
}
sl@0
   182
#endif
sl@0
   183
sl@0
   184
_STLP_BEGIN_NAMESPACE
sl@0
   185
// Compare with streamoff definition in stl/char_traits.h!
sl@0
   186
sl@0
   187
#ifdef _STLP_USE_DEFAULT_FILE_OFFSET
sl@0
   188
#  define FOPEN fopen
sl@0
   189
#  define FSEEK fseek
sl@0
   190
#  define FSTAT fstat
sl@0
   191
#  define STAT  stat
sl@0
   192
#  define FTELL ftell
sl@0
   193
#  define LSEEK lseek
sl@0
   194
#  define MMAP  mmap
sl@0
   195
#  define OPEN  open
sl@0
   196
#elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
sl@0
   197
      /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
sl@0
   198
#  define FOPEN fopen64
sl@0
   199
#  define FSEEK fseeko64
sl@0
   200
#  define FSTAT fstat64
sl@0
   201
#  define STAT  stat64
sl@0
   202
#  define FTELL ftello64
sl@0
   203
#  define LSEEK lseek64
sl@0
   204
#  define MMAP  mmap64
sl@0
   205
#  define OPEN  open64
sl@0
   206
#else
sl@0
   207
#  define OPEN  open
sl@0
   208
#  define FSEEK fseek
sl@0
   209
#  define FSTAT fstat
sl@0
   210
#  define STAT  stat
sl@0
   211
#  define FTELL ftell
sl@0
   212
#  define LSEEK lseek
sl@0
   213
#  define MMAP  mmap
sl@0
   214
#  define OPEN  open
sl@0
   215
#endif
sl@0
   216
#ifdef _STLP_USE_UNIX_IO
sl@0
   217
#  ifndef MAP_FAILED /* MMAP failure return code */
sl@0
   218
#    define MAP_FAILED -1
sl@0
   219
#  endif
sl@0
   220
#elif defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
   221
#  define LSEEK _lseek
sl@0
   222
#endif
sl@0
   223
sl@0
   224
#if !defined(__MSL__) && !defined(__MRC__) && !defined(__SC__) && !defined(_STLP_WCE)    //*TY 04/15/2000 - exclude mpw compilers also
sl@0
   225
static ios_base::openmode flag_to_openmode(int mode) {
sl@0
   226
  ios_base::openmode ret = ios_base::__default_mode;
sl@0
   227
sl@0
   228
  switch(mode & O_ACCMODE) {
sl@0
   229
  case O_RDONLY:
sl@0
   230
    ret = ios_base::in; break;
sl@0
   231
  case O_WRONLY:
sl@0
   232
    ret = ios_base::out; break;
sl@0
   233
  case O_RDWR:
sl@0
   234
    ret = ios_base::in | ios_base::out; break;
sl@0
   235
  }
sl@0
   236
sl@0
   237
  if (mode & O_APPEND)
sl@0
   238
    ret |= ios_base::app;
sl@0
   239
sl@0
   240
#  if defined (_STLP_USE_WIN32_IO)
sl@0
   241
  if (mode & O_BINARY)
sl@0
   242
    ret |= ios_base::binary;
sl@0
   243
#  endif
sl@0
   244
sl@0
   245
  return ret;
sl@0
   246
}
sl@0
   247
#endif /* MSL */
sl@0
   248
sl@0
   249
_STLP_MOVE_TO_PRIV_NAMESPACE
sl@0
   250
sl@0
   251
// Helper functions for _Filebuf_base.
sl@0
   252
sl@0
   253
bool __is_regular_file(_STLP_fd fd) {
sl@0
   254
sl@0
   255
#if defined (_STLP_UNIX)
sl@0
   256
sl@0
   257
  struct STAT buf;
sl@0
   258
  return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode);
sl@0
   259
sl@0
   260
#elif defined(__MRC__) || defined(__SC__)    //*TY 02/25/2000 - added support for MPW compilers
sl@0
   261
sl@0
   262
#  pragma unused(fd)
sl@0
   263
  return true;  // each file is a regular file under mac os, isn't it? (we don't have fstat())
sl@0
   264
sl@0
   265
#elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
sl@0
   266
sl@0
   267
  struct STAT buf;
sl@0
   268
  return FSTAT(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0 ;
sl@0
   269
sl@0
   270
#elif defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
sl@0
   271
sl@0
   272
  return (GetFileType(fd) & ~FILE_TYPE_REMOTE) == FILE_TYPE_DISK;
sl@0
   273
sl@0
   274
#else
sl@0
   275
  (void)fd;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   276
  return false;
sl@0
   277
#endif
sl@0
   278
}
sl@0
   279
sl@0
   280
// Number of characters in the file.
sl@0
   281
streamoff __file_size(_STLP_fd fd) {
sl@0
   282
  streamoff ret = 0;
sl@0
   283
sl@0
   284
#if defined (_STLP_UNIX)
sl@0
   285
sl@0
   286
  struct STAT buf;
sl@0
   287
  if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode))
sl@0
   288
    ret = buf.st_size > 0 ? buf.st_size : 0;
sl@0
   289
sl@0
   290
#elif defined(__MRC__) || defined(__SC__)    //*TY 02/25/2000 - added support for MPW compilers
sl@0
   291
sl@0
   292
#  pragma unused(fd)
sl@0
   293
sl@0
   294
#elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
sl@0
   295
sl@0
   296
  struct STAT buf;
sl@0
   297
  if (FSTAT(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0)
sl@0
   298
    ret = buf.st_size > 0 ? buf.st_size : 0;
sl@0
   299
sl@0
   300
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   301
sl@0
   302
 LARGE_INTEGER li;
sl@0
   303
 li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart);
sl@0
   304
 if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR)
sl@0
   305
   ret = li.QuadPart;
sl@0
   306
sl@0
   307
#else
sl@0
   308
  (void)fd;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   309
#endif
sl@0
   310
  return ret;
sl@0
   311
}
sl@0
   312
sl@0
   313
_STLP_MOVE_TO_STD_NAMESPACE
sl@0
   314
sl@0
   315
// Visual C++ and Intel use this, but not Metrowerks
sl@0
   316
// Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version
sl@0
   317
#if (!defined (__MSL__) && !defined (_STLP_WCE) && defined (_STLP_MSVC_LIB) && defined (_WIN32)) || \
sl@0
   318
    (defined (__MINGW32__) && defined (__MSVCRT__) && !(defined (__SYMBIAN32__) && defined(__GCCXML__)) )
sl@0
   319
sl@0
   320
// fcntl(fileno, F_GETFL) for Microsoft library
sl@0
   321
// 'semi-documented' defines:
sl@0
   322
#  define IOINFO_L2E          5
sl@0
   323
#  define IOINFO_ARRAY_ELTS   (1 << IOINFO_L2E)
sl@0
   324
#  define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \
sl@0
   325
              ((i) & (IOINFO_ARRAY_ELTS - 1)) )
sl@0
   326
#  define FAPPEND         0x20    // O_APPEND flag
sl@0
   327
#  define FTEXT           0x80    // O_TEXT flag
sl@0
   328
// end of 'semi-documented' defines
sl@0
   329
sl@0
   330
// 'semi-documented' internal structure
sl@0
   331
extern "C" {
sl@0
   332
  struct ioinfo {
sl@0
   333
    long osfhnd;    // the real os HANDLE
sl@0
   334
    char osfile;    // file handle flags
sl@0
   335
    char pipech;    // pipe buffer
sl@0
   336
#  if defined (_MT)
sl@0
   337
    // multi-threaded locking
sl@0
   338
    int lockinitflag;
sl@0
   339
    CRITICAL_SECTION lock;
sl@0
   340
#  endif  /* _MT */
sl@0
   341
  };
sl@0
   342
#  if defined (__MINGW32__)
sl@0
   343
 __MINGW_IMPORT ioinfo * __pioinfo[];
sl@0
   344
#  else
sl@0
   345
  extern _CRTIMP ioinfo * __pioinfo[];
sl@0
   346
#  endif
sl@0
   347
} // extern "C"
sl@0
   348
// end of 'semi-documented' declarations
sl@0
   349
sl@0
   350
static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
sl@0
   351
  char dosflags = 0;
sl@0
   352
  if (fd >= 0)
sl@0
   353
    dosflags = _pioinfo(fd)->osfile;
sl@0
   354
  //else
sl@0
   355
    //the file will be considered as open in binary mode with no append attribute
sl@0
   356
  // end of 'semi-documented' stuff
sl@0
   357
sl@0
   358
  int mode = 0;
sl@0
   359
  if (dosflags & FAPPEND)
sl@0
   360
    mode |= O_APPEND;
sl@0
   361
sl@0
   362
  if (dosflags & FTEXT)
sl@0
   363
    mode |= O_TEXT;
sl@0
   364
  else
sl@0
   365
    mode |= O_BINARY;
sl@0
   366
sl@0
   367
  // For Read/Write access we have to guess
sl@0
   368
  DWORD dummy, dummy2;
sl@0
   369
  BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0);
sl@0
   370
  BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL);
sl@0
   371
  if (writeOk && readOk)
sl@0
   372
    mode |= O_RDWR;
sl@0
   373
  else if (readOk)
sl@0
   374
    mode |= O_RDONLY;
sl@0
   375
  else
sl@0
   376
    mode |= O_WRONLY;
sl@0
   377
sl@0
   378
  return flag_to_openmode(mode);
sl@0
   379
}
sl@0
   380
sl@0
   381
#elif defined (__DMC__)
sl@0
   382
sl@0
   383
#  define FHND_APPEND 0x04
sl@0
   384
#  define FHND_DEVICE 0x08
sl@0
   385
#  define FHND_TEXT   0x10
sl@0
   386
sl@0
   387
extern "C" unsigned char __fhnd_info[_NFILE];
sl@0
   388
sl@0
   389
static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
sl@0
   390
  int mode = 0;
sl@0
   391
sl@0
   392
  if (__fhnd_info[fd] & FHND_APPEND)
sl@0
   393
    mode |= O_APPEND;
sl@0
   394
sl@0
   395
  if (__fhnd_info[fd] & FHND_TEXT == 0)
sl@0
   396
    mode |= O_BINARY;
sl@0
   397
sl@0
   398
  for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) {
sl@0
   399
    if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) {
sl@0
   400
      const int osflags = fp->_flag;
sl@0
   401
sl@0
   402
      if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW))
sl@0
   403
        mode |= O_RDONLY;
sl@0
   404
      else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW))
sl@0
   405
        mode |= O_WRONLY;
sl@0
   406
      else
sl@0
   407
        mode |= O_RDWR;
sl@0
   408
      break;
sl@0
   409
    }
sl@0
   410
  }
sl@0
   411
sl@0
   412
  return flag_to_openmode(mode);
sl@0
   413
}
sl@0
   414
#endif
sl@0
   415
sl@0
   416
#if !defined(__SYMBIAN32__WSD__)
sl@0
   417
size_t _Filebuf_base::_M_page_size = 4096;
sl@0
   418
#endif //__SYMBIAN32__WSD__
sl@0
   419
sl@0
   420
_STLP_DECLSPEC _Filebuf_base::_Filebuf_base()
sl@0
   421
  : _M_file_id(INVALID_STLP_FD),
sl@0
   422
#if defined (_STLP_USE_WIN32_IO)
sl@0
   423
    _M_view_id(0),
sl@0
   424
#endif
sl@0
   425
    _M_openmode(0),
sl@0
   426
    _M_is_open(false),
sl@0
   427
    _M_should_close(false)
sl@0
   428
{}
sl@0
   429
sl@0
   430
void _Filebuf_base::_S_initialize() {
sl@0
   431
#if defined (_STLP_UNIX)  && !defined (__DJGPP) && !defined (_CRAY)
sl@0
   432
#  if defined (__APPLE__)
sl@0
   433
  int mib[2];
sl@0
   434
  size_t pagesize, len;
sl@0
   435
  mib[0] = CTL_HW;
sl@0
   436
  mib[1] = HW_PAGESIZE;
sl@0
   437
  len = sizeof(pagesize);
sl@0
   438
  sysctl(mib, 2, &pagesize, &len, NULL, 0);
sl@0
   439
  _M_page_size = pagesize;
sl@0
   440
#  elif defined (__DJGPP) && defined (_CRAY)
sl@0
   441
  _M_page_size = BUFSIZ;
sl@0
   442
#  else
sl@0
   443
  _M_page_size = sysconf(_SC_PAGESIZE);
sl@0
   444
#  endif
sl@0
   445
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   446
  SYSTEM_INFO SystemInfo;
sl@0
   447
  GetSystemInfo(&SystemInfo);
sl@0
   448
  _M_page_size = SystemInfo.dwPageSize;
sl@0
   449
  // might be .dwAllocationGranularity
sl@0
   450
#endif
sl@0
   451
}
sl@0
   452
sl@0
   453
// Return the size of the file.  This is a wrapper for stat.
sl@0
   454
// Returns zero if the size cannot be determined or is ill-defined.
sl@0
   455
_STLP_DECLSPEC streamoff _Filebuf_base::_M_file_size() {
sl@0
   456
  return _STLP_PRIV __file_size(_M_file_id);
sl@0
   457
}
sl@0
   458
sl@0
   459
_STLP_DECLSPEC bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
sl@0
   460
                            long permission) {
sl@0
   461
  _STLP_fd file_no;
sl@0
   462
sl@0
   463
  if (_M_is_open)
sl@0
   464
    return false;
sl@0
   465
sl@0
   466
#if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
   467
  int flags = 0;
sl@0
   468
sl@0
   469
  // Unix makes no distinction between text and binary files.
sl@0
   470
  switch(openmode & (~ios_base::ate & ~ios_base::binary)) {
sl@0
   471
  case ios_base::out:
sl@0
   472
  case ios_base::out | ios_base::trunc:
sl@0
   473
    flags = O_WRONLY | O_CREAT | O_TRUNC;
sl@0
   474
    break;
sl@0
   475
  case ios_base::out | ios_base::app:
sl@0
   476
    flags = O_WRONLY | O_CREAT | O_APPEND;
sl@0
   477
    break;
sl@0
   478
  case ios_base::in:
sl@0
   479
    flags = O_RDONLY;
sl@0
   480
    permission = 0;             // Irrelevant unless we're writing.
sl@0
   481
    break;
sl@0
   482
  case ios_base::in | ios_base::out:
sl@0
   483
    flags = O_RDWR;
sl@0
   484
    break;
sl@0
   485
  case ios_base::in | ios_base::out | ios_base::trunc:
sl@0
   486
    flags = O_RDWR | O_CREAT | O_TRUNC;
sl@0
   487
    break;
sl@0
   488
  default:                      // The above are the only combinations of
sl@0
   489
    return false;               // flags allowed by the C++ standard.
sl@0
   490
  }
sl@0
   491
sl@0
   492
#  if defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
   493
  if (openmode & ios_base::binary)
sl@0
   494
    flags |= O_BINARY;
sl@0
   495
  else
sl@0
   496
    flags |= O_TEXT;
sl@0
   497
sl@0
   498
  file_no = _open(name, flags, permission);
sl@0
   499
#  else
sl@0
   500
  file_no = OPEN(name, flags, permission);
sl@0
   501
#  endif /* _STLP_USE_UNIX_EMULATION_IO */
sl@0
   502
sl@0
   503
  if (file_no < 0)
sl@0
   504
    return false;
sl@0
   505
sl@0
   506
  _M_is_open = true;
sl@0
   507
sl@0
   508
  if (openmode & ios_base::ate)
sl@0
   509
    if (LSEEK(file_no, 0, SEEK_END) == -1)
sl@0
   510
      _M_is_open = false;
sl@0
   511
sl@0
   512
#elif defined (_STLP_USE_STDIO_IO)
sl@0
   513
  // use FILE-based i/o
sl@0
   514
  const char* flags;
sl@0
   515
sl@0
   516
  switch(openmode & (~ios_base::ate)) {
sl@0
   517
  case ios_base::out:
sl@0
   518
  case ios_base::out | ios_base::trunc:
sl@0
   519
    flags = "w";
sl@0
   520
    break;
sl@0
   521
sl@0
   522
  case ios_base::out | ios_base::binary:
sl@0
   523
  case ios_base::out | ios_base::trunc | ios_base::binary:
sl@0
   524
    flags = "wb";
sl@0
   525
    break;
sl@0
   526
sl@0
   527
  case ios_base::out | ios_base::app:
sl@0
   528
    flags = "a";
sl@0
   529
    break;
sl@0
   530
sl@0
   531
  case ios_base::out | ios_base::app | ios_base::binary:
sl@0
   532
    flags = "ab";
sl@0
   533
    break;
sl@0
   534
sl@0
   535
  case ios_base::in:
sl@0
   536
    flags = "r";
sl@0
   537
    break;
sl@0
   538
sl@0
   539
  case ios_base::in | ios_base::binary:
sl@0
   540
    flags = "rb";
sl@0
   541
    break;
sl@0
   542
sl@0
   543
  case ios_base::in | ios_base::out:
sl@0
   544
    flags = "r+";
sl@0
   545
    break;
sl@0
   546
sl@0
   547
  case ios_base::in | ios_base::out | ios_base::binary:
sl@0
   548
    flags = "r+b";
sl@0
   549
    break;
sl@0
   550
sl@0
   551
sl@0
   552
  case ios_base::in | ios_base::out | ios_base::trunc:
sl@0
   553
    flags = "w+";
sl@0
   554
    break;
sl@0
   555
sl@0
   556
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
sl@0
   557
    flags = "w+b";
sl@0
   558
    break;
sl@0
   559
sl@0
   560
  default:                      // The above are the only combinations of
sl@0
   561
    return false;               // flags allowed by the C++ standard.
sl@0
   562
  }
sl@0
   563
sl@0
   564
  // fbp :  : set permissions !
sl@0
   565
  (void)permission; // currently unused    //*TY 02/26/2000 - added to suppress warning message
sl@0
   566
  _M_file = FOPEN(name, flags);
sl@0
   567
sl@0
   568
  if (_M_file) {
sl@0
   569
    file_no = fileno(_M_file);
sl@0
   570
  }
sl@0
   571
  else
sl@0
   572
    return false;
sl@0
   573
sl@0
   574
  // unset buffering immediately
sl@0
   575
  setbuf(_M_file, 0);
sl@0
   576
sl@0
   577
  _M_is_open = true;
sl@0
   578
sl@0
   579
  if (openmode & ios_base::ate) {
sl@0
   580
    if (FSEEK(_M_file, 0, SEEK_END) == -1)
sl@0
   581
      _M_is_open = false;
sl@0
   582
  }
sl@0
   583
sl@0
   584
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   585
  DWORD dwDesiredAccess, dwCreationDisposition;
sl@0
   586
  bool doTruncate = false;
sl@0
   587
sl@0
   588
  switch (openmode & (~ios_base::ate & ~ios_base::binary)) {
sl@0
   589
  case ios_base::out:
sl@0
   590
  case ios_base::out | ios_base::trunc:
sl@0
   591
    dwDesiredAccess = GENERIC_WRITE;
sl@0
   592
    dwCreationDisposition = OPEN_ALWAYS;
sl@0
   593
    // boris : even though it is very non-intuitive, standard
sl@0
   594
    // requires them both to behave same.
sl@0
   595
    doTruncate = true;
sl@0
   596
    break;
sl@0
   597
  case ios_base::out | ios_base::app:
sl@0
   598
    dwDesiredAccess = GENERIC_WRITE;
sl@0
   599
    dwCreationDisposition = OPEN_ALWAYS;
sl@0
   600
    break;
sl@0
   601
  case ios_base::in:
sl@0
   602
    dwDesiredAccess = GENERIC_READ;
sl@0
   603
    dwCreationDisposition = OPEN_EXISTING;
sl@0
   604
    permission = 0;             // Irrelevant unless we're writing.
sl@0
   605
    break;
sl@0
   606
  case ios_base::in | ios_base::out:
sl@0
   607
    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
sl@0
   608
    dwCreationDisposition = OPEN_EXISTING;
sl@0
   609
    break;
sl@0
   610
  case ios_base::in | ios_base::out | ios_base::trunc:
sl@0
   611
    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
sl@0
   612
    dwCreationDisposition = OPEN_ALWAYS;
sl@0
   613
    doTruncate = true;
sl@0
   614
    break;
sl@0
   615
  default:                      // The above are the only combinations of
sl@0
   616
    return false;               // flags allowed by the C++ standard.
sl@0
   617
  }
sl@0
   618
sl@0
   619
  DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
sl@0
   620
sl@0
   621
#  if defined(_STLP_USE_WIDE_INTERFACE)
sl@0
   622
    file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(),
sl@0
   623
#  else
sl@0
   624
    file_no = CreateFileA(name,
sl@0
   625
#  endif
sl@0
   626
                          dwDesiredAccess, dwShareMode, 0,
sl@0
   627
                          dwCreationDisposition, permission, 0);
sl@0
   628
sl@0
   629
  if (file_no == INVALID_STLP_FD)
sl@0
   630
    return false;
sl@0
   631
sl@0
   632
  if ((doTruncate && SetEndOfFile(file_no) == 0) ||
sl@0
   633
      (((openmode & ios_base::ate) != 0) &&
sl@0
   634
       (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER))) {
sl@0
   635
    CloseHandle(file_no);
sl@0
   636
    return false;
sl@0
   637
  }
sl@0
   638
sl@0
   639
  _M_is_open = true;
sl@0
   640
sl@0
   641
#else
sl@0
   642
#  error "Port!"
sl@0
   643
#endif /* __unix */
sl@0
   644
sl@0
   645
  _M_file_id = file_no;
sl@0
   646
  _M_should_close = _M_is_open;
sl@0
   647
  _M_openmode = openmode;
sl@0
   648
sl@0
   649
  if (_M_is_open)
sl@0
   650
    _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
sl@0
   651
sl@0
   652
  return (_M_is_open != 0);
sl@0
   653
}
sl@0
   654
sl@0
   655
sl@0
   656
_STLP_DECLSPEC bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) {
sl@0
   657
  // This doesn't really grant everyone in the world read/write
sl@0
   658
  // access.  On Unix, file-creation system calls always clear
sl@0
   659
  // bits that are set in the umask from the permissions flag.
sl@0
   660
#ifdef _STLP_USE_WIN32_IO
sl@0
   661
  return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL);
sl@0
   662
#elif defined(__MRC__) || defined(__SC__)    //*TY 02/26/2000 - added support for MPW compilers
sl@0
   663
  return this->_M_open(name, openmode, 0);
sl@0
   664
#else
sl@0
   665
  return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |
sl@0
   666
                                       S_IWGRP | S_IROTH | S_IWOTH);
sl@0
   667
#endif
sl@0
   668
}
sl@0
   669
sl@0
   670
sl@0
   671
#if defined (_STLP_USE_WIN32_IO)
sl@0
   672
bool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) {
sl@0
   673
#  if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \
sl@0
   674
      (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__)
sl@0
   675
sl@0
   676
  if (_M_is_open || __id == INVALID_STLP_FD)
sl@0
   677
    return false;
sl@0
   678
sl@0
   679
  if (init_mode != ios_base::__default_mode)
sl@0
   680
    _M_openmode = init_mode;
sl@0
   681
  else
sl@0
   682
    _M_openmode = _get_osfflags(-1, __id);
sl@0
   683
sl@0
   684
  _M_is_open = true;
sl@0
   685
  _M_file_id = __id;
sl@0
   686
  _M_should_close = false;
sl@0
   687
  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
sl@0
   688
sl@0
   689
  return true;
sl@0
   690
#  else
sl@0
   691
  (void)__id;
sl@0
   692
  (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   693
sl@0
   694
  // not available for the API
sl@0
   695
  return false;
sl@0
   696
sl@0
   697
#  endif
sl@0
   698
}
sl@0
   699
#endif /* _STLP_USE_WIN32_IO */
sl@0
   700
sl@0
   701
// Associated the filebuf with a file descriptor pointing to an already-
sl@0
   702
// open file.  Mode is set to be consistent with the way that the file
sl@0
   703
// was opened.
sl@0
   704
_STLP_DECLSPEC bool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) {
sl@0
   705
  if (_M_is_open || file_no < 0)
sl@0
   706
    return false;
sl@0
   707
sl@0
   708
#if defined (_STLP_UNIX)
sl@0
   709
  (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   710
  int mode ;
sl@0
   711
  mode = fcntl(file_no, F_GETFL);
sl@0
   712
sl@0
   713
  if (mode == -1)
sl@0
   714
    return false;
sl@0
   715
sl@0
   716
  _M_openmode = flag_to_openmode(mode);
sl@0
   717
  _M_file_id = file_no;
sl@0
   718
#elif defined(__MRC__) || defined(__SC__)    //*TY 02/26/2000 - added support for MPW compilers
sl@0
   719
  (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   720
  switch (_iob[file_no]._flag & (_IOREAD|_IOWRT|_IORW) )
sl@0
   721
  {
sl@0
   722
  case _IOREAD:
sl@0
   723
    _M_openmode = ios_base::in; break;
sl@0
   724
  case _IOWRT:
sl@0
   725
    _M_openmode = ios_base::out; break;
sl@0
   726
  case _IORW:
sl@0
   727
    _M_openmode = ios_base::in | ios_base::out; break;
sl@0
   728
  default:
sl@0
   729
    return false;
sl@0
   730
  }
sl@0
   731
  _M_file_id = file_no;
sl@0
   732
#elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
sl@0
   733
  (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   734
  int mode ;
sl@0
   735
  struct STAT buf;
sl@0
   736
  if (FSTAT(file_no, &buf) != 0)
sl@0
   737
    return false;
sl@0
   738
  mode = buf.st_mode;
sl@0
   739
sl@0
   740
  switch(mode & (_S_IWRITE | _S_IREAD) ) {
sl@0
   741
  case _S_IREAD:
sl@0
   742
    _M_openmode = ios_base::in; break;
sl@0
   743
  case _S_IWRITE:
sl@0
   744
    _M_openmode = ios_base::out; break;
sl@0
   745
  case (_S_IWRITE | _S_IREAD):
sl@0
   746
    _M_openmode = ios_base::in | ios_base::out; break;
sl@0
   747
  default:
sl@0
   748
    return false;
sl@0
   749
  }
sl@0
   750
  _M_file_id = file_no;
sl@0
   751
#elif (defined (_STLP_USE_WIN32_IO) && defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE) ) || \
sl@0
   752
      (defined (__MINGW32__) && defined (__MSVCRT__)) || \
sl@0
   753
       defined (__DMC__)
sl@0
   754
sl@0
   755
  HANDLE oshandle = (HANDLE)_get_osfhandle(file_no);
sl@0
   756
  if (oshandle == INVALID_STLP_FD)
sl@0
   757
    return false;
sl@0
   758
sl@0
   759
  if (init_mode != ios_base::__default_mode)
sl@0
   760
    _M_openmode = init_mode;
sl@0
   761
  else
sl@0
   762
    _M_openmode = _get_osfflags(file_no, oshandle);
sl@0
   763
sl@0
   764
  _M_file_id = oshandle;
sl@0
   765
#else
sl@0
   766
  (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
sl@0
   767
  // not available for the API
sl@0
   768
#  define _STLP_NO_IMPLEMENTATION
sl@0
   769
#endif
sl@0
   770
sl@0
   771
#if !defined (_STLP_NO_IMPLEMENTATION)
sl@0
   772
  _M_is_open = true;
sl@0
   773
  _M_should_close = false;
sl@0
   774
  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
sl@0
   775
  return true;
sl@0
   776
#else
sl@0
   777
#  undef _STLP_NO_IMPLEMENTATION
sl@0
   778
  return false;
sl@0
   779
#endif
sl@0
   780
}
sl@0
   781
sl@0
   782
_STLP_DECLSPEC bool _Filebuf_base::_M_close() {
sl@0
   783
  if (!_M_is_open)
sl@0
   784
    return false;
sl@0
   785
sl@0
   786
  bool ok;
sl@0
   787
sl@0
   788
  if (!_M_should_close)
sl@0
   789
    ok = true;
sl@0
   790
  else {
sl@0
   791
sl@0
   792
#if defined (_STLP_USE_UNIX_IO)
sl@0
   793
sl@0
   794
    ok = (close(_M_file_id) == 0);
sl@0
   795
sl@0
   796
#elif defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
   797
sl@0
   798
    ok = (_close(_M_file_id) == 0);
sl@0
   799
sl@0
   800
#elif defined (_STLP_USE_STDIO_IO)
sl@0
   801
sl@0
   802
    ok = (fclose(_M_file) == 0);
sl@0
   803
sl@0
   804
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   805
sl@0
   806
    if (_M_file_id != INVALID_STLP_FD) {
sl@0
   807
      ok = (CloseHandle(_M_file_id) != 0);
sl@0
   808
    }
sl@0
   809
    else {
sl@0
   810
      ok = false;
sl@0
   811
    }
sl@0
   812
sl@0
   813
#else
sl@0
   814
sl@0
   815
    ok = false;
sl@0
   816
sl@0
   817
#endif /* _STLP_USE_UNIX_IO */
sl@0
   818
  }
sl@0
   819
sl@0
   820
  _M_is_open = _M_should_close = false;
sl@0
   821
  _M_openmode = 0;
sl@0
   822
  return ok;
sl@0
   823
}
sl@0
   824
sl@0
   825
sl@0
   826
#define _STLP_LF 10
sl@0
   827
#define _STLP_CR 13
sl@0
   828
#define _STLP_CTRLZ 26
sl@0
   829
sl@0
   830
// Read up to n characters into a buffer.  Return value is number of
sl@0
   831
// characters read.
sl@0
   832
_STLP_DECLSPEC ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) {
sl@0
   833
#if defined (_STLP_USE_UNIX_IO)
sl@0
   834
sl@0
   835
  return read(_M_file_id, buf, n);
sl@0
   836
sl@0
   837
#elif defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
   838
sl@0
   839
  return _read(_M_file_id, buf, n);
sl@0
   840
sl@0
   841
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   842
  ptrdiff_t readen = 0;
sl@0
   843
  //Here cast to size_t is safe as n cannot be negative.
sl@0
   844
  size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n));
sl@0
   845
  // The following, while validating that we are still able to extract chunkSize
sl@0
   846
  // charaters to the buffer, avoids extraction of too small chunk of datas
sl@0
   847
  // which would be counter performant.
sl@0
   848
  while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) {
sl@0
   849
    DWORD NumberOfBytesRead;
sl@0
   850
    ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &NumberOfBytesRead, 0);
sl@0
   851
sl@0
   852
    if (NumberOfBytesRead == 0)
sl@0
   853
      break;
sl@0
   854
sl@0
   855
    if (!(_M_openmode & ios_base::binary)) {
sl@0
   856
      // translate CR-LFs to LFs in the buffer
sl@0
   857
      char *to = buf + readen;
sl@0
   858
      char *from = to;
sl@0
   859
      char *last = from + NumberOfBytesRead - 1;
sl@0
   860
      for (; from <= last && *from != _STLP_CTRLZ; ++from) {
sl@0
   861
        if (*from != _STLP_CR)
sl@0
   862
          *to++ = *from;
sl@0
   863
        else { // found CR
sl@0
   864
          if (from < last) { // not at buffer end
sl@0
   865
            if (*(from + 1) != _STLP_LF)
sl@0
   866
              *to++ = _STLP_CR;
sl@0
   867
          }
sl@0
   868
          else { // last char is CR, peek for LF
sl@0
   869
            char peek = ' ';
sl@0
   870
            DWORD NumberOfBytesPeeked;
sl@0
   871
            ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0);
sl@0
   872
            if (NumberOfBytesPeeked != 0) {
sl@0
   873
              if (peek != _STLP_LF) { //not a <CR><LF> combination
sl@0
   874
                *to++ = _STLP_CR;
sl@0
   875
                if ((to < buf + n) && (peek != _STLP_CR))
sl@0
   876
                  //We have enough place to store peek and it is no a special
sl@0
   877
                  //_STLP_CR character, we can store it.
sl@0
   878
                  *to++ = peek;
sl@0
   879
                else
sl@0
   880
                  SetFilePointer(_M_file_id, (LONG)-1, 0, SEEK_CUR);
sl@0
   881
              }
sl@0
   882
              else {
sl@0
   883
                // A <CR><LF> combination, we keep the <LF>:
sl@0
   884
                *to++ = _STLP_LF;
sl@0
   885
              }
sl@0
   886
            }
sl@0
   887
            else {
sl@0
   888
              /* This case is tedious, we could
sl@0
   889
               *  - put peek back in the file but this would then generate an infinite loop
sl@0
   890
               *  - report an error as we don't know if in a future call to ReadFile we won't then
sl@0
   891
               *    get a <LF>. Doing so would make all files with a <CR> last an invalid file
sl@0
   892
               *    for STLport, a hard solution for STLport clients.
sl@0
   893
               *  - store the <CR> in the returned buffer, the chosen solution, even if in this
sl@0
   894
               *    case we could miss a <CR><LF> combination.
sl@0
   895
               */
sl@0
   896
              *to++ = _STLP_CR;
sl@0
   897
            }
sl@0
   898
          }
sl@0
   899
        } // found CR
sl@0
   900
      } // for
sl@0
   901
      // seek back to TEXT end of file if hit CTRL-Z
sl@0
   902
      if (from <= last) // terminated due to CTRLZ
sl@0
   903
        SetFilePointer(_M_file_id, (LONG)((last+1) - from), 0, SEEK_CUR);
sl@0
   904
      readen += to - (buf + readen);
sl@0
   905
    }
sl@0
   906
    else
sl@0
   907
      readen += NumberOfBytesRead;
sl@0
   908
  }
sl@0
   909
  return readen;
sl@0
   910
sl@0
   911
#elif defined (_STLP_USE_STDIO_IO)
sl@0
   912
sl@0
   913
  return fread(buf, 1, n, _M_file);
sl@0
   914
sl@0
   915
#else
sl@0
   916
#  error "Port!"
sl@0
   917
#endif /* __unix */
sl@0
   918
}
sl@0
   919
sl@0
   920
// Write n characters from a buffer.  Return value: true if we managed
sl@0
   921
// to write the entire buffer, false if we didn't.
sl@0
   922
_STLP_DECLSPEC bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) {
sl@0
   923
  for (;;) {
sl@0
   924
    ptrdiff_t written;
sl@0
   925
sl@0
   926
#if defined (_STLP_USE_UNIX_IO)
sl@0
   927
sl@0
   928
    written = write(_M_file_id, buf, n);
sl@0
   929
sl@0
   930
#elif defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
   931
sl@0
   932
    written = _write(_M_file_id, buf, n);
sl@0
   933
sl@0
   934
#elif defined (_STLP_USE_WIN32_IO)
sl@0
   935
sl@0
   936
    //In the following implementation we are going to cast most of the ptrdiff_t
sl@0
   937
    //values in size_t to work with coherent unsigned values. Doing so make code
sl@0
   938
    //more simple especially in the min function call.
sl@0
   939
sl@0
   940
    // In append mode, every write does an implicit seek to the end
sl@0
   941
    // of the file.
sl@0
   942
    if (_M_openmode & ios_base::app)
sl@0
   943
      _M_seek(0, ios_base::end);
sl@0
   944
sl@0
   945
    if (_M_openmode & ios_base::binary) {
sl@0
   946
      // binary mode
sl@0
   947
      size_t bytes_to_write = (size_t)n;
sl@0
   948
      DWORD NumberOfBytesWritten;
sl@0
   949
      written = 0;
sl@0
   950
      for (; bytes_to_write != 0;) {
sl@0
   951
        WriteFile(_M_file_id, buf + written,
sl@0
   952
                  __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)),
sl@0
   953
                  &NumberOfBytesWritten, 0);
sl@0
   954
        if (NumberOfBytesWritten == 0)
sl@0
   955
          return false;
sl@0
   956
        bytes_to_write -= NumberOfBytesWritten;
sl@0
   957
        written += NumberOfBytesWritten;
sl@0
   958
      }
sl@0
   959
    }
sl@0
   960
    else {
sl@0
   961
      char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end
sl@0
   962
      char * nextblock = buf, * ptrtextbuf = textbuf;
sl@0
   963
      char * endtextbuf = textbuf + _TEXTBUF_SIZE;
sl@0
   964
      char * endblock = buf + n;
sl@0
   965
      ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE);
sl@0
   966
      char * nextlf;
sl@0
   967
sl@0
   968
      while ( (nextblocksize > 0) &&
sl@0
   969
              (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) {
sl@0
   970
        ptrdiff_t linelength = nextlf - nextblock;
sl@0
   971
        memcpy(ptrtextbuf, nextblock, linelength);
sl@0
   972
        ptrtextbuf += linelength;
sl@0
   973
        nextblock += (linelength + 1);
sl@0
   974
        * ptrtextbuf ++ = _STLP_CR;
sl@0
   975
        * ptrtextbuf ++ = _STLP_LF;
sl@0
   976
        nextblocksize = (min) (ptrdiff_t(endblock - nextblock),
sl@0
   977
                               (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf)));
sl@0
   978
      }
sl@0
   979
      // write out what's left, > condition is here since for LF at the end ,
sl@0
   980
      // endtextbuf may get < ptrtextbuf ...
sl@0
   981
      if (nextblocksize > 0) {
sl@0
   982
        memcpy(ptrtextbuf, nextblock, nextblocksize);
sl@0
   983
        ptrtextbuf += nextblocksize;
sl@0
   984
        nextblock += nextblocksize;
sl@0
   985
      }
sl@0
   986
      // now write out the translated buffer
sl@0
   987
      char * writetextbuf = textbuf;
sl@0
   988
      for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf);
sl@0
   989
           NumberOfBytesToWrite;) {
sl@0
   990
        DWORD NumberOfBytesWritten;
sl@0
   991
        WriteFile((HANDLE)_M_file_id, writetextbuf,
sl@0
   992
                  __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)),
sl@0
   993
                  &NumberOfBytesWritten, 0);
sl@0
   994
        if (!NumberOfBytesWritten) // write shortfall
sl@0
   995
          return false;
sl@0
   996
        writetextbuf += NumberOfBytesWritten;
sl@0
   997
        NumberOfBytesToWrite -= NumberOfBytesWritten;
sl@0
   998
      }
sl@0
   999
      // count non-translated characters
sl@0
  1000
      written = (nextblock - buf);
sl@0
  1001
    }
sl@0
  1002
sl@0
  1003
#elif defined (_STLP_USE_STDIO_IO)
sl@0
  1004
sl@0
  1005
    written = fwrite(buf, 1, n, _M_file);
sl@0
  1006
sl@0
  1007
#else
sl@0
  1008
#  error "Port!"
sl@0
  1009
#endif /* __unix */
sl@0
  1010
sl@0
  1011
    if (n == written)
sl@0
  1012
      return true;
sl@0
  1013
    else if (written > 0 && written < n) {
sl@0
  1014
      n -= written;
sl@0
  1015
      buf += written;
sl@0
  1016
    }
sl@0
  1017
    else
sl@0
  1018
      return false;
sl@0
  1019
  }
sl@0
  1020
}
sl@0
  1021
sl@0
  1022
sl@0
  1023
#ifdef _STLP_USE_WIN32_IO
sl@0
  1024
#  define STL_SEEK_SET FILE_BEGIN
sl@0
  1025
#  define STL_SEEK_CUR FILE_CURRENT
sl@0
  1026
#  define STL_SEEK_END FILE_END
sl@0
  1027
#else
sl@0
  1028
#  define STL_SEEK_SET SEEK_SET
sl@0
  1029
#  define STL_SEEK_CUR SEEK_CUR
sl@0
  1030
#  define STL_SEEK_END SEEK_END
sl@0
  1031
#endif
sl@0
  1032
sl@0
  1033
// Wrapper for lseek or the like.
sl@0
  1034
_STLP_DECLSPEC streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) {
sl@0
  1035
  streamoff result = -1;
sl@0
  1036
  int whence;
sl@0
  1037
sl@0
  1038
  switch(dir) {
sl@0
  1039
  case ios_base::beg:
sl@0
  1040
    if (offset < 0 /* || offset > _M_file_size() */ )
sl@0
  1041
      return streamoff(-1);
sl@0
  1042
    whence = STL_SEEK_SET;
sl@0
  1043
    break;
sl@0
  1044
  case ios_base::cur:
sl@0
  1045
    whence = STL_SEEK_CUR;
sl@0
  1046
    break;
sl@0
  1047
  case ios_base::end:
sl@0
  1048
    if (/* offset > 0 || */  -offset > _M_file_size() )
sl@0
  1049
      return streamoff(-1);
sl@0
  1050
    whence = STL_SEEK_END;
sl@0
  1051
    break;
sl@0
  1052
  default:
sl@0
  1053
    return streamoff(-1);
sl@0
  1054
  }
sl@0
  1055
sl@0
  1056
#if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
sl@0
  1057
sl@0
  1058
  result = LSEEK(_M_file_id, offset, whence);
sl@0
  1059
sl@0
  1060
#elif defined (_STLP_USE_STDIO_IO)
sl@0
  1061
sl@0
  1062
#if defined (__SYMBIAN32__)
sl@0
  1063
  /* This function is a wrapper for lseek and expects to return the offset in bytes from the beginning of the file. 
sl@0
  1064
    It is used by tellg as well as tellp (for setting/getting the file pointer). 
sl@0
  1065
    We don't want to use fseek for that. */
sl@0
  1066
  if (FSEEK(_M_file, offset, whence) != 0)
sl@0
  1067
	  return streamoff(-1);
sl@0
  1068
	result = FTELL(_M_file);
sl@0
  1069
#else
sl@0
  1070
  result = FSEEK(_M_file, offset, whence);
sl@0
  1071
#endif
sl@0
  1072
sl@0
  1073
#elif defined (_STLP_USE_WIN32_IO)
sl@0
  1074
sl@0
  1075
  LARGE_INTEGER li;
sl@0
  1076
  li.QuadPart = offset;
sl@0
  1077
  li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence);
sl@0
  1078
  if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR)
sl@0
  1079
    result = li.QuadPart;
sl@0
  1080
sl@0
  1081
#else
sl@0
  1082
#  error "Port!"
sl@0
  1083
#endif
sl@0
  1084
sl@0
  1085
  return result;
sl@0
  1086
}
sl@0
  1087
sl@0
  1088
sl@0
  1089
// Attempts to memory-map len bytes of the current file, starting
sl@0
  1090
// at position offset.  Precondition: offset is a multiple of the
sl@0
  1091
// page size.  Postcondition: return value is a null pointer if the
sl@0
  1092
// memory mapping failed.  Otherwise the return value is a pointer to
sl@0
  1093
// the memory-mapped file and the file position is set to offset.
sl@0
  1094
_STLP_DECLSPEC void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) {
sl@0
  1095
  void* base;
sl@0
  1096
#if defined (_STLP_UNIX) && !defined(__DJGPP) && !defined(_CRAY)
sl@0
  1097
  base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset);
sl@0
  1098
  if (base != (void*)MAP_FAILED) {
sl@0
  1099
    if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) {
sl@0
  1100
      this->_M_unmap(base, len);
sl@0
  1101
      base = 0;
sl@0
  1102
    }
sl@0
  1103
  } else
sl@0
  1104
    base =0;
sl@0
  1105
sl@0
  1106
#elif defined (_STLP_USE_WIN32_IO)
sl@0
  1107
  _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 ,
sl@0
  1108
                                 PAGE_READONLY, 0 /* len >> 32 */ ,
sl@0
  1109
                                 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size
sl@0
  1110
                                 0);
sl@0
  1111
sl@0
  1112
  if (_M_view_id) {
sl@0
  1113
#  if 0
sl@0
  1114
/*
sl@0
  1115
    printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n",
sl@0
  1116
     _M_view_id, _M_file_id, GetLastError(),
sl@0
  1117
     (int)cur_filesize, ULL(offset) & 0xffffffff, len);
sl@0
  1118
*/
sl@0
  1119
#  endif
sl@0
  1120
    base = MapViewOfFile(_M_view_id, FILE_MAP_READ, __STATIC_CAST(DWORD, ULL(offset) >> 32),
sl@0
  1121
                         __STATIC_CAST(DWORD, ULL(offset) & 0xffffffff),
sl@0
  1122
#  if !defined (__DMC__)
sl@0
  1123
                         __STATIC_CAST(SIZE_T, len));
sl@0
  1124
#  else
sl@0
  1125
                         __STATIC_CAST(DWORD, len));
sl@0
  1126
#  endif
sl@0
  1127
    // check if mapping succeded and is usable
sl@0
  1128
    if (base == 0  || _M_seek(offset + len, ios_base::beg) < 0) {
sl@0
  1129
      this->_M_unmap(base, len);
sl@0
  1130
      base = 0;
sl@0
  1131
    }
sl@0
  1132
  } else
sl@0
  1133
    base = 0;
sl@0
  1134
#else
sl@0
  1135
  (void)len;    //*TY 02/26/2000 - unused variables
sl@0
  1136
  (void)offset;    //*TY 02/26/2000 -
sl@0
  1137
  base = 0;
sl@0
  1138
#endif
sl@0
  1139
  return base;
sl@0
  1140
}
sl@0
  1141
sl@0
  1142
_STLP_DECLSPEC void _Filebuf_base::_M_unmap(void* base, streamoff len) {
sl@0
  1143
  // precondition : there is a valid mapping at the moment
sl@0
  1144
#if defined (_STLP_UNIX)  && !defined(__DJGPP) && !defined(_CRAY)
sl@0
  1145
  munmap((char*)base, len);
sl@0
  1146
#elif defined (_STLP_USE_WIN32_IO)
sl@0
  1147
  if (base != NULL)
sl@0
  1148
    UnmapViewOfFile(base);
sl@0
  1149
  // destroy view handle as well
sl@0
  1150
  if (_M_view_id != NULL)
sl@0
  1151
    CloseHandle(_M_view_id);
sl@0
  1152
  _M_view_id = NULL;
sl@0
  1153
  (void)len; //unused variable
sl@0
  1154
#else
sl@0
  1155
  (void)len;    //*TY 02/26/2000 - unused variables
sl@0
  1156
  (void)base;   //*TY 02/26/2000 -
sl@0
  1157
#endif
sl@0
  1158
}
sl@0
  1159
sl@0
  1160
#if defined (__SYMBIAN32__) && defined(__EPOC32__)
sl@0
  1161
_STLP_DECLSPEC size_t _Filebuf_base::__page_size()
sl@0
  1162
{
sl@0
  1163
	return _Filebuf_base::_M_page_size;
sl@0
  1164
}
sl@0
  1165
#endif
sl@0
  1166
// fbp : let us map 1 MB maximum, just be sure not to trash VM
sl@0
  1167
#define MMAP_CHUNK 0x100000L
sl@0
  1168
sl@0
  1169
_STLP_DECLSPEC int _STLP_CALL
sl@0
  1170
_Underflow<char, char_traits<char> >::_M_doit (basic_filebuf<char, char_traits<char> >* __this) {
sl@0
  1171
  if (!__this->_M_in_input_mode) {
sl@0
  1172
    if (!__this->_M_switch_to_input_mode())
sl@0
  1173
      return traits_type::eof();
sl@0
  1174
  }
sl@0
  1175
  else if (__this->_M_in_putback_mode) {
sl@0
  1176
    __this->_M_exit_putback_mode();
sl@0
  1177
    if (__this->gptr() != __this->egptr()) {
sl@0
  1178
      int_type __c = traits_type::to_int_type(*__this->gptr());
sl@0
  1179
      return __c;
sl@0
  1180
    }
sl@0
  1181
  }
sl@0
  1182
sl@0
  1183
  // If it's a disk file, and if the internal and external character
sl@0
  1184
  // sequences are guaranteed to be identical, then try to use memory
sl@0
  1185
  // mapped I/O.  Otherwise, revert to ordinary read.
sl@0
  1186
  if (__this->_M_base.__regular_file()
sl@0
  1187
      && __this->_M_always_noconv
sl@0
  1188
      && __this->_M_base._M_in_binary_mode()) {
sl@0
  1189
    // If we've mmapped part of the file already, then unmap it.
sl@0
  1190
    if (__this->_M_mmap_base)
sl@0
  1191
      __this->_M_base._M_unmap(__this->_M_mmap_base, __this->_M_mmap_len);
sl@0
  1192
    __this->_M_mmap_base = 0;
sl@0
  1193
    __this->_M_mmap_len = 0;
sl@0
  1194
sl@0
  1195
    // Determine the position where we start mapping.  It has to be
sl@0
  1196
    // a multiple of the page size.
sl@0
  1197
    streamoff __cur = __this->_M_base._M_seek(0, ios_base::cur);
sl@0
  1198
    streamoff __size = __this->_M_base._M_file_size();
sl@0
  1199
    if (__size > 0 && __cur >= 0 && __cur < __size) {
sl@0
  1200
      streamoff __offset = (__cur / __this->_M_base.__page_size()) * __this->_M_base.__page_size();
sl@0
  1201
      streamoff __remainder = __cur - __offset;
sl@0
  1202
sl@0
  1203
      __this->_M_mmap_len = __size - __offset;
sl@0
  1204
sl@0
  1205
      if (__this->_M_mmap_len > MMAP_CHUNK)
sl@0
  1206
        __this->_M_mmap_len = MMAP_CHUNK;
sl@0
  1207
sl@0
  1208
      if ((__this->_M_mmap_base =
sl@0
  1209
        __this->_M_base._M_mmap(__offset, __this->_M_mmap_len)) != 0) {
sl@0
  1210
        __this->setg((char*) __this->_M_mmap_base,
sl@0
  1211
                     (char*) __this->_M_mmap_base + __STATIC_CAST(ptrdiff_t, __remainder),
sl@0
  1212
                     (char*) __this->_M_mmap_base + __STATIC_CAST(ptrdiff_t, __this->_M_mmap_len));
sl@0
  1213
        return traits_type::to_int_type(*__this->gptr());
sl@0
  1214
      }
sl@0
  1215
    } else /* size > 0 ... */ {
sl@0
  1216
      // There is nothing to map. We unmapped the file above, now zap pointers.
sl@0
  1217
      __this->_M_mmap_base = 0;
sl@0
  1218
      __this->_M_mmap_len = 0;
sl@0
  1219
    }
sl@0
  1220
  }
sl@0
  1221
sl@0
  1222
  return __this->_M_underflow_aux();
sl@0
  1223
}
sl@0
  1224
sl@0
  1225
sl@0
  1226
//----------------------------------------------------------------------
sl@0
  1227
// Force instantiation of filebuf and fstream classes.
sl@0
  1228
#if !defined(_STLP_NO_FORCE_INSTANTIATE)
sl@0
  1229
sl@0
  1230
template class basic_filebuf<char, char_traits<char> >;
sl@0
  1231
template class basic_ifstream<char, char_traits<char> >;
sl@0
  1232
template class basic_ofstream<char, char_traits<char> >;
sl@0
  1233
template class basic_fstream<char, char_traits<char> >;
sl@0
  1234
sl@0
  1235
#  if !defined (_STLP_NO_WCHAR_T)
sl@0
  1236
template class _Underflow<wchar_t, char_traits<wchar_t> >;
sl@0
  1237
template class basic_filebuf<wchar_t, char_traits<wchar_t> >;
sl@0
  1238
template class basic_ifstream<wchar_t, char_traits<wchar_t> >;
sl@0
  1239
template class basic_ofstream<wchar_t, char_traits<wchar_t> >;
sl@0
  1240
template class basic_fstream<wchar_t, char_traits<wchar_t> >;
sl@0
  1241
#  endif /* _STLP_NO_WCHAR_T */
sl@0
  1242
sl@0
  1243
#endif
sl@0
  1244
sl@0
  1245
_STLP_END_NAMESPACE
sl@0
  1246
sl@0
  1247
// Local Variables:
sl@0
  1248
// mode:C++
sl@0
  1249
// End: