static readstat_error_t dta_emit_fmtlist(readstat_writer_t *writer, dta_ctx_t *ctx) { int i; for (i=0; i<ctx->nvar; i++) { readstat_variable_t *r_variable = readstat_get_variable(writer, i); if (r_variable->format[0]) { strncpy(&ctx->fmtlist[ctx->fmtlist_entry_len*i], r_variable->format, ctx->fmtlist_entry_len); } else { char *format = "%9s"; if (r_variable->type == READSTAT_TYPE_CHAR) { format = DTA_DEFAULT_FORMAT_BYTE; } else if (r_variable->type == READSTAT_TYPE_INT16) { format = DTA_DEFAULT_FORMAT_INT16; } else if (r_variable->type == READSTAT_TYPE_INT32) { format = DTA_DEFAULT_FORMAT_INT32; } else if (r_variable->type == READSTAT_TYPE_FLOAT) { format = DTA_DEFAULT_FORMAT_FLOAT; } else if (r_variable->type == READSTAT_TYPE_DOUBLE) { format = DTA_DEFAULT_FORMAT_DOUBLE; } strncpy(&ctx->fmtlist[ctx->fmtlist_entry_len*i], format, ctx->fmtlist_entry_len); } } return readstat_write_bytes(writer, ctx->fmtlist, ctx->fmtlist_len); }
static readstat_error_t dta_emit_variable_labels(readstat_writer_t *writer, dta_ctx_t *ctx) { int i; for (i=0; i<ctx->nvar; i++) { readstat_variable_t *r_variable = readstat_get_variable(writer, i); strncpy(&ctx->variable_labels[ctx->variable_labels_entry_len*i], r_variable->label, ctx->variable_labels_entry_len); } return readstat_write_bytes(writer, ctx->variable_labels, ctx->variable_labels_len); }
static readstat_error_t dta_emit_varlist(readstat_writer_t *writer, dta_ctx_t *ctx) { int i; for (i=0; i<ctx->nvar; i++) { readstat_variable_t *r_variable = readstat_get_variable(writer, i); strncpy(&ctx->varlist[ctx->variable_name_len*i], r_variable->name, ctx->variable_name_len); } return readstat_write_bytes(writer, ctx->varlist, ctx->varlist_len); }
static readstat_error_t dta_emit_lbllist(readstat_writer_t *writer, dta_ctx_t *ctx) { int i; for (i=0; i<ctx->nvar; i++) { readstat_variable_t *r_variable = readstat_get_variable(writer, i); if (r_variable->label_set) { strncpy(&ctx->lbllist[ctx->lbllist_entry_len*i], r_variable->label_set->name, ctx->lbllist_entry_len); } else { memset(&ctx->lbllist[ctx->lbllist_entry_len*i], '\0', ctx->lbllist_entry_len); } } return readstat_write_bytes(writer, ctx->lbllist, ctx->lbllist_len); }
static readstat_error_t dta_emit_typlist(readstat_writer_t *writer, dta_ctx_t *ctx) { readstat_error_t error = READSTAT_OK; int i; for (i=0; i<ctx->nvar; i++) { readstat_variable_t *r_variable = readstat_get_variable(writer, i); unsigned char type = 0x00; readstat_types_t user_type = r_variable->type; if (user_type == READSTAT_TYPE_CHAR) { type = DTA_111_TYPE_CODE_CHAR; } else if (user_type == READSTAT_TYPE_INT16) { type = DTA_111_TYPE_CODE_INT16; } else if (user_type == READSTAT_TYPE_INT32) { type = DTA_111_TYPE_CODE_INT32; } else if (user_type == READSTAT_TYPE_FLOAT) { type = DTA_111_TYPE_CODE_FLOAT; } else if (user_type == READSTAT_TYPE_DOUBLE) { type = DTA_111_TYPE_CODE_DOUBLE; } else if (user_type == READSTAT_TYPE_STRING) { size_t max_len = r_variable->width; if (max_len > 244) max_len = 244; type = max_len; } ctx->typlist[i] = type; } for (i=0; i<ctx->nvar; i++) { unsigned char byte = ctx->typlist[i]; error = readstat_write_bytes(writer, &byte, 1); if (error != READSTAT_OK) goto cleanup; } cleanup: return error; }
static int handle_fweight(int var_index, void *ctx) { rs_ctx_t *rs_ctx = (rs_ctx_t *)ctx; readstat_writer_t *writer = rs_ctx->writer; readstat_writer_set_fweight_variable(writer, readstat_get_variable(writer, var_index)); return 0; }
static int handle_value(int obs_index, int var_index, readstat_value_t value, void *ctx) { rs_ctx_t *rs_ctx = (rs_ctx_t *)ctx; readstat_writer_t *writer = rs_ctx->writer; readstat_variable_t *variable = readstat_get_variable(writer, var_index); readstat_types_t type = readstat_value_type(value); readstat_error_t error = READSTAT_OK; if (var_index == 0) { if (obs_index == 0) { if (rs_ctx->out_format == RS_FORMAT_SAV) { error = readstat_begin_writing_sav(writer, rs_ctx, rs_ctx->row_count); } else if (rs_ctx->out_format == RS_FORMAT_DTA) { error = readstat_begin_writing_dta(writer, rs_ctx, rs_ctx->row_count); } if (error != READSTAT_OK) goto cleanup; } if (var_index == 0) { error = readstat_begin_row(writer); if (error != READSTAT_OK) goto cleanup; } } if (readstat_value_is_system_missing(value)) { error = readstat_insert_missing_value(writer, variable); } else if (type == READSTAT_TYPE_STRING || type == READSTAT_TYPE_LONG_STRING) { error = readstat_insert_string_value(writer, variable, readstat_string_value(value)); } else if (type == READSTAT_TYPE_CHAR) { error = readstat_insert_char_value(writer, variable, readstat_char_value(value)); } else if (type == READSTAT_TYPE_INT16) { error = readstat_insert_int16_value(writer, variable, readstat_int16_value(value)); } else if (type == READSTAT_TYPE_INT32) { error = readstat_insert_int32_value(writer, variable, readstat_int32_value(value)); } else if (type == READSTAT_TYPE_FLOAT) { error = readstat_insert_float_value(writer, variable, readstat_float_value(value)); } else if (type == READSTAT_TYPE_DOUBLE) { error = readstat_insert_double_value(writer, variable, readstat_double_value(value)); } if (error != READSTAT_OK) goto cleanup; if (var_index == rs_ctx->var_count - 1) { error = readstat_end_row(writer); if (error != READSTAT_OK) goto cleanup; if (obs_index == rs_ctx->row_count - 1) { error = readstat_end_writing(writer); if (error != READSTAT_OK) goto cleanup; } } cleanup: if (error != READSTAT_OK) return 1; return 0; }
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; }