--- psiconv/trunk/lib/psiconv/parse_sheet.c 2001/07/01 12:01:59 120 +++ psiconv/trunk/lib/psiconv/parse_sheet.c 2001/07/18 12:24:08 128 @@ -25,23 +25,72 @@ #include "parse_routines.h" #include "error.h" +static psiconv_sheet_cell_layout psiconv_basic_cell_layout(void) +{ + psiconv_sheet_cell_layout result; + if (!(result = malloc(sizeof(*result)))) + goto ERROR1; + if (!(result->character = psiconv_basic_character_layout())) + goto ERROR2; + if (!(result->paragraph = psiconv_basic_paragraph_layout())) + goto ERROR3; + if (!(result->numberformat = malloc(sizeof(*result->numberformat)))) + goto ERROR4; + result->numberformat->code = psiconv_numberformat_general; + result->numberformat->decimal = 2; + return result; +ERROR4: + psiconv_free_paragraph_layout(result->paragraph); +ERROR3: + psiconv_free_character_layout(result->character); +ERROR2: + free(result); +ERROR1: + return NULL; +} + +static psiconv_sheet_cell_layout psiconv_clone_cell_layout + (psiconv_sheet_cell_layout original) +{ + psiconv_sheet_cell_layout result; + if (!(result = malloc(sizeof(*result)))) + goto ERROR1; + if (!(result->character = + psiconv_clone_character_layout(original->character))) + goto ERROR2; + if (!(result->paragraph = + psiconv_clone_paragraph_layout(original->paragraph))) + goto ERROR3; + if (!(result->numberformat = malloc(sizeof(*result->numberformat)))) + goto ERROR4; + result->numberformat->code = original->numberformat->code; + result->numberformat->decimal = original->numberformat->decimal; + return result; +ERROR4: + psiconv_free_paragraph_layout(result->paragraph); +ERROR3: + psiconv_free_character_layout(result->character); +ERROR2: + free(result); +ERROR1: + return NULL; +} + int psiconv_parse_sheet_numberformat(const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, - psiconv_sheet_numberformat *result) + 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; + goto ERROR1; if (temp != 0x02) { psiconv_warn(lev+2,off+len, "Sheet numberformat initial byte unknown value (ignored)"); @@ -52,81 +101,81 @@ 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; + goto ERROR1; psiconv_debug(lev+2,off+len,"Code: %02x",temp); if (temp == 0x00) - (*result)->code = psiconv_numberformat_general; + result->code = psiconv_numberformat_general; else if (temp == 0x02) - (*result)->code = psiconv_numberformat_fixeddecimal; + result->code = psiconv_numberformat_fixeddecimal; else if (temp == 0x04) - (*result)->code = psiconv_numberformat_scientific; + result->code = psiconv_numberformat_scientific; else if (temp == 0x06) - (*result)->code = psiconv_numberformat_currency; + result->code = psiconv_numberformat_currency; else if (temp == 0x08) - (*result)->code = psiconv_numberformat_percent; + result->code = psiconv_numberformat_percent; else if (temp == 0x0A) - (*result)->code = psiconv_numberformat_triads; + result->code = psiconv_numberformat_triads; else if (temp == 0x0C) - (*result)->code = psiconv_numberformat_boolean; + result->code = psiconv_numberformat_boolean; else if (temp == 0x0E) - (*result)->code = psiconv_numberformat_text; + result->code = psiconv_numberformat_text; else if (temp == 0x10) - (*result)->code = psiconv_numberformat_date_ddmm; + result->code = psiconv_numberformat_date_dmm; else if (temp == 0x12) - (*result)->code = psiconv_numberformat_date_mmdd; + result->code = psiconv_numberformat_date_mmd; else if (temp == 0x14) - (*result)->code = psiconv_numberformat_date_ddmmyy; + result->code = psiconv_numberformat_date_ddmmyy; else if (temp == 0x16) - (*result)->code = psiconv_numberformat_date_mmddyy; + result->code = psiconv_numberformat_date_mmddyy; else if (temp == 0x18) - (*result)->code = psiconv_numberformat_date_yymmdd; + result->code = psiconv_numberformat_date_yymmdd; else if (temp == 0x1A) - (*result)->code = psiconv_numberformat_date_ddmmm; + result->code = psiconv_numberformat_date_dmmm; else if (temp == 0x1C) - (*result)->code = psiconv_numberformat_date_ddmmmyy; + result->code = psiconv_numberformat_date_dmmmyy; else if (temp == 0x1E) - (*result)->code = psiconv_numberformat_date_ddmmmyyyy; + result->code = psiconv_numberformat_date_ddmmmyy; else if (temp == 0x20) - (*result)->code = psiconv_numberformat_date_mmm; + result->code = psiconv_numberformat_date_mmm; else if (temp == 0x22) - (*result)->code = psiconv_numberformat_date_monthname; + result->code = psiconv_numberformat_date_monthname; else if (temp == 0x24) - (*result)->code = psiconv_numberformat_date_mmmyy; + result->code = psiconv_numberformat_date_mmmyy; else if (temp == 0x26) - (*result)->code = psiconv_numberformat_date_monthnameyy; + result->code = psiconv_numberformat_date_monthnameyy; else if (temp == 0x28) - (*result)->code = psiconv_numberformat_date_monthnameddyyyy; + result->code = psiconv_numberformat_date_monthnamedyyyy; else if (temp == 0x2A) - (*result)->code = psiconv_numberformat_datetime_ddmmyyyyhhii; + result->code = psiconv_numberformat_datetime_ddmmyyyyhhii; else if (temp == 0x2C) - (*result)->code = psiconv_numberformat_datetime_ddmmyyyyHHii; + result->code = psiconv_numberformat_datetime_ddmmyyyyHHii; else if (temp == 0x2E) - (*result)->code = psiconv_numberformat_datetime_mmddyyyyhhii; + result->code = psiconv_numberformat_datetime_mmddyyyyhhii; else if (temp == 0x30) - (*result)->code = psiconv_numberformat_datetime_mmddyyyyHHii; + result->code = psiconv_numberformat_datetime_mmddyyyyHHii; else if (temp == 0x32) - (*result)->code = psiconv_numberformat_datetime_yyyymmddhhii; + result->code = psiconv_numberformat_datetime_yyyymmddhhii; else if (temp == 0x34) - (*result)->code = psiconv_numberformat_datetime_yyyymmddHHii; + result->code = psiconv_numberformat_datetime_yyyymmddHHii; else if (temp == 0x36) - (*result)->code = psiconv_numberformat_time_hhii; + result->code = psiconv_numberformat_time_hhii; else if (temp == 0x38) - (*result)->code = psiconv_numberformat_time_hhiiss; + result->code = psiconv_numberformat_time_hhiiss; else if (temp == 0x3A) - (*result)->code = psiconv_numberformat_time_HHii; + result->code = psiconv_numberformat_time_HHii; else if (temp == 0x3C) - (*result)->code = psiconv_numberformat_time_HHiiss; + result->code = psiconv_numberformat_time_HHiiss; else { psiconv_warn(lev+2,off+len,"Unknown number format (assumed general)"); - (*result)->code = psiconv_numberformat_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); + result->decimal = psiconv_read_u8(buf,lev+2,off+len,&res) >> 1; if (res) - goto ERROR2; - psiconv_debug(lev+2,off+len,"Decimals: %d",(*result)->decimal); + goto ERROR1; + psiconv_debug(lev+2,off+len,"Decimals: %d",result->decimal); len ++; if (length) @@ -136,8 +185,6 @@ "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) @@ -458,8 +505,11 @@ } int psiconv_parse_sheet_cell(const psiconv_buffer buf, int lev, - psiconv_u32 off, int *length, - psiconv_sheet_cell *result) + psiconv_u32 off, int *length, + psiconv_sheet_cell *result, + const psiconv_sheet_cell_layout default_layout, + const psiconv_sheet_line_list row_default_layouts, + const psiconv_sheet_line_list col_default_layouts) { int res=0; int len=0; @@ -576,9 +626,16 @@ goto ERROR2; } + if (!((*result)->layout = psiconv_clone_cell_layout( + psiconv_get_default_layout(row_default_layouts, + col_default_layouts, + default_layout, + (*result)->row, + (*result)->column)))) + goto ERROR2; if (has_layout) { if ((res = psiconv_parse_sheet_cell_layout(buf,lev+2,off+len, - &leng,&(*result)->layout))) + &leng,(*result)->layout))) goto ERROR2; len += leng; } @@ -613,8 +670,11 @@ } int psiconv_parse_sheet_cell_list(const psiconv_buffer buf, int lev, - psiconv_u32 off, int *length, - psiconv_sheet_cell_list *result) + psiconv_u32 off, int *length, + psiconv_sheet_cell_list *result, + const psiconv_sheet_cell_layout default_layout, + const psiconv_sheet_line_list row_default_layouts, + const psiconv_sheet_line_list col_default_layouts) { int res=0; int len=0; @@ -662,7 +722,9 @@ psiconv_progress(lev+2,off+len,"Going to read all cells"); for (i = 0; i < listlen; i++) { psiconv_progress(lev+3,off+len,"Going to read cell %d",i); - if ((res = psiconv_parse_sheet_cell(buf,lev+3,off+len,&leng,&cell))) + if ((res = psiconv_parse_sheet_cell(buf,lev+3,off+len,&leng,&cell, + default_layout,row_default_layouts, + col_default_layouts))) goto ERROR2; if ((res = psiconv_list_add(*result,cell))) goto ERROR3; @@ -780,7 +842,7 @@ int psiconv_parse_sheet_cell_layout(const psiconv_buffer buf, int lev, psiconv_u32 off, int *length, - psiconv_sheet_cell_layout *result) + psiconv_sheet_cell_layout result) { int res=0; @@ -789,18 +851,12 @@ 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 first byte (%02x expected)",0x02); temp = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) - goto ERROR2; + goto ERROR1; if (temp != 0x02) { psiconv_warn(lev+2,off+len, "Worksheet section initial byte unknown value (ignored)"); @@ -811,33 +867,29 @@ psiconv_progress(lev+2,off+len,"Going to read the default formats flag"); temp = psiconv_read_u8(buf,lev+2,off+len,&res); if (res) - goto ERROR2; + goto ERROR1; len ++; if (temp & 0x01) { - if (!((*result)->paragraph = psiconv_basic_paragraph_layout())) - goto ERROR2; 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; + result->paragraph))) + goto ERROR1; 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; if ((res = psiconv_parse_character_layout_list(buf,lev+3,off+len,&leng, - (*result)->character))) - goto ERROR2; + result->character))) + goto ERROR1; len += leng; } if (temp & 0x04) { 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); + result->numberformat); len += leng; } @@ -849,8 +901,6 @@ return 0; -ERROR2: - psiconv_free_sheet_cell_layout(*result); ERROR1: psiconv_warn(lev+1,off,"Reading of sheet cell layout failed"); if (length) @@ -867,7 +917,7 @@ psiconv_sheet_worksheet *result) { int res=0; - psiconv_u32 temp,cells_off,grid_off; + psiconv_u32 temp,cells_off,grid_off,rows_off,cols_off; int len=0; int leng; @@ -900,25 +950,27 @@ 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))) + if (!((*result)->default_layout = psiconv_basic_cell_layout())) goto ERROR2; + if ((res = psiconv_parse_sheet_cell_layout(buf,lev+2,off+len,&leng, + (*result)->default_layout))) + goto ERROR3; 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); + "Going to read the offset of the row defaults Section"); + rows_off = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) goto ERROR3; - psiconv_debug(lev+2,off+len,"Offset: %04x",temp); + psiconv_debug(lev+2,off+len,"Offset: %04x",rows_off); len += 4; psiconv_progress(lev+2,off+len, - "Going to read the offset of the 2nd ??? Section"); - temp = psiconv_read_u32(buf,lev+2,off+len,&res); + "Going to read the offset of the column defaults Section"); + cols_off = psiconv_read_u32(buf,lev+2,off+len,&res); if (res) goto ERROR3; - psiconv_debug(lev+2,off+len,"Offset: %04x",temp); + psiconv_debug(lev+2,off+len,"Offset: %04x",cols_off); len += 4; psiconv_progress(lev+2,off+len, @@ -945,10 +997,25 @@ psiconv_debug(lev+2,off+len,"Offset: %04x",temp); len += 4; + psiconv_progress(lev+2,off+len,"Going to read the row defaults"); + if ((res = psiconv_parse_sheet_line_list(buf,lev+2,rows_off,NULL, + &(*result)->row_default_layouts, + (*result)->default_layout))) + goto ERROR3; + + psiconv_progress(lev+2,off+len,"Going to read the column defaults"); + if ((res = psiconv_parse_sheet_line_list(buf,lev+2,cols_off,NULL, + &(*result)->col_default_layouts, + (*result)->default_layout))) + goto ERROR4; + 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 ERROR3; + &(*result)->cells, + (*result)->default_layout, + (*result)->row_default_layouts, + (*result)->col_default_layouts))) + goto ERROR5; /* TODO: parse grid section */ @@ -960,6 +1027,10 @@ "End of sheet worksheet section (total length: %08x)", len); return 0; +ERROR5: + psiconv_free_sheet_line_list((*result)->col_default_layouts); +ERROR4: + psiconv_free_sheet_line_list((*result)->row_default_layouts); ERROR3: psiconv_free_sheet_cell_layout((*result)->default_layout); ERROR2: @@ -974,4 +1045,122 @@ return res; } +int psiconv_parse_sheet_line(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_line *result, + const psiconv_sheet_cell_layout default_layout) +{ + int res=0; + int len=0; + int leng; + + + psiconv_progress(lev+1,off,"Going to read a sheet line"); + if (!(*result = malloc(sizeof(**result)))) + goto ERROR1; + + psiconv_progress(lev+2,off+len,"Going to read the line number"); + (*result)->position = psiconv_read_X(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Line number: %d\n",(*result)->position); + len += leng; + + if (!((*result)->layout = psiconv_clone_cell_layout(default_layout))) + goto ERROR2; + if ((res = psiconv_parse_sheet_cell_layout(buf,lev+2,off+len, + &leng,(*result)->layout))) + goto ERROR3; + len += leng; + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of the sheet line (total length: %08x)", len); + return 0; + +ERROR3: + psiconv_free_sheet_cell_layout((*result)->layout); +ERROR2: + free (*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of the sheet line failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +} + + +int psiconv_parse_sheet_line_list(const psiconv_buffer buf, int lev, + psiconv_u32 off, int *length, + psiconv_sheet_line_list *result, + const psiconv_sheet_cell_layout default_layout) +{ + int res=0; + int len=0; + psiconv_u32 temp; + psiconv_sheet_line line; + psiconv_u32 listlen,i; + int leng; + + psiconv_progress(lev+1,off,"Going to read the sheet line list"); + if (!(*result = psiconv_list_new(sizeof(struct psiconv_sheet_line_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 line 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 defined lines"); + listlen = psiconv_read_X(buf,lev+2,off+len,&leng,&res); + if (res) + goto ERROR2; + psiconv_debug(lev+2,off+len,"Number of defined lines: %d",listlen); + len += leng; + + psiconv_progress(lev+2,off+len,"Going to read all lines"); + for (i = 0; i < listlen; i++) { + psiconv_progress(lev+3,off+len,"Going to read line %d",i); + if ((res = psiconv_parse_sheet_line(buf,lev+3,off+len,&leng,&line, + default_layout))) + goto ERROR2; + if ((res = psiconv_list_add(*result,line))) + goto ERROR3; + free(line); + len += leng; + } + + if (length) + *length = len; + + psiconv_progress(lev,off+len-1, + "End of sheet line list (total length: %08x)", len); + return 0; + +ERROR3: + psiconv_free_sheet_line(line); +ERROR2: + psiconv_free_sheet_line_list(*result); +ERROR1: + psiconv_warn(lev+1,off,"Reading of Sheet Line List failed"); + if (length) + *length = 0; + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +}