File: | home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx |
Warning: | line 209, column 12 Potential leak of memory pointed to by 'pObject' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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> | |||
67 | namespace OpenStormBento | |||
68 | { | |||
69 | ||||
70 | BenError | |||
71 | CBenTOCReader::ReadLabelAndTOC() | |||
72 | { | |||
73 | BenError Err; | |||
74 | ||||
75 | unsigned long TOCOffset; | |||
76 | if ((Err = ReadLabel(&TOCOffset, &cTOCSize)) != BenErr_OK) | |||
| ||||
77 | return Err; | |||
78 | ||||
79 | sal_uLong nLength = cpContainer->GetSize(); | |||
80 | ||||
81 | if (TOCOffset > nLength) | |||
82 | return BenErr_ReadPastEndOfTOC; | |||
83 | ||||
84 | if (cTOCSize > nLength - TOCOffset) | |||
85 | return BenErr_ReadPastEndOfTOC; | |||
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 | ||||
99 | BenError | |||
100 | CBenTOCReader::ReadLabel(unsigned long * pTOCOffset, unsigned long * pTOCSize) | |||
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; | |||
105 | cpContainer->SeekFromEnd(-BEN_LABEL_SIZE24); | |||
106 | ||||
107 | BenByte Label[BEN_LABEL_SIZE24]; | |||
108 | if ((Err = cpContainer->ReadKnownSize(Label, BEN_LABEL_SIZE24)) != BenErr_OK) | |||
109 | return Err; | |||
110 | ||||
111 | if (memcmp(Label, gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE8) != 0) | |||
112 | if ((Err = SearchForLabel(Label)) != BenErr_OK) | |||
113 | return Err; | |||
114 | ||||
115 | BenByte * pCurrLabel = Label + BEN_MAGIC_BYTES_SIZE8; | |||
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) | |||
123 | return BenErr_UnknownBentoFormatVersion; | |||
124 | ||||
125 | cBlockSize = UtGetIntelWord(pCurrLabel) * 1024; pCurrLabel += 2; | |||
126 | if (cBlockSize == 0) | |||
127 | return BenErr_NotBentoContainer; | |||
128 | ||||
129 | // Check major version | |||
130 | if (UtGetIntelWord(pCurrLabel) != BEN_CURR_MAJOR_VERSION2) | |||
131 | return BenErr_UnknownBentoFormatVersion; | |||
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)(static_cast <bool> (pCurrLabel + 4 == Label + 24) ? void (0) : __assert_fail ("pCurrLabel + 4 == Label + BEN_LABEL_SIZE" , "/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx" , 139, __extension__ __PRETTY_FUNCTION__)); | |||
140 | ||||
141 | return BenErr_OK; | |||
142 | } | |||
143 | ||||
144 | #define LABEL_READ_BUFFER_SIZE500 500 | |||
145 | #define MAX_SEARCH_AMOUNT1024 * 1024 1024 * 1024 | |||
146 | ||||
147 | BenError | |||
148 | CBenTOCReader::SearchForLabel(BenByte * pLabel) | |||
149 | { | |||
150 | BenError Err; | |||
151 | ||||
152 | sal_uLong Length = cpContainer->GetSize(); | |||
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_SIZE24 + BEN_MAGIC_BYTES_SIZE8 - | |||
157 | 1; | |||
158 | ||||
159 | char Buffer[LABEL_READ_BUFFER_SIZE500] = {0}; | |||
160 | ||||
161 | unsigned long BufferStartOffset = Length; // Init to big value | |||
162 | ||||
163 | while (CurrOffset >= BEN_MAGIC_BYTES_SIZE8) | |||
164 | { | |||
165 | // Don't search backwards more than 1 meg | |||
166 | if (Length - CurrOffset > MAX_SEARCH_AMOUNT1024 * 1024) | |||
167 | break; | |||
168 | ||||
169 | // If before beginning of buffer | |||
170 | if (CurrOffset - BEN_MAGIC_BYTES_SIZE8 < BufferStartOffset) | |||
171 | { | |||
172 | unsigned long UsedBufferSize; | |||
173 | if (CurrOffset < LABEL_READ_BUFFER_SIZE500) | |||
174 | UsedBufferSize = CurrOffset; | |||
175 | else UsedBufferSize = LABEL_READ_BUFFER_SIZE500; | |||
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_SIZE8 - | |||
187 | BufferStartOffset), gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE8) == 0) | |||
188 | { | |||
189 | cpContainer->SeekToPosition(CurrOffset - | |||
190 | BEN_MAGIC_BYTES_SIZE8); | |||
191 | ||||
192 | return cpContainer->ReadKnownSize(pLabel, BEN_LABEL_SIZE24); | |||
193 | } | |||
194 | ||||
195 | --CurrOffset; | |||
196 | } | |||
197 | ||||
198 | return BenErr_NotBentoContainer; // Didn't find magic bytes | |||
199 | } | |||
200 | ||||
201 | BenError | |||
202 | CBenTOCReader::ReadTOC() | |||
203 | { | |||
204 | BenError Err; | |||
205 | BenByte LookAhead = GetCode(); | |||
206 | BenGeneration Generation = 0; | |||
207 | ||||
208 | // Read in all objects | |||
209 | while (LookAhead == BEN_NEW_OBJECT1) | |||
| ||||
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_GEN4) | |||
236 | { | |||
237 | if ((Err = GetDWord(&Generation)) != BenErr_OK) | |||
238 | return Err; | |||
239 | LookAhead = GetCode(); | |||
240 | } | |||
241 | ||||
242 | if (LookAhead == BEN_REFERENCE_LIST_ID15) | |||
243 | { | |||
244 | if ((Err = GetDWord(&ReferencedListID)) != BenErr_OK) | |||
245 | return Err; | |||
246 | LookAhead = GetCode(); | |||
247 | } | |||
248 | ||||
249 | if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME24 || | |||
250 | PropertyID == BEN_PROPID_GLOBAL_TYPE_NAME23) | |||
251 | { | |||
252 | // Read property or type name | |||
253 | ||||
254 | if (pObject != nullptr || TypeID != BEN_TYPEID_7_BIT_ASCII21 || | |||
255 | LookAhead != BEN_OFFSET4_LEN45) | |||
256 | return BenErr_NamedObjectError; | |||
257 | ||||
258 | BenContainerPos Pos; | |||
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 | ||||
267 | cpContainer->SeekToPosition(Pos); | |||
268 | ||||
269 | const auto nRemainingSize = cpContainer->remainingSize(); | |||
270 | if (Length > nRemainingSize) | |||
271 | { | |||
272 | SAL_WARN("lwp", "stream too short for claimed no of records")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "lwp")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "stream too short for claimed no of records") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"), ("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx" ":" "272" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "stream too short for claimed no of records" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "stream too short for claimed no of records"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"), ("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx" ":" "272" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "stream too short for claimed no of records") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"), ("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx" ":" "272" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "stream too short for claimed no of records" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "stream too short for claimed no of records"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lwp"), ("/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx" ":" "272" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
273 | Length = nRemainingSize; | |||
274 | } | |||
275 | ||||
276 | #define STACK_BUFFER_SIZE256 256 | |||
277 | char sStackBuffer[STACK_BUFFER_SIZE256]; | |||
278 | std::unique_ptr<char[]> sAllocBuffer; | |||
279 | char * sBuffer; | |||
280 | if (Length > STACK_BUFFER_SIZE256) | |||
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; | |||
301 | if (FindNamedObject(&cpContainer->GetNamedObjects(), | |||
302 | sName, &pPrevNamedObjectListElmt) != nullptr) | |||
303 | { | |||
304 | return BenErr_DuplicateName; | |||
305 | } | |||
306 | ||||
307 | CUtListElmt* pPrevObject = cpContainer->GetObjects().GetLast(); | |||
308 | ||||
309 | if (PropertyID
| |||
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_REFERENCES31) | |||
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_TOC1) | |||
324 | { | |||
325 | if (PropertyID == BEN_PROPID_TOC_SEED2) | |||
326 | { | |||
327 | if (TypeID != BEN_TYPEID_TOC_TYPE19 || | |||
328 | LookAhead != BEN_IMMEDIATE413) | |||
329 | return BenErr_TOCSeedError; | |||
330 | ||||
331 | BenDWord Data; | |||
332 | if ((Err = GetDWord(&Data)) != BenErr_OK) | |||
333 | return Err; | |||
334 | LookAhead = GetCode(); | |||
335 | ||||
336 | cpContainer->SetNextAvailObjectID(Data); | |||
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) | |||
348 | return BenErr_PropertyWithMoreThanOneValue; | |||
349 | ||||
350 | if (pObject == nullptr) | |||
351 | pObject = new CBenObject(cpContainer, ObjectID, | |||
352 | cpContainer->GetObjects().GetLast()); | |||
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_TYPE3); | |||
362 | } while (LookAhead == BEN_NEW_PROPERTY2); | |||
363 | } | |||
364 | ||||
365 | if (LookAhead == BEN_READ_PAST_END_OF_TOC50) | |||
366 | return BenErr_OK; | |||
367 | else return BenErr_InvalidTOC; | |||
368 | } | |||
369 | ||||
370 | BenError | |||
371 | CBenTOCReader::ReadSegments(CBenValue * pValue, BenByte * pLookAhead) | |||
372 | { | |||
373 | BenError Err; | |||
374 | ||||
375 | while (*pLookAhead >= BEN_SEGMENT_CODE_START5 && | |||
376 | *pLookAhead <= BEN_SEGMENT_CODE_END14) | |||
377 | { | |||
378 | if ((Err = ReadSegment(pValue, pLookAhead)) != | |||
379 | BenErr_OK) | |||
380 | return Err; | |||
381 | } | |||
382 | ||||
383 | return BenErr_OK; | |||
384 | } | |||
385 | ||||
386 | BenError | |||
387 | CBenTOCReader::ReadSegment(CBenValue * pValue, BenByte * pLookAhead) | |||
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 | { | |||
397 | case BEN_CONT_OFFSET4_LEN46: | |||
398 | case BEN_OFFSET4_LEN45: | |||
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_IMMEDIATE09: | |||
406 | Length = 0; Immediate = true; | |||
407 | break; | |||
408 | ||||
409 | case BEN_IMMEDIATE110: | |||
410 | Length = 1; Immediate = true; | |||
411 | break; | |||
412 | ||||
413 | case BEN_IMMEDIATE211: | |||
414 | Length = 2; Immediate = true; | |||
415 | break; | |||
416 | ||||
417 | case BEN_IMMEDIATE312: | |||
418 | Length = 3; Immediate = true; | |||
419 | break; | |||
420 | ||||
421 | case BEN_CONT_IMMEDIATE414: | |||
422 | case BEN_IMMEDIATE413: | |||
423 | Length = 4; Immediate = true; | |||
424 | break; | |||
425 | ||||
426 | case BEN_CONT_OFFSET8_LEN48: | |||
427 | case BEN_OFFSET8_LEN47: | |||
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) | |||
443 | return BenErr_64BitOffsetNotSupported; | |||
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)(static_cast <bool> (Length <= 4) ? void (0) : __assert_fail ("Length <= 4", "/home/maarten/src/libreoffice/core/lotuswordpro/source/filter/tocread.cxx" , 451, __extension__ __PRETTY_FUNCTION__)); | |||
452 | new CBenValueSegment(pValue, ImmData, static_cast<unsigned short>(Length)); | |||
453 | } | |||
454 | } | |||
455 | ||||
456 | return BenErr_OK; | |||
457 | } | |||
458 | ||||
459 | bool | |||
460 | CBenTOCReader::CanGetData(unsigned long Amt) | |||
461 | { | |||
462 | return cCurr + Amt <= cTOCSize; | |||
463 | } | |||
464 | ||||
465 | BenError | |||
466 | CBenTOCReader::GetByte(BenByte * pByte) | |||
467 | { | |||
468 | if (! CanGetData(1)) | |||
469 | return BenErr_ReadPastEndOfTOC; | |||
470 | ||||
471 | *pByte = UtGetIntelByte(cpTOC.get() + cCurr); | |||
472 | ++cCurr; | |||
473 | return BenErr_OK; | |||
474 | } | |||
475 | ||||
476 | BenError | |||
477 | CBenTOCReader::GetDWord(BenDWord * pDWord) | |||
478 | { | |||
479 | if (! CanGetData(4)) | |||
480 | return BenErr_ReadPastEndOfTOC; | |||
481 | ||||
482 | *pDWord = UtGetIntelDWord(cpTOC.get() + cCurr); | |||
483 | cCurr += 4; | |||
484 | return BenErr_OK; | |||
485 | } | |||
486 | ||||
487 | BenByte | |||
488 | CBenTOCReader::GetCode() | |||
489 | { | |||
490 | BenByte Code; | |||
491 | do | |||
492 | { | |||
493 | if (GetByte(&Code) != BenErr_OK) | |||
494 | return BEN_READ_PAST_END_OF_TOC50; | |||
495 | ||||
496 | if (Code == BEN_END_OF_BUFFER24) | |||
497 | // Advance to next block | |||
498 | cCurr = cBlockSize * ((cCurr + (cBlockSize - 1)) / | |||
499 | cBlockSize); | |||
500 | } | |||
501 | while (Code == BEN_NOOP0xFF || Code == BEN_END_OF_BUFFER24); | |||
502 | return Code; | |||
503 | } | |||
504 | ||||
505 | BenError | |||
506 | CBenTOCReader::GetData(void * pBuffer, unsigned long Amt) | |||
507 | { | |||
508 | if (! CanGetData(Amt)) | |||
509 | return BenErr_ReadPastEndOfTOC; | |||
510 | ||||
511 | std::memcpy(pBuffer, cpTOC.get() + cCurr, Amt); | |||
512 | cCurr += Amt; | |||
513 | return BenErr_OK; | |||
514 | } | |||
515 | }//end OpenStormBento namespace | |||
516 | ||||
517 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |