--- psiconv/trunk/lib/psiconv/parse_sheet.c 2001/07/18 12:24:08 128 +++ psiconv/trunk/lib/psiconv/parse_sheet.c 2001/07/24 20:32:51 129 @@ -76,6 +76,149 @@ return NULL; } +static psiconv_sheet_cell_reference_t + psiconv_read_var_cellref (const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + int *status) +{ + int len=0; + int res; + psiconv_sheet_cell_reference_t result; + psiconv_u32 temp; + + psiconv_progress(lev+1,off+len,"Going to read a sheet cell reference"); + psiconv_progress(lev+2,off+len, + "Going to read the initial byte (%02x expected)",0x00); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp != 0x00) { + psiconv_warn(lev+2,off+len, + "Sheet cell reference initial byte unknown value (ignored)"); + psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + } + len ++; + + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp & 0xffff0000) { + psiconv_warn(lev+2,off+len, + "Sheet cell row reference to unknown row (reset)"); + } + result.row.offset = temp; + result.row.absolute = psiconv_bool_true; + len += 4; + + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp & 0xffff0000) { + psiconv_warn(lev+2,off+len, + "Sheet cell column reference to unknown row (reset)"); + } + result.column.offset = temp; + result.column.absolute = psiconv_bool_true; + len += 4; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet column reference (total length: %08x)", len); + return result; +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Column Reference failed"); + if (length) + *length = 0; + if (status) + *status = res?res:-PSICONV_E_NOMEM; + return result; +} + +static psiconv_sheet_cell_block_t + psiconv_read_var_cellblock (const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + int *status) +{ + int len=0; + int res; + psiconv_sheet_cell_block_t result; + psiconv_u32 temp; + + psiconv_progress(lev+1,off+len,"Going to read a sheet cell block reference"); + psiconv_progress(lev+2,off+len, + "Going to read the initial byte (%02x expected)",0x00); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp != 0x00) { + psiconv_warn(lev+2,off+len, + "Sheet cell reference initial byte unknown value (ignored)"); + psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + } + len ++; + + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp & 0xffff0000) { + psiconv_warn(lev+2,off+len, + "Sheet block initial row reference to unknown row (reset)"); + } + result.first.row.offset = temp; + result.first.row.absolute = psiconv_bool_true; + len += 4; + + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp & 0xffff0000) { + psiconv_warn(lev+2,off+len, + "Sheet block initial column reference to unknown row (reset)"); + } + result.first.column.offset = temp; + result.first.column.absolute = psiconv_bool_true; + len += 4; + + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp & 0xffff0000) { + psiconv_warn(lev+2,off+len, + "Sheet block final row reference to unknown row (reset)"); + } + result.last.row.offset = temp; + result.last.row.absolute = psiconv_bool_true; + len += 4; + + temp = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR1; + if (temp & 0xffff0000) { + psiconv_warn(lev+2,off+len, + "Sheet block final column reference to unknown row (reset)"); + } + result.last.column.offset = temp; + result.last.column.absolute = psiconv_bool_true; + len += 4; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet cell block reference (total length: %08x)", + len); + return result; +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Cell Block Reference failed"); + if (length) + *length = 0; + if (status) + *status = res?res:-PSICONV_E_NOMEM; + return result; +} + int psiconv_parse_sheet_numberformat(const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_sheet_numberformat result) @@ -313,7 +456,7 @@ if (temp != 0x00) { psiconv_warn(lev+2,off+len, "Sheet status section unknown byte unknown value (ignored)"); - psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + psiconv_debug(lev+2,off+len,"Unknown byte: %02x",temp); } len ++; @@ -356,8 +499,8 @@ psiconv_u32 off, int *length, psiconv_sheet_workbook_section *result) { - int res=0; - psiconv_u32 temp,formulas_off,worksheets_off; + int res=0,with_name; + psiconv_u32 temp,formulas_off,worksheets_off,info_off,var_off,name_off=0; int len=0; psiconv_progress(lev+1,off,"Going to read the sheet workbook section"); @@ -365,23 +508,25 @@ goto ERROR1; psiconv_progress(lev+2,off+len, - "Going to read the initial byte (%02x expected)",0x04); + "Going to read the initial byte (%02x or $02xexpected)", + 0x02,0x04); temp = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) goto ERROR2; - if (temp != 0x04) { + if ((temp != 0x04) && temp !=0x02) { psiconv_warn(lev+2,off+len, "Sheet workbook section initial byte unknown value (ignored)"); psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); } + with_name = temp ==0x04; len ++; psiconv_progress(lev+2,off+len, - "Going to read the offset of the 1st ??? Section"); - temp = psiconv_read_u32(buf,lev+2,off+len,&res); + "Going to read the offset of the sheet info Section"); + info_off = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) goto ERROR2; - psiconv_debug(lev+2,off+len,"Offset: %04x",temp); + psiconv_debug(lev+2,off+len,"Offset: %04x",info_off); len += 4; psiconv_progress(lev+2,off+len, @@ -401,23 +546,52 @@ len += 4; psiconv_progress(lev+2,off+len, - "Going to read the offset of the 4th ??? Section"); - temp = psiconv_read_u32(buf,lev+2,off+len,&res); + "Going to read the offset of the Variable List"); + var_off = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) goto ERROR2; - psiconv_debug(lev+2,off+len,"Offset: %04x",temp); + psiconv_debug(lev+2,off+len,"Offset: %04x",var_off); len += 4; + if (with_name) { + psiconv_progress(lev+2,off+len, + "Going to read the offset of the Name Section"); + name_off = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Offset: %04x",name_off); + len += 4; + } + + + psiconv_progress(lev+2,off+len,"Going to read the info section"); + if ((res = psiconv_parse_sheet_info_section(buf,lev+2,info_off,NULL, + &(*result)->info))) + goto ERROR2; + + psiconv_progress(lev+2,off+len,"Going to read the variables list"); + if ((res = psiconv_parse_sheet_variable_list(buf,lev+2,var_off,NULL, + &(*result)->variables))) + goto ERROR3; + psiconv_progress(lev+2,off+len,"Going to read the formulas list"); - if ((res = psiconv_parse_sheet_formula_table(buf,lev+2,formulas_off,NULL, + if ((res = psiconv_parse_sheet_formula_list(buf,lev+2,formulas_off,NULL, &(*result)->formulas))) - goto ERROR2; + goto ERROR4; psiconv_progress(lev+2,off+len,"Going to read the worksheet list"); if ((res = psiconv_parse_sheet_worksheet_list(buf,lev+2,worksheets_off, NULL,&(*result)->worksheets))) - goto ERROR2; + goto ERROR5; + if (with_name) { + psiconv_progress(lev+2,off+len,"Going to read the name section"); + + if ((res = psiconv_parse_sheet_name_section(buf,lev+2,name_off,NULL, + &(*result)->name))) + goto ERROR6; + } else + (*result)->name = NULL; if (length) *length = len; @@ -426,6 +600,14 @@ "End of sheet workbook section (total length: %08x)", len); return 0; +ERROR6: + psiconv_free_sheet_worksheet_list((*result)->worksheets); +ERROR5: + psiconv_free_formula_list((*result)->formulas); +ERROR4: + psiconv_free_sheet_variable_list((*result)->variables); +ERROR3: + psiconv_free_sheet_info_section((*result)->info); ERROR2: free (*result); ERROR1: @@ -438,7 +620,115 @@ return res; } -int psiconv_parse_sheet_formula_table(const psiconv_buffer buf, int lev, +int psiconv_parse_sheet_name_section(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_name_section *result) +{ + int res=0; + psiconv_u32 temp; + int len=0,leng; + + psiconv_progress(lev+1,off,"Going to read the sheet name section"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len, + "Going to read the initial byte (%02x expected)",0x02); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (temp != 0x02) { + psiconv_warn(lev+2,off+len, + "Sheet name section initial byte unknown value (ignored)"); + psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + } + len ++; + + psiconv_progress(lev+2,off+len, "Going to read the sheet name"); + (*result)->name = psiconv_read_string(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + len += leng; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet name section (total length: %08x)", len); + return 0; + +ERROR2: + free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Name Section failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + +int psiconv_parse_sheet_info_section(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_info_section *result) +{ + int res=0; + psiconv_u32 temp; + int len=0; + + psiconv_progress(lev+1,off,"Going to read the sheet info section"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len, + "Going to read the initial byte (%02x expected)",0x02); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (temp != 0x02) { + psiconv_warn(lev+2,off+len, + "Sheet info section initial byte unknown value (ignored)"); + psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + } + len ++; + + psiconv_progress(lev+2,off+len, "Going to read the flags byte"); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + (*result)->auto_recalc = temp & 0x01 ? psiconv_bool_true:psiconv_bool_false; + psiconv_debug(lev+2,off+len,"Auto recalculation: %02x", + (*result)->auto_recalc); + if ((temp & 0xfe) != 0x02) { + psiconv_warn(lev+2,off+len,"Sheet Info Section flags byte " + "contains unknown flags (ignored)"); + psiconv_debug(lev+2,off+len,"Unknown flags: %02x",temp &0xfe); + } + + len ++; + + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet info section (total length: %08x)", len); + return 0; + +ERROR2: + free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Name Section failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + +int psiconv_parse_sheet_formula_list(const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_formula_list *result) { @@ -449,7 +739,7 @@ psiconv_u32 listlen,i; int leng; - psiconv_progress(lev+1,off,"Going to read the sheet formula table"); + psiconv_progress(lev+1,off,"Going to read the sheet formula list"); if (!(*result = psiconv_list_new(sizeof(struct psiconv_formula_s)))) goto ERROR1; @@ -460,7 +750,7 @@ goto ERROR2; if (temp != 0x02) { psiconv_warn(lev+2,off+len, - "Sheet formula table initial byte unknown value (ignored)"); + "Sheet formula list initial byte unknown value (ignored)"); psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); } len ++; @@ -487,7 +777,7 @@ *length = len; psiconv_progress(lev,off+len-1, - "End of sheet formula table (total length: %08x)", len); + "End of sheet formula list (total length: %08x)", len); return 0; ERROR3: @@ -495,7 +785,7 @@ ERROR2: psiconv_list_free(*result); ERROR1: - psiconv_warn(lev+1,off,"Reading of Sheet Formula Table failed"); + psiconv_warn(lev+1,off,"Reading of Sheet Formula list failed"); if (length) *length = 0; if (!res) @@ -1164,3 +1454,174 @@ return res; } +int psiconv_parse_sheet_variable(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_variable *result) +{ + int res=0; + int len=0; + psiconv_u32 marker; + int leng; + + psiconv_progress(lev+1,off,"Going to read a sheet variable"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len, "Going to read the variable name"); + (*result)->name = psiconv_read_string(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read the type marker"); + marker = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR3; + psiconv_debug(lev+2,off+len,"Marker: %02x",marker); + len ++; + + if (marker == 0x00) { + (*result)->type = psiconv_var_int; + psiconv_progress(lev+2,off+len,"Going to read a signed integer"); + (*result)->data.dat_int = psiconv_read_sint(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR3; + psiconv_debug(lev+2,off+len,"Value: %d",(*result)->data.dat_int); + len += leng; + } else if (marker == 0x01) { + (*result)->type = psiconv_var_float; + psiconv_progress(lev+2,off+len,"Going to read a floating point number"); + (*result)->data.dat_float = psiconv_read_float(buf,lev+2,off+len,&leng, + &res); + if (res) + goto ERROR3; + psiconv_debug(lev+2,off+len,"Value: %f",(*result)->data.dat_float); + len += leng; + } else if (marker == 0x02) { + (*result)->type = psiconv_var_string; + psiconv_progress(lev+2,off+len,"Going to read a string"); + (*result)->data.dat_string = psiconv_read_string(buf,lev+2,off+len,&leng, + &res); + if (res) + goto ERROR3; + len += leng; + } else if (marker == 0x03) { + (*result)->type = psiconv_var_cellref; + psiconv_progress(lev+2,off+len,"Going to read a cell reference"); + (*result)->data.dat_cellref = psiconv_read_var_cellref(buf,lev+2,off+len, + &leng, &res); + if (res) + goto ERROR3; + len += leng; + } else if (marker == 0x04) { + (*result)->type = psiconv_var_cellblock; + psiconv_progress(lev+2,off+len,"Going to read a cell block reference"); + (*result)->data.dat_cellblock = psiconv_read_var_cellblock(buf,lev+2, + off+len, + &leng, &res); + if (res) + goto ERROR3; + len += leng; + } else { + psiconv_warn(lev+2,off+len,"Sheet variable unknown type marker"); + res = -PSICONV_E_PARSE; + goto ERROR3; + } + + psiconv_progress(lev+2,off+len,"Going to read the variable number"); + (*result)->number = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR4; + psiconv_debug(lev+2,off+len,"Number: %08x",(*result)->number); + len += 4; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet variable (total length: %08x)", len); + return 0; + +ERROR4: + if ((*result)->type == psiconv_var_string) + free((*result)->data.dat_string); +ERROR3: + free((*result)->name); +ERROR2: + free (*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Variable failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + + +int psiconv_parse_sheet_variable_list(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_variable_list *result) +{ + int res=0; + int len=0; + psiconv_u32 temp; + psiconv_sheet_variable variable; + psiconv_u32 listlen,i; + int leng; + + psiconv_progress(lev+1,off,"Going to read the sheet variable list"); + if (!(*result = psiconv_list_new(sizeof(struct psiconv_sheet_variable_s)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len, + "Going to read the initial byte (%02x expected)",0x02); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (temp != 0x02) { + psiconv_warn(lev+2,off+len, + "Sheet variable list initial byte unknown value (ignored)"); + psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + } + len ++; + + psiconv_progress(lev+2,off+len, + "Going to read the number of variables"); + listlen = psiconv_read_X(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Number of variables: %d",listlen); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read all variables"); + for (i = 0; i < listlen; i++) { + psiconv_progress(lev+3,off+len,"Going to read variable %d",i); + if ((res = psiconv_parse_sheet_variable(buf,lev+3,off+len,&leng,&variable))) + goto ERROR2; + if ((res = psiconv_list_add(*result,variable))) + goto ERROR3; + len += leng; + } + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet variabels list (total length: %08x)", len); + return 0; + +ERROR3: + psiconv_free_sheet_variable(variable); +ERROR2: + psiconv_list_free(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Variable list failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +}