fix mput/mputi for (u)int64 > 53 bits
[scilab.git] / scilab / modules / fileio / src / cpp / mputi.hxx
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2017 - Scilab Enterprises - Antoine ELIAS
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 /*--------------------------------------------------------------------------*/
14 #ifndef __MPUTI_H__
15 #define __MPUTI_H__
16
17 #include <string.h>
18 #include "filemanager.hxx"
19 #include "mputi.hxx"
20
21 extern "C" {
22 #include "Scierror.h"
23 #include "localization.h"
24 #include "islittleendian.h"
25 #include "convert_tools.h"
26 }
27
28
29 template <typename T>
30 static T mputi_getIntVal(const T* in, int index)
31 {
32     T ret = (T)in[index];
33     return ret;
34 }
35
36 template <typename T>
37 int mputi(int fd, const T* _val, int size, const char* opt)
38 {
39     int iType = 0;
40     int iUnsigned = 0;
41     int iEndian = 0;
42
43     int iTypeLen = (int)strlen(opt);
44     int i;
45
46     types::File *pFile = FileManager::getFile(fd);
47     if (!pFile || pFile->getFiledesc() == NULL)
48     {
49         Scierror(999, _("%s: No output file.\n"), "mputi");
50         return 1;
51     }
52
53     if (iTypeLen == 1)
54     {
55         //type only
56         iUnsigned = SIGNED;
57         iType = checkType(opt[0]);
58     }
59     else if (iTypeLen == 2)
60     {
61         if (opt[0] == 'u')
62         {
63             //unsigned + type
64             iUnsigned = UNSIGNED;
65             iType = checkType(opt[1]);
66         }
67         else
68         {
69             //type + endian
70             iUnsigned = SIGNED;
71             iType = checkType(opt[0]);
72             iEndian = checkEndian(opt[1]);
73         }
74     }
75     else if (iTypeLen == 3)
76     {
77         if (opt[0] == 'u')
78         {
79             //unsigned + type
80             iUnsigned = UNSIGNED;
81             iType = checkType(opt[1]);
82             iEndian = checkEndian(opt[2]);
83         }
84     }
85
86     if (iEndian == 0)
87     {
88         //endian can be setting up by mopen call with flag swap
89         if (pFile->getFileSwap())
90         {
91             iEndian = islittleendian() ? BIG_ENDIAN : LITTLE_ENDIAN;
92         }
93         else
94         {
95             iEndian = islittleendian() ? LITTLE_ENDIAN : BIG_ENDIAN;
96         }
97     }
98     else
99     {
100         if (iEndian == LITTLE_ENDIAN)
101         {
102             iEndian = islittleendian() ? LITTLE_ENDIAN : BIG_ENDIAN;
103         }
104         else
105         {
106             iEndian = islittleendian() ? BIG_ENDIAN : LITTLE_ENDIAN;
107         }
108     }
109
110     if (iType == 0 || iEndian == 0 || iUnsigned == 0)
111     {
112         Scierror(999, _("%s: %s format not recognized.\n"), "mputi", opt);
113         return 1;
114     }
115
116     switch (iType)
117     {
118         case TYPE_LONG_LONG:
119             for (i = 0; i < size; i++)
120             {
121                 unsigned long long val;
122                 val = (unsigned long long)mputi_getIntVal(_val, i);
123                 if (writeLongLong(val, pFile->getFiledesc(), iEndian))
124                 {
125                     return 1;
126                 }
127             }
128             break;
129         case TYPE_INT:
130             for (i = 0; i < size; i++)
131             {
132                 unsigned int val;
133                 val = (unsigned int)mputi_getIntVal(_val, i);
134                 if (writeInt(val, pFile->getFiledesc(), iEndian))
135                 {
136                     return 1;
137                 }
138             }
139             break;
140         case TYPE_SHORT:
141             for (i = 0; i < size; i++)
142             {
143                 unsigned short val;
144                 val = (unsigned short)mputi_getIntVal(_val, i);
145                 if (writeShort(val, pFile->getFiledesc(), iEndian))
146                 {
147                     return 1;
148                 }
149             }
150             break;
151         case TYPE_CHAR:
152             for (i = 0; i < size; i++)
153             {
154                 unsigned char val;
155                 val = (unsigned char)mputi_getIntVal(_val, i);
156                 if (writeChar(val, pFile->getFiledesc(), iEndian))
157                 {
158                     return 1;
159                 }
160             }
161             break;
162     }
163
164     return 0;
165 }
166
167 #endif /* __MPUTI_H__ */