Experimental support for JET5 .accdb files

Right now, they are handled like JET4 file.
This commit is contained in:
Jean-Michel Vourgère 2012-07-03 00:31:23 +02:00
parent 1db0a89ee2
commit c566407eaf
7 changed files with 40 additions and 38 deletions

View File

@ -58,7 +58,8 @@ enum {
};
enum {
MDB_VER_JET3 = 0,
MDB_VER_JET4 = 1
MDB_VER_JET4 = 1,
MDB_VER_JET5 = 2
};
enum {
MDB_FORM = 0,
@ -165,6 +166,7 @@ enum {
};
#define MDB_SHEXP_DEFAULT (MDB_SHEXP_CST_NOTNULL | MDB_SHEXP_COMMENTS | MDB_SHEXP_INDEXES | MDB_SHEXP_RELATIONS)
#define IS_JET5(mdb) (mdb->f->jet_version==MDB_VER_JET5)
#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4)
#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)

View File

@ -217,7 +217,9 @@ MdbHandle *mdb_open(const char *filename, MdbFileFlags flags)
return NULL;
}
mdb->f->jet_version = mdb_get_int32(mdb->pg_buf, 0x14);
if (IS_JET4(mdb)) {
if (IS_JET5(mdb)) {
mdb->fmt = &MdbJet4Constants;
} else if (IS_JET4(mdb)) {
mdb->fmt = &MdbJet4Constants;
} else if (IS_JET3(mdb)) {
mdb->fmt = &MdbJet3Constants;

View File

@ -38,7 +38,7 @@ mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dle
return 0;
/* Uncompress 'Unicode Compressed' string into tmp */
if (IS_JET4(mdb) && (slen>=2)
if (!IS_JET3(mdb) && (slen>=2)
&& ((src[0]&0xff)==0xff) && ((src[1]&0xff)==0xfe)) {
unsigned int compress=1;
src += 2;
@ -72,8 +72,8 @@ mdb_unicode2ascii(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dle
iconv(mdb->iconv_in, &in_ptr, &len_in, &out_ptr, &len_out);
if ((!len_in) || (errno == E2BIG)) break;
/* Don't bail if impossible conversion is encountered */
in_ptr += (IS_JET4(mdb)) ? 2 : 1;
len_in -= (IS_JET4(mdb)) ? 2 : 1;
in_ptr += (IS_JET3(mdb)) ? 1 : 2;
len_in -= (IS_JET3(mdb)) ? 1 : 2;
*out_ptr++ = '?';
len_out--;
}
@ -139,7 +139,7 @@ mdb_ascii2unicode(MdbHandle *mdb, char *src, size_t slen, char *dest, size_t dle
#endif
/* Unicode Compression */
if(IS_JET4(mdb) && (dlen>4)) {
if(!IS_JET3(mdb) && (dlen>4)) {
unsigned char *tmp = g_malloc(dlen);
unsigned int tptr = 0, dptr = 0;
int comp = 1;
@ -189,7 +189,7 @@ mdb_target_charset(MdbHandle *mdb)
iconv_code = "UTF-8";
return iconv_code;
#else
if (IS_JET4(mdb))
if (!IS_JET3(mdb))
return "ISO-8859-1";
return NULL; // same as input: unknown
#endif
@ -205,7 +205,7 @@ void mdb_iconv_init(MdbHandle *mdb)
}
#ifdef HAVE_ICONV
if (IS_JET4(mdb)) {
if (!IS_JET3(mdb)) {
mdb->iconv_out = iconv_open("UCS-2LE", iconv_code);
mdb->iconv_in = iconv_open(iconv_code, "UCS-2LE");
} else {

View File

@ -76,14 +76,14 @@ mdb_read_indices(MdbTableDef *table)
table->indices = g_ptr_array_new();
if (IS_JET4(mdb)) {
cur_pos = table->index_start + 52 * table->num_real_idxs;
idx2_sz = 28;
type_offset = 23;
} else {
if (IS_JET3(mdb)) {
cur_pos = table->index_start + 39 * table->num_real_idxs;
idx2_sz = 20;
type_offset = 19;
} else {
cur_pos = table->index_start + 52 * table->num_real_idxs;
idx2_sz = 28;
type_offset = 23;
}
//fprintf(stderr, "num_idxs:%d num_real_idxs:%d\n", table->num_idxs, table->num_real_idxs);
@ -117,10 +117,10 @@ mdb_read_indices(MdbTableDef *table)
for (i=0;i<table->num_idxs;i++) {
pidx = g_ptr_array_index (table->indices, i);
if (IS_JET4(mdb)) {
name_sz=read_pg_if_16(mdb, &cur_pos);
} else {
if (IS_JET3(mdb)) {
name_sz=read_pg_if_8(mdb, &cur_pos);
} else {
name_sz=read_pg_if_16(mdb, &cur_pos);
}
tmpbuf = g_malloc(name_sz);
read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz);
@ -133,7 +133,7 @@ mdb_read_indices(MdbTableDef *table)
mdb_read_pg(mdb, index_start_pg);
cur_pos = table->index_start;
for (i=0;i<table->num_real_idxs;i++) {
if (IS_JET4(mdb)) cur_pos += 4;
if (!IS_JET3(mdb)) cur_pos += 4;
/* look for index number i */
for (j=0; j<table->num_idxs; ++j) {
pidx = g_ptr_array_index (table->indices, j);
@ -195,7 +195,7 @@ mdb_read_indices(MdbTableDef *table)
pidx->first_pg = read_pg_if_32(mdb, &cur_pos);
pidx->flags = read_pg_if_8(mdb, &cur_pos);
//fprintf(stderr, "pidx->first_pg:%d pidx->flags:0x%02x\n", pidx->first_pg, pidx->flags);
if (IS_JET4(mdb)) cur_pos += 9;
if (!IS_JET3(mdb)) cur_pos += 9;
}
return NULL;
}

View File

@ -287,14 +287,10 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
char *tmp_buf;
pcol = g_ptr_array_index(table->columns, i);
if (IS_JET4(mdb)) {
name_sz = read_pg_if_16(mdb, &cur_pos);
} else if (IS_JET3(mdb)) {
if (IS_JET3(mdb))
name_sz = read_pg_if_8(mdb, &cur_pos);
} else {
fprintf(stderr,"Unknown MDB version\n");
continue;
}
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);

View File

@ -172,12 +172,12 @@ mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
mdb_buffer_dump(pg_buf, row_start, row_end - row_start + 1);
}
if (IS_JET4(mdb)) {
row_cols = mdb_get_int16(pg_buf, row_start);
col_count_size = 2;
} else {
if (IS_JET3(mdb)) {
row_cols = mdb_get_byte(pg_buf, row_start);
col_count_size = 1;
} else {
row_cols = mdb_get_int16(pg_buf, row_start);
col_count_size = 2;
}
bitmask_sz = (row_cols + 7) / 8;
@ -185,15 +185,15 @@ mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
/* read table of variable column locations */
if (table->num_var_cols > 0) {
row_var_cols = IS_JET4(mdb) ?
mdb_get_int16(pg_buf, row_end - bitmask_sz - 1) :
mdb_get_byte(pg_buf, row_end - bitmask_sz);
row_var_cols = IS_JET3(mdb) ?
mdb_get_byte(pg_buf, row_end - bitmask_sz) :
mdb_get_int16(pg_buf, row_end - bitmask_sz - 1);
var_col_offsets = (unsigned int *)g_malloc((row_var_cols+1)*sizeof(int));
if (IS_JET4(mdb)) {
mdb_crack_row4(mdb, row_start, row_end, bitmask_sz,
if (IS_JET3(mdb)) {
mdb_crack_row3(mdb, row_start, row_end, bitmask_sz,
row_var_cols, var_col_offsets);
} else {
mdb_crack_row3(mdb, row_start, row_end, bitmask_sz,
mdb_crack_row4(mdb, row_start, row_end, bitmask_sz,
row_var_cols, var_col_offsets);
}
}
@ -415,10 +415,10 @@ mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int unsigned num_fie
}
}
}
if (IS_JET4(table->entry->mdb)) {
return mdb_pack_row4(table, row_buffer, num_fields, fields);
} else {
if (IS_JET3(table->entry->mdb)) {
return mdb_pack_row3(table, row_buffer, num_fields, fields);
} else {
return mdb_pack_row4(table, row_buffer, num_fields, fields);
}
}
int

View File

@ -70,6 +70,8 @@ main(int argc, char **argv)
printf("JET3\n");
} else if (IS_JET4(mdb)) {
printf("JET4\n");
} else if (IS_JET5(mdb)) {
printf("JET5\n");
} else {
printf(_("unknown database version\n"));
}