int arsParamSave( char *filename, ARSParam *sparam ) { FILE *fp; fp = fopen( filename, "wb" ); if( fp == NULL ) return -1; #ifdef AR_LITTLE_ENDIAN byteswap2( sparam ); #endif if( fwrite( sparam, sizeof(ARSParam), 1, fp ) != 1 ) { fclose(fp); #ifdef AR_LITTLE_ENDIAN byteswap2( sparam ); #endif return -1; } #ifdef AR_LITTLE_ENDIAN byteswap2( sparam ); #endif fclose(fp); return 0; }
static readstat_error_t xport_read_labels_v8(xport_ctx_t *ctx, int label_count) { readstat_error_t retval = READSTAT_OK; uint16_t labeldef[3]; int i; for (i=0; i<label_count; i++) { int index, name_len, label_len; if (read_bytes(ctx, labeldef, sizeof(labeldef)) != sizeof(labeldef)) { retval = READSTAT_ERROR_READ; goto cleanup; } if (machine_is_little_endian()) { index = byteswap2(labeldef[0]); name_len = byteswap2(labeldef[1]); label_len = byteswap2(labeldef[2]); } else { index = labeldef[0]; name_len = labeldef[1]; label_len = labeldef[2]; } if (index >= ctx->var_count) { retval = READSTAT_ERROR_PARSE; goto cleanup; } char name[name_len]; char label[label_len]; readstat_variable_t *variable = ctx->variables[index]; if (read_bytes(ctx, name, name_len) != name_len || read_bytes(ctx, label, label_len) != label_len) { retval = READSTAT_ERROR_READ; goto cleanup; } retval = readstat_convert(variable->name, sizeof(variable->name), name, name_len, NULL); if (retval != READSTAT_OK) goto cleanup; retval = readstat_convert(variable->label, sizeof(variable->label), label, label_len, NULL); if (retval != READSTAT_OK) goto cleanup; } retval = xport_skip_rest_of_record(ctx); if (retval != READSTAT_OK) goto cleanup; retval = xport_read_obs_header_record(ctx); if (retval != READSTAT_OK) goto cleanup; cleanup: return retval; }
// Save this (preloaded) marker to disk. int JpegMarker::Save(FILE *pFile) { const int location = ftell(pFile); if (pFile == NULL) throw("Null File in JpegMarker::Save."); unsigned short markerswapped = byteswap2(marker_); int rv = fwrite(&markerswapped, sizeof(unsigned short), 1, pFile); if (rv != 1) return 0; unsigned short slice_or_length = length_; if (marker_ == Jpeg::jpeg_sos) slice_or_length = slice_; ByteSwapInPlace(&slice_or_length, 1); rv = fwrite(&slice_or_length, sizeof(unsigned short), 1, pFile); if (rv != 1) return 0; if (marker_ == Jpeg::jpeg_sos) { WriteWithStuffBytes(pFile); // Add the EOI unsigned char eoi0 = 0xff; unsigned char eoi1 = 0xd9; fwrite(&eoi0, sizeof(eoi0), 1, pFile); fwrite(&eoi1, sizeof(eoi1), 1, pFile); } else { rv = fwrite(&data_[0], sizeof(char), data_.size(), pFile); if (rv != data_.size()) return 0; } if (debug > 0) printf("Saved marker %04x length %u at %d\n", marker_, length_, location); return 1; }
void xport_namestr_bswap(xport_namestr_t *namestr) { if (!machine_is_little_endian()) return; namestr->ntype = byteswap2(namestr->ntype); namestr->nhfun = byteswap2(namestr->nhfun); namestr->nlng = byteswap2(namestr->nlng); namestr->nvar0 = byteswap2(namestr->nlng); namestr->nfl = byteswap2(namestr->nfl); namestr->nfd = byteswap2(namestr->nfd); namestr->nfj = byteswap2(namestr->nfj); namestr->nifl = byteswap2(namestr->nifl); namestr->nifd = byteswap2(namestr->nifd); namestr->npos = byteswap4(namestr->npos); namestr->labeln = byteswap2(namestr->labeln); }
static readstat_error_t dta_read_descriptors(int fd, dta_ctx_t *ctx) { if (dta_read_tag(fd, ctx, "<variable_types>") != READSTAT_OK) return -1; size_t buffer_len = ctx->nvar * ctx->typlist_entry_len; unsigned char *buffer = malloc(buffer_len); if (read(fd, buffer, buffer_len) != buffer_len) { free(buffer); return -1; } int i; if (ctx->typlist_entry_len == 1) { for (i=0; i<ctx->nvar; i++) { ctx->typlist[i] = buffer[i]; } } else if (ctx->typlist_entry_len == 2) { memcpy(ctx->typlist, buffer, buffer_len); if (ctx->machine_needs_byte_swap) { for (i=0; i<ctx->nvar; i++) { ctx->typlist[i] = byteswap2(ctx->typlist[i]); } } } free(buffer); if (dta_read_tag(fd, ctx, "</variable_types>") != READSTAT_OK) return -1; if (dta_read_tag(fd, ctx, "<varnames>") != READSTAT_OK || read(fd, ctx->varlist, ctx->varlist_len) != ctx->varlist_len || dta_read_tag(fd, ctx, "</varnames>") != READSTAT_OK) return -1; if (dta_read_tag(fd, ctx, "<sortlist>") != READSTAT_OK || read(fd, ctx->srtlist, ctx->srtlist_len) != ctx->srtlist_len || dta_read_tag(fd, ctx, "</sortlist>") != READSTAT_OK) return -1; if (dta_read_tag(fd, ctx, "<formats>") != READSTAT_OK || read(fd, ctx->fmtlist, ctx->fmtlist_len) != ctx->fmtlist_len || dta_read_tag(fd, ctx, "</formats>") != READSTAT_OK) return -1; if (dta_read_tag(fd, ctx, "<value_label_names>") != READSTAT_OK || read(fd, ctx->lbllist, ctx->lbllist_len) != ctx->lbllist_len || dta_read_tag(fd, ctx, "</value_label_names>") != READSTAT_OK) return -1; if (dta_read_tag(fd, ctx, "<variable_labels>") != READSTAT_OK || read(fd, ctx->variable_labels, ctx->variable_labels_len) != ctx->variable_labels_len || dta_read_tag(fd, ctx, "</variable_labels>") != READSTAT_OK) return -1; return 0; }
static readstat_error_t dta_skip_expansion_fields(int fd, dta_ctx_t *ctx) { if (ctx->file_is_xmlish) { if (readstat_lseek(fd, ctx->data_offset, SEEK_SET) == -1) return READSTAT_ERROR_SEEK; return READSTAT_OK; } if (ctx->expansion_len_len == 0) return READSTAT_OK; while (1) { size_t len; char data_type; if (ctx->expansion_len_len == 2) { dta_short_expansion_field_t expansion_field; if (read(fd, &expansion_field, sizeof(expansion_field)) != sizeof(expansion_field)) return READSTAT_ERROR_READ; if (ctx->machine_needs_byte_swap) { len = byteswap2(expansion_field.len); } else { len = expansion_field.len; } data_type = expansion_field.data_type; } else { dta_expansion_field_t expansion_field; if (read(fd, &expansion_field, sizeof(expansion_field)) != sizeof(expansion_field)) return READSTAT_ERROR_READ; if (ctx->machine_needs_byte_swap) { len = byteswap4(expansion_field.len); } else { len = expansion_field.len; } data_type = expansion_field.data_type; } if (data_type == 0 && len == 0) return READSTAT_OK; if (data_type != 1) return READSTAT_ERROR_PARSE; if (readstat_lseek(fd, len, SEEK_CUR) == -1) return READSTAT_ERROR_SEEK; } return READSTAT_ERROR_PARSE; }
static readstat_error_t dta_read_descriptors(dta_ctx_t *ctx) { readstat_error_t retval = READSTAT_OK; size_t buffer_len = ctx->nvar * ctx->typlist_entry_len; unsigned char *buffer = NULL; int i; buffer = malloc(buffer_len); if ((retval = dta_read_chunk(ctx, "<variable_types>", buffer, buffer_len, "</variable_types>")) != READSTAT_OK) goto cleanup; if (ctx->typlist_entry_len == 1) { for (i=0; i<ctx->nvar; i++) { ctx->typlist[i] = buffer[i]; } } else if (ctx->typlist_entry_len == 2) { memcpy(ctx->typlist, buffer, buffer_len); if (ctx->machine_needs_byte_swap) { for (i=0; i<ctx->nvar; i++) { ctx->typlist[i] = byteswap2(ctx->typlist[i]); } } } if ((retval = dta_read_chunk(ctx, "<varnames>", ctx->varlist, ctx->varlist_len, "</varnames>")) != READSTAT_OK) goto cleanup; if ((retval = dta_read_chunk(ctx, "<sortlist>", ctx->srtlist, ctx->srtlist_len, "</sortlist>")) != READSTAT_OK) goto cleanup; if ((retval = dta_read_chunk(ctx, "<formats>", ctx->fmtlist, ctx->fmtlist_len, "</formats>")) != READSTAT_OK) goto cleanup; if ((retval = dta_read_chunk(ctx, "<value_label_names>", ctx->lbllist, ctx->lbllist_len, "</value_label_names>")) != READSTAT_OK) goto cleanup; if ((retval = dta_read_chunk(ctx, "<variable_labels>", ctx->variable_labels, ctx->variable_labels_len, "</variable_labels>")) != READSTAT_OK) goto cleanup; cleanup: if (buffer) free(buffer); return retval; }
/* {{{ void byteswapbuffer(void *pData, unsigned int uElements, unsigned int uElementSize) */ void byteswapbuffer(void *pData, unsigned int uElements, unsigned int uElementSize) { unsigned char *pbyData = (unsigned char *)pData; unsigned int cuElements = uElements; while(cuElements > 0) { if(uElementSize == 2) byteswap2(pbyData); else if(uElementSize == 4) byteswap4(pbyData); else return; pbyData += uElementSize; cuElements--; } }
readstat_error_t readstat_parse_dta(readstat_parser_t *parser, const char *filename, void *user_ctx) { readstat_error_t retval = READSTAT_OK; int i; size_t record_len = 0; int fd = -1; char *buf = NULL; dta_header_t header; dta_ctx_t *ctx = NULL; char str_buf[2048]; char *long_string = NULL; size_t file_size = 0; if ((fd = readstat_open(filename)) == -1) { retval = READSTAT_ERROR_OPEN; goto cleanup; } char magic[4]; if (read(fd, magic, 4) != 4) { retval = READSTAT_ERROR_READ; goto cleanup; } file_size = readstat_lseek(fd, 0, SEEK_END); if (file_size == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } if (readstat_lseek(fd, 0, SEEK_SET) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } if (strncmp(magic, "<sta", 4) == 0) { retval = dta_read_xmlish_preamble(fd, ctx, &header); } else { if (read(fd, &header, sizeof(header)) != sizeof(header)) { retval = READSTAT_ERROR_READ; goto cleanup; } } if ((ctx = dta_ctx_init(header.nvar, header.nobs, header.byteorder, header.ds_format)) == NULL) { retval = READSTAT_ERROR_MALLOC; goto cleanup; } ctx->user_ctx = user_ctx; ctx->file_size = file_size; ctx->progress_handler = parser->progress_handler; retval = dta_update_progress(fd, ctx); if (retval != READSTAT_OK) goto cleanup; if (parser->info_handler) { if (parser->info_handler(ctx->nobs, ctx->nvar, user_ctx)) { retval = READSTAT_ERROR_USER_ABORT; goto cleanup; } } if (ctx->file_is_xmlish) { uint16_t label_len = 0; unsigned char timestamp_len; if ((retval = dta_read_tag(fd, ctx, "<label>")) != READSTAT_OK) { goto cleanup; } if (ctx->data_label_len_len == 2) { if (read(fd, &label_len, sizeof(uint16_t)) != sizeof(uint16_t)) { retval = READSTAT_ERROR_READ; goto cleanup; } label_len = ctx->machine_needs_byte_swap ? byteswap2(label_len) : label_len; } else if (ctx->data_label_len_len == 1) { unsigned char label_len_char; if (read(fd, &label_len_char, sizeof(unsigned char)) != sizeof(unsigned char)) { retval = READSTAT_ERROR_READ; goto cleanup; } label_len = label_len_char; } if (readstat_lseek(fd, label_len, SEEK_CUR) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } if ((retval = dta_read_tag(fd, ctx, "</label>")) != READSTAT_OK) { goto cleanup; } if ((retval = dta_read_tag(fd, ctx, "<timestamp>")) != READSTAT_OK) { goto cleanup; } if (read(fd, ×tamp_len, 1) != 1) { retval = READSTAT_ERROR_READ; goto cleanup; } if (readstat_lseek(fd, timestamp_len, SEEK_CUR) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } if ((retval = dta_read_tag(fd, ctx, "</timestamp>")) != READSTAT_OK) { goto cleanup; } } else { if (readstat_lseek(fd, ctx->data_label_len, SEEK_CUR) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } if (ctx->time_stamp_len) { if (readstat_lseek(fd, ctx->time_stamp_len, SEEK_CUR) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } } } if ((retval = dta_read_tag(fd, ctx, "</header>")) != READSTAT_OK) { goto cleanup; } if (dta_read_map(fd, ctx) != READSTAT_OK) { retval = READSTAT_ERROR_READ; goto cleanup; } if (dta_read_descriptors(fd, ctx) != READSTAT_OK) { retval = READSTAT_ERROR_READ; goto cleanup; } for (i=0; i<ctx->nvar; i++) { size_t max_len; readstat_types_t type = dta_type_info(ctx->typlist[i], &max_len, ctx); record_len += max_len; if (type == READSTAT_TYPE_STRING) max_len++; /* might append NULL */ if (parser->variable_handler) { readstat_variable_t *variable = dta_init_variable(ctx, i, type); const char *value_labels = NULL; if (ctx->lbllist[ctx->lbllist_entry_len*i]) value_labels = &ctx->lbllist[ctx->lbllist_entry_len*i]; int cb_retval = parser->variable_handler(i, variable, value_labels, user_ctx); free(variable); if (cb_retval) { retval = READSTAT_ERROR_USER_ABORT; goto cleanup; } } } if ((retval = dta_skip_expansion_fields(fd, ctx)) != READSTAT_OK) { goto cleanup; } if (record_len == 0) { retval = READSTAT_ERROR_PARSE; goto cleanup; } if ((retval = dta_read_tag(fd, ctx, "<data>")) != READSTAT_OK) { goto cleanup; } if ((retval = dta_update_progress(fd, ctx)) != READSTAT_OK) { goto cleanup; } if ((buf = malloc(record_len)) == NULL) { retval = READSTAT_ERROR_MALLOC; goto cleanup; } for (i=0; i<ctx->nobs; i++) { if (read(fd, buf, record_len) != record_len) { retval = READSTAT_ERROR_READ; goto cleanup; } int j; off_t offset = 0; for (j=0; j<ctx->nvar; j++) { size_t max_len; readstat_value_t value; memset(&value, 0, sizeof(readstat_value_t)); value.type = dta_type_info(ctx->typlist[j], &max_len, ctx); if (value.type == READSTAT_TYPE_STRING) { readstat_convert(str_buf, sizeof(str_buf), &buf[offset], max_len, ctx->converter); value.v.string_value = str_buf; } else if (value.type == READSTAT_TYPE_LONG_STRING) { uint32_t v, o; v = *((uint32_t *)&buf[offset]); o = *((uint32_t *)&buf[offset+4]); if (ctx->machine_needs_byte_swap) { v = byteswap4(v); o = byteswap4(o); } if (v > 0 && o > 0) { off_t cur_pos = readstat_lseek(fd, 0, SEEK_CUR); if (cur_pos == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } retval = dta_read_long_string(fd, ctx, v, o, &long_string); if (retval != READSTAT_OK) { goto cleanup; } value.v.string_value = long_string; if (readstat_lseek(fd, cur_pos, SEEK_SET) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } } } else if (value.type == READSTAT_TYPE_CHAR) { char byte = buf[offset]; if (ctx->machine_is_twos_complement) { byte = ones_to_twos_complement1(byte); } if (byte > DTA_MAX_CHAR) { value.is_system_missing = 1; if (byte > DTA_MISSING_CHAR) { value.tag = 'a' + (byte - DTA_MISSING_CHAR_A); } } value.v.char_value = byte; } else if (value.type == READSTAT_TYPE_INT16) { int16_t num = *((int16_t *)&buf[offset]); if (ctx->machine_needs_byte_swap) { num = byteswap2(num); } if (ctx->machine_is_twos_complement) { num = ones_to_twos_complement2(num); } if (num > DTA_MAX_INT16) { value.is_system_missing = 1; if (num > DTA_MISSING_INT16) { value.tag = 'a' + (num - DTA_MISSING_INT16_A); } } value.v.i16_value = num; } else if (value.type == READSTAT_TYPE_INT32) { int32_t num = *((int32_t *)&buf[offset]); if (ctx->machine_needs_byte_swap) { num = byteswap4(num); } if (ctx->machine_is_twos_complement) { num = ones_to_twos_complement4(num); } if (num > DTA_MAX_INT32) { value.is_system_missing = 1; if (num > DTA_MISSING_INT32) { value.tag = 'a' + (num - DTA_MISSING_INT32_A); } } value.v.i32_value = num; } else if (value.type == READSTAT_TYPE_FLOAT) { uint32_t num = *((uint32_t *)&buf[offset]); float f_num = NAN; if (ctx->machine_needs_byte_swap) { num = byteswap4(num); } if (num > DTA_MAX_FLOAT) { value.is_system_missing = 1; if (num > DTA_MISSING_FLOAT) { value.tag = 'a' + ((num - DTA_MISSING_FLOAT_A) >> 11); } } else {
uint16_t sas_read2(const char *data, int bswap) { uint16_t tmp; memcpy(&tmp, data, 2); return bswap ? byteswap2(tmp) : tmp; }
static readstat_error_t xport_write_variables(readstat_writer_t *writer) { readstat_error_t retval = READSTAT_OK; int i; long offset = 0; int num_long_labels = 0; int any_has_long_format = 0; for (i=0; i<writer->variables_count; i++) { int needs_long_record = 0; readstat_variable_t *variable = readstat_get_variable(writer, i); size_t width = xport_variable_width(variable->type, variable->user_width); xport_namestr_t namestr = { .nvar0 = i, .nlng = width, .npos = offset }; if (readstat_variable_get_type_class(variable) == READSTAT_TYPE_CLASS_STRING) { namestr.ntype = SAS_COLUMN_TYPE_CHR; } else { namestr.ntype = SAS_COLUMN_TYPE_NUM; } copypad(namestr.nname, sizeof(namestr.nname), variable->name); copypad(namestr.nlabel, sizeof(namestr.nlabel), variable->label); if (variable->format[0]) { int decimals = 0; int width = 0; char name[24]; sscanf(variable->format, "%s%d.%d", name, &width, &decimals); copypad(namestr.nform, sizeof(namestr.nform), name); namestr.nfl = width; namestr.nfd = decimals; copypad(namestr.niform, sizeof(namestr.niform), name); namestr.nifl = width; namestr.nifd = decimals; if (strlen(name) > 8) { any_has_long_format = 1; needs_long_record = 1; } } namestr.nfj = (variable->alignment == READSTAT_ALIGNMENT_RIGHT); if (writer->version == 8) { copypad(namestr.longname, sizeof(namestr.longname), variable->name); size_t label_len = strlen(variable->label); if (label_len > 40) { needs_long_record = 1; } namestr.labeln = label_len; } if (needs_long_record) { num_long_labels++; } offset += width; xport_namestr_bswap(&namestr); retval = xport_write_bytes(writer, &namestr, sizeof(xport_namestr_t)); if (retval != READSTAT_OK) goto cleanup; } retval = xport_finish_record(writer); if (retval != READSTAT_OK) goto cleanup; if (writer->version == 8 && num_long_labels) { xport_header_record_t header = { .name = "LABELV8", .num1 = num_long_labels }; if (any_has_long_format) { strcpy(header.name, "LABELV9"); } retval = xport_write_header_record_v8(writer, &header); if (retval != READSTAT_OK) goto cleanup; for (i=0; i<writer->variables_count; i++) { readstat_variable_t *variable = readstat_get_variable(writer, i); size_t label_len = strlen(variable->label); size_t name_len = strlen(variable->name); int has_long_label = 0; int has_long_format = 0; int format_len = 0; char format_name[24]; memset(format_name, 0, sizeof(format_name)); has_long_label = (label_len > 40); if (variable->format[0]) { int decimals = 2; int width = 8; int matches = sscanf(variable->format, "%s%d.%d", format_name, &width, &decimals); if (matches < 1) { retval = READSTAT_ERROR_BAD_FORMAT_STRING; goto cleanup; } format_len = strlen(format_name); if (format_len > 8) { has_long_format = 1; } } if (has_long_format) { uint16_t labeldef[5] = { i, name_len, format_len, format_len, label_len }; if (machine_is_little_endian()) { labeldef[0] = byteswap2(labeldef[0]); labeldef[1] = byteswap2(labeldef[1]); labeldef[2] = byteswap2(labeldef[2]); labeldef[3] = byteswap2(labeldef[3]); labeldef[4] = byteswap2(labeldef[4]); } retval = readstat_write_bytes(writer, labeldef, sizeof(labeldef)); if (retval != READSTAT_OK) goto cleanup; retval = readstat_write_string(writer, variable->name); if (retval != READSTAT_OK) goto cleanup; retval = readstat_write_string(writer, format_name); if (retval != READSTAT_OK) goto cleanup; retval = readstat_write_string(writer, format_name); if (retval != READSTAT_OK) goto cleanup; retval = readstat_write_string(writer, variable->label); if (retval != READSTAT_OK) goto cleanup; } else if (has_long_label) { uint16_t labeldef[3] = { i, name_len, label_len }; if (machine_is_little_endian()) { labeldef[0] = byteswap2(labeldef[0]); labeldef[1] = byteswap2(labeldef[1]); labeldef[2] = byteswap2(labeldef[2]); } retval = readstat_write_bytes(writer, labeldef, sizeof(labeldef)); if (retval != READSTAT_OK) goto cleanup; retval = readstat_write_string(writer, variable->name); if (retval != READSTAT_OK) goto cleanup; retval = readstat_write_string(writer, variable->label); if (retval != READSTAT_OK) goto cleanup; } } retval = xport_finish_record(writer); if (retval != READSTAT_OK) goto cleanup; } cleanup: return retval; }
static readstat_error_t dta_handle_rows(dta_ctx_t *ctx) { readstat_io_t *io = ctx->io; char *buf = NULL; char str_buf[2048]; int i; readstat_error_t retval = READSTAT_OK; if ((buf = malloc(ctx->record_len)) == NULL) { retval = READSTAT_ERROR_MALLOC; goto cleanup; } for (i=0; i<ctx->row_limit; i++) { if (io->read(buf, ctx->record_len, io->io_ctx) != ctx->record_len) { retval = READSTAT_ERROR_READ; goto cleanup; } int j; off_t offset = 0; for (j=0; j<ctx->nvar; j++) { size_t max_len; readstat_value_t value; memset(&value, 0, sizeof(readstat_value_t)); value.type = dta_type_info(ctx->typlist[j], &max_len, ctx); if (value.type == READSTAT_TYPE_STRING) { readstat_convert(str_buf, sizeof(str_buf), &buf[offset], max_len, ctx->converter); value.v.string_value = str_buf; } else if (value.type == READSTAT_TYPE_STRING_REF) { dta_strl_t key; dta_interpret_strl_vo_bytes(ctx, (unsigned char *)&buf[offset], &key); dta_strl_t **found = bsearch(&key, ctx->strls, ctx->strls_count, sizeof(dta_strl_t *), &dta_compare_strls); if (found) { value.v.string_value = (*found)->data; } value.type = READSTAT_TYPE_STRING; } else if (value.type == READSTAT_TYPE_INT8) { int8_t byte = buf[offset]; if (ctx->machine_is_twos_complement) { byte = ones_to_twos_complement1(byte); } if (byte > ctx->max_int8) { if (ctx->supports_tagged_missing && byte > DTA_113_MISSING_INT8) { value.tag = 'a' + (byte - DTA_113_MISSING_INT8_A); value.is_tagged_missing = 1; } else { value.is_system_missing = 1; } } value.v.i8_value = byte; } else if (value.type == READSTAT_TYPE_INT16) { int16_t num = *((int16_t *)&buf[offset]); if (ctx->machine_needs_byte_swap) { num = byteswap2(num); } if (ctx->machine_is_twos_complement) { num = ones_to_twos_complement2(num); } if (num > ctx->max_int16) { if (ctx->supports_tagged_missing && num > DTA_113_MISSING_INT16) { value.tag = 'a' + (num - DTA_113_MISSING_INT16_A); value.is_tagged_missing = 1; } else { value.is_system_missing = 1; } } value.v.i16_value = num; } else if (value.type == READSTAT_TYPE_INT32) { int32_t num = *((int32_t *)&buf[offset]); if (ctx->machine_needs_byte_swap) { num = byteswap4(num); } if (ctx->machine_is_twos_complement) { num = ones_to_twos_complement4(num); } if (num > ctx->max_int32) { if (ctx->supports_tagged_missing && num > DTA_113_MISSING_INT32) { value.tag = 'a' + (num - DTA_113_MISSING_INT32_A); value.is_tagged_missing = 1; } else { value.is_system_missing = 1; } } value.v.i32_value = num; } else if (value.type == READSTAT_TYPE_FLOAT) { int32_t num = *((int32_t *)&buf[offset]); float f_num = NAN; if (ctx->machine_needs_byte_swap) { num = byteswap4(num); } if (num > ctx->max_float) { if (ctx->supports_tagged_missing && num > DTA_113_MISSING_FLOAT) { value.tag = 'a' + ((num - DTA_113_MISSING_FLOAT_A) >> 11); value.is_tagged_missing = 1; } else { value.is_system_missing = 1; } } else {
static readstat_error_t dta_read_expansion_fields(dta_ctx_t *ctx) { readstat_error_t retval = READSTAT_OK; readstat_io_t *io = ctx->io; char *buffer = NULL; if (ctx->expansion_len_len == 0) return READSTAT_OK; if (ctx->file_is_xmlish && !ctx->note_handler) { if (io->seek(ctx->data_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) { return READSTAT_ERROR_SEEK; } return READSTAT_OK; } retval = dta_read_tag(ctx, "<characteristics>"); if (retval != READSTAT_OK) goto cleanup; while (1) { size_t len; char data_type; if (ctx->file_is_xmlish) { char start[4]; if (io->read(start, sizeof(start), io->io_ctx) != sizeof(start)) { retval = READSTAT_ERROR_READ; goto cleanup; } if (memcmp(start, "</ch", sizeof(start)) == 0) { retval = dta_read_tag(ctx, "aracteristics>"); if (retval != READSTAT_OK) goto cleanup; break; } else if (memcmp(start, "<ch>", sizeof(start)) != 0) { retval = READSTAT_ERROR_PARSE; goto cleanup; } data_type = 1; } else { if (io->read(&data_type, 1, io->io_ctx) != 1) { retval = READSTAT_ERROR_READ; goto cleanup; } } if (ctx->expansion_len_len == 2) { int16_t len16; if (io->read(&len16, sizeof(int16_t), io->io_ctx) != sizeof(int16_t)) { retval = READSTAT_ERROR_READ; goto cleanup; } len = ctx->machine_needs_byte_swap ? byteswap2(len16) : len16; } else { int32_t len32; if (io->read(&len32, sizeof(int32_t), io->io_ctx) != sizeof(int32_t)) { retval = READSTAT_ERROR_READ; goto cleanup; } len = ctx->machine_needs_byte_swap ? byteswap2(len32) : len32; } if (data_type == 0 && len == 0) break; if (data_type != 1 || len > (1<<20)) { retval = READSTAT_ERROR_NOTE_IS_TOO_LONG; goto cleanup; } if (ctx->note_handler && len >= 2 * ctx->ch_metadata_len) { buffer = realloc(buffer, len + 1); buffer[len] = '\0'; if (io->read(buffer, len, io->io_ctx) != len) { retval = READSTAT_ERROR_READ; goto cleanup; } int index = 0; if (strncmp(&buffer[0], "_dta", 4) == 0 && sscanf(&buffer[ctx->ch_metadata_len], "note%d", &index) == 1) { if (ctx->note_handler(index, &buffer[2*ctx->ch_metadata_len], ctx->user_ctx)) { retval = READSTAT_ERROR_USER_ABORT; goto cleanup; } } } else { if (io->seek(len, READSTAT_SEEK_CUR, io->io_ctx) == -1) { retval = READSTAT_ERROR_SEEK; goto cleanup; } } retval = dta_read_tag(ctx, "</ch>"); if (retval != READSTAT_OK) goto cleanup; } cleanup: if (buffer) free(buffer); return retval; }