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