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,20 @@
1
+ //
2
+ // readstat_bit.h - Bit-twiddling utility functions
3
+ //
4
+
5
+ #define READSTAT_MACHINE_IS_TWOS_COMPLEMENT ((char)0xFF == (char)-1)
6
+
7
+ #undef READSTAT_MACHINE_IS_TWOS_COMPLEMENT
8
+ #define READSTAT_MACHINE_IS_TWOS_COMPLEMENT 0
9
+
10
+ int machine_is_little_endian(void);
11
+
12
+ char ones_to_twos_complement1(char num);
13
+ int16_t ones_to_twos_complement2(int16_t num);
14
+ int32_t ones_to_twos_complement4(int32_t num);
15
+ uint16_t byteswap2(uint16_t num);
16
+ uint32_t byteswap4(uint32_t num);
17
+ uint64_t byteswap8(uint64_t num);
18
+
19
+ float byteswap_float(float num);
20
+ double byteswap_double(double num);
@@ -0,0 +1,36 @@
1
+
2
+ #include <errno.h>
3
+ #include "readstat.h"
4
+ #include "readstat_iconv.h"
5
+ #include "readstat_convert.h"
6
+
7
+ readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
8
+ /* strip off spaces from the input because the programs use ASCII space
9
+ * padding even with non-ASCII encoding. */
10
+ while (src_len && (src[src_len-1] == ' ' || src[src_len-1] == '\0')) {
11
+ src_len--;
12
+ }
13
+ if (dst_len == 0) {
14
+ return READSTAT_ERROR_CONVERT_LONG_STRING;
15
+ } else if (converter) {
16
+ size_t dst_left = dst_len - 1;
17
+ char *dst_end = dst;
18
+ size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
19
+ if (status == (size_t)-1) {
20
+ if (errno == E2BIG) {
21
+ return READSTAT_ERROR_CONVERT_LONG_STRING;
22
+ } else if (errno == EILSEQ) {
23
+ return READSTAT_ERROR_CONVERT_BAD_STRING;
24
+ } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
25
+ return READSTAT_ERROR_CONVERT;
26
+ }
27
+ }
28
+ dst[dst_len - dst_left - 1] = '\0';
29
+ } else if (src_len + 1 > dst_len) {
30
+ return READSTAT_ERROR_CONVERT_LONG_STRING;
31
+ } else {
32
+ memcpy(dst, src, src_len);
33
+ dst[src_len] = '\0';
34
+ }
35
+ return READSTAT_OK;
36
+ }
@@ -0,0 +1,2 @@
1
+
2
+ readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter);
@@ -0,0 +1,126 @@
1
+
2
+ #include "readstat.h"
3
+
4
+ const char *readstat_error_message(readstat_error_t error_code) {
5
+ if (error_code == READSTAT_OK)
6
+ return NULL;
7
+
8
+ if (error_code == READSTAT_ERROR_OPEN)
9
+ return "Unable to open file";
10
+
11
+ if (error_code == READSTAT_ERROR_READ)
12
+ return "Unable to read from file";
13
+
14
+ if (error_code == READSTAT_ERROR_MALLOC)
15
+ return "Unable to allocate memory";
16
+
17
+ if (error_code == READSTAT_ERROR_USER_ABORT)
18
+ return "The parsing was aborted (callback returned non-zero value)";
19
+
20
+ if (error_code == READSTAT_ERROR_PARSE)
21
+ return "Invalid file, or file has unsupported features";
22
+
23
+ if (error_code == READSTAT_ERROR_UNSUPPORTED_COMPRESSION)
24
+ return "File has unsupported compression scheme";
25
+
26
+ if (error_code == READSTAT_ERROR_UNSUPPORTED_CHARSET)
27
+ return "File has an unsupported character set";
28
+
29
+ if (error_code == READSTAT_ERROR_COLUMN_COUNT_MISMATCH)
30
+ return "File did not contain the expected number of columns";
31
+
32
+ if (error_code == READSTAT_ERROR_ROW_COUNT_MISMATCH)
33
+ return "File did not contain the expected number of rows";
34
+
35
+ if (error_code == READSTAT_ERROR_ROW_WIDTH_MISMATCH)
36
+ return "A row in the file was not the expected length";
37
+
38
+ if (error_code == READSTAT_ERROR_BAD_FORMAT_STRING)
39
+ return "A provided format string could not be understood";
40
+
41
+ if (error_code == READSTAT_ERROR_VALUE_TYPE_MISMATCH)
42
+ return "A provided value was incompatible with the variable's declared type";
43
+
44
+ if (error_code == READSTAT_ERROR_WRITE)
45
+ return "Unable to write data";
46
+
47
+ if (error_code == READSTAT_ERROR_WRITER_NOT_INITIALIZED)
48
+ return "The writer object was not properly initialized (call and check return value of readstat_begin_writing_XXX)";
49
+
50
+ if (error_code == READSTAT_ERROR_SEEK)
51
+ return "Unable to seek within file";
52
+
53
+ if (error_code == READSTAT_ERROR_CONVERT)
54
+ return "Unable to convert string to the requested encoding";
55
+
56
+ if (error_code == READSTAT_ERROR_CONVERT_BAD_STRING)
57
+ return "Unable to convert string to the requested encoding (invalid byte sequence)";
58
+
59
+ if (error_code == READSTAT_ERROR_CONVERT_SHORT_STRING)
60
+ return "Unable to convert string to the requested encoding (incomplete byte sequence)";
61
+
62
+ if (error_code == READSTAT_ERROR_CONVERT_LONG_STRING)
63
+ return "Unable to convert string to the requested encoding (output buffer too small)";
64
+
65
+ if (error_code == READSTAT_ERROR_NUMERIC_VALUE_IS_OUT_OF_RANGE)
66
+ return "A provided numeric value was outside the range of representable values in the specified file format";
67
+
68
+ if (error_code == READSTAT_ERROR_TAGGED_VALUE_IS_OUT_OF_RANGE)
69
+ return "A provided tag value was outside the range of allowed values in the specified file format";
70
+
71
+ if (error_code == READSTAT_ERROR_STRING_VALUE_IS_TOO_LONG)
72
+ return "A provided string value was longer than the available storage size of the specified column";
73
+
74
+ if (error_code == READSTAT_ERROR_TAGGED_VALUES_NOT_SUPPORTED)
75
+ return "The file format does not supported character tags for missing values";
76
+
77
+ if (error_code == READSTAT_ERROR_UNSUPPORTED_FILE_FORMAT_VERSION)
78
+ return "This version of the file format is not supported";
79
+
80
+ if (error_code == READSTAT_ERROR_NAME_BEGINS_WITH_ILLEGAL_CHARACTER)
81
+ return "A provided name begins with an illegal character";
82
+
83
+ if (error_code == READSTAT_ERROR_NAME_CONTAINS_ILLEGAL_CHARACTER)
84
+ return "A provided name contains an illegal character";
85
+
86
+ if (error_code == READSTAT_ERROR_NAME_IS_RESERVED_WORD)
87
+ return "A provided name is a reserved word";
88
+
89
+ if (error_code == READSTAT_ERROR_NAME_IS_TOO_LONG)
90
+ return "A provided name is too long for the file format";
91
+
92
+ if (error_code == READSTAT_ERROR_NAME_IS_ZERO_LENGTH)
93
+ return "A provided name is blank or empty";
94
+
95
+ if (error_code == READSTAT_ERROR_BAD_TIMESTAMP_STRING)
96
+ return "The file's timestamp string is invalid";
97
+
98
+ if (error_code == READSTAT_ERROR_BAD_FREQUENCY_WEIGHT)
99
+ return "The provided variable can't be used as a frequency weight";
100
+
101
+ if (error_code == READSTAT_ERROR_TOO_MANY_MISSING_VALUE_DEFINITIONS)
102
+ return "The number of defined missing values exceeds the format limit";
103
+
104
+ if (error_code == READSTAT_ERROR_NOTE_IS_TOO_LONG)
105
+ return "The provided note is too long for the file format";
106
+
107
+ if (error_code == READSTAT_ERROR_STRING_REFS_NOT_SUPPORTED)
108
+ return "This version of the file format does not support string references";
109
+
110
+ if (error_code == READSTAT_ERROR_STRING_REF_IS_REQUIRED)
111
+ return "The provided value was not a valid string reference";
112
+
113
+ if (error_code == READSTAT_ERROR_ROW_IS_TOO_WIDE_FOR_PAGE)
114
+ return "A row of data will not fit into the file format";
115
+
116
+ if (error_code == READSTAT_ERROR_TOO_FEW_COLUMNS)
117
+ return "One or more columns must be provided";
118
+
119
+ if (error_code == READSTAT_ERROR_TOO_MANY_COLUMNS)
120
+ return "Too many columns for this file format version";
121
+
122
+ if (error_code == READSTAT_ERROR_BAD_TIMESTAMP_VALUE)
123
+ return "The provided file timestamp is invalid";
124
+
125
+ return "Unknown error";
126
+ }
@@ -0,0 +1,15 @@
1
+ #include <iconv.h>
2
+
3
+ /* ICONV_CONST defined by autotools during configure according
4
+ * to the current platform. Some people copy-paste the source code, so
5
+ * provide some fallback logic */
6
+ #ifndef ICONV_CONST
7
+ #define ICONV_CONST
8
+ #endif
9
+
10
+ typedef ICONV_CONST char ** readstat_iconv_inbuf_t;
11
+
12
+ typedef struct readstat_charset_entry_s {
13
+ int code;
14
+ char name[32];
15
+ } readstat_charset_entry_t;
@@ -0,0 +1,147 @@
1
+
2
+ #include <fcntl.h>
3
+ #include <stdlib.h>
4
+ #include <wchar.h>
5
+
6
+ #if defined _WIN32
7
+ # include <windows.h>
8
+ # include <io.h>
9
+ #endif
10
+
11
+ #if !defined(_MSC_VER)
12
+ # include <unistd.h>
13
+ #else
14
+ #define open _open
15
+ #define read _read
16
+ #define close _close
17
+ #endif
18
+
19
+ #if defined _WIN32 || defined __CYGWIN__
20
+ #define UNISTD_OPEN_OPTIONS O_RDONLY | O_BINARY
21
+ #elif defined _AIX
22
+ #define UNISTD_OPEN_OPTIONS O_RDONLY | O_LARGEFILE
23
+ #else
24
+ #define UNISTD_OPEN_OPTIONS O_RDONLY
25
+ #endif
26
+
27
+ #if defined _WIN32
28
+ #define lseek _lseeki64
29
+ #elif defined _AIX
30
+ #define lseek lseek64
31
+ #endif
32
+
33
+ #include "readstat.h"
34
+ #include "readstat_io_unistd.h"
35
+
36
+ int open_with_unicode(const char *path, int options)
37
+ {
38
+ #if defined _WIN32
39
+ const int buffer_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
40
+
41
+ if(buffer_size <= 0)
42
+ return -1;
43
+
44
+ wchar_t* wpath = malloc((buffer_size + 1) * sizeof(wchar_t));
45
+ const int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, buffer_size);
46
+ wpath[buffer_size] = 0;
47
+
48
+ if(res <= 0)
49
+ {
50
+ free(wpath);
51
+ return -1;
52
+ }
53
+
54
+ int fd = _wopen(wpath, options);
55
+
56
+ free(wpath);
57
+ return fd;
58
+ #else
59
+ return open(path, options);
60
+ #endif
61
+ }
62
+
63
+ int unistd_open_handler(const char *path, void *io_ctx) {
64
+ int fd = open_with_unicode(path, UNISTD_OPEN_OPTIONS);
65
+ ((unistd_io_ctx_t*) io_ctx)->fd = fd;
66
+ return fd;
67
+ }
68
+
69
+ int unistd_close_handler(void *io_ctx) {
70
+ int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
71
+ if (fd != -1)
72
+ return close(fd);
73
+ else
74
+ return 0;
75
+ }
76
+
77
+ readstat_off_t unistd_seek_handler(readstat_off_t offset,
78
+ readstat_io_flags_t whence, void *io_ctx) {
79
+ int flag = 0;
80
+ switch(whence) {
81
+ case READSTAT_SEEK_SET:
82
+ flag = SEEK_SET;
83
+ break;
84
+ case READSTAT_SEEK_CUR:
85
+ flag = SEEK_CUR;
86
+ break;
87
+ case READSTAT_SEEK_END:
88
+ flag = SEEK_END;
89
+ break;
90
+ default:
91
+ return -1;
92
+ }
93
+ int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
94
+ return lseek(fd, offset, flag);
95
+ }
96
+
97
+ ssize_t unistd_read_handler(void *buf, size_t nbyte, void *io_ctx) {
98
+ int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
99
+ ssize_t out = read(fd, buf, nbyte);
100
+ return out;
101
+ }
102
+
103
+ readstat_error_t unistd_update_handler(long file_size,
104
+ readstat_progress_handler progress_handler, void *user_ctx,
105
+ void *io_ctx) {
106
+ if (!progress_handler)
107
+ return READSTAT_OK;
108
+
109
+ int fd = ((unistd_io_ctx_t*) io_ctx)->fd;
110
+ readstat_off_t current_offset = lseek(fd, 0, SEEK_CUR);
111
+
112
+ if (current_offset == -1)
113
+ return READSTAT_ERROR_SEEK;
114
+
115
+ if (progress_handler(1.0 * current_offset / file_size, user_ctx))
116
+ return READSTAT_ERROR_USER_ABORT;
117
+
118
+ return READSTAT_OK;
119
+ }
120
+
121
+ readstat_error_t unistd_io_init(readstat_parser_t *parser) {
122
+ readstat_error_t retval = READSTAT_OK;
123
+ unistd_io_ctx_t *io_ctx = NULL;
124
+
125
+ if ((retval = readstat_set_open_handler(parser, unistd_open_handler)) != READSTAT_OK)
126
+ return retval;
127
+
128
+ if ((retval = readstat_set_close_handler(parser, unistd_close_handler)) != READSTAT_OK)
129
+ return retval;
130
+
131
+ if ((retval = readstat_set_seek_handler(parser, unistd_seek_handler)) != READSTAT_OK)
132
+ return retval;
133
+
134
+ if ((retval = readstat_set_read_handler(parser, unistd_read_handler)) != READSTAT_OK)
135
+ return retval;
136
+
137
+ if ((readstat_set_update_handler(parser, unistd_update_handler)) != READSTAT_OK)
138
+ return retval;
139
+
140
+ io_ctx = calloc(1, sizeof(unistd_io_ctx_t));
141
+ io_ctx->fd = -1;
142
+
143
+ retval = readstat_set_io_ctx(parser, (void*) io_ctx);
144
+ parser->io->io_ctx_needs_free = 1;
145
+
146
+ return retval;
147
+ }
@@ -0,0 +1,11 @@
1
+
2
+ typedef struct unistd_io_ctx_s {
3
+ int fd;
4
+ } unistd_io_ctx_t;
5
+
6
+ int unistd_open_handler(const char *path, void *io_ctx);
7
+ int unistd_close_handler(void *io_ctx);
8
+ readstat_off_t unistd_seek_handler(readstat_off_t offset, readstat_io_flags_t whence, void *io_ctx);
9
+ ssize_t unistd_read_handler(void *buf, size_t nbytes, void *io_ctx);
10
+ readstat_error_t unistd_update_handler(long file_size, readstat_progress_handler progress_handler, void *user_ctx, void *io_ctx);
11
+ readstat_error_t unistd_io_init(readstat_parser_t *parser);
@@ -0,0 +1,34 @@
1
+ #include <stdlib.h>
2
+
3
+ #define MAX_MALLOC_SIZE 0x1000000
4
+ /* =16 MiB. Needs to be at least 0x3FF00, i.e. the default ~4MB block size used
5
+ * in compressed SPSS (ZSAV) files. Some SAS installations use 16MiB page sizes
6
+ * by default, see https://github.com/tidyverse/haven/issues/697.
7
+ * The purpose here is to prevent massive allocations in the event of a
8
+ * malformed file or a bug in the library. */
9
+
10
+ void *readstat_malloc(size_t len) {
11
+ if (len > MAX_MALLOC_SIZE || len == 0) {
12
+ return NULL;
13
+ }
14
+ return malloc(len);
15
+ }
16
+
17
+ void *readstat_calloc(size_t count, size_t size) {
18
+ if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
19
+ return NULL;
20
+ }
21
+ if (count == 0 || size == 0) {
22
+ return NULL;
23
+ }
24
+ return calloc(count, size);
25
+ }
26
+
27
+ void *readstat_realloc(void *ptr, size_t len) {
28
+ if (len > MAX_MALLOC_SIZE || len == 0) {
29
+ if (ptr)
30
+ free(ptr);
31
+ return NULL;
32
+ }
33
+ return realloc(ptr, len);
34
+ }
@@ -0,0 +1,4 @@
1
+
2
+ void *readstat_malloc(size_t size);
3
+ void *readstat_calloc(size_t count, size_t size);
4
+ void *readstat_realloc(void *ptr, size_t len);
@@ -0,0 +1,53 @@
1
+ #include "readstat.h"
2
+
3
+ int readstat_get_row_count(readstat_metadata_t *metadata) {
4
+ return metadata->row_count;
5
+ }
6
+
7
+ int readstat_get_var_count(readstat_metadata_t *metadata) {
8
+ return metadata->var_count;
9
+ }
10
+
11
+ time_t readstat_get_creation_time(readstat_metadata_t *metadata) {
12
+ return metadata->creation_time;
13
+ }
14
+
15
+ time_t readstat_get_modified_time(readstat_metadata_t *metadata) {
16
+ return metadata->modified_time;
17
+ }
18
+
19
+ int readstat_get_file_format_version(readstat_metadata_t *metadata) {
20
+ return metadata->file_format_version;
21
+ }
22
+
23
+ int readstat_get_file_format_is_64bit(readstat_metadata_t *metadata) {
24
+ return metadata->is64bit;
25
+ }
26
+
27
+ readstat_compress_t readstat_get_compression(readstat_metadata_t *metadata) {
28
+ return metadata->compression;
29
+ }
30
+
31
+ readstat_endian_t readstat_get_endianness(readstat_metadata_t *metadata) {
32
+ return metadata->endianness;
33
+ }
34
+
35
+ const char *readstat_get_file_label(readstat_metadata_t *metadata) {
36
+ return metadata->file_label;
37
+ }
38
+
39
+ const char *readstat_get_file_encoding(readstat_metadata_t *metadata) {
40
+ return metadata->file_encoding;
41
+ }
42
+
43
+ const char *readstat_get_table_name(readstat_metadata_t *metadata) {
44
+ return metadata->table_name;
45
+ }
46
+
47
+ size_t readstat_get_multiple_response_sets_length(readstat_metadata_t *metadata) {
48
+ return metadata->multiple_response_sets_length;
49
+ }
50
+
51
+ const mr_set_t *readstat_get_multiple_response_sets(readstat_metadata_t *metadata) {
52
+ return metadata->mr_sets;
53
+ }
@@ -0,0 +1,121 @@
1
+
2
+ #include <stdlib.h>
3
+ #include "readstat.h"
4
+ #include "readstat_io_unistd.h"
5
+
6
+ readstat_parser_t *readstat_parser_init(void) {
7
+ readstat_parser_t *parser = calloc(1, sizeof(readstat_parser_t));
8
+ parser->io = calloc(1, sizeof(readstat_io_t));
9
+ if (unistd_io_init(parser) != READSTAT_OK) {
10
+ readstat_parser_free(parser);
11
+ return NULL;
12
+ }
13
+ parser->output_encoding = "UTF-8";
14
+ return parser;
15
+ }
16
+
17
+ void readstat_parser_free(readstat_parser_t *parser) {
18
+ if (parser) {
19
+ if (parser->io) {
20
+ readstat_set_io_ctx(parser, NULL);
21
+ free(parser->io);
22
+ }
23
+ free(parser);
24
+ }
25
+ }
26
+
27
+ readstat_error_t readstat_set_metadata_handler(readstat_parser_t *parser, readstat_metadata_handler metadata_handler) {
28
+ parser->handlers.metadata = metadata_handler;
29
+ return READSTAT_OK;
30
+ }
31
+
32
+ readstat_error_t readstat_set_note_handler(readstat_parser_t *parser, readstat_note_handler note_handler) {
33
+ parser->handlers.note = note_handler;
34
+ return READSTAT_OK;
35
+ }
36
+
37
+ readstat_error_t readstat_set_variable_handler(readstat_parser_t *parser, readstat_variable_handler variable_handler) {
38
+ parser->handlers.variable = variable_handler;
39
+ return READSTAT_OK;
40
+ }
41
+
42
+ readstat_error_t readstat_set_value_handler(readstat_parser_t *parser, readstat_value_handler value_handler) {
43
+ parser->handlers.value = value_handler;
44
+ return READSTAT_OK;
45
+ }
46
+
47
+ readstat_error_t readstat_set_value_label_handler(readstat_parser_t *parser, readstat_value_label_handler label_handler) {
48
+ parser->handlers.value_label = label_handler;
49
+ return READSTAT_OK;
50
+ }
51
+
52
+ readstat_error_t readstat_set_error_handler(readstat_parser_t *parser, readstat_error_handler error_handler) {
53
+ parser->handlers.error = error_handler;
54
+ return READSTAT_OK;
55
+ }
56
+
57
+ readstat_error_t readstat_set_progress_handler(readstat_parser_t *parser, readstat_progress_handler progress_handler) {
58
+ parser->handlers.progress = progress_handler;
59
+ return READSTAT_OK;
60
+ }
61
+
62
+ readstat_error_t readstat_set_fweight_handler(readstat_parser_t *parser, readstat_fweight_handler fweight_handler) {
63
+ parser->handlers.fweight = fweight_handler;
64
+ return READSTAT_OK;
65
+ }
66
+
67
+ readstat_error_t readstat_set_open_handler(readstat_parser_t *parser, readstat_open_handler open_handler) {
68
+ parser->io->open = open_handler;
69
+ return READSTAT_OK;
70
+ }
71
+
72
+ readstat_error_t readstat_set_close_handler(readstat_parser_t *parser, readstat_close_handler close_handler) {
73
+ parser->io->close = close_handler;
74
+ return READSTAT_OK;
75
+ }
76
+
77
+ readstat_error_t readstat_set_seek_handler(readstat_parser_t *parser, readstat_seek_handler seek_handler) {
78
+ parser->io->seek = seek_handler;
79
+ return READSTAT_OK;
80
+ }
81
+
82
+ readstat_error_t readstat_set_read_handler(readstat_parser_t *parser, readstat_read_handler read_handler) {
83
+ parser->io->read = read_handler;
84
+ return READSTAT_OK;
85
+ }
86
+
87
+ readstat_error_t readstat_set_update_handler(readstat_parser_t *parser, readstat_update_handler update_handler) {
88
+ parser->io->update = update_handler;
89
+ return READSTAT_OK;
90
+ }
91
+
92
+ readstat_error_t readstat_set_io_ctx(readstat_parser_t *parser, void *io_ctx) {
93
+ if (parser->io->io_ctx_needs_free) {
94
+ free(parser->io->io_ctx);
95
+ }
96
+
97
+ parser->io->io_ctx = io_ctx;
98
+ parser->io->io_ctx_needs_free = 0;
99
+
100
+ return READSTAT_OK;
101
+ }
102
+
103
+ readstat_error_t readstat_set_file_character_encoding(readstat_parser_t *parser, const char *encoding) {
104
+ parser->input_encoding = encoding;
105
+ return READSTAT_OK;
106
+ }
107
+
108
+ readstat_error_t readstat_set_handler_character_encoding(readstat_parser_t *parser, const char *encoding) {
109
+ parser->output_encoding = encoding;
110
+ return READSTAT_OK;
111
+ }
112
+
113
+ readstat_error_t readstat_set_row_limit(readstat_parser_t *parser, long row_limit) {
114
+ parser->row_limit = row_limit;
115
+ return READSTAT_OK;
116
+ }
117
+
118
+ readstat_error_t readstat_set_row_offset(readstat_parser_t *parser, long row_offset) {
119
+ parser->row_offset = row_offset;
120
+ return READSTAT_OK;
121
+ }
@@ -0,0 +1,6 @@
1
+ #if defined(_MSC_VER)
2
+ # define strncasecmp _strnicmp
3
+ # define strcasecmp _stricmp
4
+ #else
5
+ # include <strings.h>
6
+ #endif