LCOV - code coverage report
Current view: top level - lotuswordpro/source/filter - tocread.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 130 211 61.6 %
Date: 2014-11-03 Functions: 10 11 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "first.hxx"
      57             : #include "assert.h"
      58             : namespace OpenStormBento
      59             : {
      60             : 
      61             : BenError
      62           8 : CBenTOCReader::ReadLabelAndTOC()
      63             : {
      64             :     BenError Err;
      65             : 
      66             :     unsigned long TOCOffset;
      67           8 :     if ((Err = ReadLabel(&TOCOffset, &cTOCSize)) != BenErr_OK)
      68           0 :         return Err;
      69             : 
      70             :     unsigned long nLength;
      71           8 :     if ((Err = cpContainer->GetSize(&nLength)) != BenErr_OK)
      72           0 :         return Err;
      73             : 
      74           8 :     if (TOCOffset > nLength)
      75           0 :         return BenErr_ReadPastEndOfTOC;
      76             : 
      77           8 :     if (cTOCSize > nLength - TOCOffset)
      78           0 :         return BenErr_ReadPastEndOfTOC;
      79             : 
      80           8 :     if ((Err = cpContainer->SeekToPosition(TOCOffset)) != BenErr_OK)
      81           0 :         return Err;
      82             : 
      83           8 :     cpTOC = new BenByte[cTOCSize];
      84           8 :     if ((Err = cpContainer->ReadKnownSize(cpTOC, cTOCSize)) != BenErr_OK)
      85           0 :         return Err;
      86             : 
      87           8 :     if ((Err = ReadTOC()) != BenErr_OK)
      88           0 :         return Err;
      89             : 
      90           8 :     return BenErr_OK;
      91             : }
      92             : 
      93             : BenError
      94           8 : CBenTOCReader::ReadLabel(unsigned long * pTOCOffset, unsigned long * pTOCSize)
      95             : {
      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           8 :     if ((Err = cpContainer->SeekFromEnd(-BEN_LABEL_SIZE)) != BenErr_OK)
     100           0 :         return BenErr_NotBentoContainer;
     101             : 
     102             :     BenByte Label[BEN_LABEL_SIZE];
     103           8 :     if ((Err = cpContainer->ReadKnownSize(Label, BEN_LABEL_SIZE)) != BenErr_OK)
     104           0 :         return Err;
     105             : 
     106           8 :     if (memcmp(Label, gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) != 0)
     107           0 :         if ((Err = SearchForLabel(Label)) != BenErr_OK)
     108           0 :             return Err;
     109             : 
     110           8 :     BenByte * pCurrLabel = Label + BEN_MAGIC_BYTES_SIZE;
     111             : 
     112             : #ifndef NDEBUG
     113             :     BenWord Flags =
     114             : #endif
     115           8 :         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);
     119             : 
     120           8 :     cBlockSize = UtGetIntelWord(pCurrLabel) * 1024; pCurrLabel += 2;
     121             : 
     122             :     // Check major version
     123           8 :     if (UtGetIntelWord(pCurrLabel) != BEN_CURR_MAJOR_VERSION)
     124           0 :         return BenErr_UnknownBentoFormatVersion;
     125           8 :     pCurrLabel += 2;
     126             : 
     127           8 :     UtGetIntelWord(pCurrLabel); pCurrLabel += 2;    // Minor version
     128             : 
     129           8 :     *pTOCOffset = UtGetIntelDWord(pCurrLabel); pCurrLabel += 4;
     130           8 :     *pTOCSize = UtGetIntelDWord(pCurrLabel);
     131             : 
     132             :     assert(pCurrLabel + 4 == Label + BEN_LABEL_SIZE);
     133             : 
     134           8 :     return BenErr_OK;
     135             : }
     136             : 
     137             : #define LABEL_READ_BUFFER_SIZE 500
     138             : #define MAX_SEARCH_AMOUNT 1024 * 1024
     139             : 
     140             : BenError
     141           0 : CBenTOCReader::SearchForLabel(BenByte * pLabel)
     142             : {
     143             :     BenError Err;
     144             : 
     145             :     sal_uLong Length;
     146           0 :     if ((Err = cpContainer->GetSize(&Length)) != BenErr_OK)
     147           0 :         return Err;
     148             : 
     149             :     // Always ready to check for MagicBytes from
     150             :     // CurrOffset - BEN_MAGIC_BYTES_SIZE to CurrOffset - 1
     151           0 :     unsigned long CurrOffset = Length - BEN_LABEL_SIZE + BEN_MAGIC_BYTES_SIZE -
     152           0 :       1;
     153             : 
     154           0 :     char Buffer[LABEL_READ_BUFFER_SIZE] = {0};
     155             : 
     156           0 :     unsigned long BufferStartOffset = Length;   // Init to big value
     157             : 
     158           0 :     while (CurrOffset >= BEN_MAGIC_BYTES_SIZE)
     159             :     {
     160             :         // Don't search backwards more than 1 meg
     161           0 :         if (Length - CurrOffset > MAX_SEARCH_AMOUNT)
     162           0 :             break;
     163             : 
     164             :         // If before beginning of buffer
     165           0 :         if (CurrOffset - BEN_MAGIC_BYTES_SIZE < BufferStartOffset)
     166             :         {
     167             :             unsigned long UsedBufferSize;
     168           0 :             if (CurrOffset < LABEL_READ_BUFFER_SIZE)
     169           0 :                 UsedBufferSize = CurrOffset;
     170           0 :             else UsedBufferSize = LABEL_READ_BUFFER_SIZE;
     171             : 
     172           0 :             if ((Err = cpContainer->SeekToPosition(CurrOffset - UsedBufferSize))
     173             :               != BenErr_OK)
     174           0 :                 return Err;
     175             : 
     176           0 :             if ((Err = cpContainer->ReadKnownSize(Buffer, UsedBufferSize)) !=
     177             :               BenErr_OK)
     178           0 :                 return Err;
     179             : 
     180           0 :             BufferStartOffset = CurrOffset - UsedBufferSize;
     181             :         }
     182             : 
     183           0 :         if (memcmp(Buffer + (CurrOffset - BEN_MAGIC_BYTES_SIZE -
     184           0 :           BufferStartOffset), gsBenMagicBytes, BEN_MAGIC_BYTES_SIZE) == 0)
     185             :         {
     186           0 :             if ((Err = cpContainer->SeekToPosition(CurrOffset -
     187           0 :               BEN_MAGIC_BYTES_SIZE)) != BenErr_OK)
     188           0 :                 return Err;
     189             : 
     190           0 :             return cpContainer->ReadKnownSize(pLabel, BEN_LABEL_SIZE);
     191             :         }
     192             : 
     193           0 :         --CurrOffset;
     194             :     }
     195             : 
     196           0 :     return BenErr_NotBentoContainer;    // Didn't find magic bytes
     197             : }
     198             : 
     199             : BenError
     200           8 : CBenTOCReader::ReadTOC()
     201             : {
     202             :     BenError Err;
     203           8 :     BenByte LookAhead = GetCode();
     204           8 :     BenGeneration Generation = 0;
     205             : 
     206             :     // Read in all objects
     207         476 :     while (LookAhead == BEN_NEW_OBJECT)
     208             :     {
     209             :         BenObjectID ObjectID;
     210         460 :         if ((Err = GetDWord(&ObjectID)) != BenErr_OK)
     211           0 :             return Err;
     212         460 :         pCBenObject pObject = NULL;
     213             : 
     214             :         // Read in all properties for object
     215         554 :         do
     216             :         {
     217             :             BenObjectID PropertyID;
     218             : 
     219         554 :             if ((Err = GetDWord(&PropertyID)) != BenErr_OK)
     220           0 :                 return Err;
     221         554 :             pCBenProperty pProperty = NULL;
     222             : 
     223             :             // Read in all values for property
     224         554 :             do
     225             :             {
     226         554 :                 BenObjectID ReferencedListID = 0;
     227             : 
     228             :                 BenObjectID TypeID;
     229         554 :                 if ((Err = GetDWord(&TypeID)) != BenErr_OK)
     230           0 :                     return Err;
     231         554 :                 LookAhead = GetCode();
     232             : 
     233         554 :                 if (LookAhead == BEN_EXPLICIT_GEN)
     234             :                 {
     235          14 :                     if ((Err = GetDWord(&Generation)) != BenErr_OK)
     236           0 :                         return Err;
     237          14 :                     LookAhead = GetCode();
     238             :                 }
     239             : 
     240         554 :                 if (LookAhead == BEN_REFERENCE_LIST_ID)
     241             :                 {
     242          60 :                     if ((Err = GetDWord(&ReferencedListID)) != BenErr_OK)
     243           0 :                         return Err;
     244          60 :                     LookAhead = GetCode();
     245             :                 }
     246             : 
     247        1020 :                 if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME ||
     248         466 :                     PropertyID == BEN_PROPID_GLOBAL_TYPE_NAME)
     249             :                 {
     250             :                     // Read property or type name
     251             : 
     252         216 :                     if (pObject != NULL || TypeID != BEN_TYPEID_7_BIT_ASCII ||
     253         108 :                       LookAhead != BEN_OFFSET4_LEN4)
     254           0 :                         return BenErr_NamedObjectError;
     255             : 
     256             :                     BenContainerPos Pos;
     257             :                     unsigned long Length;
     258             : 
     259         108 :                     if ((Err = GetDWord(&Pos)) != BenErr_OK)
     260           0 :                         return Err;
     261         108 :                     if ((Err = GetDWord(&Length)) != BenErr_OK)
     262           0 :                         return Err;
     263         108 :                     LookAhead = GetCode();
     264             : 
     265         108 :                     if ((Err = cpContainer->SeekToPosition(Pos)) != BenErr_OK)
     266           0 :                         return Err;
     267             : 
     268             :                     #define STACK_BUFFER_SIZE 256
     269             :                     char sStackBuffer[STACK_BUFFER_SIZE];
     270             :                     char * sAllocBuffer;
     271             :                     char * sBuffer;
     272         108 :                     if (Length > STACK_BUFFER_SIZE)
     273             :                     {
     274           0 :                         sBuffer = new char[Length];
     275           0 :                         sAllocBuffer = sBuffer;
     276             :                     }
     277             :                     else
     278             :                     {
     279         108 :                         sBuffer = sStackBuffer;
     280         108 :                         sAllocBuffer = NULL;
     281             :                     }
     282             : 
     283         108 :                     if ((Err = cpContainer->ReadKnownSize(sBuffer, Length)) !=
     284             :                       BenErr_OK)
     285             :                     {
     286           0 :                         delete[] sAllocBuffer;
     287           0 :                         return Err;
     288             :                     }
     289             : 
     290             :                     pCUtListElmt pPrevNamedObjectListElmt;
     291         216 :                     if (FindNamedObject(&cpContainer->GetNamedObjects(),
     292         108 :                       sBuffer, &pPrevNamedObjectListElmt) != NULL)
     293             :                     {
     294           0 :                         delete[] sAllocBuffer;
     295           0 :                         return BenErr_DuplicateName;
     296             :                     }
     297             : 
     298             :                     pCBenObject pPrevObject = static_cast<pCBenObject>( cpContainer->
     299         108 :                       GetObjects().GetLast());
     300             : 
     301         108 :                     if (PropertyID == BEN_PROPID_GLOBAL_PROPERTY_NAME)
     302             :                         pObject = new CBenPropertyName(cpContainer, ObjectID,
     303          88 :                           pPrevObject, sBuffer, pPrevNamedObjectListElmt);
     304             :                     else pObject = new CBenTypeName(cpContainer, ObjectID,
     305          20 :                       pPrevObject, sBuffer, pPrevNamedObjectListElmt);
     306             : 
     307         108 :                     delete[] sAllocBuffer;
     308             :                 }
     309         446 :                 else if (PropertyID == BEN_PROPID_OBJ_REFERENCES)
     310             :                 {
     311             :                     // Don't need to read in references object--we assume
     312             :                     // that all references use object ID as key
     313          60 :                     if ((Err = ReadSegments(NULL, &LookAhead)) != BenErr_OK)
     314           0 :                         return Err;
     315             :                 }
     316         386 :                 else if (ObjectID == BEN_OBJID_TOC)
     317             :                 {
     318          40 :                     if (PropertyID == BEN_PROPID_TOC_SEED)
     319             :                     {
     320          16 :                         if (TypeID != BEN_TYPEID_TOC_TYPE ||
     321           8 :                           LookAhead !=  BEN_IMMEDIATE4)
     322           0 :                             return BenErr_TOCSeedError;
     323             : 
     324             :                         BenDWord Data;
     325           8 :                         if ((Err = GetDWord(&Data)) != BenErr_OK)
     326           0 :                             return Err;
     327           8 :                         LookAhead = GetCode();
     328             : 
     329           8 :                         cpContainer->SetNextAvailObjectID(Data);
     330             :                     }
     331             :                     else
     332             :                     {
     333             :                         // Ignore the other BEN_OBJID_TOC properties
     334          32 :                         if ((Err = ReadSegments(NULL, &LookAhead)) != BenErr_OK)
     335           0 :                             return Err;
     336             :                     }
     337             :                 }
     338             :                 else
     339             :                 {
     340         346 :                     if (pProperty != NULL)
     341           0 :                         return BenErr_PropertyWithMoreThanOneValue;
     342             : 
     343         346 :                     if (pObject == NULL)
     344             :                         pObject = new CBenObject(cpContainer, ObjectID,
     345         284 :                           cpContainer->GetObjects().GetLast());
     346             : 
     347             :                     pProperty = new CBenProperty(pObject, PropertyID, TypeID,
     348         346 :                       pObject->GetProperties().GetLast());
     349             : 
     350         346 :                     if ((Err = ReadSegments(&pProperty->UseValue(),
     351             :                       &LookAhead)) != BenErr_OK)
     352           0 :                         return Err;
     353             :                 }
     354         554 :             } while (LookAhead == BEN_NEW_TYPE);
     355         554 :         } while (LookAhead == BEN_NEW_PROPERTY);
     356             :     }
     357             : 
     358           8 :     if (LookAhead == BEN_READ_PAST_END_OF_TOC)
     359           8 :         return BenErr_OK;
     360           0 :     else return BenErr_InvalidTOC;
     361             : }
     362             : 
     363             : BenError
     364         438 : CBenTOCReader::ReadSegments(pCBenValue pValue, BenByte * pLookAhead)
     365             : {
     366             :     BenError Err;
     367             : 
     368        1758 :     while (*pLookAhead >= BEN_SEGMENT_CODE_START &&
     369         444 :       *pLookAhead <= BEN_SEGMENT_CODE_END)
     370             :     {
     371         438 :         if ((Err = ReadSegment(pValue, pLookAhead)) !=
     372             :           BenErr_OK)
     373           0 :             return Err;
     374             :     }
     375             : 
     376         438 :     return BenErr_OK;
     377             : }
     378             : 
     379             : BenError
     380         438 : CBenTOCReader::ReadSegment(pCBenValue pValue, BenByte * pLookAhead)
     381             : {
     382             :     BenError Err;
     383             : 
     384         438 :     bool Immediate = false;
     385         438 :     bool EightByteOffset = false;
     386         438 :     unsigned long Offset(0), Length(0);
     387             : 
     388         438 :     switch (*pLookAhead)
     389             :     {
     390             :         case BEN_CONT_OFFSET4_LEN4:
     391             :         case BEN_OFFSET4_LEN4:
     392         422 :             if ((Err = GetDWord(&Offset))  != BenErr_OK)
     393           0 :                 return Err;
     394         422 :             if ((Err = GetDWord(&Length))  != BenErr_OK)
     395           0 :                 return Err;
     396         422 :             break;
     397             : 
     398             :         case BEN_IMMEDIATE0:
     399           0 :             Length = 0; Immediate = true;
     400           0 :             break;
     401             : 
     402             :         case BEN_IMMEDIATE1:
     403           0 :             Length = 1; Immediate = true;
     404           0 :             break;
     405             : 
     406             :         case BEN_IMMEDIATE2:
     407           0 :             Length = 2; Immediate = true;
     408           0 :             break;
     409             : 
     410             :         case BEN_IMMEDIATE3:
     411           0 :             Length = 3; Immediate = true;
     412           0 :             break;
     413             : 
     414             :         case BEN_CONT_IMMEDIATE4:
     415             :         case BEN_IMMEDIATE4:
     416          16 :             Length = 4; Immediate = true;
     417          16 :             break;
     418             : 
     419             :         case BEN_CONT_OFFSET8_LEN4:
     420             :         case BEN_OFFSET8_LEN4:
     421           0 :             EightByteOffset = true;
     422           0 :             break;
     423             : 
     424             :         default:
     425           0 :             return BenErr_OK;
     426             :     }
     427             : 
     428             :     BenByte ImmData[4];
     429         438 :     if (Immediate && Length != 0)
     430          16 :         if ((Err = GetData(ImmData, 4)) != BenErr_OK)
     431           0 :             return Err;
     432             : 
     433         438 :     *pLookAhead = GetCode();
     434             : 
     435         438 :     if (EightByteOffset)
     436           0 :         return BenErr_64BitOffsetNotSupported;
     437             : 
     438         438 :     if (pValue != NULL)
     439             :     {
     440         346 :         if (! Immediate)
     441         346 :             new CBenValueSegment(pValue, Offset, Length);
     442           0 :         else if (Length != 0)
     443             :         {
     444             :             assert(Length <= 4);
     445           0 :             new CBenValueSegment(pValue, ImmData, (unsigned short) Length);
     446             :         }
     447             :     }
     448             : 
     449         438 :     return BenErr_OK;
     450             : }
     451             : 
     452             : bool
     453        3930 : CBenTOCReader::CanGetData(unsigned long Amt)
     454             : {
     455        3930 :     return cCurr + Amt <= cTOCSize;
     456             : }
     457             : 
     458             : BenError
     459        1204 : CBenTOCReader::GetByte(BenByte * pByte)
     460             : {
     461        1204 :     if (! CanGetData(1))
     462           8 :         return BenErr_ReadPastEndOfTOC;
     463             : 
     464        1196 :     *pByte = UtGetIntelByte(cpTOC + cCurr);
     465        1196 :     ++cCurr;
     466        1196 :     return BenErr_OK;
     467             : }
     468             : 
     469             : BenError
     470        2710 : CBenTOCReader::GetDWord(BenDWord * pDWord)
     471             : {
     472        2710 :     if (! CanGetData(4))
     473           0 :         return BenErr_ReadPastEndOfTOC;
     474             : 
     475        2710 :     *pDWord = UtGetIntelDWord(cpTOC + cCurr);
     476        2710 :     cCurr += 4;
     477        2710 :     return BenErr_OK;
     478             : }
     479             : 
     480             : BenByte
     481        1204 : CBenTOCReader::GetCode()
     482             : {
     483             :     BenByte Code;
     484        1196 :     do
     485             :     {
     486        1204 :         if (GetByte(&Code) != BenErr_OK)
     487           8 :             return BEN_READ_PAST_END_OF_TOC;
     488             : 
     489        1196 :         if (Code == BEN_END_OF_BUFFER)
     490             :             // Advance to next block
     491          14 :             cCurr = cBlockSize * ((cCurr + (cBlockSize - 1)) /
     492          14 :               cBlockSize);
     493             :     }
     494        2392 :     while (Code == BEN_NOOP || Code == BEN_END_OF_BUFFER);
     495        1182 :     return Code;
     496             : }
     497             : 
     498             : BenError
     499          16 : CBenTOCReader::GetData(BenDataPtr pBuffer, unsigned long Amt)
     500             : {
     501          16 :     if (! CanGetData(Amt))
     502           0 :         return BenErr_ReadPastEndOfTOC;
     503             : 
     504          16 :     UtHugeMemcpy(pBuffer, cpTOC + cCurr, Amt);
     505          16 :     cCurr += Amt;
     506          16 :     return BenErr_OK;
     507             : }
     508             : }//end OpenStormBento namespace
     509             : 
     510             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10