update dev300-m57
[ooovba.git] / lotuswordpro / source / filter / tocread.cxx
blob2e101ab6a5ac844566f05b79ed398d48f6dec53d
1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
4 * either of the following licenses
6 * - GNU Lesser General Public License Version 2.1
7 * - Sun Industry Standards Source License Version 1.1
9 * Sun Microsystems Inc., October, 2000
11 * GNU Lesser General Public License Version 2.1
12 * =============================================
13 * Copyright 2000 by Sun Microsystems, Inc.
14 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License version 2.1, as published by the Free Software Foundation.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
31 * Sun Industry Standards Source License Version 1.1
32 * =================================================
33 * The contents of this file are subject to the Sun Industry Standards
34 * Source License Version 1.1 (the "License"); You may not use this file
35 * except in compliance with the License. You may obtain a copy of the
36 * License at http://www.openoffice.org/license.html.
38 * Software provided under this License is provided on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
40 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
41 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
42 * See the License for the specific provisions governing your rights and
43 * obligations concerning the Software.
45 * The Initial Developer of the Original Code is: IBM Corporation
47 * Copyright: 2008 by IBM Corporation
49 * All Rights Reserved.
51 * Contributor(s): _______________________________________
54 ************************************************************************/
55 #include "first.hxx"
56 #include "assert.h"
57 namespace OpenStormBento
60 BenError
61 CBenTOCReader::ReadLabelAndTOC()
63 BenError Err;
65 unsigned long TOCOffset;
66 if ((Err = ReadLabel(&TOCOffset, &cTOCSize)) != BenErr_OK)
67 return Err;
69 if ((Err = cpContainer->SeekToPosition(TOCOffset)) != BenErr_OK)
70 return Err;
72 cpTOC = new BenByte[cTOCSize];
73 if ((Err = cpContainer->ReadKnownSize(cpTOC, cTOCSize)) != BenErr_OK)
74 return Err;
76 if ((Err = ReadTOC()) != BenErr_OK)
77 return Err;
79 return BenErr_OK;
82 BenError
83 CBenTOCReader::ReadLabel(unsigned long * pTOCOffset, unsigned long * pTOCSize)
85 // If seek fails, then probably because stream is smaller than
86 // BEN_LABEL_SIZE and thus can't be Bento container
87 BenError Err;
88 if ((Err = cpContainer->SeekFromEnd(-BEN_LABEL_SIZE)) != BenErr_OK)
89 return BenErr_NotBentoContainer;
91 BenByte Label[BEN_LABEL_SIZE];
92 if ((Err = cpContainer->ReadKnownSize(Label, BEN_LABEL_SIZE)) != BenErr_OK)
93 return Err;
95 if (memcmp(Label, gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) != 0)
96 if ((Err = SearchForLabel(Label)) != BenErr_OK)
97 return Err;
99 BenByte * pCurrLabel = Label + BEN_MAGIC_BYTES_SIZE;
101 BenWord Flags = UtGetIntelWord(pCurrLabel); pCurrLabel += 2; // Flags
102 // Newer files are 0x0101--indicates if big or little endian. Older
103 // files are 0x0 for flags
104 assert(Flags == 0x0101 || Flags == 0x0);
106 cBlockSize = UtGetIntelWord(pCurrLabel) * 1024; pCurrLabel += 2;
108 // Check major version
109 if (UtGetIntelWord(pCurrLabel) != BEN_CURR_MAJOR_VERSION)
110 return BenErr_UnknownBentoFormatVersion;
111 pCurrLabel += 2;
113 UtGetIntelWord(pCurrLabel); pCurrLabel += 2; // Minor version
115 *pTOCOffset = UtGetIntelDWord(pCurrLabel); pCurrLabel += 4;
116 *pTOCSize = UtGetIntelDWord(pCurrLabel);
118 assert(pCurrLabel + 4 == Label + BEN_LABEL_SIZE);
120 return BenErr_OK;
123 #define LABEL_READ_BUFFER_SIZE 500
124 #define MAX_SEARCH_AMOUNT 1024 * 1024
126 BenError
127 CBenTOCReader::SearchForLabel(BenByte * pLabel)
129 BenError Err;
131 unsigned long Length;
132 if ((Err = cpContainer->GetSize(&Length)) != BenErr_OK)
133 return Err;
135 // Always ready to check for MagicBytes from
136 // CurrOffset - BEN_MAGIC_BYTES_SIZE to CurrOffset - 1
137 unsigned long CurrOffset = Length - BEN_LABEL_SIZE + BEN_MAGIC_BYTES_SIZE -
140 char Buffer[LABEL_READ_BUFFER_SIZE];
142 unsigned long BufferStartOffset = Length; // Init to big value
144 while (CurrOffset >= BEN_MAGIC_BYTES_SIZE)
146 // Don't search backwards more than 1 meg
147 if (Length - CurrOffset > MAX_SEARCH_AMOUNT)
148 break;
150 unsigned long UsedBufferSize;
152 // If before beginning of buffer
153 if (CurrOffset - BEN_MAGIC_BYTES_SIZE < BufferStartOffset)
155 if (CurrOffset < LABEL_READ_BUFFER_SIZE)
156 UsedBufferSize = CurrOffset;
157 else UsedBufferSize = LABEL_READ_BUFFER_SIZE;
159 if ((Err = cpContainer->SeekToPosition(CurrOffset - UsedBufferSize))
160 != BenErr_OK)
161 return Err;
163 if ((Err = cpContainer->ReadKnownSize(Buffer, UsedBufferSize)) !=
164 BenErr_OK)
165 return Err;
167 BufferStartOffset = CurrOffset - UsedBufferSize;
170 if (memcmp(Buffer + (CurrOffset - BEN_MAGIC_BYTES_SIZE -
171 BufferStartOffset), gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) == 0)
173 if ((Err = cpContainer->SeekToPosition(CurrOffset -
174 BEN_MAGIC_BYTES_SIZE)) != BenErr_OK)
175 return Err;
177 return cpContainer->ReadKnownSize(pLabel, BEN_LABEL_SIZE);
180 --CurrOffset;
183 return BenErr_NotBentoContainer; // Didn't find magic bytes
186 BenError
187 CBenTOCReader::ReadTOC()
189 BenError Err;
190 BenByte LookAhead = GetCode();
191 BenGeneration Generation = 0;
193 // Read in all objects
194 while (LookAhead == BEN_NEW_OBJECT)
196 BenObjectID ObjectID;
197 if ((Err = GetDWord(&ObjectID)) != BenErr_OK)
198 return Err;
199 pCBenObject pObject = NULL;
201 // Read in all properties for object
204 BenObjectID PropertyID;
206 if ((Err = GetDWord(&PropertyID)) != BenErr_OK)
207 return Err;
208 pCBenProperty pProperty = NULL;
210 // Read in all values for property
213 BenObjectID ReferencedListID = 0;
215 BenObjectID TypeID;
216 if ((Err = GetDWord(&TypeID)) != BenErr_OK)
217 return Err;
218 LookAhead = GetCode();
220 if (LookAhead == BEN_EXPLICIT_GEN)
222 if ((Err = GetDWord(&Generation)) != BenErr_OK)
223 return Err;
224 LookAhead = GetCode();
227 if (LookAhead == BEN_REFERENCE_LIST_ID)
229 // Eat it, unless BENUTIL_SUPPORT turned on
230 if ((Err = GetDWord(&ReferencedListID)) != BenErr_OK)
231 return Err;
232 LookAhead = GetCode();
235 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME ||
236 PropertyID == BEN_PROPID_GLOBAL_TYPE_NAME)
238 // Read property or type name
240 if (pObject != NULL || TypeID != BEN_TYPEID_7_BIT_ASCII ||
241 LookAhead != BEN_OFFSET4_LEN4)
242 return BenErr_NamedObjectError;
244 BenContainerPos Pos;
245 unsigned long Length;
247 if ((Err = GetDWord(&Pos)) != BenErr_OK)
248 return Err;
249 if ((Err = GetDWord(&Length)) != BenErr_OK)
250 return Err;
251 LookAhead = GetCode();
253 if ((Err = cpContainer->SeekToPosition(Pos)) != BenErr_OK)
254 return Err;
256 #define STACK_BUFFER_SIZE 256
257 char sStackBuffer[STACK_BUFFER_SIZE];
258 char * sAllocBuffer;
259 char * sBuffer;
260 if (Length > STACK_BUFFER_SIZE)
262 sBuffer = new char[Length];
263 sAllocBuffer = sBuffer;
265 else
267 sBuffer = sStackBuffer;
268 sAllocBuffer = NULL;
271 if ((Err = cpContainer->ReadKnownSize(sBuffer, Length)) !=
272 BenErr_OK)
274 delete[] sAllocBuffer;
275 return Err;
278 pCBenNamedObjectListElmt pPrevNamedObjectListElmt;
279 if (FindNamedObject(cpContainer->GetNamedObjects(),
280 sBuffer, &pPrevNamedObjectListElmt) != NULL)
282 delete[] sAllocBuffer;
283 return BenErr_DuplicateName;
286 pCBenObject pPrevObject = (pCBenObject) cpContainer->
287 GetObjects()->GetLast();
289 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME)
290 pObject = new CBenPropertyName(cpContainer, ObjectID,
291 pPrevObject, sBuffer, pPrevNamedObjectListElmt);
292 else pObject = new CBenTypeName(cpContainer, ObjectID,
293 pPrevObject, sBuffer, pPrevNamedObjectListElmt);
295 delete[] sAllocBuffer;
297 // If BENUTIL_SUPPORT turned on, read in references object
298 // like regular object
299 #ifndef BENUTIL_SUPPORT
300 else if (PropertyID == BEN_PROPID_OBJ_REFERENCES)
302 // Don't need to read in references object--we assume
303 // that all references use object ID as key
304 if ((Err = ReadSegments(NULL, &LookAhead)) != BenErr_OK)
305 return Err;
307 #endif
308 else if (ObjectID == BEN_OBJID_TOC)
310 if (PropertyID == BEN_PROPID_TOC_SEED)
312 if (TypeID != BEN_TYPEID_TOC_TYPE ||
313 LookAhead != BEN_IMMEDIATE4)
314 return BenErr_TOCSeedError;
316 BenDWord Data;
317 if ((Err = GetDWord(&Data)) != BenErr_OK)
318 return Err;
319 LookAhead = GetCode();
321 cpContainer->SetNextAvailObjectID(Data);
323 else
325 // Ignore the other BEN_OBJID_TOC properties
326 if ((Err = ReadSegments(NULL, &LookAhead)) != BenErr_OK)
327 return Err;
330 else
332 if (pProperty != NULL)
333 return BenErr_PropertyWithMoreThanOneValue;
335 if (pObject == NULL)
336 pObject = new CBenObject(cpContainer, ObjectID,
337 (pCBenObject) cpContainer->GetObjects()->GetLast());
339 pProperty = new CBenProperty(pObject, PropertyID, TypeID,
340 (pCBenProperty) pObject->GetProperties()->GetLast());
342 #ifdef BENUTIL_SUPPORT
343 pProperty->UseValue()->
344 SetReferencedListObjectID(ReferencedListID);
345 #endif
347 if ((Err = ReadSegments(pProperty->UseValue(),
348 &LookAhead)) != BenErr_OK)
349 return Err;
351 } while (LookAhead == BEN_NEW_TYPE);
352 } while (LookAhead == BEN_NEW_PROPERTY);
355 if (LookAhead == BEN_READ_PAST_END_OF_TOC)
356 return BenErr_OK;
357 else return BenErr_InvalidTOC;
360 BenError
361 CBenTOCReader::ReadSegments(pCBenValue pValue, BenByte * pLookAhead)
363 BenError Err;
365 while (*pLookAhead >= BEN_SEGMENT_CODE_START &&
366 *pLookAhead <= BEN_SEGMENT_CODE_END)
368 if ((Err = ReadSegment(pValue, pLookAhead)) !=
369 BenErr_OK)
370 return Err;
373 return BenErr_OK;
376 BenError
377 CBenTOCReader::ReadSegment(pCBenValue pValue, BenByte * pLookAhead)
379 BenError Err;
381 UtBool Immediate = UT_FALSE;
382 UtBool EightByteOffset = UT_FALSE;
383 unsigned long Offset, Length;
385 switch (*pLookAhead)
387 case BEN_CONT_OFFSET4_LEN4:
388 case BEN_OFFSET4_LEN4:
389 if ((Err = GetDWord(&Offset)) != BenErr_OK)
390 return Err;
391 if ((Err = GetDWord(&Length)) != BenErr_OK)
392 return Err;
393 break;
395 case BEN_IMMEDIATE0:
396 Length = 0; Immediate = UT_TRUE;
397 break;
399 case BEN_IMMEDIATE1:
400 Length = 1; Immediate = UT_TRUE;
401 break;
403 case BEN_IMMEDIATE2:
404 Length = 2; Immediate = UT_TRUE;
405 break;
407 case BEN_IMMEDIATE3:
408 Length = 3; Immediate = UT_TRUE;
409 break;
411 case BEN_CONT_IMMEDIATE4:
412 case BEN_IMMEDIATE4:
413 Length = 4; Immediate = UT_TRUE;
414 break;
416 case BEN_CONT_OFFSET8_LEN4:
417 case BEN_OFFSET8_LEN4:
418 EightByteOffset = UT_TRUE;
419 break;
421 default:
422 return BenErr_OK;
425 BenByte ImmData[4];
426 if (Immediate && Length != 0)
427 if ((Err = GetData(ImmData, 4)) != BenErr_OK)
428 return Err;
430 *pLookAhead = GetCode();
432 if (EightByteOffset)
433 return BenErr_64BitOffsetNotSupported;
435 if (pValue != NULL)
437 if (! Immediate)
438 new CBenValueSegment(pValue, Offset, Length);
439 else if (Length != 0)
441 assert(Length <= 4);
442 new CBenValueSegment(pValue, ImmData, (unsigned short) Length);
446 return BenErr_OK;
449 UtBool
450 CBenTOCReader::CanGetData(unsigned long Amt)
452 return cCurr + Amt <= cTOCSize;
455 BenError
456 CBenTOCReader::GetByte(BenByte * pByte)
458 if (! CanGetData(1))
459 return BenErr_ReadPastEndOfTOC;
461 *pByte = UtGetIntelByte(cpTOC + cCurr);
462 ++cCurr;
463 return BenErr_OK;
466 BenError
467 CBenTOCReader::GetWord(BenWord * pWord)
469 if (! CanGetData(2))
470 return BenErr_ReadPastEndOfTOC;
472 *pWord = UtGetIntelWord(cpTOC + cCurr);
473 cCurr += 2;
474 return BenErr_OK;
477 BenError
478 CBenTOCReader::GetDWord(BenDWord * pDWord)
480 if (! CanGetData(4))
481 return BenErr_ReadPastEndOfTOC;
483 *pDWord = UtGetIntelDWord(cpTOC + cCurr);
484 cCurr += 4;
485 return BenErr_OK;
488 BenByte
489 CBenTOCReader::GetCode()
491 BenByte Code;
494 if (GetByte(&Code) != BenErr_OK)
495 return BEN_READ_PAST_END_OF_TOC;
497 if (Code == BEN_END_OF_BUFFER)
498 // Advance to next block
499 cCurr = cBlockSize * ((cCurr + (cBlockSize - 1)) /
500 cBlockSize);
502 while (Code == BEN_NOOP || Code == BEN_END_OF_BUFFER);
503 return Code;
506 BenError
507 CBenTOCReader::GetData(BenDataPtr pBuffer, unsigned long Amt)
509 if (! CanGetData(Amt))
510 return BenErr_ReadPastEndOfTOC;
512 UtHugeMemcpy(pBuffer, cpTOC + cCurr, Amt);
513 cCurr += Amt;
514 return BenErr_OK;
516 }//end OpenStormBento namespace