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