Bug 8862 mget and mput couldn't read and write 64 bit data from binary file 72/11272/4
AKindyakov [Mon, 22 Apr 2013 16:22:48 +0000 (18:22 +0200)]
Change-Id: I0f8609105b450a05489c230a6196c95bbf10677b

scilab/CHANGES_5.5.X
scilab/modules/fileio/help/en_US/mget.xml
scilab/modules/fileio/help/en_US/mput.xml
scilab/modules/fileio/help/ru_RU/mget.xml
scilab/modules/fileio/help/ru_RU/mput.xml
scilab/modules/fileio/src/c/mget.c
scilab/modules/fileio/src/c/mput.c
scilab/modules/fileio/tests/nonreg_tests/bug_8862.dia.ref [new file with mode: 0644]
scilab/modules/fileio/tests/nonreg_tests/bug_8862.tst [new file with mode: 0644]

index 72c54cb..a73c3e2 100644 (file)
@@ -99,6 +99,9 @@ Bug fixes
 
 * Bug #8824 fixed - taucs_chfact returned a segfault (not the case in mode nwni).
 
+* Bug #8862 fixed -  mget and mput couldn't read and write 64 bit data from    78
+                     binary file.
+
 * Bug #9004 fixed - bitcmp function called with one input argument returned an error.
 
 * Bug #9059 fixed - tbx_build_macros and genlib do not stop on error.
index 64c06dd..8e364cb 100644 (file)
             <varlistentry>
                 <term>l</term>
                 <listitem>
-                    <para>long</para>
+                    <para>long long int</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>i</term>
                 <listitem>
-                    <para>int</para>
+                    <para>int or long int</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
index 930fb53..c92dd17 100644 (file)
@@ -66,7 +66,8 @@
                 <term>"l", "i", "s", "ul", "ui", "us", "d", "f", "c", "uc"</term>
                 <listitem>
                     <para>
-                        for  writing respectively a long, an int, a short, an unsigned long, an unsigned int, an unsigned short, a double, a float, a char and an unsigned char. The bytes which are wrote are automatically swapped if necessary (by checking little-endian status) in order to produce machine independent binary files (in little-endian mode). This default swapping mode can be suppressed by adding a flag <code>swap = 0</code> in the <function>mopen</function> function.
+                        for  writing respectively a long long, an int (long
+                        int), a short, an unsigned long long int, an unsigned int (long int), an unsigned short, a double, a float, a char and an unsigned char. The bytes which are wrote are automatically swapped if necessary (by checking little-endian status) in order to produce machine independent binary files (in little-endian mode). This default swapping mode can be suppressed by adding a flag <code>swap = 0</code> in the <function>mopen</function> function.
                     </para>
                 </listitem>
             </varlistentry>
index 5ff48ee..56f4c27 100644 (file)
             <varlistentry>
                 <term>l</term>
                 <listitem>
-                    <para>длинное, long</para>
+                    <para>длинное, long long</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
                 <term>i</term>
                 <listitem>
-                    <para>целочисленное, int</para>
+                    <para>целочисленное, int (long int)</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
index e3c7e4f..970f350 100644 (file)
@@ -71,7 +71,8 @@
                 <term>"l", "i", "s", "ul", "ui", "us", "d", "f", "c", "uc"</term>
                 <listitem>
                     <para>
-                        для записи соответственно типов long, int, short, unsigned long, unsigned int, unsigned short, double, float, char и unsigned char. Байты, которые записываются, автоматически переставляются, если нужно (это проверяется статусом прямого порядка байтов) для того, чтобы сделать двоичные файлы, независимые от машины. Режим перестановки байтов по умолчанию может быть подавлен добавлением флага <code>swap = 0</code> в функции <function>mopen</function>.
+                        для записи соответственно типов long long, int(long
+                        int), short, unsigned long long, unsigned int(long int), unsigned short, double, float, char и unsigned char. Байты, которые записываются, автоматически переставляются, если нужно (это проверяется статусом прямого порядка байтов) для того, чтобы сделать двоичные файлы, независимые от машины. Режим перестановки байтов по умолчанию может быть подавлен добавлением флага <code>swap = 0</code> в функции <function>mopen</function>.
                     </para>
                 </listitem>
             </varlistentry>
index a8fac87..09b95dc 100644 (file)
@@ -14,9 +14,6 @@
 #include <string.h>
 #ifndef _MSC_VER
 #include <stdint.h>
-#else
-#define int32_t long
-#define uint32_t unsigned long
 #endif
 #include "mget.h"
 #include "filesmanagement.h"
@@ -32,42 +29,42 @@ int swap = 0;
 * reads data and store them without type conversion
 * =================================================*/
 /*--------------------------------------------------------------------------*/
-#define MGET_CHAR_NC(Type)                                     \
-  {                                                            \
+#define MGET_CHAR_NC(Type)                                      \
+  {                                                                              \
     Type *val = (Type *) res ;                                 \
-    items=(int)fread(val,sizeof(Type),n,fa);                   \
+    items=(int)fread(val,sizeof(Type),n,fa);   \
   }
 
 /*--------------------------------------------------------------------------*/
-#define MGET_NC(Type) {                                                \
-    Type *val = (Type *) res ;                                 \
-    if (swap) {                                                        \
-      items=0;                                                 \
-      for ( i=0; i< n; i++)  {                                 \
-       unsigned long long tmp;                                 \
-       items+=(int)fread(&tmp,sizeof(Type),1,fa);              \
-       swap_generic((char *)&tmp,(char *)val, sizeof(Type));   \
-       val++;                                                  \
-      }                                                                \
-    }                                                          \
-    else items=(int)fread(val,sizeof(Type),n,fa);              \
+#define MGET_NC(Type) {                                                                  \
+    Type *val = (Type *) res ;                                                   \
+    if (swap) {                                                                                   \
+      items=0;                                                                               \
+      for ( i=0; i< n; i++)  {                                                   \
+             unsigned long long tmp;                                                     \
+             items+=(int)fread(&tmp,sizeof(Type),1,fa);                      \
+             swap_generic((char *)&tmp,(char *)val, sizeof(Type));     \
+             val++;                                                                               \
+      }                                                                                                 \
+    }                                                                                              \
+    else items=(int)fread(val,sizeof(Type),n,fa);                       \
   }
 /*--------------------------------------------------------------------------*/
-#define MGET_GEN_NC(NumType,cf)                                        \
-  {                                                            \
-    switch (cf) {                                              \
-    case ' ':                                                  \
+#define MGET_GEN_NC(NumType,cf)                           \
+  {                                                                           \
+    switch (cf) {                                                       \
+    case ' ':                                                           \
       MGET_NC(NumType);break;                                  \
-    case 'b':                                                  \
-      swap = (islittleendian()==1)? 1:0;                       \
+    case 'b':                                                     \
+      swap = (islittleendian()==1)? 1:0;  \
     MGET_NC(NumType); break;                                   \
-    case 'l':                                                  \
-      swap = (islittleendian()==1) ? 0:1;                      \
+    case 'l':                                                           \
+      swap = (islittleendian()==1) ? 0:1; \
     MGET_NC(NumType);  break;                                  \
-    default:                                                   \
+    default:                                                      \
       sciprint(_("%s: Wrong value for input argument #%d: '%s' or '%s' or '%s' expected.\n"),"mget",4," ","b","l"); \
-      *ierr=1; return;                                         \
-    }                                                          \
+      *ierr=1; return;                                            \
+    }                                                                         \
 }
 /*--------------------------------------------------------------------------*/
 void C2F(mgetnc) (int *fd, void *res, int *n1, char *type, int *ierr)
@@ -89,50 +86,52 @@ void C2F(mgetnc) (int *fd, void *res, int *n1, char *type, int *ierr)
     switch (type[0])
     {
         case 'i':
-            MGET_GEN_NC(int, c1);
-
+            MGET_GEN_NC(long, c1);
             break;
+
         case 'l':
-            MGET_GEN_NC(int32_t, c1);
+            MGET_GEN_NC(long long, c1);
             break;
+
         case 's':
             MGET_GEN_NC(short, c1);
-
             break;
+
         case 'c':
             MGET_CHAR_NC(char);
-
             break;
+
         case 'd':
             MGET_GEN_NC(double, c1);
-
             break;
+
         case 'f':
             MGET_GEN_NC(float, c1);
-
             break;
+
         case 'u':
             switch (c1)
             {
                 case 'i':
-                    MGET_GEN_NC(unsigned int, c2);
-
+                    MGET_GEN_NC(unsigned long, c2);
                     break;
+
                 case 'l':
-                    MGET_GEN_NC(uint32_t, c2);
+                    MGET_GEN_NC(unsigned long long, c2);
                     break;
+
                 case 's':
                     MGET_GEN_NC(unsigned short, c2);
-
                     break;
+
                 case ' ':
                     MGET_GEN_NC(unsigned int, ' ');
-
                     break;
+
                 case 'c':
                     MGET_CHAR_NC(unsigned char);
-
                     break;
+
                 default:
                     *ierr = 1;
                     return;
@@ -178,50 +177,52 @@ void mget2(FILE * fa, int swap2, double *res, int n, char *type, int *ierr)
     switch (type[0])
     {
         case 'i':
-            MGET_GEN(int, c1);
-
+            MGET_GEN(long, c1);
             break;
+
         case 'l':
-            MGET_GEN(int32_t, c1);
+            MGET_GEN(long long, c1);
             break;
+
         case 's':
             MGET_GEN(short, c1);
-
             break;
+
         case 'c':
             MGET_CHAR(char);
-
             break;
+
         case 'd':
             MGET_GEN(double, c1);
-
             break;
+
         case 'f':
             MGET_GEN(float, c1);
-
             break;
+
         case 'u':
             switch (c1)
             {
                 case 'i':
-                    MGET_GEN(unsigned int, c2);
-
+                    MGET_GEN(unsigned long, c2);
                     break;
+
                 case 'l':
-                    MGET_GEN(uint32_t, c2);
+                    MGET_GEN(unsigned long long, c2);
                     break;
+
                 case 's':
                     MGET_GEN(unsigned short, c2);
-
                     break;
+
                 case ' ':
                     MGET_GEN(unsigned int, ' ');
-
                     break;
+
                 case 'c':
                     MGET_CHAR(unsigned char);
-
                     break;
+
                 default:
                     *ierr = 1;
                     return;
index d8a88fe..12dfba1 100644 (file)
@@ -14,9 +14,6 @@
 #include <string.h>
 #ifndef _MSC_VER
 #include <stdint.h>
-#else
-#define int32_t long
-#define uint32_t unsigned long
 #endif
 #include "mput.h"
 #include "filesmanagement.h"
@@ -90,10 +87,10 @@ void C2F(mputnc) (int *fd, void * res, int *n1, char *type, int *ierr)
     switch ( type[0] )
     {
         case 'i' :
-            MPUT_GEN_NC(int, c1);
+            MPUT_GEN_NC(long, c1);
             break;
         case 'l' :
-            MPUT_GEN_NC(int32_t, c1);
+            MPUT_GEN_NC(long long, c1);
             break;
         case 's' :
             MPUT_GEN_NC(short, c1);
@@ -111,10 +108,10 @@ void C2F(mputnc) (int *fd, void * res, int *n1, char *type, int *ierr)
             switch ( c1 )
             {
                 case 'i' :
-                    MPUT_GEN_NC(unsigned int, c2);
+                    MPUT_GEN_NC(unsigned long, c2);
                     break;
                 case 'l' :
-                    MPUT_GEN_NC(uint32_t, c2);
+                    MPUT_GEN_NC(unsigned long long, c2);
                     break;
                 case 's' :
                     MPUT_GEN_NC(unsigned short, c2);
@@ -192,10 +189,10 @@ void mput2 (FILE *fa, int swap2, double *res, int n, char *type, int *ierr)
     switch ( type[0] )
     {
         case 'i' :
-            MPUT_GEN(int, c1);
+            MPUT_GEN(long, c1);
             break;
         case 'l' :
-            MPUT_GEN(int32_t, c1);
+            MPUT_GEN(long long, c1);
             break;
         case 's' :
             MPUT_GEN(short, c1);
@@ -213,10 +210,10 @@ void mput2 (FILE *fa, int swap2, double *res, int n, char *type, int *ierr)
             switch ( c1 )
             {
                 case 'i' :
-                    MPUT_GEN(unsigned int, c2);
+                    MPUT_GEN(unsigned long, c2);
                     break;
                 case 'l' :
-                    MPUT_GEN(uint32_t, c2);
+                    MPUT_GEN(unsigned long long, c2);
                     break;
                 case 's' :
                     MPUT_GEN(unsigned short, c2);
diff --git a/scilab/modules/fileio/tests/nonreg_tests/bug_8862.dia.ref b/scilab/modules/fileio/tests/nonreg_tests/bug_8862.dia.ref
new file mode 100644 (file)
index 0000000..dc3820d
--- /dev/null
@@ -0,0 +1,37 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) DIGITEO - 2013 - Alexander Kindyakov
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- Non-regression test for bug 8862 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=8862
+//
+// <-- Short Description -->
+// Trying to read binary file by mget function. 
+// I want to read a uint64 bits data, then I using "mget(1,'ul',fid)".
+// I found it only reads 32bits not 64bits. the mget(1,'l',fid) does same got 32bits.
+// <-- Scilab error message -->
+// mget reading 64bits got 32bits
+bf = mopen(TMPDIR+'/foo','wb');
+ierr = execstr('mput(1996,''l'',bf);','errcatch');
+if ierr <> 0 then bugmes();quit;end
+ierr = execstr('mput(1996,''ul'',bf);','errcatch');
+if ierr <> 0 then bugmes();quit;end
+ierr = execstr('mput(10000000000,''l'',bf);','errcatch');
+if ierr <> 0 then bugmes();quit;end
+ierr = execstr('mput(10000000000,''ul'',bf);','errcatch');
+if ierr <> 0 then bugmes();quit;end
+mclose(bf);
+bf= mopen(TMPDIR+'/foo','rb');
+ierr = execstr('a = mget(1,''l'',bf);','errcatch');
+if ierr <> 0 | a <> 1996 then bugmes();quit;end
+ierr = execstr('a = mget(1,''ul'',bf);','errcatch');
+if ierr <> 0 | a <> 1996 then bugmes();quit;end
+ierr = execstr('a = mget(1,''l'',bf);','errcatch');
+if ierr <> 0 | a <> 10000000000 then bugmes();quit;end
+ierr = execstr('a = mget(1,''ul'',bf);','errcatch');
+if ierr <> 0 | a <> 10000000000 then bugmes();quit;end
+mclose(bf);
diff --git a/scilab/modules/fileio/tests/nonreg_tests/bug_8862.tst b/scilab/modules/fileio/tests/nonreg_tests/bug_8862.tst
new file mode 100644 (file)
index 0000000..70cec80
--- /dev/null
@@ -0,0 +1,41 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) DIGITEO - 2013 - Alexander Kindyakov
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- Non-regression test for bug 8862 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=8862
+//
+// <-- Short Description -->
+
+// Trying to read binary file by mget function. 
+// I want to read a uint64 bits data, then I using "mget(1,'ul',fid)".
+// I found it only reads 32bits not 64bits. the mget(1,'l',fid) does same got 32bits.
+
+// <-- Scilab error message -->
+// mget reading 64bits got 32bits
+
+bf = mopen(TMPDIR+'/foo','wb');
+ierr = execstr('mput(1996,''l'',bf);','errcatch');
+if ierr <> 0 then pause,end
+ierr = execstr('mput(1996,''ul'',bf);','errcatch');
+if ierr <> 0 then pause,end
+ierr = execstr('mput(10000000000,''l'',bf);','errcatch');
+if ierr <> 0 then pause,end
+ierr = execstr('mput(10000000000,''ul'',bf);','errcatch');
+if ierr <> 0 then pause,end
+mclose(bf);
+
+bf= mopen(TMPDIR+'/foo','rb');
+ierr = execstr('a = mget(1,''l'',bf);','errcatch');
+if ierr <> 0 | a <> 1996 then pause,end
+ierr = execstr('a = mget(1,''ul'',bf);','errcatch');
+if ierr <> 0 | a <> 1996 then pause,end
+ierr = execstr('a = mget(1,''l'',bf);','errcatch');
+if ierr <> 0 | a <> 10000000000 then pause,end
+ierr = execstr('a = mget(1,''ul'',bf);','errcatch');
+if ierr <> 0 | a <> 10000000000 then pause,end
+mclose(bf);