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