X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fsys-file-writer.c;h=dda351b9572ef9b77c27045c67077b9193eaa31b;hb=75862bc63003b33702bfd6844b8a4d1c632488b3;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..dda351b9 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); } @@ -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) @@ -705,7 +686,7 @@ write_vls_length_table (struct sfm_writer *w, struct string vls_length_map; - ds_init (&vls_length_map, 12 * dict_get_var_cnt (dict)); + ds_init (&vls_length_map); vls_hdr.rec_type = 7; vls_hdr.subtype = 14; @@ -751,7 +732,7 @@ write_longvar_table (struct sfm_writer *w, const struct dictionary *dict) struct string long_name_map; size_t i; - ds_init (&long_name_map, 10 * dict_get_var_cnt (dict)); + ds_init (&long_name_map); for (i = 0; i < dict_get_var_cnt (dict); i++) { struct variable *v = dict_get_var (dict, i); @@ -892,7 +873,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 +901,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)