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

Generated by: LCOV version 1.10