Commit f0d6bd14 authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

fix bone headed indexing scheme. (xbase_close) : release the fmt.

2001-11-01  Jody Goldberg <jgoldberg@home.com>

	* xbase.c (record_get_field) : fix bone headed indexing scheme.
	(xbase_close) : release the fmt.
	(xbase_field_new) : renamed to make sense and supply a style for dates.

	* boot.c (xbase_field_as_value) : now that record_get_field is less
	  bizzare use a sane indexing scheme here to.  Support dates.
	  Use the field length so that strings don't magicly enclude the
	  entire record.
	(xbase_file_open) : use a nice sane indexing scheme here too.
parent 5f5030a6
2001-11-01 Jody Goldberg <jgoldberg@home.com>
* xbase.c (record_get_field) : fix bone headed indexing scheme.
(xbase_close) : release the fmt.
(xbase_field_new) : renamed to make sense and supply a style for dates.
* boot.c (xbase_field_as_value) : now that record_get_field is less
bizzare use a sane indexing scheme here to. Support dates.
Use the field length so that strings don't magicly enclude the
entire record.
(xbase_file_open) : use a nice sane indexing scheme here too.
2001-10-29 Jody Goldberg <jgoldberg@home.com>
* Release 0.74
......
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/**
* boot.c: XBase support for Gnumeric
*
......@@ -14,6 +15,10 @@
#include <plugin-util.h>
#include <module-plugin-defs.h>
#include <sheet.h>
#include <datetime.h>
#include <ranges.h>
#include <mstyle.h>
#include <sheet-style.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
......@@ -22,7 +27,7 @@
GNUMERIC_MODULE_PLUGIN_INFO_DECL;
void xbase_file_open (GnumFileOpener const *fo, IOContext *io_context,
WorkbookView *wb_view, const char *filename);
WorkbookView *wb_view, char const *filename);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
......@@ -39,7 +44,7 @@ void xbase_file_open (GnumFileOpener const *fo, IOContext *io_context,
#endif
static double
xb_getdouble (const guint8 *p)
xb_getdouble (guint8 const *p)
{
double d;
int i;
......@@ -68,11 +73,10 @@ xb_setdouble (guint8 *p, double d)
#endif
static Value *
xbase_field_as_value (XBrecord *record, guint num)
xbase_field_as_value (guint8 *content, XBfield *field)
{
gint8 *s = g_strdup (record_get_field (record, num));
guint8 *s = g_strndup (content, field->len);
Value *val;
XBfield *field = record->file->format[num-1];
switch (field->type) {
case 'C':
......@@ -101,10 +105,18 @@ xbase_field_as_value (XBrecord *record, guint num)
return value_new_string (str);
}
}
case 'D':
val = value_new_string (s);
case 'D': {
/* double check that the date is stored according to spec */
int year, month, day;
if (sscanf (s, "%4d%2d%2d", &year, &month, &day)) {
GDate *date = g_date_new_dmy (day, month, year);
val = value_new_int (datetime_g_to_serial (date));
g_date_free (date);
} else
val = value_new_string (s);
g_free (s);
return val;
}
case 'I':
val = value_new_int (GINT32_FROM_LE (*(gint32 *)s));
g_free (s);
......@@ -133,17 +145,18 @@ xbase_field_as_value (XBrecord *record, guint num)
void
xbase_file_open (GnumFileOpener const *fo, IOContext *io_context,
WorkbookView *wb_view, const char *filename)
WorkbookView *wb_view, char const *filename)
{
Workbook *wb = wb_view_workbook (wb_view);
XBfile *file;
XBrecord *rec;
guint row, field;
char *name;
Sheet *sheet = NULL;
Cell *cell;
Value *val;
Workbook *wb;
XBfile *file;
XBrecord *record;
char *name;
Sheet *sheet = NULL;
Cell *cell;
Value *val;
XBfield *field;
ErrorInfo *open_error;
guint row, i;
if ((file = xbase_open (filename, &open_error)) == NULL) {
gnumeric_io_error_info_set (io_context, error_info_new_str_with_details (
......@@ -156,30 +169,38 @@ xbase_file_open (GnumFileOpener const *fo, IOContext *io_context,
*((gchar *) g_extension_pointer (name)) = '\0'; /* remove "dbf" */
rec = record_new (file);
wb = wb_view_workbook (wb_view);
sheet = sheet_new (wb, g_basename (name));
g_free (name);
workbook_sheet_attach (wb, sheet, NULL);
field = 0;
while (field < file->fields) {
cell = sheet_cell_fetch (sheet, field, 0);
cell_set_text (cell, file->format[field++]->name);
/* FIXME: apply StyleFont gnumeric-default_bold_font */
i = 0;
for (i = 0 ; i < file->fields ; i++) {
cell = sheet_cell_fetch (sheet, i, 0);
cell_set_text (cell, file->format [i]->name);
}
{
Range r;
MStyle *bold = mstyle_new ();
mstyle_set_font_bold (bold, TRUE);
sheet_style_apply_range (sheet,
range_init (&r, 0, 0, file->fields-1, 0), bold);
}
record = record_new (file);
row = 1;
do {
field = 0;
while (field < file->fields) {
cell = sheet_cell_fetch (sheet, field, row);
val = xbase_field_as_value (rec, ++field);
cell_set_value (cell, val, NULL);
for (i = 0; i < file->fields ; i++) {
field = record->file->format [i];
val = xbase_field_as_value (
record_get_field (record, i), field);
cell = sheet_cell_fetch (sheet, i, row);
cell_set_value (cell, val, field->fmt);
}
row++;
} while (record_seek (rec, SEEK_CUR, 1));
} while (record_seek (record, SEEK_CUR, 1));
record_free (rec);
record_free (record);
xbase_close (file);
sheet_flag_recompute_spans (sheet);
......
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#include <config.h>
#include "xbase.h"
#include <format.h>
#include <formats.h>
#include <gutils.h>
#include <io-context.h>
......@@ -9,13 +11,13 @@
#define XBASE_DEBUG 0
static const char *field_types = "CNLDMF?BGPYTI";
static char const * const field_types = "CNLDMF?BGPYTI";
#if XBASE_DEBUG > 0
static const char *field_type_descriptions [] = { /* FIXME: fix array size from field_types*/
"Character", "Number", "Logical", "Date", "Memo", "Floating point",
"Character name variable", "Binary", "General", "Picture", "Currency",
"DateTime", "Integer"
static char const * const field_type_descriptions [] = {
"Character", "Number", "Logical", "Date", "Memo", "Floating point",
"Character name variable", "Binary", "General", "Picture", "Currency",
"DateTime", "Integer"
};
#endif
......@@ -81,11 +83,11 @@ record_free (XBrecord *record)
* Points to binary data for num'th field in record's data.
*/
guint8 *
record_get_field (const XBrecord *record, guint num)
record_get_field (XBrecord const *record, guint num)
{
if (num > record->file->fields)
if (num >= record->file->fields)
return NULL;
return record->data + record->file->format[num-1]->pos;
return record->data + record->file->format [num]->pos;
}
static gboolean
......@@ -96,7 +98,6 @@ xbase_read_header (XBfile *x)
g_warning ("Header short");
return TRUE;
}
fprintf (stderr, "Version:\t");
switch (hdr[0]) { /* FIXME: assuming dBASE III+, not IV */
case 0x02:
fprintf (stderr, "FoxBase\n");
......@@ -160,18 +161,18 @@ xbase_read_header (XBfile *x)
}
static XBfield *
xbase_read_field (XBfile *file)
xbase_field_new (XBfile *file)
{
XBfield *ans;
guint8 buf[33];
XBfield *field;
guint8 buf[33];
char *p;
if (fread(buf, sizeof(buf[0]), 2, file->f) != 2) { /* 1 byte out ? */
g_warning ("xbase_read_field: fread error");
if (fread (buf, sizeof (guint8), 2, file->f) != 2) { /* 1 byte out ? */
g_warning ("xbase_field_new: fread error");
return NULL;
} else if (buf[0] == 0x0D || buf[0] == 0) { /* field array terminator */
if (buf[1] == 0) { /* FIXME: crude test, not in spec */
if (fseek(file->f, 263, SEEK_CUR)) /* skip DBC */
g_warning ("xbase_read_field: fseek error");
g_warning ("xbase_field_new: fseek error");
}
file->offset = ftell (file->f);
return NULL;
......@@ -184,31 +185,37 @@ xbase_read_field (XBfile *file)
fprintf (stderr, "Field:\t'%s'\n", buf);
#endif
ans = g_new (XBfield, 1);
ans->len = buf[16];
field = g_new (XBfield, 1);
field->len = buf[16];
strncpy(ans->name, buf, 10);
ans->name[10] = '\0';
if ((p = strchr (field_types, ans->type = buf[11])) == NULL)
g_warning ("Unrecognised field type '%c'", ans->type);
strncpy(field->name, buf, 10);
field->name[10] = '\0';
if ((p = strchr (field_types, field->type = buf[11])) == NULL)
g_warning ("Unrecognised field type '%c'", field->type);
#if XBASE_DEBUG > 0
else
fprintf (stderr, "Type:\t%c (%s)\n", ans->type,
fprintf (stderr, "Type:\t%c (%s)\n", field->type,
field_type_descriptions [p-field_types]);
fprintf (stderr, "Data address:\t0x%.8X\n", gnumeric_get_le_uint32 (buf + 12));
fprintf (stderr, "Length:\t%d\n", ans->len);
fprintf (stderr, "Length:\t%d\n", field->len);
fprintf (stderr, "Decimal count:\t%d\n", buf[17]);
#endif
if (file->fields) {
XBfield *tmp = file->format[file->fields-1];
ans->pos = tmp->pos + tmp->len;
field->pos = tmp->pos + tmp->len;
} else
ans->pos = 0;
return ans; /* FIXME: use more of buf if needed ? */
field->pos = 0;
if (field->type == 'D')
field->fmt = style_format_new_XL (cell_formats [FMT_DATE][0], FALSE);
else
field->fmt = NULL;
return field; /* FIXME: use more of buf if needed ? */
}
XBfile *
xbase_open (const char *filename, ErrorInfo **ret_error)
xbase_open (char const *filename, ErrorInfo **ret_error)
{
FILE *f;
XBfile *ans;
......@@ -228,7 +235,7 @@ xbase_open (const char *filename, ErrorInfo **ret_error)
* and handle errors */
ans->fields = 0;
ans->format = NULL;
while ((field = xbase_read_field (ans)) != NULL) {
while ((field = xbase_field_new (ans)) != NULL) {
ans->format = g_renew (XBfield *, ans->format, ans->fields + 1);
/* FIXME: allocate number of field formats from file size? */
ans->format[ans->fields++] = field;
......@@ -241,10 +248,13 @@ xbase_close (XBfile *x)
{
unsigned i;
fprintf (stderr, "Closing Xbase file\n");
fclose (x->f);
for (i = 0; i < x->fields; i++)
g_free (x->format[i]);
for (i = 0; i < x->fields; i++) {
XBfield *field = x->format[i];
if (field->fmt != NULL)
style_format_unref (field->fmt);
g_free (field);
}
g_free (x->format);
g_free (x);
}
......@@ -10,6 +10,7 @@ typedef struct { /* field format */
guint8 type; /* type (single ASCII char) */
guint8 len; /* byte length */
guint pos; /* position in record */
StyleFormat *fmt;
} XBfield;
typedef struct { /* database instance */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment