示例#1
0
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;
}
示例#2
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;
}
示例#3
0
 // 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;
 }
示例#4
0
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);
}
示例#5
0
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;
}
示例#6
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;
}
示例#7
0
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--;
	}
}
示例#9
0
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, &timestamp_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 {
示例#10
0
uint16_t sas_read2(const char *data, int bswap) {
    uint16_t tmp;
    memcpy(&tmp, data, 2);
    return bswap ? byteswap2(tmp) : tmp;
}
示例#11
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;
}
示例#12
0
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 {
示例#13
0
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;
}