diff --git a/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h b/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h index 68b326fad..91e97740c 100644 --- a/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h +++ b/src/migration/mdb/3rdparty/mdbtools/include/mdbtools.h @@ -1,617 +1,621 @@ /* MDB Tools - A library for reading MS Access database files * Copyright (C) 2000 Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _mdbtools_h_ #define _mdbtools_h_ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ICONV #include #endif #ifdef _WIN32 #include #endif #define MDB_DEBUG 0 #define MDB_PGSIZE 4096 //#define MDB_MAX_OBJ_NAME (256*3) /* unicode 16 -> utf-8 worst case */ #define MDB_MAX_OBJ_NAME 256 #define MDB_MAX_COLS 256 #define MDB_MAX_IDX_COLS 10 #define MDB_CATALOG_PG 18 #define MDB_MEMO_OVERHEAD 12 #define MDB_BIND_SIZE 16384 #define MDB_NO_BACKENDS 1 #define MDB_NO_STATS 1 +#ifdef _MSC_VER +#define MDB_DEPRECATED(type, funcname) type funcname +#else // Theses 2 atrbutes are not supported by all compilers: // M$VC see http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc #define MDB_DEPRECATED(type, funcname) type __attribute__((deprecated)) funcname +#endif #define MDB_CONSTRUCTOR(funcname) void __attribute__((constructor)) funcname() enum { MDB_PAGE_DB = 0, MDB_PAGE_DATA, MDB_PAGE_TABLE, MDB_PAGE_INDEX, MDB_PAGE_LEAF, MDB_PAGE_MAP }; enum { MDB_VER_JET3 = 0, MDB_VER_JET4 = 1, MDB_VER_ACCDB_2007 = 0x02, MDB_VER_ACCDB_2010 = 0x0103 }; enum { MDB_FORM = 0, MDB_TABLE, MDB_MACRO, MDB_SYSTEM_TABLE, MDB_REPORT, MDB_QUERY, MDB_LINKED_TABLE, MDB_MODULE, MDB_RELATIONSHIP, MDB_UNKNOWN_09, MDB_UNKNOWN_0A, /* User access */ MDB_DATABASE_PROPERTY, MDB_ANY = -1 }; enum { MDB_BOOL = 0x01, MDB_BYTE = 0x02, MDB_INT = 0x03, MDB_LONGINT = 0x04, MDB_MONEY = 0x05, MDB_FLOAT = 0x06, MDB_DOUBLE = 0x07, MDB_DATETIME = 0x08, MDB_BINARY = 0x09, MDB_TEXT = 0x0a, MDB_OLE = 0x0b, MDB_MEMO = 0x0c, MDB_REPID = 0x0f, MDB_NUMERIC = 0x10, MDB_COMPLEX = 0x12 }; /* SARG operators */ enum { MDB_OR = 1, MDB_AND, MDB_NOT, MDB_EQUAL, MDB_GT, MDB_LT, MDB_GTEQ, MDB_LTEQ, MDB_LIKE, MDB_ISNULL, MDB_NOTNULL }; typedef enum { MDB_TABLE_SCAN, MDB_LEAF_SCAN, MDB_INDEX_SCAN } MdbStrategy; typedef enum { MDB_NOFLAGS = 0x00, MDB_WRITABLE = 0x01 } MdbFileFlags; enum { MDB_DEBUG_LIKE = 0x0001, MDB_DEBUG_WRITE = 0x0002, MDB_DEBUG_USAGE = 0x0004, MDB_DEBUG_OLE = 0x0008, MDB_DEBUG_ROW = 0x0010, MDB_DEBUG_PROPS = 0x0020, MDB_USE_INDEX = 0x0040, MDB_NO_MEMO = 0x0080, /* don't follow memo fields */ }; #define mdb_is_logical_op(x) (x == MDB_OR || \ x == MDB_AND || \ x == MDB_NOT ) #define mdb_is_relational_op(x) (x == MDB_EQUAL || \ x == MDB_GT || \ x == MDB_LT || \ x == MDB_GTEQ || \ x == MDB_LTEQ || \ x == MDB_LIKE || \ x == MDB_ISNULL || \ x == MDB_NOTNULL ) enum { MDB_ASC, MDB_DESC }; enum { MDB_IDX_UNIQUE = 0x01, MDB_IDX_IGNORENULLS = 0x02, MDB_IDX_REQUIRED = 0x08 }; /* export schema options */ enum { MDB_SHEXP_DROPTABLE = 1<<0, /* issue drop table during export */ MDB_SHEXP_CST_NOTNULL = 1<<1, /* generate NOT NULL constraints */ MDB_SHEXP_CST_NOTEMPTY = 1<<2, /* <>'' constraints */ MDB_SHEXP_COMMENTS = 1<<3, /* export comments on columns & tables */ MDB_SHEXP_DEFVALUES = 1<<4, /* export default values */ MDB_SHEXP_INDEXES = 1<<5, /* export indices */ MDB_SHEXP_RELATIONS = 1<<6 /* export relation (foreign keys) */ }; #define MDB_SHEXP_DEFAULT (MDB_SHEXP_CST_NOTNULL | MDB_SHEXP_COMMENTS | MDB_SHEXP_INDEXES | MDB_SHEXP_RELATIONS) /* csv export binary options */ enum { MDB_BINEXPORT_STRIP, MDB_BINEXPORT_RAW, MDB_BINEXPORT_OCTAL }; #define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4) /* obsolete */ #define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3) /* forward declarations */ typedef struct mdbindex MdbIndex; typedef struct mdbsargtree MdbSargNode; #if !MDB_NO_BACKENDS typedef struct { char *name; unsigned char needs_length; /* or precision */ unsigned char needs_scale; unsigned char needs_quotes; } MdbBackendType; typedef struct { guint32 capabilities; /* see MDB_SHEXP_* */ MdbBackendType *types_table; MdbBackendType *type_shortdate; MdbBackendType *type_autonum; const char *short_now; const char *long_now; const char *charset_statement; const char *drop_statement; const char *constaint_not_empty_statement; const char *column_comment_statement; const char *table_comment_statement; gchar* (*quote_schema_name)(const gchar*, const gchar*); } MdbBackend; #endif #if !MDB_NO_STATS typedef struct { gboolean collect; unsigned long pg_reads; } MdbStatistics; #endif typedef struct { int fd; gboolean writable; char *filename; guint32 jet_version; guint32 db_key; char db_passwd[14]; #if !MDB_NO_BACKENDS MdbBackend *default_backend; char *backend_name; #endif #if !MDB_NO_STATS MdbStatistics *stats; #endif /* free map */ int map_sz; unsigned char *free_map; /* reference count */ int refs; } MdbFile; /* offset to row count on data pages...version dependant */ typedef struct { ssize_t pg_size; guint16 row_count_offset; guint16 tab_num_rows_offset; guint16 tab_num_cols_offset; guint16 tab_num_idxs_offset; guint16 tab_num_ridxs_offset; guint16 tab_usage_map_offset; guint16 tab_first_dpg_offset; guint16 tab_cols_start_offset; guint16 tab_ridx_entry_size; guint16 col_flags_offset; guint16 col_size_offset; guint16 col_num_offset; guint16 tab_col_entry_size; guint16 tab_free_map_offset; guint16 tab_col_offset_var; guint16 tab_col_offset_fixed; guint16 tab_row_col_num_offset; } MdbFormatConstants; typedef struct { MdbFile *f; guint32 cur_pg; guint16 row_num; unsigned int cur_pos; unsigned char pg_buf[MDB_PGSIZE]; unsigned char alt_pg_buf[MDB_PGSIZE]; unsigned int num_catalog; GPtrArray *catalog; #if !MDB_NO_BACKENDS MdbBackend *default_backend; char *backend_name; #endif MdbFormatConstants *fmt; #if !MDB_NO_STATS MdbStatistics *stats; #endif #ifdef HAVE_ICONV char* jet3_iconv_code; iconv_t iconv_in; iconv_t iconv_out; #endif } MdbHandle; typedef struct { MdbHandle *mdb; char object_name[MDB_MAX_OBJ_NAME+1]; int object_type; unsigned long table_pg; /* misnomer since object may not be a table */ //int num_props; please use props->len GArray *props; /* GArray of MdbProperties */ GArray *columns; int flags; } MdbCatalogEntry; typedef struct { gchar *name; GHashTable *hash; } MdbProperties; typedef union { int i; double d; char s[256]; } MdbAny; struct S_MdbTableDef; /* forward definition */ typedef struct { struct S_MdbTableDef *table; char name[MDB_MAX_OBJ_NAME+1]; int col_type; int col_size; void *bind_ptr; int *len_ptr; GHashTable *properties; unsigned int num_sargs; GPtrArray *sargs; GPtrArray *idx_sarg_cache; unsigned char is_fixed; int query_order; /* col_num is the current column order, * does not include deletes */ int col_num; int cur_value_start; int cur_value_len; /* MEMO/OLE readers */ guint32 cur_blob_pg_row; int chunk_size; /* numerics only */ int col_prec; int col_scale; unsigned char is_long_auto; unsigned char is_uuid_auto; MdbProperties *props; /* info needed for handling deleted/added columns */ int fixed_offset; unsigned int var_col_num; /* row_col_num is the row column number order, * including deleted columns */ int row_col_num; } MdbColumn; struct mdbsargtree { int op; MdbColumn *col; MdbAny value; void *parent; MdbSargNode *left; MdbSargNode *right; }; typedef struct { guint32 pg; int start_pos; int offset; int len; guint16 idx_starts[2000]; unsigned char cache_value[256]; } MdbIndexPage; typedef int (*MdbSargTreeFunc)(MdbSargNode *, gpointer data); #define MDB_MAX_INDEX_DEPTH 10 typedef struct { int cur_depth; guint32 last_leaf_found; int clean_up_mode; MdbIndexPage pages[MDB_MAX_INDEX_DEPTH]; } MdbIndexChain; typedef struct S_MdbTableDef { MdbCatalogEntry *entry; char name[MDB_MAX_OBJ_NAME+1]; unsigned int num_cols; GPtrArray *columns; unsigned int num_rows; int index_start; unsigned int num_real_idxs; unsigned int num_idxs; GPtrArray *indices; guint32 first_data_pg; guint32 cur_pg_num; guint32 cur_phys_pg; unsigned int cur_row; int noskip_del; /* don't skip deleted rows */ /* object allocation map */ guint32 map_base_pg; size_t map_sz; unsigned char *usage_map; /* pages with free space left */ guint32 freemap_base_pg; size_t freemap_sz; unsigned char *free_usage_map; /* query planner */ MdbSargNode *sarg_tree; MdbStrategy strategy; MdbIndex *scan_idx; MdbHandle *mdbidx; MdbIndexChain *chain; MdbProperties *props; unsigned int num_var_cols; /* to know if row has variable columns */ /* temp table */ unsigned int is_temp_table; GPtrArray *temp_table_pages; } MdbTableDef; struct mdbindex { int index_num; char name[MDB_MAX_OBJ_NAME+1]; unsigned char index_type; guint32 first_pg; int num_rows; /* number rows in index */ unsigned int num_keys; short key_col_num[MDB_MAX_IDX_COLS]; unsigned char key_col_order[MDB_MAX_IDX_COLS]; unsigned char flags; MdbTableDef *table; }; typedef struct { char name[MDB_MAX_OBJ_NAME+1]; } MdbColumnProp; typedef struct { void *value; int siz; int start; unsigned char is_null; unsigned char is_fixed; int colnum; int offset; } MdbField; typedef struct { int op; MdbAny value; } MdbSarg; /* mem.c */ extern MDB_DEPRECATED(void, mdb_init()); extern MDB_DEPRECATED(void, mdb_exit()); /* file.c */ extern ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg); extern ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg); extern unsigned char mdb_get_byte(void *buf, int offset); extern int mdb_get_int16(void *buf, int offset); extern long mdb_get_int32(void *buf, int offset); extern long mdb_get_int32_msb(void *buf, int offset); extern float mdb_get_single(void *buf, int offset); extern double mdb_get_double(void *buf, int offset); extern unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset); extern int mdb_pg_get_int16(MdbHandle *mdb, int offset); extern long mdb_pg_get_int32(MdbHandle *mdb, int offset); extern float mdb_pg_get_single(MdbHandle *mdb, int offset); extern double mdb_pg_get_double(MdbHandle *mdb, int offset); extern void mdb_set_encoding(MdbHandle *mdb, const char *encoding_name); extern MdbHandle *mdb_open(const char *filename, MdbFileFlags flags); extern void mdb_close(MdbHandle *mdb); extern MdbHandle *mdb_clone_handle(MdbHandle *mdb); extern void mdb_swap_pgbuf(MdbHandle *mdb); /* catalog.c */ extern void mdb_free_catalog(MdbHandle *mdb); extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type); MdbCatalogEntry *mdb_get_catalogentry_by_name(MdbHandle *mdb, const gchar* name); extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type); extern const char *mdb_get_objtype_string(int obj_type); /* table.c */ extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry); extern void mdb_free_tabledef(MdbTableDef *table); extern MdbTableDef *mdb_read_table(MdbCatalogEntry *entry); extern MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type); extern void mdb_append_column(GPtrArray *columns, MdbColumn *in_col); extern void mdb_free_columns(GPtrArray *columns); extern GPtrArray *mdb_read_columns(MdbTableDef *table); extern void mdb_table_dump(MdbCatalogEntry *entry); extern guint8 read_pg_if_8(MdbHandle *mdb, int *cur_pos); extern guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos); extern guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos); extern void *read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len); extern int mdb_is_user_table(MdbCatalogEntry *entry); extern int mdb_is_system_table(MdbCatalogEntry *entry); extern const char *mdb_table_get_prop(const MdbTableDef *table, const gchar *key); extern const char *mdb_col_get_prop(const MdbColumn *col, const gchar *key); /* data.c */ extern int mdb_bind_column_by_name(MdbTableDef *table, const gchar *col_name, void *bind_ptr, int *len_ptr); extern void mdb_data_dump(MdbTableDef *table); extern void mdb_date_to_tm(double td, struct tm *t); extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr, int *len_ptr); extern int mdb_rewind_table(MdbTableDef *table); extern int mdb_fetch_row(MdbTableDef *table); extern int mdb_is_fixed_col(MdbColumn *col); extern char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int size); extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, void **buf, int *off, size_t *len); extern int mdb_find_row(MdbHandle *mdb, int row, int *start, size_t *len); extern int mdb_find_end_of_row(MdbHandle *mdb, int row); extern int mdb_col_fixed_size(MdbColumn *col); extern int mdb_col_disp_size(MdbColumn *col); extern size_t mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr); extern size_t mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size); extern void* mdb_ole_read_full(MdbHandle *mdb, MdbColumn *col, size_t *size); extern void mdb_set_date_fmt(const char *); extern int mdb_read_row(MdbTableDef *table, unsigned int row); /* dump.c */ extern void mdb_buffer_dump(const void *buf, int start, size_t len); #if !MDB_NO_BACKENDS /* backend.c */ extern MDB_DEPRECATED(char*, mdb_get_coltype_string(MdbBackend *backend, int col_type)); extern MDB_DEPRECATED(int, mdb_coltype_takes_length(MdbBackend *backend, int col_type)); extern const MdbBackendType* mdb_get_colbacktype(const MdbColumn *col); extern const char* mdb_get_colbacktype_string(const MdbColumn *col); extern int mdb_colbacktype_takes_length(const MdbColumn *col); extern MDB_DEPRECATED(void, mdb_init_backends()); extern void mdb_register_backend(char *backend_name, guint32 capabilities, MdbBackendType *backend_type, MdbBackendType *type_shortdate, MdbBackendType *type_autonum, const char *short_now, const char *long_now, const char *charset_statement, const char *drop_statement, const char *constaint_not_empty_statement, const char *column_comment_statement, const char *table_comment_statement, gchar* (*quote_schema_name)(const gchar*, const gchar*)); extern MDB_DEPRECATED(void, mdb_remove_backends()); extern int mdb_set_default_backend(MdbHandle *mdb, const char *backend_name); extern void mdb_print_schema(MdbHandle *mdb, FILE *outfile, char *tabname, char *dbnamespace, guint32 export_options); #endif /* sargs.c */ extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields); extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field); extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data); extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data); extern int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg); extern int mdb_test_string(MdbSargNode *node, char *s); extern int mdb_test_int(MdbSargNode *node, gint32 i); extern int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg); /* index.c */ extern GPtrArray *mdb_read_indices(MdbTableDef *table); extern void mdb_index_dump(MdbTableDef *table, MdbIndex *idx); extern void mdb_index_scan_free(MdbTableDef *table); extern int mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg); extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row); extern void mdb_index_hash_text(char *text, char *hash); extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table); extern int mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row); extern void mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest); extern void mdb_free_indices(GPtrArray *indices); void mdb_index_page_reset(MdbIndexPage *ipg); extern int mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg); #if !MDB_NO_STATS /* stats.c */ extern void mdb_stats_on(MdbHandle *mdb); extern void mdb_stats_off(MdbHandle *mdb); extern void mdb_dump_stats(MdbHandle *mdb); #endif /* like.c */ extern int mdb_like_cmp(char *s, char *r); /* write.c */ extern void mdb_put_int16(void *buf, guint32 offset, guint32 value); extern void mdb_put_int32(void *buf, guint32 offset, guint32 value); extern void mdb_put_int32_msb(void *buf, guint32 offset, guint32 value); extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields); extern guint16 mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size); extern int mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum); extern int mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields); extern int mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields); extern int mdb_replace_row(MdbTableDef *table, int row, void *new_row, int new_row_size); extern int mdb_pg_get_freespace(MdbHandle *mdb); extern int mdb_update_row(MdbTableDef *table); extern void *mdb_new_data_pg(MdbCatalogEntry *entry); /* map.c */ extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size); extern gint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg); /* props.c */ extern void mdb_free_props(MdbProperties *props); extern void mdb_dump_props(MdbProperties *props, FILE *outfile, int show_name); extern GArray* mdb_kkd_to_props(MdbHandle *mdb, void *kkd, size_t len); /* worktable.c */ extern MdbTableDef *mdb_create_temp_table(MdbHandle *mdb, char *name); extern void mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col); extern void mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed); extern void mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int column); extern void mdb_temp_columns_end(MdbTableDef *table); /* options.c */ extern int mdb_get_option(unsigned long optnum); extern void mdb_debug(int klass, const char *fmt, ...); /* iconv.c */ extern int mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dlen); extern int mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dlen); extern void mdb_iconv_init(MdbHandle *mdb); extern void mdb_iconv_close(MdbHandle *mdb); extern const char* mdb_target_charset(MdbHandle *mdb); #ifdef __cplusplus } #endif #endif /* _mdbtools_h_ */ diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c b/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c index 488d5701b..0c8c91d61 100644 --- a/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c +++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/money.c @@ -1,167 +1,170 @@ /* MDB Tools - A library for reading MS Access database file * Copyright (C) 1998-1999 Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "mdbtools.h" #ifdef DMALLOC #include "dmalloc.h" #endif #define MAX_NUMERIC_PRECISION 28 /* ** these routines are copied from the freetds project which does something ** very similiar */ static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier); static int do_carry(unsigned char *product); static char *array_to_string(unsigned char *array, int unsigned scale, int neg); /** * mdb_money_to_string * @mdb: Handle to open MDB database file * @start: Offset of the field within the current page * * Returns: the allocated string that has received the value. */ char *mdb_money_to_string(MdbHandle *mdb, int start) { - int num_bytes=8, scale=4; +#define num_bytes 8 + int scale=4; int i; int neg=0; unsigned char multiplier[MAX_NUMERIC_PRECISION], temp[MAX_NUMERIC_PRECISION]; unsigned char product[MAX_NUMERIC_PRECISION]; unsigned char bytes[num_bytes]; memset(multiplier,0,MAX_NUMERIC_PRECISION); memset(product,0,MAX_NUMERIC_PRECISION); multiplier[0]=1; memcpy(bytes, mdb->pg_buf + start, num_bytes); /* Perform two's complement for negative numbers */ if (bytes[num_bytes-1] & 0x80) { neg = 1; for (i=0;ipg_buf + start + 1, num_bytes); /* Perform two's complement for negative numbers */ if (mdb->pg_buf[start] & 0x80) neg = 1; for (i=0;i9) { product[j+1]+=product[j]/10; product[j]=product[j]%10; } } if (product[j]>9) { product[j]=product[j]%10; } return 0; } static char *array_to_string(unsigned char *array, unsigned int scale, int neg) { char *s; unsigned int top, i, j=0; for (top=MAX_NUMERIC_PRECISION;(top>0) && (top-1>scale) && !array[top-1];top--); /* allocate enough space for all digits + minus sign + decimal point + trailing NULL byte */ s = (char *) g_malloc(MAX_NUMERIC_PRECISION+3); if (neg) s[j++] = '-'; if (top == 0) { s[j++] = '0'; } else { for (i=top; i>0; i--) { if (i == scale) s[j++]='.'; s[j++]=array[i-1]+'0'; } } s[j]='\0'; return s; } diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c b/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c index 38e0660de..670d2269a 100644 --- a/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c +++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/props.c @@ -1,215 +1,215 @@ /* MDB Tools - A library for reading MS Access database file * Copyright (C) 2000-2011 Brian Bruns and others * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mdbtools.h" static GPtrArray * mdb_read_props_list(MdbHandle *mdb, gchar *kkd, int len) { guint32 record_len; int pos = 0; gchar *name; GPtrArray *names = NULL; int i=0; names = g_ptr_array_new(); #if MDB_DEBUG mdb_buffer_dump(kkd, 0, len); #endif pos = 0; while (pos < len) { record_len = mdb_get_int16(kkd, pos); pos += 2; if (mdb_get_option(MDB_DEBUG_PROPS)) { fprintf(stderr, "%02d ",i++); mdb_buffer_dump(kkd, pos - 2, record_len + 2); } name = g_malloc(3*record_len + 1); /* worst case scenario is 3 bytes out per byte in */ mdb_unicode2ascii(mdb, &kkd[pos], record_len, name, 3*record_len); pos += record_len; g_ptr_array_add(names, name); #if MDB_DEBUG printf("new len = %d\n", names->len); #endif } return names; } static gboolean free_hash_entry(gpointer key, gpointer value, gpointer user_data) { g_free(key); g_free(value); return TRUE; } void mdb_free_props(MdbProperties *props) { if (!props) return; if (props->name) g_free(props->name); if (props->hash) { g_hash_table_foreach(props->hash, (GHFunc)free_hash_entry, 0); g_hash_table_destroy(props->hash); } g_free(props); } static void free_names(GPtrArray *names) { g_ptr_array_foreach(names, (GFunc)g_free, NULL); g_ptr_array_free(names, TRUE); } MdbProperties * mdb_alloc_props() { MdbProperties *props; props = g_malloc0(sizeof(MdbProperties)); return props; } static MdbProperties * mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len) { guint32 record_len, name_len; int pos = 0; int elem, dtype, dsize; gchar *name, *value; MdbProperties *props; int i=0; #if MDB_DEBUG mdb_buffer_dump(kkd, 0, len); #endif pos = 0; record_len = mdb_get_int16(kkd, pos); pos += 4; name_len = mdb_get_int16(kkd, pos); pos += 2; props = mdb_alloc_props(); if (name_len) { props->name = g_malloc(3*name_len + 1); mdb_unicode2ascii(mdb, kkd+pos, name_len, props->name, 3*name_len); mdb_debug(MDB_DEBUG_PROPS,"prop block named: %s", props->name); } pos += name_len; props->hash = g_hash_table_new(g_str_hash, g_str_equal); while (pos < len) { record_len = mdb_get_int16(kkd, pos); dtype = kkd[pos + 3]; elem = mdb_get_int16(kkd, pos + 4); dsize = mdb_get_int16(kkd, pos + 6); value = g_malloc(dsize + 1); strncpy(value, &kkd[pos + 8], dsize); value[dsize] = '\0'; name = g_ptr_array_index(names,elem); if (mdb_get_option(MDB_DEBUG_PROPS)) { fprintf(stderr, "%02d ",i++); mdb_debug(MDB_DEBUG_PROPS,"elem %d (%s) dsize %d dtype %d", elem, name, dsize, dtype); mdb_buffer_dump(value, 0, dsize); } if (dtype == MDB_MEMO) dtype = MDB_TEXT; if (dtype == MDB_BOOL) { g_hash_table_insert(props->hash, g_strdup(name), g_strdup(kkd[pos + 8] ? "yes" : "no")); } else { g_hash_table_insert(props->hash, g_strdup(name), mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize)); } g_free(value); pos += record_len; } return props; } static void print_keyvalue(gpointer key, gpointer value, gpointer outfile) { fprintf((FILE*)outfile,"\t%s: %s\n", (gchar *)key, (gchar *)value); } void mdb_dump_props(MdbProperties *props, FILE *outfile, int show_name) { if (show_name) fprintf(outfile,"name: %s\n", props->name ? props->name : "(none)"); g_hash_table_foreach(props->hash, print_keyvalue, outfile); if (show_name) fputc('\n', outfile); } /* * That function takes a raw KKD/MR2 binary buffer, * typically read from LvProp in table MSysbjects * and returns a GArray of MdbProps* */ GArray* mdb_kkd_to_props(MdbHandle *mdb, void *buffer, size_t len) { guint32 record_len; guint16 record_type; size_t pos; GPtrArray *names = NULL; MdbProperties *props; GArray *result; #if MDB_DEBUG mdb_buffer_dump(buffer, 0, len); #endif mdb_debug(MDB_DEBUG_PROPS,"starting prop parsing of type %s", buffer); if (strcmp("KKD", buffer) && strcmp("MR2", buffer)) { fprintf(stderr, "Unrecognized format.\n"); mdb_buffer_dump(buffer, 0, len); return NULL; } result = g_array_new(0, 0, sizeof(MdbProperties*)); pos = 4; while (pos < len) { - record_len = mdb_get_int32(buffer, pos); - record_type = mdb_get_int16(buffer, pos + 4); + record_len = mdb_get_int32(buffer, (int)pos); + record_type = mdb_get_int16(buffer, (int)pos + 4); mdb_debug(MDB_DEBUG_PROPS,"prop chunk type:0x%04x len:%d", record_type, record_len); //mdb_buffer_dump(buffer, pos+4, record_len); switch (record_type) { case 0x80: if (names) free_names(names); - names = mdb_read_props_list(mdb, buffer+pos+6, record_len - 6); + names = mdb_read_props_list(mdb, (gchar *)buffer+pos+6, record_len - 6); break; case 0x00: case 0x01: if (!names) { fprintf(stderr,"sequence error!\n"); break; } - props = mdb_read_props(mdb, names, buffer+pos+6, record_len - 6); + props = mdb_read_props(mdb, names, (gchar *)buffer+pos+6, record_len - 6); g_array_append_val(result, props); //mdb_dump_props(props, stderr, 1); break; default: fprintf(stderr,"Unknown record type %d\n", record_type); break; } pos += record_len; } if (names) free_names(names); return result; } diff --git a/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c b/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c index 2590e5735..896e8fa1a 100644 --- a/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c +++ b/src/migration/mdb/3rdparty/mdbtools/libmdb/table.c @@ -1,420 +1,421 @@ /* MDB Tools - A library for reading MS Access database file * Copyright (C) 2000 Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mdbtools.h" #ifdef DMALLOC #include "dmalloc.h" #endif static gint mdb_col_comparer(MdbColumn **a, MdbColumn **b) { if ((*a)->col_num > (*b)->col_num) return 1; else if ((*a)->col_num < (*b)->col_num) return -1; else return 0; } unsigned char mdb_col_needs_size(int col_type) { if (col_type == MDB_TEXT) { return TRUE; } else { return FALSE; } } MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry) { MdbTableDef *table; table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef)); table->entry=entry; strcpy(table->name, entry->object_name); return table; } void mdb_free_tabledef(MdbTableDef *table) { if (!table) return; if (table->is_temp_table) { unsigned int i; /* Temp table pages are being stored in memory */ for (i=0; itemp_table_pages->len; i++) g_free(g_ptr_array_index(table->temp_table_pages,i)); g_ptr_array_free(table->temp_table_pages, TRUE); /* Temp tables use dummy entries */ g_free(table->entry); } mdb_free_columns(table->columns); mdb_free_indices(table->indices); g_free(table->usage_map); g_free(table->free_usage_map); g_free(table); } MdbTableDef *mdb_read_table(MdbCatalogEntry *entry) { MdbTableDef *table; MdbHandle *mdb = entry->mdb; MdbFormatConstants *fmt = mdb->fmt; int row_start, pg_row; void *buf, *pg_buf = mdb->pg_buf; guint i; mdb_read_pg(mdb, entry->table_pg); if (mdb_get_byte(pg_buf, 0) != 0x02) /* not a valid table def page */ return NULL; table = mdb_alloc_tabledef(entry); mdb_get_int16(pg_buf, 8); /* len */ table->num_rows = mdb_get_int32(pg_buf, fmt->tab_num_rows_offset); table->num_var_cols = mdb_get_int16(pg_buf, fmt->tab_num_cols_offset-2); table->num_cols = mdb_get_int16(pg_buf, fmt->tab_num_cols_offset); table->num_idxs = mdb_get_int32(pg_buf, fmt->tab_num_idxs_offset); table->num_real_idxs = mdb_get_int32(pg_buf, fmt->tab_num_ridxs_offset); /* grab a copy of the usage map */ pg_row = mdb_get_int32(pg_buf, fmt->tab_usage_map_offset); mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz)); - table->usage_map = g_memdup((char*)buf + row_start, table->map_sz); + table->usage_map = g_memdup((char*)buf + row_start, (int)table->map_sz); if (mdb_get_option(MDB_DEBUG_USAGE)) mdb_buffer_dump(buf, row_start, table->map_sz); mdb_debug(MDB_DEBUG_USAGE,"usage map found on page %ld row %d start %d len %d", pg_row >> 8, pg_row & 0xff, row_start, table->map_sz); /* grab a copy of the free space page map */ pg_row = mdb_get_int32(pg_buf, fmt->tab_free_map_offset); mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->freemap_sz)); - table->free_usage_map = g_memdup((char*)buf + row_start, table->freemap_sz); + table->free_usage_map = g_memdup((char*)buf + row_start, (int)table->freemap_sz); mdb_debug(MDB_DEBUG_USAGE,"free map found on page %ld row %d start %d len %d\n", pg_row >> 8, pg_row & 0xff, row_start, table->freemap_sz); table->first_data_pg = mdb_get_int16(pg_buf, fmt->tab_first_dpg_offset); if (entry->props) for (i=0; iprops->len; ++i) { MdbProperties *props = g_array_index(entry->props, MdbProperties*, i); if (!props->name) table->props = props; } return table; } MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type) { unsigned int i; MdbCatalogEntry *entry; mdb_read_catalog(mdb, obj_type); for (i=0; inum_catalog; i++) { entry = g_ptr_array_index(mdb->catalog, i); if (!strcasecmp(entry->object_name, table_name)) return mdb_read_table(entry); } return NULL; } guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos) { char c[4]; read_pg_if_n(mdb, c, cur_pos, 4); return mdb_get_int32(c, 0); } guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos) { char c[2]; read_pg_if_n(mdb, c, cur_pos, 2); return mdb_get_int16(c, 0); } guint8 read_pg_if_8(MdbHandle *mdb, int *cur_pos) { guint8 c; read_pg_if_n(mdb, &c, cur_pos, 1); return c; } /* * Read data into a buffer, advancing pages and setting the * page cursor as needed. In the case that buf in NULL, pages * are still advanced and the page cursor is still updated. */ void * -read_pg_if_n(MdbHandle *mdb, void *buf, int *cur_pos, size_t len) +read_pg_if_n(MdbHandle *mdb, void *void_buf, int *cur_pos, size_t len) { + gchar *buf = void_buf; /* Advance to page which contains the first byte */ while (*cur_pos >= mdb->fmt->pg_size) { mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4)); - *cur_pos -= (mdb->fmt->pg_size - 8); + *cur_pos -= (int)(mdb->fmt->pg_size - 8); } /* Copy pages into buffer */ - while (*cur_pos + len >= mdb->fmt->pg_size) { + while ((ssize_t)(*cur_pos + len) >= mdb->fmt->pg_size) { int piece_len = mdb->fmt->pg_size - *cur_pos; if (buf) { memcpy(buf, mdb->pg_buf + *cur_pos, piece_len); buf += piece_len; } len -= piece_len; mdb_read_pg(mdb, mdb_get_int32(mdb->pg_buf,4)); *cur_pos = 8; } /* Copy into buffer from final page */ if (len && buf) { memcpy(buf, mdb->pg_buf + *cur_pos, len); } *cur_pos += len; return buf; } void mdb_append_column(GPtrArray *columns, MdbColumn *in_col) { g_ptr_array_add(columns, g_memdup(in_col,sizeof(MdbColumn))); } void mdb_free_columns(GPtrArray *columns) { unsigned int i, j; MdbColumn *col; if (!columns) return; for (i=0; ilen; i++) { col = (MdbColumn *) g_ptr_array_index(columns, i); if (col->sargs) { for (j=0; jsargs->len; j++) { g_free( g_ptr_array_index(col->sargs, j)); } g_ptr_array_free(col->sargs, TRUE); } g_free(col); } g_ptr_array_free(columns, TRUE); } GPtrArray *mdb_read_columns(MdbTableDef *table) { MdbHandle *mdb = table->entry->mdb; MdbFormatConstants *fmt = mdb->fmt; MdbColumn *pcol; unsigned char *col; unsigned int i, j; int cur_pos; size_t name_sz; GArray *allprops; table->columns = g_ptr_array_new(); col = (unsigned char *) g_malloc(fmt->tab_col_entry_size); cur_pos = fmt->tab_cols_start_offset + (table->num_real_idxs * fmt->tab_ridx_entry_size); /* new code based on patch submitted by Tim Nelson 2000.09.27 */ /* ** column attributes */ for (i=0;inum_cols;i++) { #ifdef MDB_DEBUG /* printf("column %d\n", i); mdb_buffer_dump(mdb->pg_buf, cur_pos, fmt->tab_col_entry_size); */ #endif read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size); pcol = (MdbColumn *) g_malloc0(sizeof(MdbColumn)); pcol->table = table; pcol->col_type = col[0]; // col_num_offset == 1 or 5 pcol->col_num = col[fmt->col_num_offset]; //fprintf(stdout,"----- column %d -----\n",pcol->col_num); // col_var == 3 or 7 pcol->var_col_num = mdb_get_int16(col, fmt->tab_col_offset_var); //fprintf(stdout,"var column pos %d\n",pcol->var_col_num); // col_var == 5 or 9 pcol->row_col_num = mdb_get_int16(col, fmt->tab_row_col_num_offset); //fprintf(stdout,"row column num %d\n",pcol->row_col_num); /* FIXME: can this be right in Jet3 and Jet4? */ if (pcol->col_type == MDB_NUMERIC) { pcol->col_prec = col[11]; pcol->col_scale = col[12]; } // col_flags_offset == 13 or 15 pcol->is_fixed = col[fmt->col_flags_offset] & 0x01 ? 1 : 0; pcol->is_long_auto = col[fmt->col_flags_offset] & 0x04 ? 1 : 0; pcol->is_uuid_auto = col[fmt->col_flags_offset] & 0x40 ? 1 : 0; // tab_col_offset_fixed == 14 or 21 pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed); //fprintf(stdout,"fixed column offset %d\n",pcol->fixed_offset); //fprintf(stdout,"col type %s\n",pcol->is_fixed ? "fixed" : "variable"); if (pcol->col_type != MDB_BOOL) { // col_size_offset == 16 or 23 pcol->col_size = mdb_get_int16(col, fmt->col_size_offset); } else { pcol->col_size=0; } g_ptr_array_add(table->columns, pcol); } g_free (col); /* ** column names - ordered the same as the column attributes table */ for (i=0;inum_cols;i++) { char *tmp_buf; pcol = g_ptr_array_index(table->columns, i); if (IS_JET3(mdb)) name_sz = read_pg_if_8(mdb, &cur_pos); else name_sz = read_pg_if_16(mdb, &cur_pos); tmp_buf = (char *) g_malloc(name_sz); read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz); mdb_unicode2ascii(mdb, tmp_buf, name_sz, pcol->name, MDB_MAX_OBJ_NAME); g_free(tmp_buf); } /* Sort the columns by col_num */ g_ptr_array_sort(table->columns, (GCompareFunc)mdb_col_comparer); allprops = table->entry->props; if (allprops) for (i=0;inum_cols;i++) { pcol = g_ptr_array_index(table->columns, i); for (j=0; jlen; ++j) { MdbProperties *props = g_array_index(allprops, MdbProperties*, j); if (props->name && !strcmp(props->name, pcol->name)) { pcol->props = props; break; } } } table->index_start = cur_pos; return table->columns; } #if !MDB_NO_BACKENDS void mdb_table_dump(MdbCatalogEntry *entry) { MdbTableDef *table; MdbColumn *col; int coln; MdbIndex *idx; unsigned int i, bitn; guint32 pgnum; table = mdb_read_table(entry); fprintf(stdout,"definition page = %lu\n",entry->table_pg); fprintf(stdout,"number of datarows = %d\n",table->num_rows); fprintf(stdout,"number of columns = %d\n",table->num_cols); fprintf(stdout,"number of indices = %d\n",table->num_real_idxs); if (table->props) mdb_dump_props(table->props, stdout, 0); mdb_read_columns(table); mdb_read_indices(table); for (i=0;inum_cols;i++) { col = g_ptr_array_index(table->columns,i); fprintf(stdout,"column %d Name: %-20s Type: %s(%d)\n", i, col->name, mdb_get_colbacktype_string(col), col->col_size); if (col->props) mdb_dump_props(col->props, stdout, 0); } for (i=0;inum_idxs;i++) { idx = g_ptr_array_index (table->indices, i); mdb_index_dump(table, idx); } if (table->usage_map) { printf("pages reserved by this object\n"); printf("usage map pg %" G_GUINT32_FORMAT "\n", table->map_base_pg); printf("free map pg %" G_GUINT32_FORMAT "\n", table->freemap_base_pg); pgnum = mdb_get_int32(table->usage_map,1); /* the first 5 bytes of the usage map mean something */ coln = 0; for (i=5;imap_sz;i++) { for (bitn=0;bitn<8;bitn++) { if (table->usage_map[i] & 1 << bitn) { coln++; printf("%6" G_GUINT32_FORMAT, pgnum); if (coln==10) { printf("\n"); coln = 0; } else { printf(" "); } } pgnum++; } } printf("\n"); } } #endif int mdb_is_user_table(MdbCatalogEntry *entry) { return ((entry->object_type == MDB_TABLE) && !(entry->flags & 0x80000002)) ? 1 : 0; } int mdb_is_system_table(MdbCatalogEntry *entry) { return ((entry->object_type == MDB_TABLE) && (entry->flags & 0x80000002)) ? 1 : 0; } const char * mdb_table_get_prop(const MdbTableDef *table, const gchar *key) { if (!table->props) return NULL; return g_hash_table_lookup(table->props->hash, key); } const char * mdb_col_get_prop(const MdbColumn *col, const gchar *key) { if (!col->props) return NULL; return g_hash_table_lookup(col->props->hash, key); }