fix mput/mputi for (u)int64 > 53 bits 38/18938/3
Antoine ELIAS [Tue, 24 Jan 2017 12:16:47 +0000 (13:16 +0100)]
Change-Id: Iddd55699bbe4e2e95e1a653bbd65cf1df63564f5

scilab/modules/fileio/fileio.vcxproj
scilab/modules/fileio/fileio.vcxproj.filters
scilab/modules/fileio/sci_gateway/cpp/sci_mput.cpp
scilab/modules/fileio/src/c/convert_tools.h
scilab/modules/fileio/src/cpp/mputi.hxx [new file with mode: 0644]

index e803a28..143004f 100644 (file)
@@ -335,6 +335,7 @@ lib /DEF:"$(ProjectDir)preferences_Import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Pla
     <ClInclude Include="includes\splitpath.h" />
     <ClInclude Include="includes\URIFileToFilename.h" />
     <ClInclude Include="src\cpp\mgetstr.h" />
+    <ClInclude Include="src\cpp\mputi.hxx" />
     <ClInclude Include="src\cpp\scilab_sscanf.hxx" />
     <ClInclude Include="src\c\basename.h" />
     <ClInclude Include="src\c\convert_tools.h" />
index 0236bca..cb2ed44 100644 (file)
     <ClInclude Include="includes\mputl.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="src\cpp\mputi.hxx">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="src\c\fileio.rc">
index 21c318e..1b9a62e 100644 (file)
@@ -1,9 +1,9 @@
 /*
-* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-* Copyright (C) 2006 - INRIA - Allan CORNET
-* Copyright (C) 2009 - DIGITEO - Allan CORNET
-* Copyright (C) 2010 - DIGITEO - Antoine ELIAS
-*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2006 - INRIA - Allan CORNET
+ * Copyright (C) 2009 - DIGITEO - Allan CORNET
+ * Copyright (C) 2010 - DIGITEO - Antoine ELIAS
+ *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
@@ -12,8 +12,9 @@
  * and continues to be available under such terms.
  * For more information, see the COPYING file which you should have received
  * along with this program.
-*
-*/
+ *
+ */
+
 /*--------------------------------------------------------------------------*/
 #include "filemanager.hxx"
 #include "fileio_gw.hxx"
@@ -21,6 +22,7 @@
 #include "double.hxx"
 #include "int.hxx"
 #include "function.hxx"
+#include "mputi.hxx"
 
 extern "C"
 {
@@ -35,11 +37,11 @@ extern "C"
 /*--------------------------------------------------------------------------*/
 types::Function::ReturnValue sci_mput(types::typed_list &in, int _iRetCount, types::typed_list &out)
 {
-    char* pstType   = os_strdup("l");//default type value : long
-    int iSize       = 0;
-    int iFile       = -1; //default file : last opened file
-    double* pData   = NULL;
-    int iErr        = 0;
+    char* pstType = os_strdup("l");//default type value : long
+    int iSize = 0;
+    int iFile = -1; //default file : last opened file
+    double* pData = NULL;
+    int iErr = 0;
 
     if (in.size() < 1 || in.size() > 3)
     {
@@ -95,91 +97,89 @@ types::Function::ReturnValue sci_mput(types::typed_list &in, int _iRetCount, typ
 
     if (in[0]->isDouble())
     {
+        int iErr = 0;
         pData = in[0]->getAs<types::Double>()->get();
+        C2F(mput)(&iFile, pData, &iSize, pstType, &iErr);
+
+        if (iErr)
+        {
+            FREE(pstType);
+            Scierror(10000, "");
+            return types::Function::Error;
+        }
     }
     else
     {
-        pData = (double*)malloc(iSize * sizeof(double));
-        if (in[0]->isInt8())
+        int err = 0;
+        switch (in[0]->getType())
         {
-            char* piData = in[0]->getAs<types::Int8>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabInt8:
             {
-                pData[i] = (double)piData[i];
+                char* piData = NULL;
+                piData = in[0]->getAs<types::Int8>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isUInt8())
-        {
-            unsigned char* piData = in[0]->getAs<types::UInt8>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabInt16:
             {
-                pData[i] = (double)piData[i];
+                short* piData = NULL;
+                piData = in[0]->getAs<types::Int16>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isInt16())
-        {
-            short* piData = in[0]->getAs<types::Int16>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabInt32:
             {
-                pData[i] = (double)piData[i];
+                int* piData = NULL;
+                piData = in[0]->getAs<types::Int32>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isUInt16())
-        {
-            unsigned short* piData = in[0]->getAs<types::UInt16>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabInt64:
             {
-                pData[i] = (double)piData[i];
+                long long* piData = NULL;
+                piData = in[0]->getAs<types::Int64>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isInt32())
-        {
-            int* piData = in[0]->getAs<types::Int32>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabUInt8:
             {
-                pData[i] = (double)piData[i];
+                unsigned char* piData = NULL;
+                piData = in[0]->getAs<types::UInt8>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isUInt32())
-        {
-            unsigned int* piData = in[0]->getAs<types::UInt32>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabUInt16:
             {
-                pData[i] = (double)piData[i];
+                unsigned short* piData = NULL;
+                piData = in[0]->getAs<types::UInt16>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isInt64())
-        {
-            long long* piData = in[0]->getAs<types::Int64>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabUInt32:
             {
-                pData[i] = (double)piData[i];
+                unsigned int* piData = NULL;
+                piData = in[0]->getAs<types::UInt32>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
-        }
-        else if (in[0]->isUInt64())
-        {
-            unsigned long long* piData = in[0]->getAs<types::UInt64>()->get();
-            for (int i = 0; i < iSize; i++)
+            case types::InternalType::ScilabUInt64:
             {
-                pData[i] = (double)piData[i];
+                unsigned long long* piData = NULL;
+                piData = in[0]->getAs<types::UInt64>()->get();
+                err = mputi(iFile, piData, iSize, pstType);
+                break;
             }
         }
-    }
 
-    C2F(mput)(&iFile, pData, &iSize, pstType, &iErr);
-
-    FREE(pstType);
-    if (in[0]->isDouble() == false)
-    {
-        free(pData);
-    }
-
-    if (iErr)
-    {
-        Scierror(10000, "");
-        return types::Function::Error;
+        if (err)
+        {
+            FREE(pstType);
+            Scierror(10000, "");
+            return types::Function::Error;
+        }
     }
 
+    FREE(pstType);
     return types::Function::OK;
 }
 /*--------------------------------------------------------------------------*/
index 32cd07a..a870b65 100644 (file)
@@ -12,7 +12,9 @@
  * along with this program.
  *
  */
+
 #include <stdio.h>
+#include "dynlib_fileio.h"
 
 #ifndef __CONVERT_TOOLS_H__
 #define __CONVERT_TOOLS_H__
@@ -40,17 +42,17 @@ int swap_int(int _val);
 char swap_char(char _val);
 long long swap_long_long(long long _val);
 
-int writeInt(int _val, FILE* _pF, int _iEndian);
-int writeLongLong(long long _val, FILE* _pF, int _iEndian);
-int writeShort(short _val, FILE* _pF, int _iEndian);
-int writeChar(char _val, FILE* _pF, int _iEndian);
+FILEIO_IMPEXP int writeInt(int _val, FILE* _pF, int _iEndian);
+FILEIO_IMPEXP int writeLongLong(long long _val, FILE* _pF, int _iEndian);
+FILEIO_IMPEXP int writeShort(short _val, FILE* _pF, int _iEndian);
+FILEIO_IMPEXP int writeChar(char _val, FILE* _pF, int _iEndian);
 
-int readInt(FILE* _pF, int _iEndian, unsigned int* val);
-int readLongLong(FILE* _pF, int _iEndian, unsigned long long* val);
-int readShort(FILE* _pF, int _iEndian, unsigned short* val);
-int readChar(FILE* _pF, int _iEndian, unsigned char* val);
+FILEIO_IMPEXP int readInt(FILE* _pF, int _iEndian, unsigned int* val);
+FILEIO_IMPEXP int readLongLong(FILE* _pF, int _iEndian, unsigned long long* val);
+FILEIO_IMPEXP int readShort(FILE* _pF, int _iEndian, unsigned short* val);
+FILEIO_IMPEXP int readChar(FILE* _pF, int _iEndian, unsigned char* val);
 
-int checkEndian(char _endian);
-int checkType(char _type);
+FILEIO_IMPEXP int checkEndian(char _endian);
+FILEIO_IMPEXP int checkType(char _type);
 
 #endif /* !__CONVERT_TOOLS_H__ */
diff --git a/scilab/modules/fileio/src/cpp/mputi.hxx b/scilab/modules/fileio/src/cpp/mputi.hxx
new file mode 100644 (file)
index 0000000..5bc5db3
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2017 - Scilab Enterprises - Antoine ELIAS
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+ *
+ */
+
+/*--------------------------------------------------------------------------*/
+#ifndef __MPUTI_H__
+#define __MPUTI_H__
+
+#include <string.h>
+#include "filemanager.hxx"
+#include "mputi.hxx"
+
+extern "C" {
+#include "Scierror.h"
+#include "localization.h"
+#include "islittleendian.h"
+#include "convert_tools.h"
+}
+
+
+template <typename T>
+static T mputi_getIntVal(const T* in, int index)
+{
+    T ret = (T)in[index];
+    return ret;
+}
+
+template <typename T>
+int mputi(int fd, const T* _val, int size, const char* opt)
+{
+    int iType = 0;
+    int iUnsigned = 0;
+    int iEndian = 0;
+
+    int iTypeLen = (int)strlen(opt);
+    int i;
+
+    types::File *pFile = FileManager::getFile(fd);
+    if (!pFile || pFile->getFiledesc() == NULL)
+    {
+        Scierror(999, _("%s: No output file.\n"), "mputi");
+        return 1;
+    }
+
+    if (iTypeLen == 1)
+    {
+        //type only
+        iUnsigned = SIGNED;
+        iType = checkType(opt[0]);
+    }
+    else if (iTypeLen == 2)
+    {
+        if (opt[0] == 'u')
+        {
+            //unsigned + type
+            iUnsigned = UNSIGNED;
+            iType = checkType(opt[1]);
+        }
+        else
+        {
+            //type + endian
+            iUnsigned = SIGNED;
+            iType = checkType(opt[0]);
+            iEndian = checkEndian(opt[1]);
+        }
+    }
+    else if (iTypeLen == 3)
+    {
+        if (opt[0] == 'u')
+        {
+            //unsigned + type
+            iUnsigned = UNSIGNED;
+            iType = checkType(opt[1]);
+            iEndian = checkEndian(opt[2]);
+        }
+    }
+
+    if (iEndian == 0)
+    {
+        //endian can be setting up by mopen call with flag swap
+        if (pFile->getFileSwap())
+        {
+            iEndian = islittleendian() ? BIG_ENDIAN : LITTLE_ENDIAN;
+        }
+        else
+        {
+            iEndian = islittleendian() ? LITTLE_ENDIAN : BIG_ENDIAN;
+        }
+    }
+    else
+    {
+        if (iEndian == LITTLE_ENDIAN)
+        {
+            iEndian = islittleendian() ? LITTLE_ENDIAN : BIG_ENDIAN;
+        }
+        else
+        {
+            iEndian = islittleendian() ? BIG_ENDIAN : LITTLE_ENDIAN;
+        }
+    }
+
+    if (iType == 0 || iEndian == 0 || iUnsigned == 0)
+    {
+        Scierror(999, _("%s: %s format not recognized.\n"), "mputi", opt);
+        return 1;
+    }
+
+    switch (iType)
+    {
+        case TYPE_LONG_LONG:
+            for (i = 0; i < size; i++)
+            {
+                unsigned long long val;
+                val = (unsigned long long)mputi_getIntVal(_val, i);
+                if (writeLongLong(val, pFile->getFiledesc(), iEndian))
+                {
+                    return 1;
+                }
+            }
+            break;
+        case TYPE_INT:
+            for (i = 0; i < size; i++)
+            {
+                unsigned int val;
+                val = (unsigned int)mputi_getIntVal(_val, i);
+                if (writeInt(val, pFile->getFiledesc(), iEndian))
+                {
+                    return 1;
+                }
+            }
+            break;
+        case TYPE_SHORT:
+            for (i = 0; i < size; i++)
+            {
+                unsigned short val;
+                val = (unsigned short)mputi_getIntVal(_val, i);
+                if (writeShort(val, pFile->getFiledesc(), iEndian))
+                {
+                    return 1;
+                }
+            }
+            break;
+        case TYPE_CHAR:
+            for (i = 0; i < size; i++)
+            {
+                unsigned char val;
+                val = (unsigned char)mputi_getIntVal(_val, i);
+                if (writeChar(val, pFile->getFiledesc(), iEndian))
+                {
+                    return 1;
+                }
+            }
+            break;
+    }
+
+    return 0;
+}
+
+#endif /* __MPUTI_H__ */