Commit 3083f162 authored by Michael Meeks's avatar Michael Meeks
Browse files

Fixed embarassing bug in OLE creation,

parent a114259c
......@@ -5,6 +5,11 @@
(dump): Removed spurious #undefs
(ms_ole_write_bb, ms_ole_write_sb): Fixed for mid-stream
writes.
(next_free_bb): Limit extension to 10 blocks.
Fix sillyness in UNUSED_BLOCK setting.
(ms_ole_create): Fix killer stupid bug ! setting whole map to
END_OF_CHAIN instead of UNUSED_BLOCK ! idiot !
Correctly terminated the root directory chain.
* ms-ole.h (struct _MS_OLE_STREAM): Add tell method, and fix
broken comments.
......
......@@ -18,7 +18,7 @@
/* Implementational detail - not for global header */
#define OLE_DEBUG 1
#define OLE_DEBUG 0
/* These take a _guint8_ pointer */
#define GET_GUINT8(p) (*((const guint8 *)(p)+0))
......@@ -314,6 +314,25 @@ dump_allocation (MS_OLE *f)
}
}
/* Things that should be true */
static void
check (MS_OLE *f)
{
guint32 numbbd = GET_NUM_BBD_BLOCKS(f);
guint32 maxbb = numbbd*(BB_BLOCK_SIZE/sizeof(BBPtr));
guint32 lp;
for (lp=NUM_BB(f);lp<maxbb;lp++) {
BBPtr blk = GET_GUINT32(GET_BB_CHAIN_PTR(f,lp));
if (blk != UNUSED_BLOCK) {
printf ("Serious blocking error\n");
dump_allocation (f);
g_on_error_stack_trace (NULL);
}
}
}
/* Create a nice linear array and return count of the number in the array */
static GArray *
read_link_array (MS_OLE *f, BBPtr first)
......@@ -384,6 +403,7 @@ ms_ole_analyse (MS_OLE *f)
}
}
#endif
check (f);
return 1;
}
......@@ -468,8 +488,9 @@ ms_ole_create (const char *name)
/* the first BBD block : 1 */
for (lp=0;lp<BB_BLOCK_SIZE/4;lp++)
SET_GUINT32(GET_BB_START_PTR(f,1) + lp*4, END_OF_CHAIN);
SET_GUINT32(GET_BB_START_PTR(f,1) + lp*4, UNUSED_BLOCK);
SET_GUINT32(GET_BB_CHAIN_PTR(f,0), END_OF_CHAIN); /* Root chain */
SET_GUINT32(GET_BB_CHAIN_PTR(f,1), SPECIAL_BLOCK); /* Itself */
SET_GUINT32(GET_BB_CHAIN_PTR(f,2), END_OF_CHAIN); /* SBD chain */
SET_GUINT32(GET_BB_CHAIN_PTR(f,3), END_OF_CHAIN); /* SBF stream */
......@@ -481,6 +502,7 @@ ms_ole_create (const char *name)
SET_SBD_STARTBLOCK (f, f->header.sbd_startblock);
read_root_list (f);
/* The first PPS block : 0 */
lp = 0;
......@@ -522,6 +544,7 @@ ms_ole_create (const char *name)
return 0;
}
check (f);
return f;
}
......@@ -682,22 +705,30 @@ next_free_bb (MS_OLE *f)
blk = 0;
while (blk < NUM_BB(f))
if (GET_GUINT32(GET_BB_CHAIN_PTR(f,blk)) == UNUSED_BLOCK)
if (GET_GUINT32(GET_BB_CHAIN_PTR(f,blk)) == UNUSED_BLOCK) {
check (f);
return blk;
else
} else
blk++;
check (f);
if (blk < GET_NUM_BBD_BLOCKS(f)*(BB_BLOCK_SIZE/sizeof(BBPtr))) {
/* Must not extend beyond our capability to describe the state of each block */
gint32 extblks = GET_NUM_BBD_BLOCKS(f)*(BB_BLOCK_SIZE/sizeof(BBPtr)) - NUM_BB(f);
/* Extend and remap file */
//#if OLE_DEBUG > 0
printf ("Extend & remap file by %d blocks...\n", extblks);
//#endif
BBPtr tmpblk;
if (extblks > 10) /* Silly */
extblks = 10;
#if OLE_DEBUG > 0
printf ("Extend & remap file by %d blocks (%d, %d)...\n", extblks,
GET_NUM_BBD_BLOCKS(f), NUM_BB(f));
#endif
g_assert (extblks>0);
/* Extend and remap file */
extend_file (f, extblks);
g_assert (blk < NUM_BB(f));
g_assert (GET_GUINT32(GET_BB_CHAIN_PTR(f,blk)) == UNUSED_BLOCK);
check (f);
tmpblk = GET_GUINT32(GET_BB_CHAIN_PTR(f,blk));
g_assert (tmpblk==UNUSED_BLOCK);
return blk;
}
......@@ -710,13 +741,14 @@ next_free_bb (MS_OLE *f)
SET_BBD_LIST(f, idx, blk);
SET_NUM_BBD_BLOCKS(f, idx+1);
/* Setup that block */
for (lp=0;lp<(BB_BLOCK_SIZE/sizeof(BBPtr))-1;lp++)
for (lp=0;lp<(BB_BLOCK_SIZE/sizeof(BBPtr));lp++)
SET_GUINT32(GET_BB_START_PTR(f, blk) + lp*sizeof(BBPtr), UNUSED_BLOCK);
SET_GUINT32(GET_BB_CHAIN_PTR(f, blk), SPECIAL_BLOCK); /* blk is the new BBD item */
#if OLE_DEBUG > 1
printf ("Should be 10 more free blocks at least !\n");
dump_allocation(f);
#endif
check (f);
return next_free_bb (f);
}
......
......@@ -214,19 +214,47 @@ biff_boundsheet_write_last (MS_OLE_STREAM *s, guint32 pos,
s->lseek (s, oldpos, MS_OLE_SEEK_SET);
}
typedef struct {
SHEET *sheet;
BIFF_PUT *bp;
} CellArgs;
static void
write_cell (gpointer key, Cell *cell, CellArgs *a)
{
BIFF_PUT *bp = a->bp;
g_return_if_fail (a);
g_return_if_fail (cell);
if (cell->value && VALUE_IS_NUMBER (cell->value)) {
guint8 *data;
data = ms_biff_put_len_next (bp, BIFF_NUMBER, 14);
EX_SETROW(bp, cell->row->pos);
EX_SETCOL(bp, cell->col->pos);
EX_SETXF (bp, 0);
BIFF_SETDOUBLE (bp->data + 6,
value_get_as_float (cell->value));
ms_biff_put_len_commit (bp);
}
}
static void
write_sheet (BIFF_PUT *bp, SHEET *sheet)
{
guint8 *data;
sheet->streamPos = bp->streamPos; /* (?) */
CellArgs args;
sheet->streamPos = bp->streamPos;
args.sheet = sheet;
args.bp = bp;
biff_bof_write (bp, sheet->wb->ver, eBiffTWorksheet);
data = ms_biff_put_len_next (bp, BIFF_NUMBER, 14);
EX_SETROW(bp, 0);
EX_SETCOL(bp, 0);
EX_SETXF (bp, 0);
BIFF_SETDOUBLE (bp->data + 6, 1.2345678);
ms_biff_put_len_commit (bp);
/* FIXME: INDEX, UG! see S59D99.HTM */
/* Finding cell records in Biff files see: S59E28.HTM */
g_hash_table_foreach (sheet->gnum_sheet->cell_hash,
(GHFunc)write_cell, &args);
biff_eof_write (bp);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment