[CRT]
[reactos.git] / reactos / lib / sdk / crt / stdio / file.c
index 6425575..b35d402 100644 (file)
@@ -83,31 +83,22 @@ int *__p___mb_cur_max(void);
 /* values for wxflag in file descriptor */
 #define WX_OPEN           0x01
 #define WX_ATEOF          0x02
+#define WX_READNL         0x04  /* read started with \n */
 #define WX_READEOF        0x04  /* like ATEOF, but for underlying file rather than buffer */
 #define WX_READCR         0x08  /* underlying file is at \r */
 #define WX_DONTINHERIT    0x10
 #define WX_APPEND         0x20
 #define WX_TEXT           0x80
 
-/* values for exflag - it's used differently in msvcr90.dll*/
-#define EF_UTF8           0x01
-#define EF_UTF16          0x02
-#define EF_CRIT_INIT      0x04
-#define EF_UNK_UNICODE    0x08
-
-static char utf8_bom[3] = { 0xef, 0xbb, 0xbf };
-static char utf16_bom[2] = { 0xff, 0xfe };
-
 /* FIXME: this should be allocated dynamically */
 #define MAX_FILES 2048
 #define FD_BLOCK_SIZE 64
 
-/* ioinfo structure size is different in msvcrXX.dll's */
 typedef struct {
     HANDLE              handle;
     unsigned char       wxflag;
     char                unk1;
-    int                 exflag;
+    BOOL                crit_init;
     CRITICAL_SECTION    crit;
 } ioinfo;
 
@@ -1247,9 +1238,7 @@ void CDECL rewind(FILE* file)
 static int get_flags(const wchar_t* mode, int *open_flags, int* stream_flags)
 {
   int plus = strchrW(mode, '+') != NULL;
-  
-  while(*mode == ' ') mode++;
-  
+
   switch(*mode++)
   {
   case 'R': case 'r':
@@ -1270,10 +1259,7 @@ static int get_flags(const wchar_t* mode, int *open_flags, int* stream_flags)
     return -1;
   }
 
-  /* FIXME */
-  /* *stream_flags |= MSVCRT__commode; */
-  
-  while (*mode && *mode!=',')
+  while (*mode)
     switch (*mode++)
     {
     case 'B': case 'b':
@@ -1284,83 +1270,12 @@ static int get_flags(const wchar_t* mode, int *open_flags, int* stream_flags)
       *open_flags |=  _O_TEXT;
       *open_flags &= ~_O_BINARY;
       break;
-    case 'D':
-      *open_flags |= _O_TEMPORARY;
-      break;
-    case 'T':
-      *open_flags |= _O_SHORT_LIVED;
-      break;
-      /* FIXME 
-   case 'c':
-      *stream_flags |= _IOCOMMIT;
-      break;
-    case 'n':
-      *stream_flags &= ~_IOCOMMIT;
-      break;      
-      */
-    case 'N':
-      *open_flags |= _O_NOINHERIT;
-      break;
     case '+':
     case ' ':
-    case 'a':
-    case 'w':
-      break;
-    case 'S':
-    case 'R':
-      FIXME("ignoring cache optimization flag: %c\n", mode[-1]);
       break;
     default:
-      ERR("incorrect mode flag: %c\n", mode[-1]);
-      break;
-    }
-
-  if(*mode == ',')
-  {
-    static const WCHAR ccs[] = {'c','c','s'};
-    static const WCHAR utf8[] = {'u','t','f','-','8'};
-    static const WCHAR utf16le[] = {'u','t','f','-','1','6','l','e'};
-    static const WCHAR unicode[] = {'u','n','i','c','o','d','e'};
-
-    mode++;
-    while(*mode == ' ') mode++;
-    if(!MSVCRT_CHECK_PMT(!strncmpW(ccs, mode, sizeof(ccs)/sizeof(ccs[0]))))
-      return -1;
-    mode += sizeof(ccs)/sizeof(ccs[0]);
-    while(*mode == ' ') mode++;
-    if(!MSVCRT_CHECK_PMT(*mode == '='))
-        return -1;
-    mode++;
-    while(*mode == ' ') mode++;
-
-    if(!strncmpiW(utf8, mode, sizeof(utf8)/sizeof(utf8[0])))
-    {
-      *open_flags |= _O_U8TEXT;
-      mode += sizeof(utf8)/sizeof(utf8[0]);
-    }
-    else if(!strncmpiW(utf16le, mode, sizeof(utf16le)/sizeof(utf16le[0])))
-    {
-      *open_flags |= _O_U16TEXT;
-      mode += sizeof(utf16le)/sizeof(utf16le[0]);
-    }
-    else if(!strncmpiW(unicode, mode, sizeof(unicode)/sizeof(unicode[0])))
-    {
-      *open_flags |= _O_WTEXT;
-      mode += sizeof(unicode)/sizeof(unicode[0]);
+      FIXME(":unknown flag %c not supported\n",mode[-1]);
     }
-    else
-    {
-      _invalid_parameter(NULL, NULL, NULL, 0, 0);
-      *_errno() = EINVAL;
-      return -1;
-    }
-
-    while(*mode == ' ') mode++;
-  }
-
- if(!MSVCRT_CHECK_PMT(*mode == 0))
-    return -1;
-  
   return 0;
 }
 
@@ -1549,23 +1464,19 @@ wchar_t * CDECL _wmktemp(wchar_t *pattern)
     int         wxflags = 0;
     unsigned unsupp; /* until we support everything */
 
-    if (oflags & _O_APPEND)                     wxflags |= WX_APPEND;
-    if (oflags & _O_BINARY)                     {/* Nothing to do */}
-    else if (oflags & _O_TEXT)                  wxflags |= WX_TEXT;
-    else if (oflags & _O_WTEXT)                 wxflags |= WX_TEXT;
-    else if (oflags & _O_U16TEXT)               wxflags |= WX_TEXT;
-    else if (oflags & _O_U8TEXT)                wxflags |= WX_TEXT;    
-    else if (*__p__fmode() & _O_BINARY)         {/* Nothing to do */}
+    if (oflags & _O_APPEND)              wxflags |= WX_APPEND;
+    if (oflags & _O_BINARY)              {/* Nothing to do */}
+    else if (oflags & _O_TEXT)           wxflags |= WX_TEXT;
+    else if (*__p__fmode() & _O_BINARY)  {/* Nothing to do */}
     else                                        wxflags |= WX_TEXT; /* default to TEXT*/
-    if (oflags & _O_NOINHERIT)                  wxflags |= WX_DONTINHERIT;
+    if (oflags & _O_NOINHERIT)           wxflags |= WX_DONTINHERIT;
 
     if ((unsupp = oflags & ~(
                     _O_BINARY|_O_TEXT|_O_APPEND|
                     _O_TRUNC|_O_EXCL|_O_CREAT|
                     _O_RDWR|_O_WRONLY|_O_TEMPORARY|
                     _O_NOINHERIT|
-                    _O_SEQUENTIAL|_O_RANDOM|_O_SHORT_LIVED|
-                    _O_WTEXT|_O_U16TEXT|_O_U8TEXT
+                    _O_SEQUENTIAL|_O_RANDOM|_O_SHORT_LIVED
                     )))
         ERR(":unsupported oflags 0x%04x\n",unsupp);
 
@@ -1643,8 +1554,7 @@ int CDECL _sopen_s( int *fd, const char *path, int oflags, int shflags, int pmod
 
   if (!fd)
   {
-    MSVCRT_INVALID_PMT("null out fd pointer");
-    *_errno() = EINVAL;
+    MSVCRT_INVALID_PMT("null out fd pointer", EINVAL);
     return EINVAL;
   }
 
@@ -1746,29 +1656,6 @@ int CDECL _sopen( const char *path, int oflags, int shflags, ... )
   return fd;
 }
 
-static int check_bom(HANDLE h, int oflags, BOOL seek)
-{
-    char bom[sizeof(utf8_bom)];
-    DWORD r;
-
-    oflags &= ~(_O_WTEXT|_O_U16TEXT|_O_U8TEXT);
-
-    if (!ReadFile(h, bom, sizeof(utf8_bom), &r, NULL))
-        return oflags;
-
-    if (r==sizeof(utf8_bom) && !memcmp(bom, utf8_bom, sizeof(utf8_bom))) {
-        oflags |= _O_U8TEXT;
-    }else if (r>=sizeof(utf16_bom) && !memcmp(bom, utf16_bom, sizeof(utf16_bom))) {
-        if (seek && r>2)
-            SetFilePointer(h, 2, NULL, FILE_BEGIN);
-        oflags |= _O_U16TEXT;
-    }else if (seek) {
-        SetFilePointer(h, 0, NULL, FILE_BEGIN);
-    }
-
-    return oflags;
-}
-
 /*********************************************************************
  *              _wsopen_s (MSVCRT.@)
  */
@@ -1785,8 +1672,7 @@ int CDECL _wsopen_s( int *fd, const wchar_t* path, int oflags, int shflags, int
 
   if (!fd)
   {
-    MSVCRT_INVALID_PMT("null out fd pointer");
-    *_errno() = EINVAL;
+    MSVCRT_INVALID_PMT("null out fd pointer", EINVAL);
     return EINVAL;
   }
 
@@ -1852,21 +1738,6 @@ int CDECL _wsopen_s( int *fd, const wchar_t* path, int oflags, int shflags, int
   sa.lpSecurityDescriptor = NULL;
   sa.bInheritHandle       = (oflags & _O_NOINHERIT) ? FALSE : TRUE;
 
-   if ((oflags&(_O_WTEXT|_O_U16TEXT|_O_U8TEXT))
-          && (creation==OPEN_ALWAYS || creation==OPEN_EXISTING)
-          && !(access&GENERIC_READ))
-  {
-      hand = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
-              &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
-      if (hand != INVALID_HANDLE_VALUE)
-      {
-          oflags = check_bom(hand, oflags, FALSE);
-          CloseHandle(hand);
-      }
-      else
-          oflags &= ~(_O_WTEXT|_O_U16TEXT|_O_U8TEXT);
-  }
-  
   hand = CreateFileW(path, access, sharing, &sa, creation, attrib, 0);
 
   if (hand == INVALID_HANDLE_VALUE)  {
@@ -1875,56 +1746,7 @@ int CDECL _wsopen_s( int *fd, const wchar_t* path, int oflags, int shflags, int
     return *_errno();
   }
 
-   if (oflags & (_O_WTEXT|_O_U16TEXT|_O_U8TEXT))
-  {
-      if ((access & GENERIC_WRITE) && (creation==CREATE_NEW
-                  || creation==CREATE_ALWAYS || creation==TRUNCATE_EXISTING
-                  || (creation==OPEN_ALWAYS && GetLastError()==ERROR_ALREADY_EXISTS)))
-      {
-          if (oflags & _O_U8TEXT)
-          {
-              DWORD written = 0, tmp;
-
-              while(written!=sizeof(utf8_bom) && WriteFile(hand, (char*)utf8_bom+written,
-                          sizeof(utf8_bom)-written, &tmp, NULL))
-                  written += tmp;
-              if (written != sizeof(utf8_bom)) {
-                  WARN("error writing BOM\n");
-                  CloseHandle(hand);
-                  *_errno() = GetLastError();
-                  return *_errno();
-              }
-          }
-          else
-          {
-              DWORD written = 0, tmp;
-
-              while(written!=sizeof(utf16_bom) && WriteFile(hand, (char*)utf16_bom+written,
-                          sizeof(utf16_bom)-written, &tmp, NULL))
-                  written += tmp;
-              if (written != sizeof(utf16_bom))
-              {
-                  WARN("error writing BOM\n");
-                  CloseHandle(hand);
-                  *_errno() = GetLastError();
-                  return *_errno();
-              }
-          }
-      }
-      else if (access & GENERIC_READ)
-          oflags = check_bom(hand, oflags, TRUE);
-  }
-  
   *fd = alloc_fd(hand, wxflag);
-  if (*fd == -1)
-      return *_errno();
-
-  if (oflags & _O_WTEXT)
-      get_ioinfo(*fd)->exflag |= EF_UTF16|EF_UNK_UNICODE;
-  else if (oflags & _O_U16TEXT)
-      get_ioinfo(*fd)->exflag |= EF_UTF16;
-  else if (oflags & _O_U8TEXT)
-      get_ioinfo(*fd)->exflag |= EF_UTF8;
 
   TRACE(":fd (%d) handle (%p)\n", *fd, hand);
   return 0;
@@ -2990,7 +2812,7 @@ FILE* CDECL _wfreopen(const wchar_t *path, const wchar_t *mode, FILE* file)
 {
   int open_flags, stream_flags, fd;
 
-  TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file->_file);
+  TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file ? file->_file : -1);
 
   LOCK_FILES();
   if (!file || ((fd = file->_file) < 0) || fd > fdend)
@@ -3073,8 +2895,6 @@ int CDECL fsetpos(FILE* file, const fpos_t *pos)
  */
 __int64 CDECL _ftelli64(FILE* file)
 {
-    /* TODO: just call fgetpos and return lower half of result */
-    int off=0;
     __int64 pos;
 
     _lock_file(file);
@@ -3084,26 +2904,50 @@ __int64 CDECL _ftelli64(FILE* file)
         return -1;
     }
     if(file->_bufsiz)  {
-        if( file->_flag & _IOWRT ) {
-            off = file->_ptr - file->_base;
+        if(file->_flag & _IOWRT) {
+            pos += file->_ptr - file->_base;
+
+            if(get_ioinfo(file->_file)->wxflag & WX_TEXT) {
+                char *p;
+
+                for(p=file->_base; p<file->_ptr; p++)
+                    if(*p == '\n')
+                        pos++;
+            }
+        } else if(!file->_cnt) { /* nothing to do */
+        } else if(_lseeki64(file->_file, 0, SEEK_END)==pos) {
+            int i;
+
+            pos -= file->_cnt;
+            if(get_ioinfo(file->_file)->wxflag & WX_TEXT) {
+                for(i=0; i<file->_cnt; i++)
+                    if(file->_ptr[i] == '\n')
+                        pos--;
+            }
         } else {
-            off = -file->_cnt;
-            if (get_ioinfo(file->_file)->wxflag & WX_TEXT) {
-                /* Black magic correction for CR removal */
-                int i;
-                for (i=0; i<file->_cnt; i++) {
-                    if (file->_ptr[i] == '\n')
-                        off--;
-                }
-                /* Black magic when reading CR at buffer boundary*/
-                if(get_ioinfo(file->_file)->wxflag & WX_READCR)
-                    off--;
+            char *p;
+
+            if(_lseeki64(file->_file, pos, SEEK_SET) != pos) {
+                _unlock_file(file);
+                return -1;
+            }
+
+            pos -= file->_bufsiz;
+            pos += file->_ptr - file->_base;
+
+            if(get_ioinfo(file->_file)->wxflag & WX_TEXT) {
+                if(get_ioinfo(file->_file)->wxflag & WX_READNL)
+                    pos--;
+
+                for(p=file->_base; p<file->_ptr; p++)
+                    if(*p == '\n')
+                        pos++;
             }
         }
     }
 
     _unlock_file(file);
-    return off + pos;
+    return pos;
 }
 
 /*********************************************************************