LibreOffice Module lotuswordpro (master) 1
tocread.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
6 *
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
9 *
10 * Sun Microsystems Inc., October, 2000
11 *
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
16 *
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.
20 *
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.
25 *
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
30 *
31 *
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.
38 *
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.
45 *
46 * The Initial Developer of the Original Code is: IBM Corporation
47 *
48 * Copyright: 2008 by IBM Corporation
49 *
50 * All Rights Reserved.
51 *
52 * Contributor(s): _______________________________________
53 *
54 *
55 ************************************************************************/
56
57#include <sal/config.h>
58#include <sal/log.hxx>
59
60#include <cstring>
61
62#include "first.hxx"
63#include "bentoid.hxx"
64#include "tocread.hxx"
65#include "ut.hxx"
66#include <assert.h>
67namespace OpenStormBento
68{
69
72{
73 BenError Err;
74
75 tools::ULong TOCOffset;
76 if ((Err = ReadLabel(&TOCOffset, &cTOCSize)) != BenErr_OK)
77 return Err;
78
80
81 if (TOCOffset > nLength)
83
84 if (cTOCSize > nLength - TOCOffset)
86
87 cpContainer->SeekToPosition(TOCOffset);
88
89 cpTOC.reset( new BenByte[cTOCSize] );
90 if ((Err = cpContainer->ReadKnownSize(cpTOC.get(), cTOCSize)) != BenErr_OK)
91 return Err;
92
93 if ((Err = ReadTOC()) != BenErr_OK)
94 return Err;
95
96 return BenErr_OK;
97}
98
101{
102 // If seek fails, then probably because stream is smaller than
103 // BEN_LABEL_SIZE and thus can't be Bento container
104 BenError Err;
106
109 return Err;
110
111 if (memcmp(Label, gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) != 0)
112 if ((Err = SearchForLabel(Label)) != BenErr_OK)
113 return Err;
114
115 BenByte * pCurrLabel = Label + BEN_MAGIC_BYTES_SIZE;
116
117 BenWord Flags =
118 UtGetIntelWord(pCurrLabel);
119 pCurrLabel += 2; // Flags
120 // Newer files are 0x0101--indicates if big or little endian. Older
121 // files are 0x0 for flags
122 if (Flags != 0x0101 && Flags != 0x0)
124
125 cBlockSize = UtGetIntelWord(pCurrLabel) * 1024; pCurrLabel += 2;
126 if (cBlockSize == 0)
128
129 // Check major version
130 if (UtGetIntelWord(pCurrLabel) != BEN_CURR_MAJOR_VERSION)
132 pCurrLabel += 2;
133
134 pCurrLabel += 2; // Minor version
135
136 *pTOCOffset = UtGetIntelDWord(pCurrLabel); pCurrLabel += 4;
137 *pTOCSize = UtGetIntelDWord(pCurrLabel);
138
139 assert(pCurrLabel + 4 == Label + BEN_LABEL_SIZE);
140
141 return BenErr_OK;
142}
143
144#define LABEL_READ_BUFFER_SIZE 500
145#define MAX_SEARCH_AMOUNT 1024 * 1024
146
149{
150 BenError Err;
151
153
154 // Always ready to check for MagicBytes from
155 // CurrOffset - BEN_MAGIC_BYTES_SIZE to CurrOffset - 1
156 unsigned long CurrOffset = Length - BEN_LABEL_SIZE + BEN_MAGIC_BYTES_SIZE -
157 1;
158
159 char Buffer[LABEL_READ_BUFFER_SIZE] = {0};
160
161 unsigned long BufferStartOffset = Length; // Init to big value
162
163 while (CurrOffset >= BEN_MAGIC_BYTES_SIZE)
164 {
165 // Don't search backwards more than 1 meg
166 if (Length - CurrOffset > MAX_SEARCH_AMOUNT)
167 break;
168
169 // If before beginning of buffer
170 if (CurrOffset - BEN_MAGIC_BYTES_SIZE < BufferStartOffset)
171 {
172 unsigned long UsedBufferSize;
173 if (CurrOffset < LABEL_READ_BUFFER_SIZE)
174 UsedBufferSize = CurrOffset;
175 else UsedBufferSize = LABEL_READ_BUFFER_SIZE;
176
177 cpContainer->SeekToPosition(CurrOffset - UsedBufferSize);
178
179 if ((Err = cpContainer->ReadKnownSize(Buffer, UsedBufferSize)) !=
180 BenErr_OK)
181 return Err;
182
183 BufferStartOffset = CurrOffset - UsedBufferSize;
184 }
185
186 if (memcmp(Buffer + (CurrOffset - BEN_MAGIC_BYTES_SIZE -
187 BufferStartOffset), gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) == 0)
188 {
189 cpContainer->SeekToPosition(CurrOffset -
191
193 }
194
195 --CurrOffset;
196 }
197
198 return BenErr_NotBentoContainer; // Didn't find magic bytes
199}
200
203{
204 BenError Err;
205 BenByte LookAhead = GetCode();
206 BenGeneration Generation = 0;
207
208 // Read in all objects
209 while (LookAhead == BEN_NEW_OBJECT)
210 {
211 BenObjectID ObjectID;
212 if ((Err = GetDWord(&ObjectID)) != BenErr_OK)
213 return Err;
214 CBenObject * pObject = nullptr;
215
216 // Read in all properties for object
217 do
218 {
219 BenObjectID PropertyID;
220
221 if ((Err = GetDWord(&PropertyID)) != BenErr_OK)
222 return Err;
223 CBenProperty * pProperty = nullptr;
224
225 // Read in all values for property
226 do
227 {
228 BenObjectID ReferencedListID = 0;
229
230 BenObjectID TypeID;
231 if ((Err = GetDWord(&TypeID)) != BenErr_OK)
232 return Err;
233 LookAhead = GetCode();
234
235 if (LookAhead == BEN_EXPLICIT_GEN)
236 {
237 if ((Err = GetDWord(&Generation)) != BenErr_OK)
238 return Err;
239 LookAhead = GetCode();
240 }
241
242 if (LookAhead == BEN_REFERENCE_LIST_ID)
243 {
244 if ((Err = GetDWord(&ReferencedListID)) != BenErr_OK)
245 return Err;
246 LookAhead = GetCode();
247 }
248
249 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME ||
250 PropertyID == BEN_PROPID_GLOBAL_TYPE_NAME)
251 {
252 // Read property or type name
253
254 if (pObject != nullptr || TypeID != BEN_TYPEID_7_BIT_ASCII ||
255 LookAhead != BEN_OFFSET4_LEN4)
257
259 sal_uInt32 Length;
260
261 if ((Err = GetDWord(&Pos)) != BenErr_OK)
262 return Err;
263 if ((Err = GetDWord(&Length)) != BenErr_OK)
264 return Err;
265 LookAhead = GetCode();
266
268
269 const auto nRemainingSize = cpContainer->remainingSize();
270 if (Length > nRemainingSize)
271 {
272 SAL_WARN("lwp", "stream too short for claimed no of records");
273 Length = nRemainingSize;
274 }
275
276 #define STACK_BUFFER_SIZE 256
277 char sStackBuffer[STACK_BUFFER_SIZE];
278 std::unique_ptr<char[]> sAllocBuffer;
279 char * sBuffer;
281 {
282 sAllocBuffer.reset(new char[Length]);
283 sBuffer = sAllocBuffer.get();
284 }
285 else
286 {
287 sBuffer = sStackBuffer;
288 }
289
290 if ((Err = cpContainer->ReadKnownSize(sBuffer, Length)) !=
291 BenErr_OK)
292 {
293 return Err;
294 }
295
296 OString sName;
297 if (Length)
298 sName = OString(sBuffer, Length - 1);
299
300 CUtListElmt * pPrevNamedObjectListElmt;
302 sName, &pPrevNamedObjectListElmt) != nullptr)
303 {
305 }
306
307 CUtListElmt* pPrevObject = cpContainer->GetObjects().GetLast();
308
309 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME)
310 pObject = new CBenPropertyName(cpContainer, ObjectID,
311 pPrevObject, sName, pPrevNamedObjectListElmt);
312 else
313 pObject = new CBenTypeName(cpContainer, ObjectID,
314 pPrevObject, sName, pPrevNamedObjectListElmt);
315 }
316 else if (PropertyID == BEN_PROPID_OBJ_REFERENCES)
317 {
318 // Don't need to read in references object--we assume
319 // that all references use object ID as key
320 if ((Err = ReadSegments(nullptr, &LookAhead)) != BenErr_OK)
321 return Err;
322 }
323 else if (ObjectID == BEN_OBJID_TOC)
324 {
325 if (PropertyID == BEN_PROPID_TOC_SEED)
326 {
327 if (TypeID != BEN_TYPEID_TOC_TYPE ||
328 LookAhead != BEN_IMMEDIATE4)
329 return BenErr_TOCSeedError;
330
332 if ((Err = GetDWord(&Data)) != BenErr_OK)
333 return Err;
334 LookAhead = GetCode();
335
337 }
338 else
339 {
340 // Ignore the other BEN_OBJID_TOC properties
341 if ((Err = ReadSegments(nullptr, &LookAhead)) != BenErr_OK)
342 return Err;
343 }
344 }
345 else
346 {
347 if (pProperty != nullptr)
349
350 if (pObject == nullptr)
351 pObject = new CBenObject(cpContainer, ObjectID,
353
354 pProperty = new CBenProperty(pObject, PropertyID, TypeID,
355 pObject->GetProperties().GetLast());
356
357 if ((Err = ReadSegments(&pProperty->UseValue(),
358 &LookAhead)) != BenErr_OK)
359 return Err;
360 }
361 } while (LookAhead == BEN_NEW_TYPE);
362 } while (LookAhead == BEN_NEW_PROPERTY);
363 }
364
365 if (LookAhead == BEN_READ_PAST_END_OF_TOC)
366 return BenErr_OK;
367 else return BenErr_InvalidTOC;
368}
369
372{
373 BenError Err;
374
375 while (*pLookAhead >= BEN_SEGMENT_CODE_START &&
376 *pLookAhead <= BEN_SEGMENT_CODE_END)
377 {
378 if ((Err = ReadSegment(pValue, pLookAhead)) !=
379 BenErr_OK)
380 return Err;
381 }
382
383 return BenErr_OK;
384}
385
388{
389 BenError Err;
390
391 bool Immediate = false;
392 bool EightByteOffset = false;
393 sal_uInt32 Offset(0), Length(0);
394
395 switch (*pLookAhead)
396 {
398 case BEN_OFFSET4_LEN4:
399 if ((Err = GetDWord(&Offset)) != BenErr_OK)
400 return Err;
401 if ((Err = GetDWord(&Length)) != BenErr_OK)
402 return Err;
403 break;
404
405 case BEN_IMMEDIATE0:
406 Length = 0; Immediate = true;
407 break;
408
409 case BEN_IMMEDIATE1:
410 Length = 1; Immediate = true;
411 break;
412
413 case BEN_IMMEDIATE2:
414 Length = 2; Immediate = true;
415 break;
416
417 case BEN_IMMEDIATE3:
418 Length = 3; Immediate = true;
419 break;
420
422 case BEN_IMMEDIATE4:
423 Length = 4; Immediate = true;
424 break;
425
427 case BEN_OFFSET8_LEN4:
428 EightByteOffset = true;
429 break;
430
431 default:
432 return BenErr_OK;
433 }
434
435 BenByte ImmData[4];
436 if (Immediate && Length != 0)
437 if ((Err = GetData(ImmData, 4)) != BenErr_OK)
438 return Err;
439
440 *pLookAhead = GetCode();
441
442 if (EightByteOffset)
444
445 if (pValue != nullptr)
446 {
447 if (! Immediate)
448 new CBenValueSegment(pValue, Offset, Length);
449 else if (Length != 0)
450 {
451 assert(Length <= 4);
452 new CBenValueSegment(pValue, ImmData, static_cast<unsigned short>(Length));
453 }
454 }
455
456 return BenErr_OK;
457}
458
459bool
461{
462 return cCurr + Amt <= cTOCSize;
463}
464
467{
468 if (! CanGetData(1))
470
471 *pByte = UtGetIntelByte(cpTOC.get() + cCurr);
472 ++cCurr;
473 return BenErr_OK;
474}
475
478{
479 if (! CanGetData(4))
481
482 *pDWord = UtGetIntelDWord(cpTOC.get() + cCurr);
483 cCurr += 4;
484 return BenErr_OK;
485}
486
489{
490 BenByte Code;
491 do
492 {
493 if (GetByte(&Code) != BenErr_OK)
495
496 if (Code == BEN_END_OF_BUFFER)
497 {
498 assert(cBlockSize && "cBlockSize of 0 should have already caused BenErr_UnknownBentoFormatVersion in CBenTOCReader::ReadLabel");
499 // Advance to next block
500 cCurr = cBlockSize * ((cCurr + (cBlockSize - 1)) /
501 cBlockSize);
502 }
503 }
504 while (Code == BEN_NOOP || Code == BEN_END_OF_BUFFER);
505 return Code;
506}
507
510{
511 if (! CanGetData(Amt))
513
514 std::memcpy(pBuffer, cpTOC.get() + cCurr, Amt);
515 cCurr += Amt;
516 return BenErr_OK;
517}
518}//end OpenStormBento namespace
519
520/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Sequence< sal_Int8 > Buffer
#define BEN_MAGIC_BYTES_SIZE
Definition: bento.hxx:82
#define BEN_CURR_MAJOR_VERSION
Definition: bento.hxx:80
#define BEN_LABEL_SIZE
Definition: bento.hxx:83
#define BEN_IMMEDIATE2
Definition: bentoid.hxx:81
#define BEN_NEW_TYPE
Definition: bentoid.hxx:71
#define BEN_CONT_OFFSET4_LEN4
Definition: bentoid.hxx:76
#define BEN_IMMEDIATE0
Definition: bentoid.hxx:79
#define BEN_IMMEDIATE4
Definition: bentoid.hxx:83
#define BEN_CONT_OFFSET8_LEN4
Definition: bentoid.hxx:78
#define BEN_END_OF_BUFFER
Definition: bentoid.hxx:88
#define BEN_NOOP
Definition: bentoid.hxx:90
#define BEN_EXPLICIT_GEN
Definition: bentoid.hxx:72
#define BEN_REFERENCE_LIST_ID
Definition: bentoid.hxx:87
#define BEN_READ_PAST_END_OF_TOC
Definition: bentoid.hxx:89
#define BEN_PROPID_GLOBAL_PROPERTY_NAME
Definition: bentoid.hxx:66
#define BEN_PROPID_OBJ_REFERENCES
Definition: bentoid.hxx:67
#define BEN_NEW_PROPERTY
Definition: bentoid.hxx:70
#define BEN_SEGMENT_CODE_START
Definition: bentoid.hxx:74
#define BEN_OBJID_TOC
Definition: bentoid.hxx:61
#define BEN_TYPEID_TOC_TYPE
Definition: bentoid.hxx:63
#define BEN_PROPID_TOC_SEED
Definition: bentoid.hxx:62
#define BEN_NEW_OBJECT
Definition: bentoid.hxx:69
#define BEN_OFFSET8_LEN4
Definition: bentoid.hxx:77
#define BEN_IMMEDIATE1
Definition: bentoid.hxx:80
#define BEN_PROPID_GLOBAL_TYPE_NAME
Definition: bentoid.hxx:65
#define BEN_TYPEID_7_BIT_ASCII
Definition: bentoid.hxx:64
#define BEN_IMMEDIATE3
Definition: bentoid.hxx:82
#define BEN_OFFSET4_LEN4
Definition: bentoid.hxx:75
#define BEN_SEGMENT_CODE_END
Definition: bentoid.hxx:85
#define BEN_CONT_IMMEDIATE4
Definition: bentoid.hxx:84
CBenValue & UseValue()
Definition: bento.hxx:288
std::unique_ptr< BenByte[]> cpTOC
Definition: tocread.hxx:91
LtcBenContainer * cpContainer
Definition: tocread.hxx:90
BenError ReadSegment(CBenValue *pValue, BenByte *pLookAhead)
Definition: tocread.cxx:387
BenError GetByte(BenByte *pByte)
Definition: tocread.cxx:466
BenError ReadLabel(tools::ULong *pTOCOffset, tools::ULong *pTOCSize)
Definition: tocread.cxx:100
bool CanGetData(tools::ULong Amt)
Definition: tocread.cxx:460
BenError SearchForLabel(BenByte *pLabel)
Definition: tocread.cxx:148
BenError ReadSegments(CBenValue *pValue, BenByte *pLookAhead)
Definition: tocread.cxx:371
BenError GetData(void *pBuffer, tools::ULong Amt)
Definition: tocread.cxx:509
BenError GetDWord(BenDWord *pDWord)
Definition: tocread.cxx:477
CUtListElmt * GetLast()
Definition: utlist.hxx:102
sal_uLong remainingSize() const
Definition: bencont.cxx:321
BenError ReadKnownSize(void *pBuffer, size_t Amt)
Read buffer from bento file with specified size.
Definition: bencont.cxx:183
sal_uLong GetSize() const
Definition: bento.hxx:225
void SeekToPosition(BenContainerPos Pos)
Seek to position from the beginning of the bento file.
Definition: bencont.cxx:196
void SetNextAvailObjectID(BenObjectID ID)
Definition: bento.hxx:217
void SeekFromEnd(tools::Long Offset)
Seek to position compare to end of bento file.
Definition: bencont.cxx:204
EmbeddedObjectRef * pObject
OUString sName
#define SAL_WARN(area, stream)
Flags
const char gsBenMagicBytes[]
Definition: bencont.cxx:66
sal_uInt16 UtGetIntelWord(sal_uInt8 const *pData)
Definition: ut.hxx:62
@ BenErr_InvalidTOC
Definition: bento.hxx:95
@ BenErr_DuplicateName
Definition: bento.hxx:108
@ BenErr_NotBentoContainer
Definition: bento.hxx:111
@ BenErr_64BitOffsetNotSupported
Definition: bento.hxx:96
@ BenErr_PropertyWithMoreThanOneValue
Definition: bento.hxx:112
@ BenErr_UnknownBentoFormatVersion
Definition: bento.hxx:92
@ BenErr_TOCSeedError
Definition: bento.hxx:106
@ BenErr_NamedObjectError
Definition: bento.hxx:93
@ BenErr_ReadPastEndOfTOC
Definition: bento.hxx:97
sal_uInt8 UtGetIntelByte(sal_uInt8 const *pData)
Definition: ut.hxx:69
CBenNamedObject * FindNamedObject(CUtList *pList, std::string_view rName, CUtListElmt **ppPrev)
Definition: benlist.cxx:59
sal_uInt32 BenContainerPos
Definition: bento.hxx:134
sal_uInt8 BenByte
Definition: bento.hxx:128
sal_uInt32 UtGetIntelDWord(sal_uInt8 const *pData)
Definition: ut.hxx:64
sal_uInt32 BenDWord
Definition: bento.hxx:132
sal_uInt16 BenWord
Definition: bento.hxx:131
sal_uInt32 BenObjectID
Definition: bento.hxx:135
sal_uInt32 BenGeneration
Definition: bento.hxx:136
Length
unsigned long ULong
sal_uIntPtr sal_uLong
#define MAX_SEARCH_AMOUNT
Definition: tocread.cxx:145
#define STACK_BUFFER_SIZE
#define LABEL_READ_BUFFER_SIZE
Definition: tocread.cxx:144
sal_Int32 nLength