X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fsys-file-writer.c;h=000534c4844a2dd6bd2237c658add8f66c949109;hb=04fb909bd65eee66428d131ff34a6e1fde42e243;hp=fe2c27c8102c71f23852d9d9ada4abd44b78f2b4;hpb=f4a8d7e70526f52b3148f386344158f4b6f343ca;p=pspp-builds.git diff --git a/src/data/sys-file-writer.c b/src/data/sys-file-writer.c index fe2c27c8..000534c4 100644 --- a/src/data/sys-file-writer.c +++ b/src/data/sys-file-writer.c @@ -42,6 +42,7 @@ #include "value-labels.h" #include "variable.h" #include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -61,6 +62,7 @@ struct sfm_writer int compress; /* 1=compressed, 0=not compressed. */ int case_cnt; /* Number of cases written so far. */ size_t flt64_cnt; /* Number of flt64 elements in case. */ + bool has_vls; /* Does the dict have very long strings? */ /* Compression buffering. */ flt64 *buf; /* Buffered data. */ @@ -103,7 +105,6 @@ static void write_variable_display_parameters (struct sfm_writer *w, const struct dictionary *dict); static void write_documents (struct sfm_writer *, const struct dictionary *); -static int does_dict_need_translation (const struct dictionary *); static inline int var_flt64_cnt (const struct variable *v) @@ -194,10 +195,11 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, w->fh = fh; w->file = fdopen (fd, "w"); - w->needs_translation = does_dict_need_translation (d); + w->needs_translation = dict_compacting_would_change (d); w->compress = opts.compress; w->case_cnt = 0; w->flt64_cnt = 0; + w->has_vls = false; w->buf = w->end = w->ptr = NULL; w->x = w->y = NULL; @@ -212,8 +214,8 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, sv->width = dv->width; /* spss compatibility nonsense */ if ( dv->width > MAX_LONG_STRING ) - sv->width = (dv->width / MAX_LONG_STRING) * (MAX_LONG_STRING + 1) - + (dv->width % MAX_LONG_STRING) ; + w->has_vls = true; + sv->fv = dv->fv; sv->flt64_cnt = var_flt64_cnt (dv); } @@ -293,9 +295,9 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, { struct { - int32_t rec_type P; - int32_t filler P; - } + int32_t rec_type ; + int32_t filler ; + } ATTRIBUTE((packed)) rec_999; rec_999.rec_type = 999; @@ -328,27 +330,6 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d, goto error; } -/* Returns zero if dictionary D's cases are ordered in the - natural manner, with the first variable followed by the - second, and so on, - nonzero otherwise. */ -static int -does_dict_need_translation (const struct dictionary *d) -{ - size_t case_idx; - size_t i; - - case_idx = 0; - for (i = 0; i < dict_get_var_cnt (d); i++) - { - struct variable *v = dict_get_var (d, i); - if (v->fv != case_idx) - return 1; - case_idx += v->nv; - } - return 0; -} - /* Returns value of X truncated to two least-significant digits. */ static int rerange (int x) @@ -508,9 +489,9 @@ write_variable (struct sfm_writer *w, const struct variable *v) { struct label { - int32_t label_len P; - char label[255] P; - } + int32_t label_len ; + char label[255] ; + } ATTRIBUTE((packed)) l; int ext_len; @@ -552,17 +533,17 @@ write_value_labels (struct sfm_writer *w, struct variable *v, int idx) { struct value_label_rec { - int32_t rec_type P; - int32_t n_labels P; - flt64 labels[1] P; - }; + int32_t rec_type ; + int32_t n_labels ; + flt64 labels[1] ; + } ATTRIBUTE((packed)); struct var_idx_rec { - int32_t rec_type P; - int32_t n_vars P; - int32_t vars[1] P; - }; + int32_t rec_type ; + int32_t n_vars ; + int32_t vars[1] ; + } ATTRIBUTE((packed)); struct val_labs_iterator *i; struct value_label_rec *vlr; @@ -613,11 +594,10 @@ static void write_documents (struct sfm_writer *w, const struct dictionary *d) { struct - { - int32_t rec_type P; /* Always 6. */ - int32_t n_lines P; /* Number of lines of documents. */ - } - rec_6; + { + int32_t rec_type ; /* Always 6. */ + int32_t n_lines ; /* Number of lines of documents. */ + } ATTRIBUTE((packed)) rec_6; const char *documents; size_t n_lines; @@ -640,11 +620,11 @@ write_variable_display_parameters (struct sfm_writer *w, struct { - int32_t rec_type P; - int32_t subtype P; - int32_t elem_size P; - int32_t n_elem P; - } vdp_hdr; + int32_t rec_type ; + int32_t subtype ; + int32_t elem_size ; + int32_t n_elem ; + } ATTRIBUTE((packed)) vdp_hdr; vdp_hdr.rec_type = 7; vdp_hdr.subtype = 11; @@ -658,11 +638,10 @@ write_variable_display_parameters (struct sfm_writer *w, struct variable *v; struct { - int32_t measure P; - int32_t width P; - int32_t align P; - } - params; + int32_t measure ; + int32_t width ; + int32_t align ; + } ATTRIBUTE((packed)) params; v = dict_get_var(dict, i); @@ -695,17 +674,16 @@ write_vls_length_table (struct sfm_writer *w, { int i; struct - { - int32_t rec_type P; - int32_t subtype P; - int32_t elem_size P; - int32_t n_elem P; - } - vls_hdr; + { + int32_t rec_type ; + int32_t subtype ; + int32_t elem_size ; + int32_t n_elem ; + } ATTRIBUTE((packed)) vls_hdr; struct string vls_length_map; - ds_init (&vls_length_map, 12 * dict_get_var_cnt (dict)); + ds_init_empty (&vls_length_map); vls_hdr.rec_type = 7; vls_hdr.subtype = 14; @@ -719,9 +697,9 @@ write_vls_length_table (struct sfm_writer *w, if ( v->width <= MAX_LONG_STRING ) continue; - ds_printf (&vls_length_map, "%s=%05d", v->short_name, v->width); - ds_putc (&vls_length_map, '\0'); - ds_putc (&vls_length_map, '\t'); + ds_put_format (&vls_length_map, "%s=%05d", v->short_name, v->width); + ds_put_char (&vls_length_map, '\0'); + ds_put_char (&vls_length_map, '\t'); } vls_hdr.n_elem = ds_length (&vls_length_map); @@ -741,24 +719,23 @@ write_longvar_table (struct sfm_writer *w, const struct dictionary *dict) { struct { - int32_t rec_type P; - int32_t subtype P; - int32_t elem_size P; - int32_t n_elem P; - } - lv_hdr; + int32_t rec_type ; + int32_t subtype ; + int32_t elem_size ; + int32_t n_elem ; + } ATTRIBUTE((packed)) lv_hdr; struct string long_name_map; size_t i; - ds_init (&long_name_map, 10 * dict_get_var_cnt (dict)); + ds_init_empty (&long_name_map); for (i = 0; i < dict_get_var_cnt (dict); i++) { struct variable *v = dict_get_var (dict, i); if (i) - ds_putc (&long_name_map, '\t'); - ds_printf (&long_name_map, "%s=%s", v->short_name, v->name); + ds_put_char (&long_name_map, '\t'); + ds_put_format (&long_name_map, "%s=%s", v->short_name, v->name); } lv_hdr.rec_type = 7; @@ -778,18 +755,17 @@ write_rec_7_34 (struct sfm_writer *w) { struct { - int32_t rec_type_3 P; - int32_t subtype_3 P; - int32_t data_type_3 P; - int32_t n_elem_3 P; - int32_t elem_3[8] P; - int32_t rec_type_4 P; - int32_t subtype_4 P; - int32_t data_type_4 P; - int32_t n_elem_4 P; - flt64 elem_4[3] P; - } - rec_7; + int32_t rec_type_3 ; + int32_t subtype_3 ; + int32_t data_type_3 ; + int32_t n_elem_3 ; + int32_t elem_3[8] ; + int32_t rec_type_4 ; + int32_t subtype_4 ; + int32_t data_type_4 ; + int32_t n_elem_4 ; + flt64 elem_4[3] ; + } ATTRIBUTE((packed)) rec_7; /* Components of the version number, from major to minor. */ int version_component[3]; @@ -892,7 +868,7 @@ sfm_write_case (struct sfm_writer *w, const struct ccase *c) w->case_cnt++; if (!w->needs_translation && !w->compress - && sizeof (flt64) == sizeof (union value)) + && sizeof (flt64) == sizeof (union value) && ! w->has_vls ) { /* Fast path: external and internal representations are the same and the dictionary is properly ordered. Write @@ -920,14 +896,23 @@ sfm_write_case (struct sfm_writer *w, const struct ccase *c) memset(bounce_cur, ' ', v->flt64_cnt * sizeof (flt64)); if (v->width == 0) - *bounce_cur = case_num (c, v->fv); - else { - buf_copy_rpad((char*)bounce_cur, v->flt64_cnt * sizeof (flt64), - case_data(c, v->fv)->s, - v->width); + *bounce_cur = case_num (c, v->fv); + bounce_cur += v->flt64_cnt; + } + else + { int ofs = 0; + while (ofs < v->width) + { + int chunk = MIN (MAX_LONG_STRING, v->width - ofs); + int nv = DIV_RND_UP (chunk, sizeof (flt64)); + buf_copy_rpad ((char *) bounce_cur, nv * sizeof (flt64), + case_data (c, v->fv)->s + ofs, chunk); + bounce_cur += nv; + ofs += chunk; + } } - bounce_cur += v->flt64_cnt; + } if (!w->compress)