#include "value-labels.h"
#include "variable.h"
#include <libpspp/version.h>
+#include <minmax.h>
#include "gettext.h"
#define _(msgid) gettext (msgid)
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. */
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;
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);
}
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;
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);
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;
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
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;
}
- 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;
+ }
+ }
+
}
if (!w->compress)