--- psiconv/trunk/lib/psiconv/parse_sheet.c 2001/03/04 22:10:45 110 +++ psiconv/trunk/lib/psiconv/parse_sheet.c 2001/03/06 23:59:46 111 @@ -25,6 +25,129 @@ #include "parse_routines.h" #include "error.h" +int psiconv_parse_sheet_numberformat(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_numberformat *result) +{ + int res=0; + int len=0; + psiconv_u8 temp; + + psiconv_progress(lev+1,off,"Going to read a sheet numberformat"); + 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 numberformat 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 code byte"); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Code: %02x",temp); + if (temp == 0x00) + (*result)->code = psiconv_numberformat_general; + else if (temp == 0x02) + (*result)->code = psiconv_numberformat_fixeddecimal; + else if (temp == 0x04) + (*result)->code = psiconv_numberformat_scientific; + else if (temp == 0x06) + (*result)->code = psiconv_numberformat_currency; + else if (temp == 0x08) + (*result)->code = psiconv_numberformat_percent; + else if (temp == 0x0A) + (*result)->code = psiconv_numberformat_triads; + else if (temp == 0x0C) + (*result)->code = psiconv_numberformat_boolean; + else if (temp == 0x0E) + (*result)->code = psiconv_numberformat_text; + else if (temp == 0x10) + (*result)->code = psiconv_numberformat_date_ddmm; + else if (temp == 0x12) + (*result)->code = psiconv_numberformat_date_mmdd; + else if (temp == 0x14) + (*result)->code = psiconv_numberformat_date_ddmmyy; + else if (temp == 0x16) + (*result)->code = psiconv_numberformat_date_mmddyy; + else if (temp == 0x18) + (*result)->code = psiconv_numberformat_date_yymmdd; + else if (temp == 0x1A) + (*result)->code = psiconv_numberformat_date_ddmmm; + else if (temp == 0x1C) + (*result)->code = psiconv_numberformat_date_ddmmmyy; + else if (temp == 0x1E) + (*result)->code = psiconv_numberformat_date_ddmmmyyyy; + else if (temp == 0x20) + (*result)->code = psiconv_numberformat_date_mmm; + else if (temp == 0x22) + (*result)->code = psiconv_numberformat_date_monthname; + else if (temp == 0x24) + (*result)->code = psiconv_numberformat_date_mmmyy; + else if (temp == 0x26) + (*result)->code = psiconv_numberformat_date_monthnameyy; + else if (temp == 0x28) + (*result)->code = psiconv_numberformat_date_monthnameddyyyy; + else if (temp == 0x2A) + (*result)->code = psiconv_numberformat_datetime_ddmmyyyyhhii; + else if (temp == 0x2C) + (*result)->code = psiconv_numberformat_datetime_ddmmyyyyHHii; + else if (temp == 0x2E) + (*result)->code = psiconv_numberformat_datetime_mmddyyyyhhii; + else if (temp == 0x30) + (*result)->code = psiconv_numberformat_datetime_mmddyyyyHHii; + else if (temp == 0x32) + (*result)->code = psiconv_numberformat_datetime_yyyymmddhhii; + else if (temp == 0x34) + (*result)->code = psiconv_numberformat_datetime_yyyymmddHHii; + else if (temp == 0x36) + (*result)->code = psiconv_numberformat_time_hhii; + else if (temp == 0x38) + (*result)->code = psiconv_numberformat_time_hhiiss; + else if (temp == 0x3A) + (*result)->code = psiconv_numberformat_time_HHii; + else if (temp == 0x3C) + (*result)->code = psiconv_numberformat_time_HHiiss; + else { + psiconv_warn(lev+2,off+len,"Unknown number format (assumed general)"); + (*result)->code = psiconv_numberformat_general; + } + len ++; + + psiconv_progress(lev+2,off+len, "Going to read the number of decimals"); + (*result)->decimal = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Decimals: %d",(*result)->decimal); + len ++; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet number format (total length: %08x)", len); + return 0; + +ERROR2: + free (*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Number Format failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + int psiconv_parse_sheet_status_section(const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, psiconv_sheet_status_section *result) @@ -223,11 +346,11 @@ len += 4; psiconv_progress(lev+2,off+len, - "Going to read the offset of the Worksheets Section"); + "Going to read the offset of the Worksheet List"); worksheets_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",worksheets_off); len += 4; psiconv_progress(lev+2,off+len, @@ -243,9 +366,9 @@ &(*result)->formulas))) goto ERROR2; - psiconv_progress(lev+2,off+len,"Going to read the worksheets"); - if ((res = psiconv_parse_sheet_worksheet_section(buf,lev+2,worksheets_off, - NULL,&(*result)->worksheet))) + 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; @@ -348,6 +471,9 @@ if (!(*result = malloc(sizeof(**result)))) goto ERROR1; + (*result)->layout = NULL; + (*result)->type = psiconv_cell_blank; + psiconv_progress(lev+2,off+len,"Going to read the cell position"); temp = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) @@ -365,6 +491,10 @@ (*result)->row = (temp >> 10) & 0x3FFF; psiconv_debug(lev+2,off+len,"Cell position is col:%02x row:%04x", (*result)->column,(*result)->row); + if (temp & 0x03) { + psiconv_warn(lev+2,off+len,"Unknown flags in cell position (ignored)"); + psiconv_debug(lev+2,off+len,"Flags: %02x",temp & 0x03); + } psiconv_progress(lev+2,off+len,"Going to read the cell type"); temp = psiconv_read_u8(buf,lev+2,off+len,&res); @@ -388,88 +518,69 @@ } else if ((*result)->type == psiconv_cell_bool) { psiconv_progress(lev+2,off+len,"Going to read a boolean"); - temp = psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) + if ((res = psiconv_parse_bool(buf,lev+2,off+len,&leng, + &(*result)->data.dat_bool))) goto ERROR2; - len ++; psiconv_debug(lev+2,off+len,"Cell contents: %01x",temp); (*result)->data.dat_bool = temp?psiconv_bool_true:psiconv_bool_false; - + len += leng; } else if ((*result)->type == psiconv_cell_error) { psiconv_progress(lev+2,off+len,"Going to read the error code"); - (*result)->data.dat_error = psiconv_read_u16(buf,lev+2,off+len,&res); - if (res) - goto ERROR2; - len += 2; + temp = psiconv_read_u16(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (temp == 0) + (*result)->data.dat_error = psiconv_sheet_error_none; + else if (temp == 1) + (*result)->data.dat_error = psiconv_sheet_error_null; + else if (temp == 2) + (*result)->data.dat_error = psiconv_sheet_error_divzero; + else if (temp == 3) + (*result)->data.dat_error = psiconv_sheet_error_value; + else if (temp == 4) + (*result)->data.dat_error = psiconv_sheet_error_reference; + else if (temp == 5) + (*result)->data.dat_error = psiconv_sheet_error_name; + else if (temp == 6) + (*result)->data.dat_error = psiconv_sheet_error_number; + else if (temp == 7) + (*result)->data.dat_error = psiconv_sheet_error_notavail; + else { + psiconv_warn(lev+2,off+len,"Unknown error code (default assumed)"); + psiconv_debug(lev+2,off+len,"Error code: %04x",temp); + (*result)->data.dat_error = psiconv_sheet_error_none; + } psiconv_debug(lev+2,off+len,"Cell contents: %04x", - (*result)->data.dat_error); - + (*result)->data.dat_error); + len += 2; } else if ((*result)->type == psiconv_cell_float) { psiconv_progress(lev+2,off+len,"Going to read a float"); (*result)->data.dat_float = psiconv_read_float(buf,lev+2,off+len,&leng,&res); - if (res) - goto ERROR2; - len += leng; + if (res) + goto ERROR2; psiconv_debug(lev+2,off+len,"Cell contents: %f",(*result)->data.dat_float); - + len += leng; } else if ((*result)->type == psiconv_cell_string) { psiconv_progress(lev+2,off+len,"Going to read a string"); (*result)->data.dat_string = - psiconv_read_short_string(buf,lev+2,off+len,&leng,&res); - if (res) - goto ERROR2; - len += leng; + psiconv_read_string(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; psiconv_debug(lev+2,off+len,"Cell contents: `%s'", (*result)->data.dat_string); + len += leng; } else { psiconv_warn(lev+2,off+len,"Unknown Sheet Cell type: %02x",(*result)->type); + res = PSICONV_E_PARSE; + goto ERROR2; } if (has_layout) { - psiconv_progress(lev+2,off+len,"Going to read the cell layout"); - - psiconv_progress(lev+2,off+len,"Going to read the cell layout flags"); - temp = psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) + if ((res = psiconv_parse_sheet_cell_layout(buf,lev+2,off+len, + &leng,&(*result)->layout))) goto ERROR2; - len ++; - - if (temp & 0x01) { - if (!((*result)->paragraph = psiconv_basic_paragraph_layout())) - goto ERROR2; - psiconv_progress(lev+3,off+len,"Going to read the paragraph codes"); - if ((res = psiconv_parse_paragraph_layout_list(buf,lev+3,off+len,&leng, - (*result)->paragraph))) - goto ERROR2; - len += leng; - } - - if (temp & 0x02) { - psiconv_progress(lev+3,off+len,"Going to read the character codes"); - if (!((*result)->character = psiconv_basic_character_layout())) - goto ERROR2; - if ((res = psiconv_parse_character_layout_list(buf,lev+3,off+len,&leng, - (*result)->character))) - goto ERROR2; - len += leng; - } - - if (temp & 0x04) { -/* TODO: default number format */ - psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2; - len ++; - psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2; - len ++; - psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2; - len ++; - } + len += leng; } if ((*result)->calculated) { @@ -479,7 +590,7 @@ goto ERROR2; psiconv_debug(lev+2,off+len,"Cell formula reference: %d",temp); len += leng; - (*result)->ref_formula = temp; + (*result)->ref_formula = temp; } if (length) @@ -512,7 +623,7 @@ psiconv_u32 listlen,i; int leng; - psiconv_progress(lev+1,off,"Going to read the sheet cells list"); + psiconv_progress(lev+1,off,"Going to read the sheet cell list"); if (!(*result = psiconv_list_new(sizeof(struct psiconv_sheet_cell_s)))) goto ERROR1; @@ -580,95 +691,112 @@ } -int psiconv_parse_sheet_worksheet_section(const psiconv_buffer buf, int lev, - psiconv_u32 off, int *length, - psiconv_sheet_worksheet_section *result) +int psiconv_parse_sheet_worksheet_list( const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_worksheet_list *result) { + psiconv_sheet_worksheet worksheet; int res=0; - psiconv_u32 temp,cells_off,grid_off; int len=0; - int leng; + psiconv_u8 temp; + psiconv_u32 offset; + int leng,i,nr; - /* TODO: this is the section that might be an XListE instead... */ - psiconv_progress(lev+2,off+len, - "Going to read the initial bytes (%02x expected)",0x02); - temp = psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) + psiconv_progress(lev+1,off,"Going to read the worksheet list"); + if (!(*result = psiconv_list_new(sizeof(*worksheet)))) goto ERROR1; - if (temp != 0x04) { - psiconv_warn(lev+2,off+len, - "Sheet worksheet 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 initial bytes (%02x expected)",0x02); temp = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) - goto ERROR1; - if (temp != 0x04) { + goto ERROR2; + if (temp != 0x02) { psiconv_warn(lev+2,off+len, - "Sheet worksheet section initial byte unknown value (ignored)"); + "Sheet worksheet 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 initial bytes (%02x expected)",0x00); - temp = psiconv_read_u8(buf,lev+2,off+len,&res); + psiconv_progress(lev+2,off+len,"Going to read the list length"); + nr = psiconv_read_X(buf,lev+2,off+len,&leng,&res); if (res) - goto ERROR1; - if (temp != 0x04) { - psiconv_warn(lev+2,off+len, - "Sheet worksheet section initial byte unknown value (ignored)"); - psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); + goto ERROR2; + psiconv_debug(lev+2,off+len,"Length: %02x",nr); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read the list"); + for (i=0 ; i < nr; i++) { + psiconv_progress(lev+3,off+len,"Going to read element %d",i); + psiconv_progress(lev+4,off+len, + "Going to read the initial byte (%02x expected)",0x00); + temp = psiconv_read_u8(buf,lev+4,off+len,&res); + if (res) + goto ERROR2; + if (temp != 0x00) { + psiconv_warn(lev+4,off+len, + "Sheet worksheet element initial byte unknown value (ignored)"); + psiconv_debug(lev+4,off+len,"Initial byte: %02x",temp); + } + len ++; + + psiconv_progress(lev+4,off+len,"Going to read the worksheet offset"); + offset = psiconv_read_u32(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+4,off+len,"Offset: %08x",offset); + len += 4; + + if ((res = psiconv_parse_sheet_worksheet(buf,lev+4,offset,NULL, + &worksheet))) + goto ERROR2; + if ((res = psiconv_list_add(*result,worksheet))) + goto ERROR3; + psiconv_free_sheet_worksheet(worksheet); } - len ++; - psiconv_progress(lev+2,off+len, - "Going to read the offset of the Worksheet Section"); - temp = psiconv_read_u32(buf,lev+2,off+len,&res); - if (res) - goto ERROR1; - psiconv_debug(lev+2,off+len,"Offset: %04x",temp); - len += 4; + if (length) + *length = len; - len = 0; - off = temp; + psiconv_progress(lev,off+len-1, + "End of worksheet list (total length: %08x)", len); - /* this is the real worksheet section from here */ - - psiconv_progress(lev+1,off,"Going to read the sheet worksheet section"); - if (!(*result = malloc(sizeof(**result)))) - goto ERROR1; + return 0; - psiconv_progress(lev+2,off+len, - "Going to read the initial bytes (%02x expected)",0x04); - temp = psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2; - if (temp != 0x04) { - psiconv_warn(lev+2,off+len, - "Worksheet section initial byte unknown value (ignored)"); - psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); - } - len ++; +ERROR3: + psiconv_free_sheet_worksheet(worksheet); +ERROR2: + psiconv_free_sheet_worksheet_list(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of worksheet list failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} - psiconv_progress(lev+2,off+len, - "Going to read the initial bytes (%02x expected)",0x01); - temp = psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2; - if (temp != 0x01) { - psiconv_warn(lev+2,off+len, - "Worksheet section initial byte unknown value (ignored)"); - psiconv_debug(lev+2,off+len,"Initial byte: %02x",temp); - } - len ++; +int psiconv_parse_sheet_cell_layout(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_cell_layout *result) + +{ + int res=0; + int len=0; + int leng; + psiconv_u8 temp; + + psiconv_progress(lev+1,off,"Going to read a sheet cell layout"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + (*result)->character = NULL; + (*result)->paragraph = NULL; + (*result)->numberformat = NULL; + psiconv_progress(lev+2,off+len, - "Going to read the initial bytes (%02x expected)",0x02); + "Going to read the first byte (%02x expected)",0x02); temp = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) goto ERROR2; @@ -691,41 +819,96 @@ psiconv_progress(lev+3,off+len,"Going to read the default paragraph codes"); if ((res = psiconv_parse_paragraph_layout_list(buf,lev+3,off+len,&leng, (*result)->paragraph))) - goto ERROR2_1; + goto ERROR2; len += leng; } if (temp & 0x02) { psiconv_progress(lev+3,off+len,"Going to read the default character codes"); if (!((*result)->character = psiconv_basic_character_layout())) - goto ERROR2_1; + goto ERROR2; if ((res = psiconv_parse_character_layout_list(buf,lev+3,off+len,&leng, (*result)->character))) - goto ERROR2_2; + goto ERROR2; len += leng; } if (temp & 0x04) { -/* TODO: default number format */ - psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2_3; - len ++; - psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2_3; - len ++; - psiconv_read_u8(buf,lev+2,off+len,&res); - if (res) - goto ERROR2_3; - len ++; + psiconv_progress(lev+3,off+len, "Going to read the default number format"); + psiconv_parse_sheet_numberformat(buf,lev+3,off+len,&leng, + &(*result)->numberformat); + len += leng; } + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet cell layout (total length: %08x)", len); + + return 0; + +ERROR2: + psiconv_free_sheet_cell_layout(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of sheet cell layout failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + +int psiconv_parse_sheet_worksheet(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_worksheet *result) +{ + int res=0; + psiconv_u32 temp,cells_off,grid_off; + int len=0; + int leng; + + psiconv_progress(lev+1,off,"Going to read the sheet worksheet section"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len, + "Going to read the initial bytes (%02x expected)",0x04); + temp = psiconv_read_u8(buf,lev+2,off+len,&res); + if (res) + goto ERROR2; + if (temp != 0x04) { + psiconv_warn(lev+2,off+len, + "Worksheet 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; + psiconv_debug(lev+2,off+len,"Flags byte: %02x",temp); + (*result)->show_zeros = (temp & 0x01)?psiconv_bool_true:psiconv_bool_false; + if (temp & 0xfe) { + psiconv_warn(lev+2,off+len, + "Worksheet section flags byte unknown bits (ignored)"); + } + len ++; + + psiconv_progress(lev+2,off+len,"Going to read the default cell layout"); + if ((res = psiconv_parse_sheet_cell_layout(buf,lev+2,off+len,&leng, + &(*result)->default_layout))) + goto ERROR2; + len += leng; + 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); if (res) - goto ERROR2; + goto ERROR3; psiconv_debug(lev+2,off+len,"Offset: %04x",temp); len += 4; @@ -733,7 +916,7 @@ "Going to read the offset of the 2nd ??? Section"); temp = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) - goto ERROR2; + goto ERROR3; psiconv_debug(lev+2,off+len,"Offset: %04x",temp); len += 4; @@ -741,7 +924,7 @@ "Going to read the offset of the Cells List"); cells_off = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) - goto ERROR2; + goto ERROR3; psiconv_debug(lev+2,off+len,"Offset: %04x",cells_off); len += 4; @@ -749,7 +932,7 @@ "Going to read the offset of the Grid Section"); grid_off = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) - goto ERROR2; + goto ERROR3; psiconv_debug(lev+2,off+len,"Offset: %04x",grid_off); len += 4; @@ -757,14 +940,14 @@ "Going to read the offset of the 3rd ??? Section"); temp = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) - goto ERROR2; + goto ERROR3; psiconv_debug(lev+2,off+len,"Offset: %04x",temp); len += 4; psiconv_progress(lev+2,off+len,"Going to read the cells list"); if ((res = psiconv_parse_sheet_cell_list(buf,lev+2,cells_off,NULL, &(*result)->cells))) - goto ERROR2; + goto ERROR3; /* TODO: parse grid section */ @@ -776,14 +959,8 @@ "End of sheet worksheet section (total length: %08x)", len); return 0; -ERROR2_3: - psiconv_free_numberformat((*result)->numberformat); -ERROR2_2: - psiconv_free_character_layout((*result)->character); -ERROR2_1: - psiconv_free_paragraph_layout((*result)->paragraph); -goto ERROR2; - +ERROR3: + psiconv_free_sheet_cell_layout((*result)->default_layout); ERROR2: free (*result); ERROR1: