xref: /aoo41x/main/sot/source/sdstor/stgelem.cxx (revision 334aff22)
1046d9d1fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3046d9d1fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4046d9d1fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5046d9d1fSAndrew Rist  * distributed with this work for additional information
6046d9d1fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7046d9d1fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8046d9d1fSAndrew Rist  * "License"); you may not use this file except in compliance
9046d9d1fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10046d9d1fSAndrew Rist  *
11046d9d1fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12046d9d1fSAndrew Rist  *
13046d9d1fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14046d9d1fSAndrew Rist  * software distributed under the License is distributed on an
15046d9d1fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16046d9d1fSAndrew Rist  * KIND, either express or implied.  See the License for the
17046d9d1fSAndrew Rist  * specific language governing permissions and limitations
18046d9d1fSAndrew Rist  * under the License.
19046d9d1fSAndrew Rist  *
20046d9d1fSAndrew Rist  *************************************************************/
21046d9d1fSAndrew Rist 
22046d9d1fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sot.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <string.h> // memset(), memcpy()
28cdf0e10cSrcweir #include <rtl/ustring.hxx>
29cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
30cdf0e10cSrcweir #include <unotools/charclass.hxx>
31cdf0e10cSrcweir #include "sot/stg.hxx"
32cdf0e10cSrcweir #include "stgelem.hxx"
33cdf0e10cSrcweir #include "stgcache.hxx"
34cdf0e10cSrcweir #include "stgstrms.hxx"
35cdf0e10cSrcweir #include "stgdir.hxx"
36cdf0e10cSrcweir #include "stgio.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir static sal_uInt8 cStgSignature[ 8 ] = { 0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1 };
39cdf0e10cSrcweir 
40cdf0e10cSrcweir ////////////////////////////// struct ClsId  /////////////////////////////
41cdf0e10cSrcweir 
operator >>(SvStream & r,ClsId & rId)42cdf0e10cSrcweir SvStream& operator >>( SvStream& r, ClsId& rId )
43cdf0e10cSrcweir {
44cdf0e10cSrcweir     r >> rId.n1
45cdf0e10cSrcweir 	  >> rId.n2
46cdf0e10cSrcweir 	  >> rId.n3
47cdf0e10cSrcweir 	  >> rId.n4
48cdf0e10cSrcweir 	  >> rId.n5
49cdf0e10cSrcweir 	  >> rId.n6
50cdf0e10cSrcweir 	  >> rId.n7
51cdf0e10cSrcweir 	  >> rId.n8
52cdf0e10cSrcweir 	  >> rId.n9
53cdf0e10cSrcweir 	  >> rId.n10
54cdf0e10cSrcweir 	  >> rId.n11;
55cdf0e10cSrcweir 	return r;
56cdf0e10cSrcweir }
57cdf0e10cSrcweir 
operator <<(SvStream & r,const ClsId & rId)58cdf0e10cSrcweir SvStream& operator <<( SvStream& r, const ClsId& rId )
59cdf0e10cSrcweir {
60cdf0e10cSrcweir 	return
61cdf0e10cSrcweir 	   r  << (sal_Int32) rId.n1
62cdf0e10cSrcweir 		  << (sal_Int16) rId.n2
63cdf0e10cSrcweir 		  << (sal_Int16) rId.n3
64cdf0e10cSrcweir 		  << (sal_uInt8) rId.n4
65cdf0e10cSrcweir 		  << (sal_uInt8) rId.n5
66cdf0e10cSrcweir 		  << (sal_uInt8) rId.n6
67cdf0e10cSrcweir 		  << (sal_uInt8) rId.n7
68cdf0e10cSrcweir 		  << (sal_uInt8) rId.n8
69cdf0e10cSrcweir 		  << (sal_uInt8) rId.n9
70cdf0e10cSrcweir 		  << (sal_uInt8) rId.n10
71cdf0e10cSrcweir 		  << (sal_uInt8) rId.n11;
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir ///////////////////////////// class StgHeader ////////////////////////////
75cdf0e10cSrcweir 
StgHeader()76cdf0e10cSrcweir StgHeader::StgHeader()
77297a844aSArmin Le Grand : nVersion( 0 )
78297a844aSArmin Le Grand , nByteOrder( 0 )
79297a844aSArmin Le Grand , nPageSize( 0 )
80297a844aSArmin Le Grand , nDataPageSize( 0 )
81297a844aSArmin Le Grand , bDirty( 0 )
82297a844aSArmin Le Grand , nFATSize( 0 )
83297a844aSArmin Le Grand , nTOCstrm( 0 )
84297a844aSArmin Le Grand , nReserved( 0 )
85297a844aSArmin Le Grand , nThreshold( 0 )
86297a844aSArmin Le Grand , nDataFAT( 0 )
87297a844aSArmin Le Grand , nDataFATSize( 0 )
88297a844aSArmin Le Grand , nMasterChain( 0 )
89297a844aSArmin Le Grand , nMaster( 0 )
90cdf0e10cSrcweir {
91297a844aSArmin Le Grand     memset( cSignature, 0, sizeof( cSignature ) );
92297a844aSArmin Le Grand     memset( &aClsId, 0, sizeof( ClsId ) );
93297a844aSArmin Le Grand     memset( cReserved, 0, sizeof( cReserved ) );
94297a844aSArmin Le Grand     memset( nMasterFAT, 0, sizeof( nMasterFAT ) );
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
Init()97cdf0e10cSrcweir void StgHeader::Init()
98cdf0e10cSrcweir {
99cdf0e10cSrcweir     memcpy( cSignature, cStgSignature, 8 );
100297a844aSArmin Le Grand     memset( &aClsId, 0, sizeof( ClsId ) );
101cdf0e10cSrcweir     nVersion      = 0x0003003B;
102cdf0e10cSrcweir     nByteOrder    = 0xFFFE;
103cdf0e10cSrcweir     nPageSize     = 9;          // 512 bytes
104cdf0e10cSrcweir     nDataPageSize = 6;          // 64 bytes
105297a844aSArmin Le Grand     bDirty = 0;
106297a844aSArmin Le Grand     memset( cReserved, 0, sizeof( cReserved ) );
107297a844aSArmin Le Grand     nFATSize = 0;
108297a844aSArmin Le Grand     nTOCstrm = 0;
109297a844aSArmin Le Grand     nReserved = 0;
110cdf0e10cSrcweir     nThreshold    = 4096;
111297a844aSArmin Le Grand     nDataFAT = 0;
112cdf0e10cSrcweir 	nDataFATSize  = 0;
113cdf0e10cSrcweir     nMasterChain  = STG_EOF;
114297a844aSArmin Le Grand 
115cdf0e10cSrcweir     SetTOCStart( STG_EOF );
116cdf0e10cSrcweir     SetDataFATStart( STG_EOF );
11740300343SOliver-Rainer Wittmann     for( short i = 0; i < cFATPagesInHeader; i++ )
118cdf0e10cSrcweir         SetFATPage( i, STG_FREE );
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
Load(StgIo & rIo)121cdf0e10cSrcweir sal_Bool StgHeader::Load( StgIo& rIo )
122cdf0e10cSrcweir {
123297a844aSArmin Le Grand     sal_Bool bResult = sal_False;
124297a844aSArmin Le Grand     if ( rIo.GetStrm() )
125297a844aSArmin Le Grand     {
126297a844aSArmin Le Grand         SvStream& r = *rIo.GetStrm();
127297a844aSArmin Le Grand         bResult = Load( r );
128297a844aSArmin Le Grand 	    bResult = ( bResult && rIo.Good() );
129297a844aSArmin Le Grand     }
130297a844aSArmin Le Grand 
131297a844aSArmin Le Grand     return bResult;
132cdf0e10cSrcweir }
133cdf0e10cSrcweir 
Load(SvStream & r)134cdf0e10cSrcweir sal_Bool StgHeader::Load( SvStream& r )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir 	r.Seek( 0L );
137cdf0e10cSrcweir     r.Read( cSignature, 8 );
138cdf0e10cSrcweir 	r >> aClsId						// 08 Class ID
139cdf0e10cSrcweir 	  >> nVersion 					// 1A version number
140cdf0e10cSrcweir 	  >> nByteOrder 				// 1C Unicode byte order indicator
141cdf0e10cSrcweir 	  >> nPageSize 					// 1E 1 << nPageSize = block size
142cdf0e10cSrcweir 	  >> nDataPageSize;				// 20 1 << this size == data block size
143cdf0e10cSrcweir 	r.SeekRel( 10 );
144cdf0e10cSrcweir 	r >> nFATSize					// 2C total number of FAT pages
145cdf0e10cSrcweir 	  >> nTOCstrm 					// 30 starting page for the TOC stream
146cdf0e10cSrcweir 	  >> nReserved 					// 34
147cdf0e10cSrcweir 	  >> nThreshold  				// 38 minimum file size for big data
148cdf0e10cSrcweir 	  >> nDataFAT 					// 3C page # of 1st data FAT block
149cdf0e10cSrcweir 	  >> nDataFATSize				// 40 # of data FATpages
150cdf0e10cSrcweir 	  >> nMasterChain 				// 44 chain to the next master block
151cdf0e10cSrcweir 	  >> nMaster;					// 48 # of additional master blocks
15240300343SOliver-Rainer Wittmann 	for( short i = 0; i < cFATPagesInHeader; i++ )
153cdf0e10cSrcweir 		r >> nMasterFAT[ i ];
154297a844aSArmin Le Grand 
155297a844aSArmin Le Grand     return ( r.GetErrorCode() == ERRCODE_NONE && Check() );
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
Store(StgIo & rIo)158cdf0e10cSrcweir sal_Bool StgHeader::Store( StgIo& rIo )
159cdf0e10cSrcweir {
160cdf0e10cSrcweir 	if( !bDirty )
161cdf0e10cSrcweir 		return sal_True;
162cdf0e10cSrcweir 	SvStream& r = *rIo.GetStrm();
163cdf0e10cSrcweir 	r.Seek( 0L );
164cdf0e10cSrcweir     r.Write( cSignature, 8 + 16 );
165cdf0e10cSrcweir 	r << nVersion 					// 1A version number
166cdf0e10cSrcweir 	  << nByteOrder 				// 1C Unicode byte order indicator
167cdf0e10cSrcweir 	  << nPageSize 					// 1E 1 << nPageSize = block size
168cdf0e10cSrcweir 	  << nDataPageSize 				// 20 1 << this size == data block size
169cdf0e10cSrcweir 	  << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int16) 0
170cdf0e10cSrcweir 	  << nFATSize					// 2C total number of FAT pages
171cdf0e10cSrcweir 	  << nTOCstrm 					// 30 starting page for the TOC stream
172cdf0e10cSrcweir 	  << nReserved 					// 34
173cdf0e10cSrcweir 	  << nThreshold  				// 38 minimum file size for big data
174cdf0e10cSrcweir 	  << nDataFAT 					// 3C page # of 1st data FAT block
175cdf0e10cSrcweir 	  << nDataFATSize				// 40 # of data FAT pages
176cdf0e10cSrcweir 	  << nMasterChain 				// 44 chain to the next master block
177cdf0e10cSrcweir 	  << nMaster;					// 48 # of additional master blocks
17840300343SOliver-Rainer Wittmann 	for( short i = 0; i < cFATPagesInHeader; i++ )
179cdf0e10cSrcweir 		r << nMasterFAT[ i ];
180cdf0e10cSrcweir 	bDirty = !rIo.Good();
181cdf0e10cSrcweir 	return sal_Bool( !bDirty );
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
lcl_wontoverflow(short shift)184cdf0e10cSrcweir static bool lcl_wontoverflow(short shift)
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     return shift >= 0 && shift < (short)sizeof(short) * 8 - 1;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir // Perform thorough checks also on unknown variables
Check()190cdf0e10cSrcweir sal_Bool StgHeader::Check()
191cdf0e10cSrcweir {
192cdf0e10cSrcweir     return sal_Bool( memcmp( cSignature, cStgSignature, 8 ) == 0
193cdf0e10cSrcweir             && (short) ( nVersion >> 16 ) == 3 )
194297a844aSArmin Le Grand             && nPageSize == 9
195cdf0e10cSrcweir             && lcl_wontoverflow(nPageSize)
196297a844aSArmin Le Grand             && lcl_wontoverflow(nDataPageSize)
197297a844aSArmin Le Grand             && nFATSize > 0
198297a844aSArmin Le Grand             && nTOCstrm >= 0
199297a844aSArmin Le Grand             && nThreshold > 0
20040300343SOliver-Rainer Wittmann             && ( nDataFAT == STG_EOF || ( nDataFAT >= 0 && nDataFATSize > 0 ) )
201*334aff22SOliver-Rainer Wittmann             && ( nMasterChain == STG_FREE || nMasterChain == STG_EOF || ( nMasterChain >=0 && nMaster > 0 ) )
202297a844aSArmin Le Grand             && nMaster >= 0;
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
GetFATPage(short n) const205cdf0e10cSrcweir sal_Int32 StgHeader::GetFATPage( short n ) const
206cdf0e10cSrcweir {
20740300343SOliver-Rainer Wittmann     if( n >= 0 && n < cFATPagesInHeader )
208cdf0e10cSrcweir         return nMasterFAT[ n ];
209cdf0e10cSrcweir     else
210cdf0e10cSrcweir         return STG_EOF;
211cdf0e10cSrcweir }
212cdf0e10cSrcweir 
SetFATPage(short n,sal_Int32 nb)213cdf0e10cSrcweir void StgHeader::SetFATPage( short n, sal_Int32 nb )
214cdf0e10cSrcweir {
21540300343SOliver-Rainer Wittmann     if( n >= 0 && n < cFATPagesInHeader )
216cdf0e10cSrcweir 	{
217cdf0e10cSrcweir 		if( nMasterFAT[ n ] != nb )
218cdf0e10cSrcweir         	bDirty = sal_True, nMasterFAT[ n ] = nb;
219cdf0e10cSrcweir 	}
220cdf0e10cSrcweir }
221cdf0e10cSrcweir 
SetClassId(const ClsId & r)222cdf0e10cSrcweir void StgHeader::SetClassId( const ClsId& r )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	if( memcmp( &aClsId, &r, sizeof( ClsId ) ) )
225cdf0e10cSrcweir 		bDirty = sal_True, memcpy( &aClsId, &r, sizeof( ClsId ) );
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
SetTOCStart(sal_Int32 n)228cdf0e10cSrcweir void StgHeader::SetTOCStart( sal_Int32 n )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir 	if( n != nTOCstrm ) bDirty = sal_True, nTOCstrm = n;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
SetDataFATStart(sal_Int32 n)233cdf0e10cSrcweir void StgHeader::SetDataFATStart( sal_Int32 n )
234cdf0e10cSrcweir {
235cdf0e10cSrcweir 	if( n != nDataFAT ) bDirty = sal_True, nDataFAT = n;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
SetDataFATSize(sal_Int32 n)238cdf0e10cSrcweir void StgHeader::SetDataFATSize( sal_Int32 n )
239cdf0e10cSrcweir {
240cdf0e10cSrcweir 	if( n != nDataFATSize ) bDirty = sal_True, nDataFATSize = n;
241cdf0e10cSrcweir }
242cdf0e10cSrcweir 
SetFATSize(sal_Int32 n)243cdf0e10cSrcweir void StgHeader::SetFATSize( sal_Int32 n )
244cdf0e10cSrcweir {
245cdf0e10cSrcweir 	if( n != nFATSize ) bDirty = sal_True, nFATSize = n;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
SetFATChain(sal_Int32 n)248cdf0e10cSrcweir void StgHeader::SetFATChain( sal_Int32 n )
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	if( n != nMasterChain )
251cdf0e10cSrcweir 		bDirty = sal_True, nMasterChain = n;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
SetMasters(sal_Int32 n)254cdf0e10cSrcweir void StgHeader::SetMasters( sal_Int32 n )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir 	if( n != nMaster ) bDirty = sal_True, nMaster = n;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir ///////////////////////////// class StgEntry /////////////////////////////
260cdf0e10cSrcweir 
261cdf0e10cSrcweir // This class is only a wrapper around teh dir entry structure
262cdf0e10cSrcweir // which retrieves and sets data.
263cdf0e10cSrcweir 
264cdf0e10cSrcweir // The name must be smaller than 32 chars. Conversion into Unicode
265cdf0e10cSrcweir // is easy, since the 1st 256 characters of the Windows ANSI set
266cdf0e10cSrcweir // equal the 1st 256 Unicode characters.
267cdf0e10cSrcweir /*
268cdf0e10cSrcweir void ToUnicode_Impl( String& rName )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir 	rName.Erase( 32 );
271cdf0e10cSrcweir 	rName.Convert( ::GetSystemCharSet(), CHARSET_ANSI );
272cdf0e10cSrcweir 	// brute force is OK
273cdf0e10cSrcweir 	sal_uInt8* p = (sal_uInt8*) rName.GetCharStr();
274cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < rName.Len(); i++, p++ )
275cdf0e10cSrcweir     {
276cdf0e10cSrcweir         // check each character and substitute blanks for illegal ones
277cdf0e10cSrcweir         sal_uInt8 cChar = *p;
278cdf0e10cSrcweir         if( cChar == '!' || cChar == ':' || cChar == '\\' || cChar == '/' )
279cdf0e10cSrcweir 			*p = ' ';
280cdf0e10cSrcweir     }
281cdf0e10cSrcweir }
282cdf0e10cSrcweir */
283cdf0e10cSrcweir /*
284cdf0e10cSrcweir static void FromUnicode( String& rName )
285cdf0e10cSrcweir {
286cdf0e10cSrcweir 	rName.Convert( CHARSET_ANSI, ::GetSystemCharSet() );
287cdf0e10cSrcweir }
288cdf0e10cSrcweir */
Init()289cdf0e10cSrcweir sal_Bool StgEntry::Init()
290cdf0e10cSrcweir {
291297a844aSArmin Le Grand     memset( nName, 0, sizeof( nName ) );
292297a844aSArmin Le Grand     nNameLen = 0;
293297a844aSArmin Le Grand     cType = 0;
294297a844aSArmin Le Grand     cFlags = 0;
295297a844aSArmin Le Grand     nLeft = 0;
296297a844aSArmin Le Grand     nRight = 0;
297297a844aSArmin Le Grand     nChild = 0;
298297a844aSArmin Le Grand 	memset( &aClsId, 0, sizeof( aClsId ) );
299297a844aSArmin Le Grand     nFlags = 0;
300297a844aSArmin Le Grand     nMtime[0] = 0; nMtime[1] = 0;
301297a844aSArmin Le Grand     nAtime[0] = 0; nAtime[1] = 0;
302297a844aSArmin Le Grand     nPage1 = 0;
303297a844aSArmin Le Grand     nSize = 0;
304297a844aSArmin Le Grand     nUnknown = 0;
305297a844aSArmin Le Grand 
306cdf0e10cSrcweir     SetLeaf( STG_LEFT,  STG_FREE );
307cdf0e10cSrcweir     SetLeaf( STG_RIGHT, STG_FREE );
308cdf0e10cSrcweir     SetLeaf( STG_CHILD, STG_FREE );
309cdf0e10cSrcweir     SetLeaf( STG_DATA,  STG_EOF );
310cdf0e10cSrcweir     return sal_True;
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
ToUpperUnicode(const String & rStr)313cdf0e10cSrcweir static String ToUpperUnicode( const String & rStr )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir 	// I don't know the locale, so en_US is hopefully fine
316cdf0e10cSrcweir 	/*
317cdf0e10cSrcweir 	com.sun.star.lang.Locale aLocale;
318cdf0e10cSrcweir 	aLocale.Language = OUString::createFromAscii( "en" );
319cdf0e10cSrcweir 	aLocale.Country  = OUString::createFromAscii( "US" );
320cdf0e10cSrcweir 	*/
321cdf0e10cSrcweir 	static rtl::OUString aEN=rtl::OUString::createFromAscii( "en" );
322cdf0e10cSrcweir 	static rtl::OUString aUS=rtl::OUString::createFromAscii( "US" );
323cdf0e10cSrcweir 	static CharClass aCC( com::sun::star::lang::Locale( aEN, aUS, rtl::OUString() ) );
324cdf0e10cSrcweir 	return aCC.toUpper( rStr, 0, rStr.Len() );
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 
SetName(const String & rName)328cdf0e10cSrcweir sal_Bool StgEntry::SetName( const String& rName )
329cdf0e10cSrcweir {
330cdf0e10cSrcweir     // I don't know the locale, so en_US is hopefully fine
331cdf0e10cSrcweir     aName = ToUpperUnicode( rName );
332cdf0e10cSrcweir     aName.Erase( 31 );
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     int i;
335cdf0e10cSrcweir     for( i = 0; i < aName.Len() && i < 32; i++ )
336cdf0e10cSrcweir         nName[ i ] = rName.GetChar( sal_uInt16( i ));
337cdf0e10cSrcweir     while( i < 32 )
338cdf0e10cSrcweir         nName[ i++ ] = 0;
339cdf0e10cSrcweir     nNameLen = ( aName.Len() + 1 ) << 1;
340cdf0e10cSrcweir     return sal_True;
341cdf0e10cSrcweir }
342cdf0e10cSrcweir 
GetLeaf(StgEntryRef eRef) const343cdf0e10cSrcweir sal_Int32 StgEntry::GetLeaf( StgEntryRef eRef ) const
344cdf0e10cSrcweir {
345cdf0e10cSrcweir     sal_Int32 n = -1;
346cdf0e10cSrcweir     switch( eRef )
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         case STG_LEFT:  n = nLeft;  break;
349cdf0e10cSrcweir         case STG_RIGHT: n = nRight; break;
350cdf0e10cSrcweir         case STG_CHILD: n = nChild; break;
351cdf0e10cSrcweir         case STG_DATA:  n = nPage1; break;
352cdf0e10cSrcweir     }
353cdf0e10cSrcweir     return n;
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
SetLeaf(StgEntryRef eRef,sal_Int32 nPage)356cdf0e10cSrcweir void StgEntry::SetLeaf( StgEntryRef eRef, sal_Int32 nPage )
357cdf0e10cSrcweir {
358cdf0e10cSrcweir     switch( eRef )
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         case STG_LEFT:  nLeft  = nPage; break;
361cdf0e10cSrcweir         case STG_RIGHT: nRight = nPage; break;
362cdf0e10cSrcweir         case STG_CHILD: nChild = nPage; break;
363cdf0e10cSrcweir         case STG_DATA:  nPage1 = nPage; break;
364cdf0e10cSrcweir     }
365cdf0e10cSrcweir }
366cdf0e10cSrcweir 
GetTime(StgEntryTime eTime) const367cdf0e10cSrcweir const sal_Int32* StgEntry::GetTime( StgEntryTime eTime ) const
368cdf0e10cSrcweir {
369cdf0e10cSrcweir     return( eTime == STG_MODIFIED ) ? nMtime : nAtime;
370cdf0e10cSrcweir }
371cdf0e10cSrcweir 
SetTime(StgEntryTime eTime,sal_Int32 * pTime)372cdf0e10cSrcweir void StgEntry::SetTime( StgEntryTime eTime, sal_Int32* pTime )
373cdf0e10cSrcweir {
374cdf0e10cSrcweir     if( eTime == STG_MODIFIED )
375cdf0e10cSrcweir         nMtime[ 0 ] = *pTime++, nMtime[ 1 ] = *pTime;
376cdf0e10cSrcweir     else
377cdf0e10cSrcweir         nAtime[ 0 ] = *pTime++, nAtime[ 1 ] = *pTime;
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
SetClassId(const ClsId & r)380cdf0e10cSrcweir void StgEntry::SetClassId( const ClsId& r )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir 	memcpy( &aClsId, &r, sizeof( ClsId ) );
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
GetName(String & rName) const385cdf0e10cSrcweir void StgEntry::GetName( String& rName ) const
386cdf0e10cSrcweir {
387cdf0e10cSrcweir     sal_uInt16 n = nNameLen;
388cdf0e10cSrcweir     if( n )
389cdf0e10cSrcweir         n = ( n >> 1 ) - 1;
390cdf0e10cSrcweir 	rName = String( nName, n );
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
393cdf0e10cSrcweir // Compare two entries. Do this case-insensitive.
394cdf0e10cSrcweir 
Compare(const StgEntry & r) const395cdf0e10cSrcweir short StgEntry::Compare( const StgEntry& r ) const
396cdf0e10cSrcweir {
397cdf0e10cSrcweir 	/*
398cdf0e10cSrcweir     short nRes = r.nNameLen - nNameLen;
399cdf0e10cSrcweir     if( !nRes ) return strcmp( r.aName, aName );
400cdf0e10cSrcweir 	else return nRes;
401cdf0e10cSrcweir 	*/
402cdf0e10cSrcweir     sal_Int32 nRes = r.nNameLen - nNameLen;
403cdf0e10cSrcweir     if( !nRes )
404cdf0e10cSrcweir 		nRes = r.aName.CompareTo( aName );
405cdf0e10cSrcweir 	return (short)nRes;
406cdf0e10cSrcweir 	//return aName.CompareTo( r.aName );
407cdf0e10cSrcweir }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir // These load/store operations are a bit more complicated,
410cdf0e10cSrcweir // since they have to copy their contents into a packed structure.
411cdf0e10cSrcweir 
Load(const void * pFrom,sal_uInt32 nBufSize)412297a844aSArmin Le Grand sal_Bool StgEntry::Load( const void* pFrom, sal_uInt32 nBufSize )
413cdf0e10cSrcweir {
414297a844aSArmin Le Grand     if ( nBufSize < 128 )
415297a844aSArmin Le Grand         return sal_False;
416297a844aSArmin Le Grand 
417297a844aSArmin Le Grand 	SvMemoryStream r( (sal_Char*) pFrom, nBufSize, STREAM_READ );
418cdf0e10cSrcweir 	for( short i = 0; i < 32; i++ )
419cdf0e10cSrcweir 		r >> nName[ i ];			// 00 name as WCHAR
420cdf0e10cSrcweir 	r >> nNameLen 					// 40 size of name in bytes including 00H
421cdf0e10cSrcweir 	  >> cType 						// 42 entry type
422cdf0e10cSrcweir 	  >> cFlags						// 43 0 or 1 (tree balance?)
423cdf0e10cSrcweir 	  >> nLeft						// 44 left node entry
424cdf0e10cSrcweir 	  >> nRight						// 48 right node entry
425cdf0e10cSrcweir 	  >> nChild						// 4C 1st child entry if storage
426cdf0e10cSrcweir 	  >> aClsId						// 50 class ID (optional)
427cdf0e10cSrcweir 	  >> nFlags						// 60 state flags(?)
428cdf0e10cSrcweir 	  >> nMtime[ 0 ]				// 64 modification time
429cdf0e10cSrcweir 	  >> nMtime[ 1 ]				// 64 modification time
430cdf0e10cSrcweir 	  >> nAtime[ 0 ] 				// 6C creation and access time
431cdf0e10cSrcweir 	  >> nAtime[ 1 ] 				// 6C creation and access time
432cdf0e10cSrcweir 	  >> nPage1						// 74 starting block (either direct or translated)
433cdf0e10cSrcweir 	  >> nSize 						// 78 file size
434cdf0e10cSrcweir 	  >> nUnknown;					// 7C unknown
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     sal_uInt16 n = nNameLen;
437cdf0e10cSrcweir     if( n )
438cdf0e10cSrcweir 		n = ( n >> 1 ) - 1;
43940300343SOliver-Rainer Wittmann 	if ( n > 31 ||
44040300343SOliver-Rainer Wittmann          (nSize < 0 && cType != STG_STORAGE) ||
441*334aff22SOliver-Rainer Wittmann          ( nPage1 < 0 && nPage1 != STG_FREE && nPage1 != STG_EOF ) )
442cdf0e10cSrcweir     {
443cdf0e10cSrcweir         // the size makes no sence for the substorage
444cdf0e10cSrcweir         // TODO/LATER: actually the size should be an unsigned value, but in this case it would mean a stream of more than 2Gb
445cdf0e10cSrcweir 		return sal_False;
446cdf0e10cSrcweir     }
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	aName = String( nName, n );
449cdf0e10cSrcweir 	// I don't know the locale, so en_US is hopefully fine
450cdf0e10cSrcweir 	aName = ToUpperUnicode( aName );
451cdf0e10cSrcweir 	aName.Erase( 31 );
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 	return sal_True;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
Store(void * pTo)456cdf0e10cSrcweir void StgEntry::Store( void* pTo )
457cdf0e10cSrcweir {
458cdf0e10cSrcweir 	SvMemoryStream r( (sal_Char *)pTo, 128, STREAM_WRITE );
459cdf0e10cSrcweir 	for( short i = 0; i < 32; i++ )
460cdf0e10cSrcweir 		r << nName[ i ];			// 00 name as WCHAR
461cdf0e10cSrcweir 	r << nNameLen 					// 40 size of name in bytes including 00H
462cdf0e10cSrcweir 	  << cType 						// 42 entry type
463cdf0e10cSrcweir 	  << cFlags						// 43 0 or 1 (tree balance?)
464cdf0e10cSrcweir 	  << nLeft						// 44 left node entry
465cdf0e10cSrcweir 	  << nRight						// 48 right node entry
466cdf0e10cSrcweir 	  << nChild						// 4C 1st child entry if storage;
467cdf0e10cSrcweir 	  << aClsId						// 50 class ID (optional)
468cdf0e10cSrcweir 	  << nFlags						// 60 state flags(?)
469cdf0e10cSrcweir 	  << nMtime[ 0 ]				// 64 modification time
470cdf0e10cSrcweir 	  << nMtime[ 1 ]				// 64 modification time
471cdf0e10cSrcweir 	  << nAtime[ 0 ] 				// 6C creation and access time
472cdf0e10cSrcweir 	  << nAtime[ 1 ] 				// 6C creation and access time
473cdf0e10cSrcweir 	  << nPage1						// 74 starting block (either direct or translated)
474cdf0e10cSrcweir 	  << nSize 						// 78 file size
475cdf0e10cSrcweir 	  << nUnknown;					// 7C unknown
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478