fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / lotuswordpro / source / filter / tocread.cxx
blob135281abcde7aaae64c49bf0932df2e33ea80631
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 #include "first.hxx"
57 #include "assert.h"
58 namespace OpenStormBento
61 BenError
62 CBenTOCReader::ReadLabelAndTOC()
64 BenError Err;
66 unsigned long TOCOffset;
67 if ((Err = ReadLabel(&TOCOffset, &cTOCSize)) != BenErr_OK)
68 return Err;
70 sal_uLong nLength;
71 if ((Err = cpContainer->GetSize(&nLength)) != BenErr_OK)
72 return Err;
74 if (TOCOffset > nLength)
75 return BenErr_ReadPastEndOfTOC;
77 if (cTOCSize > nLength - TOCOffset)
78 return BenErr_ReadPastEndOfTOC;
80 if ((Err = cpContainer->SeekToPosition(TOCOffset)) != BenErr_OK)
81 return Err;
83 cpTOC = new BenByte[cTOCSize];
84 if ((Err = cpContainer->ReadKnownSize(cpTOC, cTOCSize)) != BenErr_OK)
85 return Err;
87 if ((Err = ReadTOC()) != BenErr_OK)
88 return Err;
90 return BenErr_OK;
93 BenError
94 CBenTOCReader::ReadLabel(unsigned long * pTOCOffset, unsigned long * pTOCSize)
96 // If seek fails, then probably because stream is smaller than
97 // BEN_LABEL_SIZE and thus can't be Bento container
98 BenError Err;
99 if ((Err = cpContainer->SeekFromEnd(-BEN_LABEL_SIZE)) != BenErr_OK)
100 return BenErr_NotBentoContainer;
102 BenByte Label[BEN_LABEL_SIZE];
103 if ((Err = cpContainer->ReadKnownSize(Label, BEN_LABEL_SIZE)) != BenErr_OK)
104 return Err;
106 if (memcmp(Label, gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) != 0)
107 if ((Err = SearchForLabel(Label)) != BenErr_OK)
108 return Err;
110 BenByte * pCurrLabel = Label + BEN_MAGIC_BYTES_SIZE;
112 #ifndef NDEBUG
113 BenWord Flags =
114 #endif
115 UtGetIntelWord(pCurrLabel); pCurrLabel += 2; // Flags
116 // Newer files are 0x0101--indicates if big or little endian. Older
117 // files are 0x0 for flags
118 assert(Flags == 0x0101 || Flags == 0x0);
120 cBlockSize = UtGetIntelWord(pCurrLabel) * 1024; pCurrLabel += 2;
122 // Check major version
123 if (UtGetIntelWord(pCurrLabel) != BEN_CURR_MAJOR_VERSION)
124 return BenErr_UnknownBentoFormatVersion;
125 pCurrLabel += 2;
127 pCurrLabel += 2; // Minor version
129 *pTOCOffset = UtGetIntelDWord(pCurrLabel); pCurrLabel += 4;
130 *pTOCSize = UtGetIntelDWord(pCurrLabel);
132 assert(pCurrLabel + 4 == Label + BEN_LABEL_SIZE);
134 return BenErr_OK;
137 #define LABEL_READ_BUFFER_SIZE 500
138 #define MAX_SEARCH_AMOUNT 1024 * 1024
140 BenError
141 CBenTOCReader::SearchForLabel(BenByte * pLabel)
143 BenError Err;
145 sal_uLong Length;
146 if ((Err = cpContainer->GetSize(&Length)) != BenErr_OK)
147 return Err;
149 // Always ready to check for MagicBytes from
150 // CurrOffset - BEN_MAGIC_BYTES_SIZE to CurrOffset - 1
151 unsigned long CurrOffset = Length - BEN_LABEL_SIZE + BEN_MAGIC_BYTES_SIZE -
154 char Buffer[LABEL_READ_BUFFER_SIZE] = {0};
156 unsigned long BufferStartOffset = Length; // Init to big value
158 while (CurrOffset >= BEN_MAGIC_BYTES_SIZE)
160 // Don't search backwards more than 1 meg
161 if (Length - CurrOffset > MAX_SEARCH_AMOUNT)
162 break;
164 // If before beginning of buffer
165 if (CurrOffset - BEN_MAGIC_BYTES_SIZE < BufferStartOffset)
167 unsigned long UsedBufferSize;
168 if (CurrOffset < LABEL_READ_BUFFER_SIZE)
169 UsedBufferSize = CurrOffset;
170 else UsedBufferSize = LABEL_READ_BUFFER_SIZE;
172 if ((Err = cpContainer->SeekToPosition(CurrOffset - UsedBufferSize))
173 != BenErr_OK)
174 return Err;
176 if ((Err = cpContainer->ReadKnownSize(Buffer, UsedBufferSize)) !=
177 BenErr_OK)
178 return Err;
180 BufferStartOffset = CurrOffset - UsedBufferSize;
183 if (memcmp(Buffer + (CurrOffset - BEN_MAGIC_BYTES_SIZE -
184 BufferStartOffset), gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) == 0)
186 if ((Err = cpContainer->SeekToPosition(CurrOffset -
187 BEN_MAGIC_BYTES_SIZE)) != BenErr_OK)
188 return Err;
190 return cpContainer->ReadKnownSize(pLabel, BEN_LABEL_SIZE);
193 --CurrOffset;
196 return BenErr_NotBentoContainer; // Didn't find magic bytes
199 BenError
200 CBenTOCReader::ReadTOC()
202 BenError Err;
203 BenByte LookAhead = GetCode();
204 BenGeneration Generation = 0;
206 // Read in all objects
207 while (LookAhead == BEN_NEW_OBJECT)
209 BenObjectID ObjectID;
210 if ((Err = GetDWord(&ObjectID)) != BenErr_OK)
211 return Err;
212 pCBenObject pObject = NULL;
214 // Read in all properties for object
217 BenObjectID PropertyID;
219 if ((Err = GetDWord(&PropertyID)) != BenErr_OK)
220 return Err;
221 pCBenProperty pProperty = NULL;
223 // Read in all values for property
226 BenObjectID ReferencedListID = 0;
228 BenObjectID TypeID;
229 if ((Err = GetDWord(&TypeID)) != BenErr_OK)
230 return Err;
231 LookAhead = GetCode();
233 if (LookAhead == BEN_EXPLICIT_GEN)
235 if ((Err = GetDWord(&Generation)) != BenErr_OK)
236 return Err;
237 LookAhead = GetCode();
240 if (LookAhead == BEN_REFERENCE_LIST_ID)
242 if ((Err = GetDWord(&ReferencedListID)) != BenErr_OK)
243 return Err;
244 LookAhead = GetCode();
247 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME ||
248 PropertyID == BEN_PROPID_GLOBAL_TYPE_NAME)
250 // Read property or type name
252 if (pObject != NULL || TypeID != BEN_TYPEID_7_BIT_ASCII ||
253 LookAhead != BEN_OFFSET4_LEN4)
254 return BenErr_NamedObjectError;
256 BenContainerPos Pos;
257 unsigned long Length;
259 if ((Err = GetDWord(&Pos)) != BenErr_OK)
260 return Err;
261 if ((Err = GetDWord(&Length)) != BenErr_OK)
262 return Err;
263 LookAhead = GetCode();
265 if ((Err = cpContainer->SeekToPosition(Pos)) != BenErr_OK)
266 return Err;
268 #define STACK_BUFFER_SIZE 256
269 char sStackBuffer[STACK_BUFFER_SIZE];
270 char * sAllocBuffer;
271 char * sBuffer;
272 if (Length > STACK_BUFFER_SIZE)
274 sBuffer = new char[Length];
275 sAllocBuffer = sBuffer;
277 else
279 sBuffer = sStackBuffer;
280 sAllocBuffer = NULL;
283 if ((Err = cpContainer->ReadKnownSize(sBuffer, Length)) !=
284 BenErr_OK)
286 delete[] sAllocBuffer;
287 return Err;
290 pCUtListElmt pPrevNamedObjectListElmt;
291 if (FindNamedObject(&cpContainer->GetNamedObjects(),
292 sBuffer, &pPrevNamedObjectListElmt) != NULL)
294 delete[] sAllocBuffer;
295 return BenErr_DuplicateName;
298 pCBenObject pPrevObject = static_cast<pCBenObject>( cpContainer->
299 GetObjects().GetLast());
301 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME)
302 pObject = new CBenPropertyName(cpContainer, ObjectID,
303 pPrevObject, sBuffer, pPrevNamedObjectListElmt);
304 else pObject = new CBenTypeName(cpContainer, ObjectID,
305 pPrevObject, sBuffer, pPrevNamedObjectListElmt);
307 delete[] sAllocBuffer;
309 else if (PropertyID == BEN_PROPID_OBJ_REFERENCES)
311 // Don't need to read in references object--we assume
312 // that all references use object ID as key
313 if ((Err = ReadSegments(NULL, &LookAhead)) != BenErr_OK)
314 return Err;
316 else if (ObjectID == BEN_OBJID_TOC)
318 if (PropertyID == BEN_PROPID_TOC_SEED)
320 if (TypeID != BEN_TYPEID_TOC_TYPE ||
321 LookAhead != BEN_IMMEDIATE4)
322 return BenErr_TOCSeedError;
324 BenDWord Data;
325 if ((Err = GetDWord(&Data)) != BenErr_OK)
326 return Err;
327 LookAhead = GetCode();
329 cpContainer->SetNextAvailObjectID(Data);
331 else
333 // Ignore the other BEN_OBJID_TOC properties
334 if ((Err = ReadSegments(NULL, &LookAhead)) != BenErr_OK)
335 return Err;
338 else
340 if (pProperty != NULL)
341 return BenErr_PropertyWithMoreThanOneValue;
343 if (pObject == NULL)
344 pObject = new CBenObject(cpContainer, ObjectID,
345 cpContainer->GetObjects().GetLast());
347 pProperty = new CBenProperty(pObject, PropertyID, TypeID,
348 pObject->GetProperties().GetLast());
350 if ((Err = ReadSegments(&pProperty->UseValue(),
351 &LookAhead)) != BenErr_OK)
352 return Err;
354 } while (LookAhead == BEN_NEW_TYPE);
355 } while (LookAhead == BEN_NEW_PROPERTY);
358 if (LookAhead == BEN_READ_PAST_END_OF_TOC)
359 return BenErr_OK;
360 else return BenErr_InvalidTOC;
363 BenError
364 CBenTOCReader::ReadSegments(pCBenValue pValue, BenByte * pLookAhead)
366 BenError Err;
368 while (*pLookAhead >= BEN_SEGMENT_CODE_START &&
369 *pLookAhead <= BEN_SEGMENT_CODE_END)
371 if ((Err = ReadSegment(pValue, pLookAhead)) !=
372 BenErr_OK)
373 return Err;
376 return BenErr_OK;
379 BenError
380 CBenTOCReader::ReadSegment(pCBenValue pValue, BenByte * pLookAhead)
382 BenError Err;
384 bool Immediate = false;
385 bool EightByteOffset = false;
386 unsigned long Offset(0), Length(0);
388 switch (*pLookAhead)
390 case BEN_CONT_OFFSET4_LEN4:
391 case BEN_OFFSET4_LEN4:
392 if ((Err = GetDWord(&Offset)) != BenErr_OK)
393 return Err;
394 if ((Err = GetDWord(&Length)) != BenErr_OK)
395 return Err;
396 break;
398 case BEN_IMMEDIATE0:
399 Length = 0; Immediate = true;
400 break;
402 case BEN_IMMEDIATE1:
403 Length = 1; Immediate = true;
404 break;
406 case BEN_IMMEDIATE2:
407 Length = 2; Immediate = true;
408 break;
410 case BEN_IMMEDIATE3:
411 Length = 3; Immediate = true;
412 break;
414 case BEN_CONT_IMMEDIATE4:
415 case BEN_IMMEDIATE4:
416 Length = 4; Immediate = true;
417 break;
419 case BEN_CONT_OFFSET8_LEN4:
420 case BEN_OFFSET8_LEN4:
421 EightByteOffset = true;
422 break;
424 default:
425 return BenErr_OK;
428 BenByte ImmData[4];
429 if (Immediate && Length != 0)
430 if ((Err = GetData(ImmData, 4)) != BenErr_OK)
431 return Err;
433 *pLookAhead = GetCode();
435 if (EightByteOffset)
436 return BenErr_64BitOffsetNotSupported;
438 if (pValue != NULL)
440 if (! Immediate)
441 new CBenValueSegment(pValue, Offset, Length);
442 else if (Length != 0)
444 assert(Length <= 4);
445 new CBenValueSegment(pValue, ImmData, (unsigned short) Length);
449 return BenErr_OK;
452 bool
453 CBenTOCReader::CanGetData(unsigned long Amt)
455 return cCurr + Amt <= cTOCSize;
458 BenError
459 CBenTOCReader::GetByte(BenByte * pByte)
461 if (! CanGetData(1))
462 return BenErr_ReadPastEndOfTOC;
464 *pByte = UtGetIntelByte(cpTOC + cCurr);
465 ++cCurr;
466 return BenErr_OK;
469 BenError
470 CBenTOCReader::GetDWord(BenDWord * pDWord)
472 if (! CanGetData(4))
473 return BenErr_ReadPastEndOfTOC;
475 *pDWord = UtGetIntelDWord(cpTOC + cCurr);
476 cCurr += 4;
477 return BenErr_OK;
480 BenByte
481 CBenTOCReader::GetCode()
483 BenByte Code;
486 if (GetByte(&Code) != BenErr_OK)
487 return BEN_READ_PAST_END_OF_TOC;
489 if (Code == BEN_END_OF_BUFFER)
490 // Advance to next block
491 cCurr = cBlockSize * ((cCurr + (cBlockSize - 1)) /
492 cBlockSize);
494 while (Code == BEN_NOOP || Code == BEN_END_OF_BUFFER);
495 return Code;
498 BenError
499 CBenTOCReader::GetData(BenDataPtr pBuffer, unsigned long Amt)
501 if (! CanGetData(Amt))
502 return BenErr_ReadPastEndOfTOC;
504 UtHugeMemcpy(pBuffer, cpTOC + cCurr, Amt);
505 cCurr += Amt;
506 return BenErr_OK;
508 }//end OpenStormBento namespace
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */