guint8 read_pg_if_8(MdbHandle *mdb, int *cur_pos) { guint8 c; read_pg_if_n(mdb, &c, cur_pos, 1); return c; }
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); }
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); }
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; 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;i<table->num_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;i<table->num_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); GArray *allprops = table->entry->props; if (allprops) for (i=0;i<table->num_cols;i++) { pcol = g_ptr_array_index(table->columns, i); for (j=0; j<allprops->len; ++j) { MdbProperties *props = g_array_index(allprops, MdbProperties*, j); if (props->name && pcol->name && !strcmp(props->name, pcol->name)) { pcol->props = props; break; } } } table->index_start = cur_pos; return table->columns; }
GPtrArray *mdb_read_columns(MdbTableDef *table) { MdbHandle *mdb = table->entry->mdb; MdbFormatConstants *fmt = mdb->fmt; MdbColumn *pcol; unsigned char *col; unsigned int i; int cur_pos; size_t name_sz; 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;i<table->num_cols;i++) { #ifdef MDB_DEBUG /* printf("column %d\n", i); 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->col_type = col[0]; pcol->col_num = col[fmt->col_num_offset]; pcol->var_col_num = mdb_get_int16(col, fmt->tab_col_offset_var); pcol->row_col_num = mdb_get_int16(col, fmt->tab_row_col_num_offset); /* 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]; } pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0; pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed); if (pcol->col_type != MDB_BOOL) { 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;i<table->num_cols;i++) { 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)) { name_sz = read_pg_if_8(mdb, &cur_pos); } else { fprintf(stderr,"Unknown MDB version\n"); continue; } 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); table->index_start = cur_pos; return table->columns; }
GPtrArray * mdb_read_indices(MdbTableDef *table) { MdbCatalogEntry *entry = table->entry; MdbHandle *mdb = entry->mdb; MdbFormatConstants *fmt = mdb->fmt; MdbIndex *pidx; unsigned int i, j; int idx_num, key_num, col_num; int cur_pos, name_sz, idx2_sz, type_offset; int index_start_pg = mdb->cur_pg; guchar *tmpbuf; 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 { cur_pos = table->index_start + 39 * table->num_real_idxs; idx2_sz = 20; type_offset = 19; } tmpbuf = (guchar *) g_malloc(idx2_sz); for (i=0;i<table->num_idxs;i++) { read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz); cur_pos += idx2_sz; pidx = (MdbIndex *) g_malloc0(sizeof(MdbIndex)); pidx->table = table; pidx->index_num = mdb_get_int16(tmpbuf, 4); pidx->index_type = tmpbuf[type_offset]; g_ptr_array_add(table->indices, pidx); } g_free(tmpbuf); 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); cur_pos += 2; tmpbuf = g_malloc(name_sz); read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz); cur_pos += name_sz; mdb_unicode2ascii(mdb, tmpbuf, 0, name_sz, pidx->name); g_free(tmpbuf); } else { read_pg_if(mdb, &cur_pos, 0); name_sz=mdb->pg_buf[cur_pos++]; read_pg_if_n(mdb, (unsigned char *) pidx->name, &cur_pos, name_sz); cur_pos += name_sz; pidx->name[name_sz]='\0'; } //fprintf(stderr, "index name %s\n", pidx->name); } mdb_read_alt_pg(mdb, entry->table_pg); mdb_read_pg(mdb, index_start_pg); cur_pos = table->index_start; idx_num=0; for (i=0;i<table->num_real_idxs;i++) { if (IS_JET4(mdb)) cur_pos += 4; do { pidx = g_ptr_array_index (table->indices, idx_num++); } while (pidx && pidx->index_type==2); /* if there are more real indexes than index entries left after removing type 2's decrement real indexes and continue. Happens on Northwind Orders table. */ if (!pidx) { table->num_real_idxs--; continue; } pidx->num_rows = mdb_get_int32(mdb->alt_pg_buf, fmt->tab_cols_start_offset + (i*fmt->tab_ridx_entry_size)); key_num=0; for (j=0;j<MDB_MAX_IDX_COLS;j++) { col_num=read_pg_if_16(mdb,&cur_pos); cur_pos += 2; read_pg_if(mdb, &cur_pos, 0); cur_pos++; if (col_num == 0xFFFF) continue; /* set column number to a 1 based column number and store */ pidx->key_col_num[key_num] = col_num + 1; pidx->key_col_order[key_num] = (mdb->pg_buf[cur_pos-1]) ? MDB_ASC : MDB_DESC; key_num++; } pidx->num_keys = key_num; cur_pos += 4; pidx->first_pg = read_pg_if_32(mdb, &cur_pos); cur_pos += 4; read_pg_if(mdb, &cur_pos, 0); pidx->flags = mdb->pg_buf[cur_pos++]; if (IS_JET4(mdb)) cur_pos += 9; } return NULL; }