Mercurial > forge
annotate extra/NaN/src/xptopen.cpp @ 12678:e4374feb2e3f octave-forge
[nan-tb] fix bug when file open fails; address several compiler warnings
author | schloegl |
---|---|
date | Thu, 20 Aug 2015 09:01:53 +0000 |
parents | 4e0e24d27b82 |
children | 13815b367946 |
rev | line source |
---|---|
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1 //------------------------------------------------------------------- |
11615 | 2 // XPTOPEN is C-MEX implementation for reading various |
3 // statistical data formats including SAS/XPT, SPSS/PASW, | |
4 // STATA and ARFF data formats. Basic support for writing | |
5 // SAS/XPT is also supported. | |
6 // Endian conversion is done automatically. | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
7 // |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
8 // usage: x = xptopen(filename) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
9 // usage: x = xptopen(filename,'r') |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
10 // read filename and return variables in struct x |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
11 // usage: xptopen(filename,'w',x) |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
12 // save fields of struct x in filename |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
13 // usage: x = xptopen(filename,'a',x) |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
14 // append fields of struct x to filename |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
15 // |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
16 // References: |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
17 // |
11615 | 18 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
19 // This program is free software; you can redistribute it and/or modify |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
20 // it under the terms of the GNU General Public License as published by |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
21 // the Free Software Foundation; either version 3 of the License, or |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
22 // (at your option) any later version. |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
23 // |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
24 // This program is distributed in the hope that it will be useful, |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
25 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
26 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
27 // GNU General Public License for more details. |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
28 // |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
29 // You should have received a copy of the GNU General Public License |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
30 // along with this program; if not, see <http://www.gnu.org/licenses/>. |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
31 // |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
32 // $Id$ |
11615 | 33 // Copyright (C) 2010,2011,2012,2013 Alois Schloegl <alois.schloegl@ist.ac.at> |
7415
780e178d44f7
remove obsolete code; improve reading variable names (prevents seg-fault in some special case); write: put XPTOPEN into header; experimental date/time conversion
schloegl
parents:
7376
diff
changeset
|
34 // This function is part of the NaN-toolbox |
7889 | 35 // http://pub.ist.ac.at/~schloegl/matlab/NaN/ |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
36 // |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
37 // References: |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
38 // [1] TS-140 THE RECORD LAYOUT OF A DATA SET IN SAS TRANSPORT (XPORT) FORMAT |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
39 // http://support.sas.com/techsup/technote/ts140.html |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
40 // [2] IBM floating point format |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
41 // http://en.wikipedia.org/wiki/IBM_Floating_Point_Architecture |
7426 | 42 // [3] see http://old.nabble.com/Re%3A-IBM-integer-and-double-formats-p20428979.html |
43 // [4] STATA File Format | |
7762 | 44 // http://www.stata.com/help.cgi?dta |
7426 | 45 // http://www.stata.com/help.cgi?dta_113 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
46 //------------------------------------------------------------------- |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
47 |
7426 | 48 /* |
49 SPSS file format | |
50 // http://cvs.savannah.gnu.org/pspp/doc/data-file-format.texi?root=pspp&content-type=text%2Fplain | |
51 */ | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
52 |
12584 | 53 #define TEST_CONVERSION 0 // 0: ieee754, 1: SAS converter (big endian bug), 2: experimental |
54 #define DEBUG 1 | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
55 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
56 #include <ctype.h> |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
57 #include <math.h> |
8045 | 58 //#include <sqlite.h> |
7888 | 59 #include <stdint.h> |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
60 #include <stdio.h> |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
61 #include <string.h> |
8105 | 62 #include <sys/param.h> |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
63 #include <time.h> |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
64 #include "mex.h" |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
65 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
66 #ifdef tmwtypes_h |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
67 #if (MX_API_VER<=0x07020000) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
68 typedef int mwSize; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
69 typedef int mwIndex; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
70 #endif |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
71 #endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
72 |
7426 | 73 #define NaN (0.0/0.0) |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
74 #define fix(m) (m<0 ? ceil(m) : floor(m)) |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
75 #define max(a,b) (((a) > (b)) ? (a) : (b)) |
7415
780e178d44f7
remove obsolete code; improve reading variable names (prevents seg-fault in some special case); write: put XPTOPEN into header; experimental date/time conversion
schloegl
parents:
7376
diff
changeset
|
76 #define min(a,b) (((a) < (b)) ? (a) : (b)) |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
77 |
10134 | 78 |
10133 | 79 #if 0 |
80 | |
12310 | 81 #elif defined(__linux__) |
82 # include <endian.h> | |
83 # include <byteswap.h> | |
84 | |
85 #elif defined(__CYGWIN__) | |
10134 | 86 # include <endian.h> |
10133 | 87 # include <byteswap.h> |
88 | |
89 #elif defined(__GLIBC__) // for Hurd | |
10134 | 90 # include <endian.h> |
10133 | 91 # include <byteswap.h> |
92 | |
93 #elif defined(__MINGW32__) | |
9970 | 94 /* use local version because MINGW does not provide byteswap.h */ |
10133 | 95 # define __BIG_ENDIAN 4321 |
96 # define __LITTLE_ENDIAN 1234 | |
97 # define __BYTE_ORDER __LITTLE_ENDIAN | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
98 |
9970 | 99 #elif defined(__NetBSD__) |
100 # include <sys/bswap.h> | |
101 # define __BIG_ENDIAN _BIG_ENDIAN | |
102 # define __LITTLE_ENDIAN _LITTLE_ENDIAN | |
103 # define __BYTE_ORDER _BYTE_ORDER | |
104 # define bswap_16(x) bswap16(x) | |
105 # define bswap_32(x) bswap32(x) | |
106 # define bswap_64(x) bswap64(x) | |
107 | |
11616
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
108 #elif defined(_APPLE_) && defined(_MACH_) |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
109 # include <machine/endian.h> |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
110 # define _BYTE_ORDER __DARWIN_BYTE_ORDER |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
111 # define _LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
112 # define _BIG_ENDIAN __DARWIN_BIG_ENDIAN |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
113 # define bswap_16(x) __bswap16(x) |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
114 # define bswap_32(x) __bswap32(x) |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
115 # define bswap_64(x) __bswap64(x) |
bbe18d223f02
add patch as suggested by Dirk http://savannah.gnu.org/bugs/?38670
schloegl
parents:
11615
diff
changeset
|
116 |
9970 | 117 #elif defined(__APPLE__) |
118 # include <CoreFoundation/CFByteOrder.h> | |
10133 | 119 # define __BIG_ENDIAN 4321 |
120 # define __LITTLE_ENDIAN 1234 | |
121 #if (defined(__LITTLE_ENDIAN__) && (__LITTLE_ENDIAN__ == 1)) | |
122 #define __BYTE_ORDER __LITTLE_ENDIAN | |
123 #else | |
124 #define __BYTE_ORDER __BIG_ENDIAN | |
125 #endif | |
9970 | 126 # define bswap_16(x) CFSwapInt16(x) |
127 # define bswap_32(x) CFSwapInt32(x) | |
128 # define bswap_64(x) CFSwapInt64(x) | |
7490 | 129 |
10133 | 130 #elif (defined(BSD) && (BSD >= 199103)) && !defined(__GLIBC__) |
9970 | 131 # include <machine/endian.h> |
132 # define __BIG_ENDIAN _BIG_ENDIAN | |
133 # define __LITTLE_ENDIAN _LITTLE_ENDIAN | |
134 # define __BYTE_ORDER _BYTE_ORDER | |
135 # define bswap_16(x) __bswap16(x) | |
136 # define bswap_32(x) __bswap32(x) | |
137 # define bswap_64(x) __bswap64(x) | |
8105 | 138 |
9970 | 139 #elif defined(__GNUC__) |
140 /* use byteswap macros from the host system, hopefully optimized ones ;-) */ | |
141 # include <endian.h> | |
142 # include <byteswap.h> | |
143 # define bswap_16(x) __bswap_16 (x) | |
144 # define bswap_32(x) __bswap_32 (x) | |
145 # define bswap_64(x) __bswap_64 (x) | |
146 | |
147 #elif defined(__sparc__) | |
148 # define __BIG_ENDIAN 4321 | |
149 # define __LITTLE_ENDIAN 1234 | |
150 # define __BYTE_ORDER __BIG_ENDIAN | |
151 | |
10134 | 152 #else |
153 # error Unknown platform | |
9970 | 154 #endif |
155 | |
10134 | 156 #if defined(__MINGW32__) || defined(__sparc__) |
9970 | 157 |
158 # ifndef bswap_16 | |
159 # define bswap_16(x) \ | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
160 ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8)) |
9970 | 161 # endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
162 |
9970 | 163 # ifndef bswap_32 |
164 # define bswap_32(x) \ | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
165 ((((x) & 0xff000000) >> 24) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
166 | (((x) & 0x00ff0000) >> 8) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
167 | (((x) & 0x0000ff00) << 8) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
168 | (((x) & 0x000000ff) << 24)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
169 |
9970 | 170 # endif |
171 | |
172 # ifndef bswap_64 | |
173 # define bswap_64(x) \ | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
174 ((((x) & 0xff00000000000000ull) >> 56) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
175 | (((x) & 0x00ff000000000000ull) >> 40) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
176 | (((x) & 0x0000ff0000000000ull) >> 24) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
177 | (((x) & 0x000000ff00000000ull) >> 8) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
178 | (((x) & 0x00000000ff000000ull) << 8) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
179 | (((x) & 0x0000000000ff0000ull) << 24) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
180 | (((x) & 0x000000000000ff00ull) << 40) \ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
181 | (((x) & 0x00000000000000ffull) << 56)) |
9970 | 182 # endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
183 |
10134 | 184 #endif |
185 | |
186 | |
187 #if !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN) | |
188 #error ENDIANITY is not known | |
189 #endif | |
190 | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
191 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
192 #if __BYTE_ORDER == __BIG_ENDIAN |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
193 #define l_endian_u16(x) ((uint16_t)bswap_16((uint16_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
194 #define l_endian_u32(x) ((uint32_t)bswap_32((uint32_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
195 #define l_endian_u64(x) ((uint64_t)bswap_64((uint64_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
196 #define l_endian_i16(x) ((int16_t)bswap_16((int16_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
197 #define l_endian_i32(x) ((int32_t)bswap_32((int32_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
198 #define l_endian_i64(x) ((int64_t)bswap_64((int64_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
199 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
200 #define b_endian_u16(x) ((uint16_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
201 #define b_endian_u32(x) ((uint32_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
202 #define b_endian_u64(x) ((uint64_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
203 #define b_endian_i16(x) ((int16_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
204 #define b_endian_i32(x) ((int32_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
205 #define b_endian_i64(x) ((int64_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
206 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
207 #elif __BYTE_ORDER==__LITTLE_ENDIAN |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
208 #define l_endian_u16(x) ((uint16_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
209 #define l_endian_u32(x) ((uint32_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
210 #define l_endian_u64(x) ((uint64_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
211 #define l_endian_i16(x) ((int16_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
212 #define l_endian_i32(x) ((int32_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
213 #define l_endian_i64(x) ((int64_t)(x)) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
214 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
215 #define b_endian_u16(x) ((uint16_t)bswap_16((uint16_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
216 #define b_endian_u32(x) ((uint32_t)bswap_32((uint32_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
217 #define b_endian_u64(x) ((uint64_t)bswap_64((uint64_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
218 #define b_endian_i16(x) ((int16_t)bswap_16((int16_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
219 #define b_endian_i32(x) ((int32_t)bswap_32((int32_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
220 #define b_endian_i64(x) ((int64_t)bswap_64((int64_t)(x))) |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
221 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
222 #endif /* __BYTE_ORDER */ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
223 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
224 |
7774 | 225 /* |
226 Including ZLIB enables reading gzipped files (they are decompressed on-the-fly) | |
227 The output files can be zipped, too. | |
228 */ | |
229 | |
9421
8d2b4cc5c0a1
remove requirement of ZLIB; remove obsolete nan2conv.m
schloegl
parents:
8927
diff
changeset
|
230 #ifdef WITH_ZLIB |
7774 | 231 #include <zlib.h> |
9421
8d2b4cc5c0a1
remove requirement of ZLIB; remove obsolete nan2conv.m
schloegl
parents:
8927
diff
changeset
|
232 #endif |
7774 | 233 |
234 | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
235 double xpt2d(uint64_t x); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
236 uint64_t d2xpt(double x); |
7434 | 237 double tm_time2gdf_time(struct tm *t); |
7426 | 238 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
239 void mexFunction(int POutputCount, mxArray* POutput[], int PInputCount, const mxArray *PInputs[]) |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
240 { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
241 const char L1[] = "HEADER RECORD*******LIBRARY HEADER RECORD!!!!!!!000000000000000000000000000000 "; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
242 const char L2[] = "SAS SAS SASLIB 6.06 bsd4.2 13APR89:10:20:06"; |
8927 | 243 //const char L3[] = ""; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
244 const char L4[] = "HEADER RECORD*******MEMBER HEADER RECORD!!!!!!!000000000000000001600000000140 "; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
245 const char L5[] = "HEADER RECORD*******DSCRPTR HEADER RECORD!!!!!!!000000000000000000000000000000 "; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
246 const char L6[] = "SAS ABC SASLIB 6.06 bsd4.2 13APR89:10:20:06"; |
8927 | 247 //const char L7[] = ""; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
248 const char L8[] = "HEADER RECORD*******NAMESTR HEADER RECORD!!!!!!!000000000200000000000000000000 "; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
249 const char LO[] = "HEADER RECORD*******OBS HEADER RECORD!!!!!!!000000000000000000000000000000 "; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
250 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
251 const char DATEFORMAT[] = "%d%b%y:%H:%M:%S"; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
252 char *fn = NULL; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
253 char Mode[3] = "r"; |
8927 | 254 size_t count = 0, HeadLen0=80*8, HeadLen2=0, sz2 = 0; |
8039 | 255 uint32_t NS = 0; |
7426 | 256 char H0[HeadLen0]; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
257 char *H2 = NULL; |
7774 | 258 char SWAP = 0; |
259 | |
260 #ifndef ZLIB_H | |
261 FILE *fid; | |
262 #else | |
263 gzFile fid; | |
264 #define fopen gzopen | |
265 #define fread(a,b,c,d) (gzread(d,a,b*c)/b) | |
266 #define fwrite(a,b,c,d) (gzwrite(d,a,b*c)/b) | |
267 #define feof gzeof | |
268 #define fseek gzseek | |
269 #define fclose gzclose | |
270 #define rewind(fid) (gzseek(fid,0,SEEK_SET)) | |
271 #endif | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
272 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
273 // check for proper number of input and output arguments |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
274 if ( PInputCount > 0 && mxGetClassID(PInputs[0])==mxCHAR_CLASS) { |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
275 size_t buflen = (mxGetM(PInputs[0]) * mxGetN(PInputs[0]) * sizeof(mxChar)) + 1; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
276 fn = (char*)malloc(buflen); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
277 mxGetString(PInputs[0], fn, buflen); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
278 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
279 else { |
7774 | 280 mexPrintf("XPTOPEN read of several file formats and writing of the SAS Transport Format (*.xpt)\n"); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
281 mexPrintf("\n\tX = xptopen(filename)\n"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
282 mexPrintf("\tX = xptopen(filename,'r')\n"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
283 mexPrintf("\t\tread filename and return variables in struct X\n"); |
9421
8d2b4cc5c0a1
remove requirement of ZLIB; remove obsolete nan2conv.m
schloegl
parents:
8927
diff
changeset
|
284 #ifdef ZLIB_H |
7774 | 285 mexPrintf("\tSupported are ARFF, SAS-XPT and STATA files with or w/o zlib/gzip compression.\n"); |
9421
8d2b4cc5c0a1
remove requirement of ZLIB; remove obsolete nan2conv.m
schloegl
parents:
8927
diff
changeset
|
286 #else |
8d2b4cc5c0a1
remove requirement of ZLIB; remove obsolete nan2conv.m
schloegl
parents:
8927
diff
changeset
|
287 mexPrintf("\tSupported are ARFF, SAS-XPT and STATA files.\n"); |
8d2b4cc5c0a1
remove requirement of ZLIB; remove obsolete nan2conv.m
schloegl
parents:
8927
diff
changeset
|
288 #endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
289 mexPrintf("\n\tX = xptopen(filename,'w',X)\n"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
290 mexPrintf("\t\tsave fields of struct X in filename.\n\n"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
291 mexPrintf("\tThe fields of X must be column vectors of equal length.\n"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
292 mexPrintf("\tEach vector is either a numeric vector or a cell array of strings.\n"); |
7426 | 293 mexPrintf("\nThe SAS-XPT format stores Date/Time as numeric value counting the number of days since 1960-01-01.\n\n"); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
294 return; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
295 } |
7762 | 296 |
8039 | 297 if (PInputCount > 1) |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
298 if (mxGetClassID(PInputs[1])==mxCHAR_CLASS && mxGetNumberOfElements(PInputs[1])) { |
7426 | 299 mxGetString(PInputs[1],Mode,3); |
300 Mode[2]=0; | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
301 } |
7426 | 302 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
303 fid = fopen(fn,Mode); |
12678
e4374feb2e3f
[nan-tb] fix bug when file open fails; address several compiler warnings
schloegl
parents:
12584
diff
changeset
|
304 if (fid == NULL) { |
12584 | 305 mexErrMsgTxt("Can not open file!\n"); |
7774 | 306 } |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
307 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
308 if (Mode[0]=='r' || Mode[0]=='a' ) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
309 count += fread(H0,1,80*8,fid); |
7426 | 310 enum FileFormat { |
8039 | 311 noFile, unknown, ARFF, SASXPT, SPSS, SQLite, STATA |
7426 | 312 }; |
313 enum FileFormat TYPE; /* type of file format */ | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
314 uint8_t LittleEndian; /* 1 if file is LittleEndian data format and 0 for big endian data format*/ |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
315 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
316 TYPE = unknown; |
7762 | 317 if (!memcmp(H0,"$FL2@(#) SPSS DATA FILE",23) || !memcmp(H0,"$FL2@(#) PASW STATISTICS DATA FILE",27)) { |
7426 | 318 /* |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
319 SPSS file format |
7426 | 320 */ |
8927 | 321 uint32_t M=0; |
322 | |
7774 | 323 mexWarnMsgTxt("XPTOPEN: support of for SPSS file format is very experimental (do not use it for production use)\n"); |
7762 | 324 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
325 TYPE = SPSS; |
7426 | 326 switch (*(uint32_t*)(H0+64)) { |
327 case 0x00000002: | |
328 case 0x00000003: | |
329 LittleEndian = 1; | |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
330 SWAP = __BYTE_ORDER==__BIG_ENDIAN; |
7426 | 331 NS = l_endian_u32(*(uint32_t*)(H0+68)); |
332 M = l_endian_u32(*(uint32_t*)(H0+80)); | |
333 break; | |
334 case 0x02000000: | |
335 case 0x03000000: | |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
336 SWAP = __BYTE_ORDER==__LITTLE_ENDIAN; |
7426 | 337 LittleEndian = 0; |
7774 | 338 NS = b_endian_u32(*(uint32_t*)(H0+68)); |
339 M = b_endian_u32(*(uint32_t*)(H0+80)); | |
7426 | 340 break; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
341 default: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
342 TYPE = unknown; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
343 } |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
344 NS = *(int32_t*)(H0+80); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
345 M = *(int32_t*)(H0+80); |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
346 if (SWAP) { |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
347 NS = bswap_32(NS); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
348 M = bswap_32(M); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
349 } |
7434 | 350 HeadLen0 = 184; |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
351 char *H2 = (char*)malloc(NS*32); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
352 size_t c2 = 0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
353 |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
354 /* |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
355 Read Variable SPSS header |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
356 */ |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
357 int ns = 0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
358 const char **ListOfVarNames = (const char**)malloc((NS+1) * sizeof(char*)); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
359 char *VarNames = (char*)malloc((NS+1) * sizeof(char) * 9); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
360 double *MISSINGS = (double*)malloc((NS+1) * sizeof(double)); |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
361 for (uint32_t k=0; k<NS; k++) { |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
362 int32_t rec_type, type, FlagHasLabel, FlagMissing; |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
363 c2 += fread(&rec_type,1,4,fid); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
364 c2 += fread(&type,1,4,fid); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
365 c2 += fread(&FlagHasLabel,1,4,fid); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
366 c2 += fread(&FlagMissing,1,4,fid); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
367 fseek(fid,4,SEEK_CUR); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
368 if (SWAP) { |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
369 rec_type = bswap_32(rec_type); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
370 type = bswap_32(type); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
371 FlagHasLabel = bswap_32(FlagHasLabel); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
372 } |
12556 | 373 |
374 if (rec_type != 2) | |
12678
e4374feb2e3f
[nan-tb] fix bug when file open fails; address several compiler warnings
schloegl
parents:
12584
diff
changeset
|
375 mexErrMsgTxt("invalid SPSS file\n"); |
12556 | 376 |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
377 c2 += fread(VarNames+9*ns,1,8,fid); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
378 VarNames[9*ns+8] = 0; |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
379 ListOfVarNames[ns] = VarNames+9*ns; |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
380 if (FlagHasLabel==1) { |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
381 int32_t LenLabel; |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
382 c2 += fread(&LenLabel,1,4,fid); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
383 if (SWAP) LenLabel = bswap_32(LenLabel); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
384 if (LenLabel%4) LenLabel += 4 - LenLabel % 4; |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
385 fseek(fid,LenLabel,SEEK_CUR); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
386 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
387 if (FlagMissing) |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
388 c2 += fread(MISSINGS+ns,1,8,fid); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
389 |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
390 if (type != -1) ns++; |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
391 } |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
392 |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
393 |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
394 NS = ns; |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
395 mxArray **R = (mxArray**) mxMalloc(NS * sizeof(mxArray*)); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
396 /* ToDo: |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
397 EXTRACT data |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
398 */ |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
399 |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
400 /* convert into output */ |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
401 POutput[0] = mxCreateStructMatrix(1, 1, NS, ListOfVarNames); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
402 for (uint32_t k = 0; k < NS; k++) { |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
403 mxSetField(POutput[0], 0, ListOfVarNames[k], R[k]); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
404 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
405 |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
406 if (MISSINGS) free(MISSINGS); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
407 if (VarNames) free(VarNames); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
408 if (ListOfVarNames) free(ListOfVarNames); |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
409 if (H2) free(H2); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
410 } |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
411 |
7434 | 412 if (TYPE == SPSS) { |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
413 /* |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
414 The records must appear in the following order: |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
415 - File header record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
416 - Variable records. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
417 - All pairs of value labels records and value label variables records, |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
418 if present. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
419 - Document record, if present. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
420 - Any of the following records, if present, in any order: |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
421 Machine integer info record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
422 Machine floating-point info record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
423 Variable display parameter record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
424 Long variable names record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
425 Miscellaneous informational records. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
426 - Dictionary termination record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
427 - Data record. |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
428 |
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
429 */ ; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
430 } |
8039 | 431 |
432 else if (!memcmp(H0,"SQLite format 3\000",16) && H0[21]==64 && H0[22]==32 && H0[23]==32 ) { | |
433 TYPE = SQLite; | |
434 | |
435 fclose(fid); | |
436 mexErrMsgTxt("SQLite format not supported yet"); | |
437 return; | |
438 } | |
439 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
440 else if ((H0[0]>=0x6e || H0[0]<=114) && (H0[1]==1 || H0[1]==2) && H0[2]==1 && H0[3]==0) { |
7426 | 441 /* |
442 STATA File Format | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
443 http://www.stata.com/help.cgi?dta |
7426 | 444 http://www.stata.com/help.cgi?dta_113 |
7762 | 445 Stata files written by R start with 0x6e |
7426 | 446 */ |
8927 | 447 uint32_t M=0; |
448 | |
7426 | 449 TYPE = STATA; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
450 // Header 119 bytes |
7426 | 451 LittleEndian = H0[1]==2; |
452 if (LittleEndian) { | |
453 NS = l_endian_u16(*(uint16_t*)(H0+4)); | |
7774 | 454 M = l_endian_u32(*(uint32_t*)(H0+6)); |
7426 | 455 } |
456 else { | |
457 NS = b_endian_u16(*(uint16_t*)(H0+4)); | |
458 M = b_endian_u32(*(uint32_t*)(H0+6)); | |
459 } | |
460 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
461 // Descriptors |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
462 int fmtlen = (H0[0]==113) ? 12 : 49; |
7426 | 463 fseek(fid,109,SEEK_SET); |
464 size_t HeadLen2 = 2+NS*(1+33+2+fmtlen+33+81); | |
465 char *H1 = (char*)malloc(HeadLen2); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
466 HeadLen2 = fread(H1,1,HeadLen2,fid); |
7426 | 467 |
468 // expansion fields | |
8927 | 469 char typ; int32_t len; |
7426 | 470 char flagSWAP = (((__BYTE_ORDER == __BIG_ENDIAN) && LittleEndian) || ((__BYTE_ORDER == __LITTLE_ENDIAN) && !LittleEndian)); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
471 do { |
12678
e4374feb2e3f
[nan-tb] fix bug when file open fails; address several compiler warnings
schloegl
parents:
12584
diff
changeset
|
472 if (!fread(&typ,1,1,fid)) break; |
e4374feb2e3f
[nan-tb] fix bug when file open fails; address several compiler warnings
schloegl
parents:
12584
diff
changeset
|
473 if (!fread(&len,4,1,fid)) break; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
474 if (flagSWAP) bswap_32(len); |
7426 | 475 fseek(fid,len,SEEK_CUR); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
476 } while (len); |
7426 | 477 uint8_t *typlist = (uint8_t*)H1; |
7574
7d52643b01c4
SPSS: decode some more header information - still not ready
schloegl
parents:
7490
diff
changeset
|
478 |
7426 | 479 /* |
480 char *varlist = H1+NS; | |
481 char *srtlist; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
482 char *fmtlist = H1+NS*36+2; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
483 char *lbllist = H1+NS*(36+fmtlen)+2; |
7426 | 484 */ |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
485 |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
486 mxArray **R = (mxArray**) mxMalloc(NS*sizeof(mxArray*)); |
7426 | 487 size_t *bi = (size_t*) malloc((NS+1)*sizeof(size_t*)); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
488 const char **ListOfVarNames = (const char**)malloc(NS * sizeof(char*)); |
7426 | 489 bi[0] = 0; |
490 for (size_t k = 0; k < NS; k++) { | |
491 size_t sz; | |
492 ListOfVarNames[k] = H1+NS+33*k; | |
493 switch (typlist[k]) { | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
494 case 0xfb: sz = 1; break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
495 case 0xfc: sz = 2; break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
496 case 0xfd: sz = 4; break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
497 case 0xfe: sz = 4; break; |
7426 | 498 case 0xff: sz = 8; break; |
8927 | 499 default: sz = typlist[k]; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
500 } |
7426 | 501 bi[k+1] = bi[k]+sz; |
502 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
503 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
504 // data |
7426 | 505 uint8_t *data = (uint8_t *) malloc(bi[NS] * M); |
506 fread(data, bi[NS], M, fid); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
507 |
7426 | 508 char *f = (char*)malloc(bi[NS]+1); |
509 for (size_t k = 0; k < NS; k++) { | |
510 switch (typlist[k]) { | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
511 case 0xfb: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
512 R[k] = mxCreateDoubleMatrix(M, 1, mxREAL); |
7426 | 513 for (size_t m = 0; m < M; m++) { |
514 int8_t d = *(int8_t*)(data+bi[k]+m*bi[NS]); | |
515 ((double*)mxGetData(R[k]))[m] = (d>100) ? NaN : d; | |
516 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
517 break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
518 case 0xfc: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
519 R[k] = mxCreateDoubleMatrix(M, 1, mxREAL); |
7426 | 520 if (flagSWAP) for (size_t m = 0; m < M; m++) { |
521 int16_t d = (int16_t) bswap_16(*(uint16_t*)(data+bi[k]+m*bi[NS])); | |
522 ((double*)mxGetData(R[k]))[m] = (d>32740) ? NaN : d; | |
523 } | |
524 else for (size_t m = 0; m < M; m++) { | |
525 int16_t d = *(int16_t*)(data+bi[k]+m*bi[NS]); | |
526 ((double*)mxGetData(R[k]))[m] = (d>32740) ? NaN : d; | |
527 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
528 break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
529 case 0xfd: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
530 R[k] = mxCreateDoubleMatrix(M, 1, mxREAL); |
7426 | 531 if (flagSWAP) for (size_t m = 0; m < M; m++) { |
532 int32_t d = (int32_t)bswap_32(*(uint32_t*)(data+bi[k]+m*bi[NS])); | |
533 ((double*)mxGetData(R[k]))[m] = (d>2147483620) ? NaN : d; | |
534 } | |
535 else for (size_t m = 0; m < M; m++) { | |
536 int32_t d = *(int32_t*)(data+bi[k]+m*bi[NS]); | |
537 ((double*)mxGetData(R[k]))[m] = (d>2147483620) ? NaN : d; | |
538 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
539 break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
540 case 0xfe: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
541 R[k] = mxCreateNumericMatrix(M, 1, mxSINGLE_CLASS, mxREAL); |
7426 | 542 if (flagSWAP) for (size_t m = 0; m < M; m++) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
543 ((uint32_t*)mxGetData(R[k]))[m] = bswap_32(*(uint32_t*)(data+bi[k]+m*bi[NS]));; |
7426 | 544 } |
545 else for (size_t m = 0; m < M; m++) { | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
546 ((uint32_t*)mxGetData(R[k]))[m] = *(uint32_t*)(data+bi[k]+m*bi[NS]); |
7426 | 547 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
548 break; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
549 case 0xff: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
550 R[k] = mxCreateDoubleMatrix(M, 1, mxREAL); |
7426 | 551 if (flagSWAP) for (size_t m = 0; m < M; m++) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
552 ((uint64_t*)mxGetData(R[k]))[m] = bswap_64(*(uint64_t*)(data+bi[k]+m*bi[NS])); |
7426 | 553 } |
554 else for (size_t m = 0; m < M; m++) { | |
555 ((uint64_t*)mxGetData(R[k]))[m] = *(uint64_t*)(data+bi[k]+m*bi[NS]); | |
556 } | |
557 break; | |
558 default: | |
559 R[k] = mxCreateCellMatrix(M, 1); | |
560 size_t sz = typlist[k]; | |
561 for (size_t m = 0; m < M; m++) { | |
562 memcpy(f, data+bi[k]+m*bi[NS], sz); | |
563 f[sz] = 0; | |
564 mxSetCell(R[k], m, mxCreateString(f)); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
565 } |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
566 } |
7426 | 567 } |
7774 | 568 if (f) free(f); |
7426 | 569 if (H1) free(H1); |
570 if (bi) free(bi); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
571 |
7426 | 572 /* convert into output */ |
573 POutput[0] = mxCreateStructMatrix(1, 1, NS, ListOfVarNames); | |
574 for (size_t k = 0; k < NS; k++) { | |
575 mxSetField(POutput[0], 0, ListOfVarNames[k], R[k]); | |
576 } | |
577 | |
578 if (ListOfVarNames) free(ListOfVarNames); | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
579 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
580 |
7426 | 581 else if (H0[0]=='%' || H0[0]=='@') { |
582 /* | |
583 ARFF | |
584 */ | |
8927 | 585 uint32_t M=0; |
586 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
587 TYPE = ARFF; |
7426 | 588 rewind(fid); |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
589 |
7434 | 590 char *H1 = NULL; |
7426 | 591 count = 0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
592 size_t ns = 0; |
7434 | 593 char *vartyp = NULL; |
594 char **datestr = NULL; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
595 const char **ListOfVarNames = NULL; |
7434 | 596 mxArray **R = NULL; |
597 size_t m = 0; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
598 |
7426 | 599 while (!feof(fid)) { |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
600 HeadLen0 = max(1024,HeadLen0*2); |
7434 | 601 H1 = (char*)realloc(H1,HeadLen0); |
602 count += fread(H1+count,1,HeadLen0-count-1,fid); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
603 } |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
604 H1[count] = 0; |
7434 | 605 |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
606 switch (H1[count-1]) { |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
607 case 0x0a: |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
608 case 0x0d: |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
609 H1[count] = 0; |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
610 break; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
611 default: |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
612 H1[count] = 0x0a; |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
613 } |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
614 H1[count+1] = 0; |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
615 |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
616 char *line = strtok(H1,"\x0a\0x0d"); |
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
617 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
618 int status = 0; |
7426 | 619 while (line) { |
7434 | 620 |
12584 | 621 if (!strncasecmp(line,"@relation",9)) { |
7426 | 622 status = 1; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
623 } |
7426 | 624 |
12584 | 625 else if (status == 1 && !strncasecmp(line,"@attribute",10)) { |
7434 | 626 if (ns<=NS) { |
627 ns = max(16, ns*2); | |
628 ListOfVarNames = (const char**)realloc(ListOfVarNames,ns*sizeof(char*)); | |
629 vartyp = (char*)realloc(vartyp,ns*sizeof(char)); | |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
630 R = (mxArray**) mxRealloc(R,ns*sizeof(mxArray*)); |
7434 | 631 } |
632 size_t k = 10; | |
633 char *p1, *p2; | |
634 while (isspace(line[k])) k++; | |
635 p1 = line+k; | |
636 while (!isspace(line[k])) k++; | |
637 line[k++]=0; | |
638 while (isspace(line[k])) k++; | |
639 p2 = line+k; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
640 |
7434 | 641 ListOfVarNames[NS] = p1; |
12584 | 642 if (!strncasecmp(p2,"numeric",7)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
643 vartyp[NS] = 1; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
644 } |
12584 | 645 else if (!strncasecmp(p2,"integer",7)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
646 vartyp[NS] = 2; |
7434 | 647 } |
12584 | 648 else if (!strncasecmp(p2,"real",4)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
649 vartyp[NS] = 3; |
7434 | 650 } |
12584 | 651 else if (!strncasecmp(p2,"string",6)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
652 vartyp[NS] = 4; |
7434 | 653 } |
12584 | 654 else if (!strncasecmp(p2,"{",1)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
655 vartyp[NS] = 5; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
656 } |
12584 | 657 else if (!strncasecmp(p2,"date",4)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
658 vartyp[NS] = 6; |
7434 | 659 datestr = (char**)realloc(datestr,(NS+1)*sizeof(char*)); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
660 p2+=4; |
7434 | 661 while (isspace(*p2)) p2++; |
662 datestr[NS] = p2; | |
663 if (p2[0]==34) { | |
664 p2++; | |
665 while (p2[0]!=34 && p2[0]) p2++; | |
666 p2[1]=0; | |
667 } | |
668 } | |
12584 | 669 else if (!strncasecmp(p2,"relational",10)) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
670 vartyp[NS] = 7; |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
671 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
672 else vartyp[NS] = 99; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
673 |
7426 | 674 NS++; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
675 } |
7426 | 676 |
12584 | 677 else if (status == 1 && !strncasecmp(line,"@data",5)) { |
7434 | 678 status = 2; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
679 char *p = line; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
680 while (*p) p++; // goto end of current line |
7434 | 681 p++; // skip \x00 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
682 M = 0; |
7434 | 683 while (*p) { |
684 if (p[0]==0x0a || p[0]==0x0d) { | |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
685 // count number of <CR> |
7434 | 686 M++; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
687 // skip next char (deals with <CR><NL>) |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
688 p+=2; |
7434 | 689 } |
690 else p++; | |
691 } | |
692 for (size_t k=0; k<NS; k++) { | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
693 if (vartyp[k]==4 || vartyp[k]==5) |
7434 | 694 R[k] = mxCreateCellMatrix(M, 1); |
695 else | |
696 R[k] = mxCreateDoubleMatrix(M, 1, mxREAL); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
697 } |
7426 | 698 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
699 |
7434 | 700 else if (status == 2) { |
701 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
702 size_t p = 0,k; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
703 for (ns = 0; ns<NS; ns++) { |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
704 // read next token |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
705 while (isspace(line[p])) p++; |
7434 | 706 if (line[p]==39) { |
707 p++; k=p; | |
708 while (line[k]!=39 && line[k]) k++; | |
709 // if (!line[k]) ; // error | |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
710 line[k++] = 0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
711 } |
7434 | 712 else |
713 k=p; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
714 while (line[k] != ',' && line[k] != 0) k++; |
7434 | 715 line[k] = 0; |
716 | |
717 if (vartyp[ns] < 4) { | |
718 double d = atof(line+p); | |
719 *(mxGetPr(R[ns])+m) = d; | |
720 } | |
721 else if (vartyp[ns] < 6) { | |
722 mxSetCell(R[ns], m, mxCreateString(line+p)); | |
723 } | |
724 else if (vartyp[ns] == 6) { | |
725 size_t kk[6],n=0, N=strlen(datestr[ns]); | |
726 char T0[6][5]; | |
12678
e4374feb2e3f
[nan-tb] fix bug when file open fails; address several compiler warnings
schloegl
parents:
12584
diff
changeset
|
727 int ix = 0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
728 struct tm t; |
7434 | 729 |
730 for (n=0; n < N; n++) { | |
731 switch (datestr[ns][n]) { | |
732 case 'Y': | |
733 ix = 0; | |
734 break; | |
735 case 'M': | |
736 ix = 1; | |
737 break; | |
738 case 'd': | |
739 ix = 2; | |
740 break; | |
741 case 'H': | |
742 ix = 3; | |
743 break; | |
744 case 'm': | |
745 ix = 4; | |
746 break; | |
747 case 's': | |
748 ix = 5; | |
749 break; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
750 default: |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
751 ix = 99; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
752 } |
7434 | 753 |
754 if (ix < 6) { | |
755 T0[ix][kk[ix]++] = line[p+n]; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
756 } |
7434 | 757 } |
758 for (n=0; n<6; n++) { | |
759 T0[n][kk[n]] = 0; | |
760 } | |
761 t.tm_year = atoi(T0[0]); | |
762 t.tm_mon = atoi(T0[1]); | |
763 t.tm_mday = atoi(T0[2]); | |
764 t.tm_hour = atoi(T0[3]); | |
765 t.tm_min = atoi(T0[4]); | |
766 t.tm_sec = atoi(T0[5]); | |
767 | |
768 *(mxGetPr(R[ns])+m) = tm_time2gdf_time(&t); | |
769 } | |
770 p = k+1; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
771 } |
7434 | 772 m++; |
773 } | |
774 line = strtok(NULL, "\x0a\x0d"); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
775 } |
7434 | 776 |
777 /* convert into output */ | |
778 POutput[0] = mxCreateStructMatrix(1, 1, NS, ListOfVarNames); | |
779 for (size_t k = 0; k < NS; k++) { | |
780 mxSetField(POutput[0], 0, ListOfVarNames[k], R[k]); | |
781 } | |
7426 | 782 |
7434 | 783 if (ListOfVarNames) free(ListOfVarNames); |
784 if (vartyp) free(vartyp); | |
785 if (datestr) free(datestr); | |
786 if (H1) free(H1); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
787 } |
7426 | 788 |
789 else if (!memcmp(H0,"HEADER RECORD*******LIBRARY HEADER RECORD!!!!!!!000000000000000000000000000000",78)) { | |
790 /* | |
791 SAS Transport file format (XPORT) | |
792 */ | |
8927 | 793 size_t M=0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
794 TYPE = SASXPT; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
795 |
7426 | 796 /* TODO: sanity checks */ |
797 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
798 char tmp[5]; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
799 memcpy(tmp,H0+7*80+54,4); |
7426 | 800 tmp[4] = 0; |
801 NS = atoi(tmp); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
802 |
7426 | 803 char *tmp2; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
804 sz2 = strtoul(H0+4*80-6, &tmp2, 10); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
805 |
7426 | 806 HeadLen2 = NS*sz2; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
807 if (HeadLen2 % 80) HeadLen2 = (HeadLen2 / 80 + 1) * 80; |
7426 | 808 |
809 /* read namestr header, and header line "OBS" */ | |
810 H2 = (char*) realloc(H2, HeadLen2+81); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
811 count += fread(H2,1,HeadLen2+80,fid); |
7426 | 812 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
813 /* size of single record */ |
7426 | 814 size_t pos=0, recsize = 0, POS = 0; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
815 for (size_t k = 0; k < NS; k++) |
7426 | 816 recsize += b_endian_u16(*(int16_t*)(H2+k*sz2+4)); |
817 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
818 /* read data section */ |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
819 size_t szData = 0; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
820 uint8_t *Data = NULL; |
7426 | 821 while (!feof(fid)) { |
822 size_t szNew = max(16,szData*2); | |
823 Data = (uint8_t*)realloc(Data,szNew); | |
824 szData += fread(Data+szData,1,szNew-szData,fid); | |
825 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
826 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
827 M = szData/recsize; |
7426 | 828 |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
829 mxArray **R = (mxArray**) mxMalloc(NS*sizeof(mxArray*)); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
830 const char **ListOfVarNames = (const char**)malloc(NS * sizeof(char*)); |
7426 | 831 char *VarNames = (char*)malloc(NS * 9); |
832 | |
833 for (size_t k = 0; k < NS; k++) { | |
834 size_t maxlen = b_endian_u16(*(int16_t*)(H2+k*sz2+4)); | |
835 | |
836 ListOfVarNames[k] = VarNames+pos; | |
10135 | 837 size_t n = k*sz2+8; |
8927 | 838 // int flagDate = (!memcmp(H2+n+48,"DATE ",8) || !memcmp(H2+n+48,"MONNAME ",8)); // not used |
7426 | 839 do { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
840 VarNames[pos++] = H2[n]; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
841 } while (isalnum(H2[++n]) && (n < k*sz2+16)); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
842 |
7426 | 843 |
844 VarNames[pos++] = 0; | |
845 | |
846 if ((*(int16_t*)(H2+k*sz2)) == b_endian_u16(1) && (*(int16_t*)(H2+k*sz2+4)) == b_endian_u16(8) ) { | |
847 // numerical data | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
848 R[k] = mxCreateDoubleMatrix(M, 1, mxREAL); |
7426 | 849 for (size_t m=0; m<M; m++) { |
850 double d = xpt2d(b_endian_u64(*(uint64_t*)(Data+m*recsize+POS))); | |
851 | |
852 // if (flagDate) d += 715876; // add number of days from 0000-Jan-01 to 1960-Jan-01 | |
853 | |
854 *(mxGetPr(R[k])+m) = d; | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
855 |
7426 | 856 } |
857 } | |
858 else if ((*(int16_t*)(H2+k*sz2)) == b_endian_u16(2)) { | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
859 // character string |
7426 | 860 R[k] = mxCreateCellMatrix(M, 1); |
861 char *f = (char*)malloc(maxlen+1); | |
862 for (size_t m=0; m<M; m++) { | |
863 memcpy(f, Data+m*recsize+POS, maxlen); | |
864 f[maxlen] = 0; | |
865 mxSetCell(R[k], m, mxCreateString(f)); | |
866 } | |
867 if (f) free(f); | |
868 } | |
869 POS += maxlen; | |
870 } | |
871 | |
872 POutput[0] = mxCreateStructMatrix(1, 1, NS, ListOfVarNames); | |
873 for (size_t k = 0; k < NS; k++) { | |
874 mxSetField(POutput[0], 0, ListOfVarNames[k], R[k]); | |
875 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
876 |
7426 | 877 if (VarNames) free(VarNames); |
878 if (ListOfVarNames) free(ListOfVarNames); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
879 if (Data) free(Data); |
7426 | 880 /* end of reading SAS format */ |
881 } | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
882 |
7426 | 883 else { |
884 fclose(fid); | |
885 mexErrMsgTxt("file format not supported"); | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
886 return; |
7426 | 887 } |
888 | |
889 | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
890 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
891 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
892 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
893 // if (Mode[0]=='w' || Mode[0]=='a' ) { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
894 if (Mode[0]=='w') { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
895 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
896 NS += mxGetNumberOfFields(PInputs[2]); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
897 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
898 // generate default (fixed) header |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
899 if (Mode[0]=='w') { |
7426 | 900 memset(H0,' ',80*8); |
901 memcpy(H0,L1,strlen(L1)); | |
902 memcpy(H0+80,L2,strlen(L2)); | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
903 |
7426 | 904 memcpy(H0+80*3,L4,strlen(L4)); |
905 memcpy(H0+80*4,L5,strlen(L5)); | |
906 memcpy(H0+80*5,L6,strlen(L6)); | |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
907 |
7426 | 908 memcpy(H0+80*7,L8,strlen(L8)); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
909 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
910 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
911 time_t t; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
912 time(&t); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
913 char tt[20]; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
914 strftime(tt, 17, DATEFORMAT, localtime(&t)); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
915 memcpy(H0+80*2-16,tt,16); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
916 memcpy(H0+80*2,tt,16); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
917 memcpy(H0+80*5+8,fn,min(8,strcspn(fn,".\x00"))); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
918 memcpy(H0+80*5+32,"XPTOPEN.MEX (OCTAVE/MATLAB)",27); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
919 memcpy(H0+80*6-16,tt,16); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
920 memcpy(H0+80*6,tt,16); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
921 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
922 char tmp[17]; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
923 sprintf(tmp,"%04i", NS); // number of variables |
7426 | 924 memcpy(H0+80*7+54, tmp, 4); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
925 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
926 if (sz2==0) sz2 = 140; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
927 if (sz2 < 136) |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
928 mexErrMsgTxt("error XPTOPEN: incorrect length of namestr field"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
929 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
930 /* generate variable NAMESTR header */ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
931 HeadLen2 = NS*sz2; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
932 if (HeadLen2 % 80) HeadLen2 = (HeadLen2 / 80 + 1) * 80; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
933 H2 = (char*) realloc(H2,HeadLen2); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
934 memset(H2,0,HeadLen2); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
935 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
936 mwIndex M = 0; |
7462
40c9ff0bf296
reading ARFF files improved; SPSS: better identification
schloegl
parents:
7434
diff
changeset
|
937 mxArray **F = (mxArray**) mxMalloc(NS*sizeof(mxArray*)); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
938 char **Fstr = (char**) malloc(NS*sizeof(char*)); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
939 size_t *MAXLEN = (size_t*) malloc(NS*sizeof(size_t*)); |
10135 | 940 for (uint16_t k = 0; k < NS; k++) { |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
941 Fstr[k] = NULL; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
942 MAXLEN[k]=0; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
943 F[k] = mxGetFieldByNumber(PInputs[2],0,k); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
944 if (k==0) M = mxGetM(F[k]); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
945 else if (M != mxGetM(F[k])) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
946 if (H2) free(H2); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
947 if (F) free(F); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
948 mexErrMsgTxt("Error XPTOPEN: number of elements (rows) do not fit !!!"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
949 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
950 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
951 if (mxIsChar(F[k])) { |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
952 *(int16_t*)(H2+k*sz2) = b_endian_u16(2); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
953 *(int16_t*)(H2+k*sz2+4) = b_endian_u16(mxGetN(F[k])); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
954 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
955 else if (mxIsCell(F[k])) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
956 size_t maxlen = 0; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
957 for (mwIndex m = 0; m<M; m++) { |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
958 mxArray *f = mxGetCell(F[k],m); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
959 if (mxIsChar(f) || mxIsEmpty(f)) { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
960 size_t len = mxGetNumberOfElements(f); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
961 if (maxlen<len) maxlen = len; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
962 } |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
963 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
964 Fstr[k] = (char*) malloc(maxlen+1); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
965 *(int16_t*)(H2+k*sz2) = b_endian_u16(2); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
966 *(int16_t*)(H2+k*sz2+4) = b_endian_u16(maxlen); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
967 MAXLEN[k] = maxlen; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
968 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
969 else { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
970 *(int16_t*)(H2+k*sz2) = b_endian_u16(1); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
971 *(int16_t*)(H2+k*sz2+4) = b_endian_u16(8); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
972 } |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
973 *(int16_t*)(H2+k*sz2+6) = b_endian_u16(k); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
974 strncpy(H2+k*sz2+8,mxGetFieldNameByNumber(PInputs[2],k),8); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
975 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
976 |
7426 | 977 count = fwrite(H0, 1, HeadLen0, fid); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
978 count += fwrite(H2, 1, HeadLen2, fid); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
979 /* write OBS header line */ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
980 count += fwrite(LO, 1, strlen(LO), fid); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
981 for (mwIndex m = 0; m < M; m++) { |
10135 | 982 for (uint16_t k = 0; k < NS; k++) { |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
983 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
984 if (*(int16_t*)(H2+k*sz2) == b_endian_u16(1)) { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
985 // numeric |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
986 uint64_t u64 = b_endian_u64(d2xpt(*(mxGetPr(F[k])+m))); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
987 count += fwrite(&u64, 1, 8, fid); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
988 } |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
989 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
990 /* else if (mxIsChar(F[k])) { |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
991 *(int16_t*)(H2+k*sz2) = b_endian_u16(2); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
992 *(int16_t*)(H2+k*sz2+4) = b_endian_u16(mxGetN(F[k])); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
993 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
994 */ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
995 else if (mxIsCell(F[k])) { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
996 size_t maxlen = MAXLEN[k]; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
997 mxArray *f = mxGetCell(F[k],m); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
998 mxGetString(f, Fstr[k], maxlen+1); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
999 count += fwrite(Fstr[k], 1, maxlen, fid); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1000 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1001 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1002 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1003 /* |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1004 // padding to full multiple of 80 byte: |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1005 // FIXME: this might introduce spurios sample values |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1006 char d = count%80; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1007 while (d--) fwrite("\x20",1,1,fid); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1008 */ |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1009 // free memory |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1010 for (size_t k=0; k<NS; k++) if (Fstr[k]) free(Fstr[k]); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1011 if (Fstr) free(Fstr); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1012 if (MAXLEN) free(MAXLEN); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1013 Fstr = NULL; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1014 } |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1015 fclose(fid); |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1016 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1017 if (H2) free(H2); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1018 H2 = NULL; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1019 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1020 return; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1021 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1022 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1023 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1024 /* |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1025 XPT2D converts from little-endian IBM to little-endian IEEE format |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1026 */ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1027 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1028 double xpt2d(uint64_t x) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1029 // x is little-endian 64bit IBM floating point format |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1030 char c = *((char*)&x+7) & 0x7f; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1031 uint64_t u = x; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1032 *((char*)&u+7)=0; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1033 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1034 #if __BYTE_ORDER == __BIG_ENDIAN |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1035 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1036 mexErrMsgTxt("IEEE-to-IBM conversion on big-endian platform not supported, yet"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1037 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1038 #elif __BYTE_ORDER==__LITTLE_ENDIAN |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1039 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1040 #if DEBUG |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1041 mexPrintf("xpt2d(%016Lx): [0x%x]\n",x,c); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1042 #endif |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1043 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1044 // missing values |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1045 if ((c==0x2e || c==0x5f || (c>0x40 && c<0x5b)) && !u ) |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1046 return(NaN); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1047 |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1048 int s,e; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1049 s = *(((char*)&x) + 7) & 0x80; // sign |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1050 e = (*(((char*)&x) + 7) & 0x7f) - 64; // exponent |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1051 *(((char*)&x) + 7) = 0; // mantisse x |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1052 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1053 #if DEBUG |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1054 mexPrintf("%x %x %016Lx\n",s,e,x); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1055 #endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1056 |
8927 | 1057 double y = ldexp((double)x, e*4-56); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1058 if (s) return(-y); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1059 else return( y); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1060 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1061 #endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1062 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1063 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1064 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1065 /* |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1066 D2XPT converts from little-endian IEEE to little-endian IBM format |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1067 */ |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1068 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1069 uint64_t d2xpt(double x) { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1070 uint64_t s,m; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1071 int e; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1072 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1073 #if __BYTE_ORDER == __BIG_ENDIAN |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1074 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1075 mexErrMsgTxt("IEEE-to-IBM conversion on big-endian platform not supported, yet"); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1076 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1077 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1078 #elif __BYTE_ORDER==__LITTLE_ENDIAN |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1079 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1080 if (x != x) return(0x2eLL << 56); // NaN - not a number |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1081 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1082 if (fabs(x) == 1.0/0.0) return(0x5fLL << 56); // +-infinity |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1083 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1084 if (x == 0.0) return(0); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1085 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1086 if (x > 0.0) s=0; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1087 else s=1; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1088 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1089 x = frexp(x,&e); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1090 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1091 #if DEBUG |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1092 mexPrintf("d2xpt(%f)\n",x); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1093 #endif |
7426 | 1094 // see http://old.nabble.com/Re%3A-IBM-integer-and-double-formats-p20428979.html |
12678
e4374feb2e3f
[nan-tb] fix bug when file open fails; address several compiler warnings
schloegl
parents:
12584
diff
changeset
|
1095 memcpy(&m, &x, 8); |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1096 *(((char*)&m) + 6) &= 0x0f; // |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1097 if (e) *(((char*)&m) + 6) |= 0x10; // reconstruct implicit leading '1' for normalized numbers |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1098 m <<= (3-(-e & 3)); |
8927 | 1099 *(((uint8_t*)&m) + 7) = s ? 0x80 : 0; |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1100 e = (e + (-e & 3)) / 4 + 64; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1101 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1102 if (e >= 128) return(0x5f); // overflow |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1103 if (e < 0) { |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1104 uint64_t h = 1<<(4*-e - 1); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1105 m = m / (2*h) + (m & h && m & (3*h-1) ? 1 : 0); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1106 e = 0; |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1107 } |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1108 return (((uint64_t)e)<<56 | m); |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1109 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1110 #endif |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1111 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1112 } |
7376
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1113 |
37789a34b615
add reading and writing of XPT (SAS Transport File) format
schloegl
parents:
diff
changeset
|
1114 |
7434 | 1115 double tm_time2gdf_time(struct tm *t) { |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1116 /* based Octave's datevec.m |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1117 it referes Peter Baum's algorithm at http://vsg.cape.com/~pbaum/date/date0.htm |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1118 but the link is not working anymore as of 2008-12-03. |
7434 | 1119 |
1120 Other links to Peter Baum's algorithm are | |
1121 http://www.rexswain.com/b2mmddyy.rex | |
1122 http://www.dpwr.net/forums/index.php?s=ecfa72e38be61327403126e23aeea7e5&showtopic=4309 | |
1123 */ | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1124 |
7434 | 1125 int Y,M,s; //h,m, |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1126 double D; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1127 |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1128 D = t->tm_mday; |
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1129 M = t->tm_mon+1; |
7434 | 1130 Y = t->tm_year+1900; |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1131 |
7434 | 1132 // Set start of year to March by moving Jan. and Feb. to previous year. |
1133 // Correct for months > 12 by moving to subsequent years. | |
10135 | 1134 Y += (int)fix ((M-14.0)/12); |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1135 |
7434 | 1136 const int monthstart[] = {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275}; |
1137 // Lookup number of days since start of the current year. | |
1138 D += monthstart[t->tm_mon % 12] + 60; | |
1139 | |
1140 // Add number of days to the start of the current year. Correct | |
1141 // for leap year every 4 years except centuries not divisible by 400. | |
1142 D += 365*Y + floor (Y/4) - floor (Y/100) + floor (Y/400); | |
1143 | |
1144 // Add fraction representing current second of the day. | |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1145 s = t->tm_hour*3600 + t->tm_min*60 + t->tm_sec; |
7434 | 1146 |
7760
c211a946f136
fix check of input arguments; support for STATA files versuions less than 114; remove trailing blanks
schloegl
parents:
7574
diff
changeset
|
1147 // s -= timezone; |
7434 | 1148 return(D + s/86400.0); |
1149 } | |
1150 |