LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/basic/source/classes - image.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 89 251 35.5 %
Date: 2013-07-09 Functions: 9 19 47.4 %
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             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <tools/stream.hxx>
      21             : #include <tools/tenccvt.hxx>
      22             : #include <osl/thread.h>
      23             : #include <basic/sbx.hxx>
      24             : #include "sb.hxx"
      25             : #include <string.h>     // memset() etc
      26             : #include "image.hxx"
      27             : #include <codegen.hxx>
      28         162 : SbiImage::SbiImage()
      29             : {
      30         162 :     pStringOff = NULL;
      31         162 :     pStrings   = NULL;
      32         162 :     pCode      = NULL;
      33         162 :     pLegacyPCode       = NULL;
      34         162 :     nFlags     = 0;
      35         162 :     nStrings   = 0;
      36         162 :     nStringSize= 0;
      37         162 :     nCodeSize  = 0;
      38             :     nLegacyCodeSize  =
      39         162 :     nDimBase   = 0;
      40             :     bInit      =
      41         162 :     bError     = false;
      42         162 :     bFirstInit = true;
      43         162 :     eCharSet   = osl_getThreadTextEncoding();
      44         162 : }
      45             : 
      46          52 : SbiImage::~SbiImage()
      47             : {
      48          26 :     Clear();
      49          26 : }
      50             : 
      51          26 : void SbiImage::Clear()
      52             : {
      53          26 :     delete[] pStringOff;
      54          26 :     delete[] pStrings;
      55          26 :     delete[] pCode;
      56          26 :     ReleaseLegacyBuffer();
      57          26 :     pStringOff = NULL;
      58          26 :     pStrings   = NULL;
      59          26 :     pCode      = NULL;
      60          26 :     nFlags     = 0;
      61          26 :     nStrings   = 0;
      62          26 :     nStringSize= 0;
      63          26 :     nLegacyCodeSize  = 0;
      64          26 :     nCodeSize  = 0;
      65          26 :     eCharSet   = osl_getThreadTextEncoding();
      66          26 :     nDimBase   = 0;
      67          26 :     bError     = false;
      68          26 : }
      69             : 
      70             : /**************************************************************************
      71             : *
      72             : *    Service-Routines for Load/Store
      73             : *
      74             : **************************************************************************/
      75             : 
      76           0 : bool SbiGood( SvStream& r )
      77             : {
      78           0 :     return !r.IsEof() && r.GetError() == SVSTREAM_OK;
      79             : }
      80             : 
      81             : // Open Record
      82           0 : sal_uIntPtr SbiOpenRecord( SvStream& r, sal_uInt16 nSignature, sal_uInt16 nElem )
      83             : {
      84           0 :     sal_uIntPtr nPos = r.Tell();
      85           0 :     r << nSignature << (sal_Int32) 0 << nElem;
      86           0 :     return nPos;
      87             : }
      88             : 
      89             : // Close Record
      90           0 : void SbiCloseRecord( SvStream& r, sal_uIntPtr nOff )
      91             : {
      92           0 :     sal_uIntPtr nPos = r.Tell();
      93           0 :     r.Seek( nOff + 2 );
      94           0 :     r << (sal_Int32) ( nPos - nOff - 8 );
      95           0 :     r.Seek( nPos );
      96           0 : }
      97             : 
      98             : /**************************************************************************
      99             : *
     100             : *    Load/Store
     101             : *
     102             : **************************************************************************/
     103             : 
     104           0 : bool SbiImage::Load( SvStream& r, sal_uInt32& nVersion )
     105             : {
     106             : 
     107             :     sal_uInt16 nSign, nCount;
     108             :     sal_uInt32 nLen, nOff;
     109             : 
     110           0 :     Clear();
     111             :     // Read Master-Record
     112           0 :     r >> nSign >> nLen >> nCount;
     113           0 :     sal_uIntPtr nLast = r.Tell() + nLen;
     114             :     sal_uInt32 nCharSet;               // System charset
     115             :     sal_uInt32 lDimBase;
     116             :     sal_uInt16 nReserved1;
     117             :     sal_uInt32 nReserved2;
     118             :     sal_uInt32 nReserved3;
     119           0 :     bool bBadVer = false;
     120           0 :     if( nSign == B_MODULE )
     121             :     {
     122           0 :         r >> nVersion >> nCharSet >> lDimBase
     123           0 :           >> nFlags >> nReserved1 >> nReserved2 >> nReserved3;
     124           0 :         eCharSet = nCharSet;
     125           0 :         eCharSet = GetSOLoadTextEncoding( eCharSet );
     126           0 :         bBadVer  = ( nVersion > B_CURVERSION );
     127           0 :         nDimBase = (sal_uInt16) lDimBase;
     128             :     }
     129             : 
     130           0 :     bool bLegacy = ( nVersion < B_EXT_IMG_VERSION );
     131             : 
     132             :     sal_uIntPtr nNext;
     133           0 :     while( ( nNext = r.Tell() ) < nLast )
     134             :     {
     135             : 
     136           0 :         r >> nSign >> nLen >> nCount;
     137           0 :         nNext += nLen + 8;
     138           0 :         if( r.GetError() == SVSTREAM_OK )
     139             :         {
     140           0 :             switch( nSign )
     141             :             {
     142             :             case B_NAME:
     143           0 :                 aName = r.ReadUniOrByteString(eCharSet);
     144           0 :                 break;
     145             :             case B_COMMENT:
     146           0 :                 aComment = r.ReadUniOrByteString(eCharSet );
     147           0 :                 break;
     148             :             case B_SOURCE:
     149             :             {
     150           0 :                 aOUSource = r.ReadUniOrByteString(eCharSet);
     151           0 :                 break;
     152             :             }
     153             :             case B_EXTSOURCE:
     154             :             {
     155           0 :                 for( sal_uInt16 j = 0 ; j < nCount ; j++ )
     156             :                 {
     157           0 :                     aOUSource += r.ReadUniOrByteString(eCharSet);
     158             :                 }
     159           0 :                 break;
     160             :             }
     161             :             case B_PCODE:
     162           0 :                 if( bBadVer ) break;
     163           0 :                 pCode = new char[ nLen ];
     164           0 :                 nCodeSize = nLen;
     165           0 :                 r.Read( pCode, nCodeSize );
     166           0 :                 if ( bLegacy )
     167             :                 {
     168           0 :                     ReleaseLegacyBuffer(); // release any previously held buffer
     169           0 :                     nLegacyCodeSize = (sal_uInt16) nCodeSize;
     170           0 :                     pLegacyPCode = pCode;
     171             : 
     172           0 :                     PCodeBuffConvertor< sal_uInt16, sal_uInt32 > aLegacyToNew( (sal_uInt8*)pLegacyPCode, nLegacyCodeSize );
     173           0 :                     aLegacyToNew.convert();
     174           0 :                     pCode = (char*)aLegacyToNew.GetBuffer();
     175           0 :                     nCodeSize = aLegacyToNew.GetSize();
     176             :                     // we don't release the legacy buffer
     177             :                     // right now, thats because the module
     178             :                     // needs it to fix up the method
     179             :                     // nStart members. When that is done
     180             :                     // the module can release the buffer
     181             :                     // or it can wait until this routine
     182             :                     // is called again or when this class                       // destructs all of which will trigger
     183             :                     // release of the buffer.
     184             :                 }
     185           0 :                 break;
     186             :             case B_PUBLICS:
     187             :             case B_POOLDIR:
     188             :             case B_SYMPOOL:
     189             :             case B_LINERANGES:
     190           0 :                 break;
     191             :             case B_STRINGPOOL:
     192           0 :                 if( bBadVer ) break;
     193           0 :                 MakeStrings( nCount );
     194             :                 short i;
     195           0 :                 for( i = 0; i < nStrings && SbiGood( r ); i++ )
     196             :                 {
     197           0 :                     r >> nOff;
     198           0 :                     pStringOff[ i ] = (sal_uInt16) nOff;
     199             :                 }
     200           0 :                 r >> nLen;
     201           0 :                 if( SbiGood( r ) )
     202             :                 {
     203           0 :                     delete [] pStrings;
     204           0 :                     pStrings = new sal_Unicode[ nLen ];
     205           0 :                     nStringSize = (sal_uInt16) nLen;
     206             : 
     207           0 :                     char* pByteStrings = new char[ nLen ];
     208           0 :                     r.Read( pByteStrings, nStringSize );
     209           0 :                     for( short j = 0; j < nStrings; j++ )
     210             :                     {
     211           0 :                         sal_uInt16 nOff2 = (sal_uInt16) pStringOff[ j ];
     212           0 :                         OUString aStr( pByteStrings + nOff2, strlen(pByteStrings + nOff2), eCharSet );
     213           0 :                         memcpy( pStrings + nOff2, aStr.getStr(), (aStr.getLength() + 1) * sizeof( sal_Unicode ) );
     214           0 :                     }
     215           0 :                     delete[] pByteStrings;
     216             :                 }
     217           0 :                 break;
     218             :             case B_MODEND:
     219           0 :                 goto done;
     220             :             default:
     221           0 :                 break;
     222             :             }
     223             :         }
     224             :         else
     225             :         {
     226           0 :             break;
     227             :         }
     228           0 :         r.Seek( nNext );
     229             :     }
     230             : done:
     231           0 :     r.Seek( nLast );
     232           0 :     if( !SbiGood( r ) )
     233             :     {
     234           0 :         bError = true;
     235             :     }
     236           0 :     return !bError;
     237             : }
     238             : 
     239           0 : bool SbiImage::Save( SvStream& r, sal_uInt32 nVer )
     240             : {
     241           0 :     bool bLegacy = ( nVer < B_EXT_IMG_VERSION );
     242             : 
     243             :     // detect if old code exceeds legacy limits
     244             :     // if so, then disallow save
     245           0 :     if ( bLegacy && ExceedsLegacyLimits() )
     246             :     {
     247           0 :         SbiImage aEmptyImg;
     248           0 :         aEmptyImg.aName = aName;
     249           0 :         aEmptyImg.Save( r, B_LEGACYVERSION );
     250           0 :         return true;
     251             :     }
     252             :     // First of all the header
     253           0 :     sal_uIntPtr nStart = SbiOpenRecord( r, B_MODULE, 1 );
     254             :     sal_uIntPtr nPos;
     255             : 
     256           0 :     eCharSet = GetSOStoreTextEncoding( eCharSet );
     257           0 :     if ( bLegacy )
     258             :     {
     259           0 :         r << (sal_Int32) B_LEGACYVERSION;
     260             :     }
     261             :     else
     262             :     {
     263           0 :         r << (sal_Int32) B_CURVERSION;
     264             :     }
     265           0 :     r  << (sal_Int32) eCharSet
     266           0 :        << (sal_Int32) nDimBase
     267           0 :        << (sal_Int16) nFlags
     268           0 :        << (sal_Int16) 0
     269           0 :        << (sal_Int32) 0
     270           0 :        << (sal_Int32) 0;
     271             : 
     272             :     // Name?
     273           0 :     if( !aName.isEmpty() && SbiGood( r ) )
     274             :     {
     275           0 :         nPos = SbiOpenRecord( r, B_NAME, 1 );
     276           0 :         r.WriteUniOrByteString( aName, eCharSet );
     277           0 :         SbiCloseRecord( r, nPos );
     278             :     }
     279             :     // Comment?
     280           0 :     if( !aComment.isEmpty() && SbiGood( r ) )
     281             :     {
     282           0 :         nPos = SbiOpenRecord( r, B_COMMENT, 1 );
     283           0 :         r.WriteUniOrByteString( aComment, eCharSet );
     284           0 :         SbiCloseRecord( r, nPos );
     285             :     }
     286             :     // Source?
     287           0 :     if( !aOUSource.isEmpty() && SbiGood( r ) )
     288             :     {
     289           0 :         nPos = SbiOpenRecord( r, B_SOURCE, 1 );
     290           0 :         r.WriteUniOrByteString( aOUSource, eCharSet );
     291           0 :         SbiCloseRecord( r, nPos );
     292             :     }
     293             :     // Binary data?
     294           0 :     if( pCode && SbiGood( r ) )
     295             :     {
     296           0 :         nPos = SbiOpenRecord( r, B_PCODE, 1 );
     297           0 :         if ( bLegacy )
     298             :         {
     299           0 :             ReleaseLegacyBuffer(); // release any previously held buffer
     300           0 :             PCodeBuffConvertor< sal_uInt32, sal_uInt16 > aNewToLegacy( (sal_uInt8*)pCode, nCodeSize );
     301           0 :             aNewToLegacy.convert();
     302           0 :             pLegacyPCode = (char*)aNewToLegacy.GetBuffer();
     303           0 :             nLegacyCodeSize = aNewToLegacy.GetSize();
     304           0 :             r.Write( pLegacyPCode, nLegacyCodeSize );
     305             :         }
     306             :         else
     307             :         {
     308           0 :             r.Write( pCode, nCodeSize );
     309             :         }
     310           0 :         SbiCloseRecord( r, nPos );
     311             :     }
     312             :     // String-Pool?
     313           0 :     if( nStrings )
     314             :     {
     315           0 :         nPos = SbiOpenRecord( r, B_STRINGPOOL, nStrings );
     316             :         // For every String:
     317             :         //  sal_uInt32 Offset of the Strings in the Stringblock
     318             :         short i;
     319             : 
     320           0 :         for( i = 0; i < nStrings && SbiGood( r ); i++ )
     321             :         {
     322           0 :             r << (sal_uInt32) pStringOff[ i ];
     323             :         }
     324             :         // Then the String-Block
     325           0 :         char* pByteStrings = new char[ nStringSize ];
     326           0 :         for( i = 0; i < nStrings; i++ )
     327             :         {
     328           0 :             sal_uInt16 nOff = (sal_uInt16) pStringOff[ i ];
     329           0 :             OString aStr(OUStringToOString(OUString(pStrings + nOff), eCharSet));
     330           0 :             memcpy( pByteStrings + nOff, aStr.getStr(), (aStr.getLength() + 1) * sizeof( char ) );
     331           0 :         }
     332           0 :         r << (sal_uInt32) nStringSize;
     333           0 :         r.Write( pByteStrings, nStringSize );
     334             : 
     335           0 :         delete[] pByteStrings;
     336           0 :         SbiCloseRecord( r, nPos );
     337             :     }
     338             :     // Set overall length
     339           0 :     SbiCloseRecord( r, nStart );
     340           0 :     if( !SbiGood( r ) )
     341             :     {
     342           0 :         bError = true;
     343             :     }
     344           0 :     return !bError;
     345             : }
     346             : 
     347             : /**************************************************************************
     348             : *
     349             : *    Routines called by the compiler
     350             : *
     351             : **************************************************************************/
     352             : 
     353         162 : void SbiImage::MakeStrings( short nSize )
     354             : {
     355         162 :     nStrings = 0;
     356         162 :     nStringIdx = 0;
     357         162 :     nStringOff = 0;
     358         162 :     nStringSize = 1024;
     359         162 :     pStrings = new sal_Unicode[ nStringSize ];
     360         162 :     pStringOff = new sal_uInt32[ nSize ];
     361         162 :     if( pStrings && pStringOff )
     362             :     {
     363         162 :         nStrings = nSize;
     364         162 :         memset( pStringOff, 0, nSize * sizeof( sal_uInt32 ) );
     365         162 :         memset( pStrings, 0, nStringSize * sizeof( sal_Unicode ) );
     366             :     }
     367             :     else
     368             :     {
     369           0 :         bError = true;
     370             :     }
     371         162 : }
     372             : 
     373             : // Add a string to StringPool. The String buffer is dynamically
     374             : // growing in 1K-Steps
     375        5680 : void SbiImage::AddString( const OUString& r )
     376             : {
     377        5680 :     if( nStringIdx >= nStrings )
     378             :     {
     379           0 :         bError = true;
     380             :     }
     381        5680 :     if( !bError )
     382             :     {
     383        5680 :         sal_Int32  len = r.getLength() + 1;
     384        5680 :         sal_uInt32 needed = nStringOff + len;
     385        5680 :         if( needed > 0xFFFFFF00L )
     386             :         {
     387           0 :             bError = true;  // out of mem!
     388             :         }
     389        5680 :         else if( needed > nStringSize )
     390             :         {
     391          37 :             sal_uInt32 nNewLen = needed + 1024;
     392          37 :             nNewLen &= 0xFFFFFC00;  // trim to 1K border
     393          37 :             sal_Unicode* p = NULL;
     394          37 :             if( (p = new sal_Unicode[ nNewLen ]) != NULL )
     395             :             {
     396          37 :                 memcpy( p, pStrings, nStringSize * sizeof( sal_Unicode ) );
     397          37 :                 delete[] pStrings;
     398          37 :                 pStrings = p;
     399          37 :                 nStringSize = sal::static_int_cast< sal_uInt16 >(nNewLen);
     400             :             }
     401             :             else
     402             :             {
     403           0 :                 bError = true;
     404             :             }
     405             :         }
     406        5680 :         if( !bError )
     407             :         {
     408        5680 :             pStringOff[ nStringIdx++ ] = nStringOff;
     409        5680 :             memcpy( pStrings + nStringOff, r.getStr(), len * sizeof( sal_Unicode ) );
     410        5680 :             nStringOff = nStringOff + len;
     411             :             // Last String? The update the size of the buffer
     412        5680 :             if( nStringIdx >= nStrings )
     413             :             {
     414         162 :                 nStringSize = nStringOff;
     415             :             }
     416             :         }
     417             :     }
     418        5680 : }
     419             : 
     420             : // Add code block
     421             : // The block was fetched by the compiler from class SbBuffer and
     422             : // is already created with new. Additionally it contains all Integers
     423             : // in Big Endian format, so can be directly read/written.
     424         162 : void SbiImage::AddCode( char* p, sal_uInt32 s )
     425             : {
     426         162 :     pCode = p;
     427         162 :     nCodeSize = s;
     428         162 : }
     429             : 
     430             : // Add user type
     431           0 : void SbiImage::AddType(SbxObject* pObject)
     432             : {
     433           0 :     if( !rTypes.Is() )
     434             :     {
     435           0 :         rTypes = new SbxArray;
     436             :     }
     437           0 :     SbxObject *pCopyObject = new SbxObject(*pObject);
     438           0 :     rTypes->Insert (pCopyObject,rTypes->Count());
     439           0 : }
     440             : 
     441           0 : void SbiImage::AddEnum(SbxObject* pObject) // Register enum type
     442             : {
     443           0 :     if( !rEnums.Is() )
     444             :     {
     445           0 :         rEnums = new SbxArray;
     446             :     }
     447           0 :     rEnums->Insert( pObject, rEnums->Count() );
     448           0 : }
     449             : 
     450             : 
     451             : /**************************************************************************
     452             : *
     453             : *    Accessing the image
     454             : *
     455             : **************************************************************************/
     456             : 
     457             : // Note: IDs start with 1
     458       21980 : OUString SbiImage::GetString( short nId ) const
     459             : {
     460       21980 :     if( nId && nId <= nStrings )
     461             :     {
     462       21980 :         sal_uInt32 nOff = pStringOff[ nId - 1 ];
     463       21980 :         sal_Unicode* pStr = pStrings + nOff;
     464             : 
     465             :         // #i42467: Special treatment for vbNullChar
     466       21980 :         if( *pStr == 0 )
     467             :         {
     468         187 :             sal_uInt32 nNextOff = (nId < nStrings) ? pStringOff[ nId ] : nStringOff;
     469         187 :             sal_uInt32 nLen = nNextOff - nOff - 1;
     470         187 :             if( nLen == 1 )
     471             :             {
     472             :                 // Force length 1 and make char 0 afterwards
     473           0 :                 OUString aNullCharStr( (sal_Unicode)0);
     474           0 :                 return aNullCharStr;
     475             :             }
     476             :         }
     477             :         else
     478             :         {
     479       21793 :             return OUString(pStr);
     480             :         }
     481             :     }
     482         187 :     return OUString();
     483             : }
     484             : 
     485         154 : const SbxObject* SbiImage::FindType (OUString aTypeName) const
     486             : {
     487         154 :     return rTypes.Is() ? (SbxObject*)rTypes->Find(aTypeName,SbxCLASS_OBJECT) : NULL;
     488             : }
     489             : 
     490           0 : sal_uInt16 SbiImage::CalcLegacyOffset( sal_Int32 nOffset )
     491             : {
     492           0 :     return SbiCodeGen::calcLegacyOffSet( (sal_uInt8*)pCode, nOffset ) ;
     493             : }
     494             : 
     495           0 : sal_uInt32 SbiImage::CalcNewOffset( sal_Int16 nOffset )
     496             : {
     497           0 :     return SbiCodeGen::calcNewOffSet( (sal_uInt8*)pLegacyPCode, nOffset ) ;
     498             : }
     499             : 
     500          26 : void  SbiImage::ReleaseLegacyBuffer()
     501             : {
     502          26 :     delete[] pLegacyPCode;
     503          26 :     pLegacyPCode = NULL;
     504          26 :     nLegacyCodeSize = 0;
     505          26 : }
     506             : 
     507           0 : bool SbiImage::ExceedsLegacyLimits()
     508             : {
     509           0 :     return ( nStringSize > 0xFF00L ) || ( CalcLegacyOffset( nCodeSize ) > 0xFF00L );
     510             : }
     511             : 
     512             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10