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

Generated by: LCOV version 1.10