js-stream-sas7bdat 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/binding.gyp +58 -0
  2. package/package.json +4 -2
  3. package/src/binding/ReadStat/LICENSE +19 -0
  4. package/src/binding/ReadStat/README.md +483 -0
  5. package/src/binding/ReadStat/src/CKHashTable.c +309 -0
  6. package/src/binding/ReadStat/src/CKHashTable.h +37 -0
  7. package/src/binding/ReadStat/src/readstat.h +627 -0
  8. package/src/binding/ReadStat/src/readstat_bits.c +69 -0
  9. package/src/binding/ReadStat/src/readstat_bits.h +20 -0
  10. package/src/binding/ReadStat/src/readstat_convert.c +36 -0
  11. package/src/binding/ReadStat/src/readstat_convert.h +2 -0
  12. package/src/binding/ReadStat/src/readstat_error.c +126 -0
  13. package/src/binding/ReadStat/src/readstat_iconv.h +15 -0
  14. package/src/binding/ReadStat/src/readstat_io_unistd.c +147 -0
  15. package/src/binding/ReadStat/src/readstat_io_unistd.h +11 -0
  16. package/src/binding/ReadStat/src/readstat_malloc.c +34 -0
  17. package/src/binding/ReadStat/src/readstat_malloc.h +4 -0
  18. package/src/binding/ReadStat/src/readstat_metadata.c +53 -0
  19. package/src/binding/ReadStat/src/readstat_parser.c +121 -0
  20. package/src/binding/ReadStat/src/readstat_strings.h +6 -0
  21. package/src/binding/ReadStat/src/readstat_value.c +178 -0
  22. package/src/binding/ReadStat/src/readstat_variable.c +123 -0
  23. package/src/binding/ReadStat/src/readstat_writer.c +677 -0
  24. package/src/binding/ReadStat/src/readstat_writer.h +21 -0
  25. package/src/binding/ReadStat/src/sas/ieee.c +420 -0
  26. package/src/binding/ReadStat/src/sas/ieee.h +6 -0
  27. package/src/binding/ReadStat/src/sas/readstat_sas.c +528 -0
  28. package/src/binding/ReadStat/src/sas/readstat_sas.h +131 -0
  29. package/src/binding/ReadStat/src/sas/readstat_sas7bcat_read.c +515 -0
  30. package/src/binding/ReadStat/src/sas/readstat_sas7bcat_write.c +218 -0
  31. package/src/binding/ReadStat/src/sas/readstat_sas7bdat_read.c +1304 -0
  32. package/src/binding/ReadStat/src/sas/readstat_sas7bdat_write.c +812 -0
  33. package/src/binding/ReadStat/src/sas/readstat_sas_rle.c +286 -0
  34. package/src/binding/ReadStat/src/sas/readstat_sas_rle.h +8 -0
  35. package/src/binding/ReadStat/src/sas/readstat_xport.c +28 -0
  36. package/src/binding/ReadStat/src/sas/readstat_xport.h +47 -0
  37. package/src/binding/ReadStat/src/sas/readstat_xport_parse_format.c +265 -0
  38. package/src/binding/ReadStat/src/sas/readstat_xport_parse_format.h +4 -0
  39. package/src/binding/ReadStat/src/sas/readstat_xport_parse_format.rl +68 -0
  40. package/src/binding/ReadStat/src/sas/readstat_xport_read.c +777 -0
  41. package/src/binding/ReadStat/src/sas/readstat_xport_write.c +561 -0
  42. package/src/binding/readstat_binding.cc +393 -0
@@ -0,0 +1,218 @@
1
+
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <time.h>
5
+ #include <iconv.h>
6
+
7
+ #include "../readstat.h"
8
+ #include "../readstat_writer.h"
9
+ #include "readstat_sas.h"
10
+ #include "readstat_sas_rle.h"
11
+
12
+ typedef struct sas7bcat_block_s {
13
+ size_t len;
14
+ char data[1]; // Flexible array; use [1] for C++-98 compatibility
15
+ } sas7bcat_block_t;
16
+
17
+ static sas7bcat_block_t *sas7bcat_block_for_label_set(readstat_label_set_t *r_label_set) {
18
+ size_t len = 0;
19
+ size_t name_len = strlen(r_label_set->name);
20
+ int j;
21
+ char name[32];
22
+
23
+ len += 106;
24
+
25
+ if (name_len > 8) {
26
+ len += 32; // long name
27
+ if (name_len > 32) {
28
+ name_len = 32;
29
+ }
30
+ }
31
+
32
+ memcpy(&name[0], r_label_set->name, name_len);
33
+
34
+ for (j=0; j<r_label_set->value_labels_count; j++) {
35
+ readstat_value_label_t *value_label = readstat_get_value_label(r_label_set, j);
36
+ len += 30; // Value: 14-byte header + 16-byte padded value
37
+
38
+ len += 8 + 2 + value_label->label_len + 1;
39
+ }
40
+
41
+ sas7bcat_block_t *block = calloc(1, sizeof(sas7bcat_block_t) + len);
42
+ block->len = len;
43
+
44
+ off_t begin = 106;
45
+ int32_t count = r_label_set->value_labels_count;
46
+ memcpy(&block->data[38], &count, sizeof(int32_t));
47
+ memcpy(&block->data[42], &count, sizeof(int32_t));
48
+ if (name_len > 8) {
49
+ int16_t flags = 0x80;
50
+ memcpy(&block->data[2], &flags, sizeof(int16_t));
51
+ memcpy(&block->data[8], name, 8);
52
+
53
+ memset(&block->data[106], ' ', 32);
54
+ memcpy(&block->data[106], name, name_len);
55
+
56
+ begin += 32;
57
+ } else {
58
+ memset(&block->data[8], ' ', 8);
59
+ memcpy(&block->data[8], name, name_len);
60
+ }
61
+
62
+ char *lbp1 = &block->data[begin];
63
+ char *lbp2 = &block->data[begin+r_label_set->value_labels_count*30];
64
+
65
+ for (j=0; j<r_label_set->value_labels_count; j++) {
66
+ readstat_value_label_t *value_label = readstat_get_value_label(r_label_set, j);
67
+ int16_t value_entry_len = 24; // size - 6
68
+ memcpy(&lbp1[2], &value_entry_len, sizeof(int16_t));
69
+ int32_t index = j;
70
+ memcpy(&lbp1[10], &index, sizeof(int32_t));
71
+ if (r_label_set->type == READSTAT_TYPE_STRING) {
72
+ size_t string_len = value_label->string_key_len;
73
+ if (string_len > 16)
74
+ string_len = 16;
75
+ memset(&lbp1[14], ' ', 16);
76
+ memcpy(&lbp1[14], value_label->string_key, string_len);
77
+ } else {
78
+ uint64_t big_endian_value;
79
+ double double_value = -1.0 * value_label->double_key;
80
+ memcpy(&big_endian_value, &double_value, sizeof(double));
81
+ if (machine_is_little_endian()) {
82
+ big_endian_value = byteswap8(big_endian_value);
83
+ }
84
+ memcpy(&lbp1[22], &big_endian_value, sizeof(uint64_t));
85
+ }
86
+
87
+ int16_t label_len = value_label->label_len;
88
+ memcpy(&lbp2[8], &label_len, sizeof(int16_t));
89
+ memcpy(&lbp2[10], value_label->label, label_len);
90
+
91
+ lbp1 += 6 + value_entry_len;
92
+ lbp2 += 8 + 2 + value_label->label_len + 1;
93
+ }
94
+
95
+ return block;
96
+ }
97
+
98
+ static readstat_error_t sas7bcat_emit_header(readstat_writer_t *writer, sas_header_info_t *hinfo) {
99
+ sas_header_start_t header_start = {
100
+ .a2 = hinfo->u64 ? SAS_ALIGNMENT_OFFSET_4 : SAS_ALIGNMENT_OFFSET_0,
101
+ .a1 = SAS_ALIGNMENT_OFFSET_0,
102
+ .endian = machine_is_little_endian() ? SAS_ENDIAN_LITTLE : SAS_ENDIAN_BIG,
103
+ .file_format = SAS_FILE_FORMAT_UNIX,
104
+ .encoding = 20, /* UTF-8 */
105
+ .file_type = "SAS FILE",
106
+ .file_info = "CATALOG "
107
+ };
108
+
109
+ memcpy(&header_start.magic, sas7bcat_magic_number, sizeof(header_start.magic));
110
+
111
+ return sas_write_header(writer, hinfo, header_start);
112
+ }
113
+
114
+ static readstat_error_t sas7bcat_begin_data(void *writer_ctx) {
115
+ readstat_writer_t *writer = (readstat_writer_t *)writer_ctx;
116
+ readstat_error_t retval = READSTAT_OK;
117
+
118
+ int i;
119
+ sas_header_info_t *hinfo = sas_header_info_init(writer, 0);
120
+ sas7bcat_block_t **blocks = malloc(writer->label_sets_count * sizeof(sas7bcat_block_t));
121
+ char *page = malloc(hinfo->page_size);
122
+
123
+ for (i=0; i<writer->label_sets_count; i++) {
124
+ blocks[i] = sas7bcat_block_for_label_set(writer->label_sets[i]);
125
+ }
126
+
127
+ hinfo->page_count = 4;
128
+
129
+ // Header
130
+ retval = sas7bcat_emit_header(writer, hinfo);
131
+ if (retval != READSTAT_OK)
132
+ goto cleanup;
133
+
134
+ // Page 0
135
+ retval = readstat_write_zeros(writer, hinfo->page_size);
136
+ if (retval != READSTAT_OK)
137
+ goto cleanup;
138
+
139
+ memset(page, '\0', hinfo->page_size);
140
+
141
+ // Page 1
142
+ char *xlsr = &page[856];
143
+ int32_t block_idx = 4;
144
+ int16_t block_off = 16;
145
+ for (i=0; i<writer->label_sets_count; i++) {
146
+ if (xlsr + 212 > page + hinfo->page_size)
147
+ break;
148
+
149
+ memcpy(&xlsr[0], "XLSR", 4);
150
+
151
+ memcpy(&xlsr[4], &block_idx, sizeof(int32_t));
152
+ memcpy(&xlsr[8], &block_off, sizeof(int16_t));
153
+
154
+ xlsr[50] = 'O';
155
+
156
+ block_off += blocks[i]->len;
157
+
158
+ xlsr += 212;
159
+ }
160
+
161
+ retval = readstat_write_bytes(writer, page, hinfo->page_size);
162
+ if (retval != READSTAT_OK)
163
+ goto cleanup;
164
+
165
+ // Page 2
166
+ retval = readstat_write_zeros(writer, hinfo->page_size);
167
+ if (retval != READSTAT_OK)
168
+ goto cleanup;
169
+
170
+ // Page 3
171
+ memset(page, '\0', hinfo->page_size);
172
+
173
+ char block_header[16];
174
+ block_off = 16;
175
+ for (i=0; i<writer->label_sets_count; i++) {
176
+ if (block_off + sizeof(block_header) + blocks[i]->len > hinfo->page_size)
177
+ break;
178
+
179
+ memset(block_header, '\0', sizeof(block_header));
180
+
181
+ int32_t next_page = 0;
182
+ int16_t next_off = 0;
183
+ int16_t block_len = blocks[i]->len;
184
+ memcpy(&block_header[0], &next_page, sizeof(int32_t));
185
+ memcpy(&block_header[4], &next_off, sizeof(int16_t));
186
+ memcpy(&block_header[6], &block_len, sizeof(int16_t));
187
+
188
+ memcpy(&page[block_off], block_header, sizeof(block_header));
189
+ block_off += sizeof(block_header);
190
+
191
+ memcpy(&page[block_off], blocks[i]->data, blocks[i]->len);
192
+ block_off += blocks[i]->len;
193
+ }
194
+
195
+ retval = readstat_write_bytes(writer, page, hinfo->page_size);
196
+ if (retval != READSTAT_OK)
197
+ goto cleanup;
198
+
199
+ cleanup:
200
+ for (i=0; i<writer->label_sets_count; i++) {
201
+ free(blocks[i]);
202
+ }
203
+ free(blocks);
204
+ free(hinfo);
205
+ free(page);
206
+
207
+ return retval;
208
+ }
209
+
210
+ readstat_error_t readstat_begin_writing_sas7bcat(readstat_writer_t *writer, void *user_ctx) {
211
+
212
+ if (writer->version == 0)
213
+ writer->version = SAS_DEFAULT_FILE_VERSION;
214
+
215
+ writer->callbacks.begin_data = &sas7bcat_begin_data;
216
+
217
+ return readstat_begin_writing_file(writer, user_ctx, 0);
218
+ }