xref: /aoo42x/main/sot/source/sdstor/stgelem.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sot.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <string.h> // memset(), memcpy()
32*cdf0e10cSrcweir #include <rtl/ustring.hxx>
33*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
34*cdf0e10cSrcweir #include <unotools/charclass.hxx>
35*cdf0e10cSrcweir #include "sot/stg.hxx"
36*cdf0e10cSrcweir #include "stgelem.hxx"
37*cdf0e10cSrcweir #include "stgcache.hxx"
38*cdf0e10cSrcweir #include "stgstrms.hxx"
39*cdf0e10cSrcweir #include "stgdir.hxx"
40*cdf0e10cSrcweir #include "stgio.hxx"
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir static sal_uInt8 cStgSignature[ 8 ] = { 0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1 };
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir ////////////////////////////// struct ClsId  /////////////////////////////
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir SvStream& operator >>( SvStream& r, ClsId& rId )
47*cdf0e10cSrcweir {
48*cdf0e10cSrcweir     r >> rId.n1
49*cdf0e10cSrcweir 	  >> rId.n2
50*cdf0e10cSrcweir 	  >> rId.n3
51*cdf0e10cSrcweir 	  >> rId.n4
52*cdf0e10cSrcweir 	  >> rId.n5
53*cdf0e10cSrcweir 	  >> rId.n6
54*cdf0e10cSrcweir 	  >> rId.n7
55*cdf0e10cSrcweir 	  >> rId.n8
56*cdf0e10cSrcweir 	  >> rId.n9
57*cdf0e10cSrcweir 	  >> rId.n10
58*cdf0e10cSrcweir 	  >> rId.n11;
59*cdf0e10cSrcweir 	return r;
60*cdf0e10cSrcweir }
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir SvStream& operator <<( SvStream& r, const ClsId& rId )
63*cdf0e10cSrcweir {
64*cdf0e10cSrcweir 	return
65*cdf0e10cSrcweir 	   r  << (sal_Int32) rId.n1
66*cdf0e10cSrcweir 		  << (sal_Int16) rId.n2
67*cdf0e10cSrcweir 		  << (sal_Int16) rId.n3
68*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n4
69*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n5
70*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n6
71*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n7
72*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n8
73*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n9
74*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n10
75*cdf0e10cSrcweir 		  << (sal_uInt8) rId.n11;
76*cdf0e10cSrcweir }
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir ///////////////////////////// class StgHeader ////////////////////////////
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir StgHeader::StgHeader()
81*cdf0e10cSrcweir {
82*cdf0e10cSrcweir     memset( this, 0, sizeof( StgHeader ) );
83*cdf0e10cSrcweir }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir void StgHeader::Init()
86*cdf0e10cSrcweir {
87*cdf0e10cSrcweir     memset( this, 0, sizeof( StgHeader ) );
88*cdf0e10cSrcweir     memcpy( cSignature, cStgSignature, 8 );
89*cdf0e10cSrcweir     nVersion      = 0x0003003B;
90*cdf0e10cSrcweir     nByteOrder    = 0xFFFE;
91*cdf0e10cSrcweir     nPageSize     = 9;          // 512 bytes
92*cdf0e10cSrcweir     nDataPageSize = 6;          // 64 bytes
93*cdf0e10cSrcweir     nThreshold    = 4096;
94*cdf0e10cSrcweir 	nDataFATSize  = 0;
95*cdf0e10cSrcweir     nMasterChain  = STG_EOF;
96*cdf0e10cSrcweir     SetTOCStart( STG_EOF );
97*cdf0e10cSrcweir     SetDataFATStart( STG_EOF );
98*cdf0e10cSrcweir     for( short i = 0; i < 109; i++ )
99*cdf0e10cSrcweir         SetFATPage( i, STG_FREE );
100*cdf0e10cSrcweir }
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir sal_Bool StgHeader::Load( StgIo& rIo )
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir 	SvStream& r = *rIo.GetStrm();
105*cdf0e10cSrcweir     Load( r );
106*cdf0e10cSrcweir 	return rIo.Good();
107*cdf0e10cSrcweir }
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir sal_Bool StgHeader::Load( SvStream& r )
110*cdf0e10cSrcweir {
111*cdf0e10cSrcweir 	r.Seek( 0L );
112*cdf0e10cSrcweir     r.Read( cSignature, 8 );
113*cdf0e10cSrcweir 	r >> aClsId						// 08 Class ID
114*cdf0e10cSrcweir 	  >> nVersion 					// 1A version number
115*cdf0e10cSrcweir 	  >> nByteOrder 				// 1C Unicode byte order indicator
116*cdf0e10cSrcweir 	  >> nPageSize 					// 1E 1 << nPageSize = block size
117*cdf0e10cSrcweir 	  >> nDataPageSize;				// 20 1 << this size == data block size
118*cdf0e10cSrcweir 	r.SeekRel( 10 );
119*cdf0e10cSrcweir 	r >> nFATSize					// 2C total number of FAT pages
120*cdf0e10cSrcweir 	  >> nTOCstrm 					// 30 starting page for the TOC stream
121*cdf0e10cSrcweir 	  >> nReserved 					// 34
122*cdf0e10cSrcweir 	  >> nThreshold  				// 38 minimum file size for big data
123*cdf0e10cSrcweir 	  >> nDataFAT 					// 3C page # of 1st data FAT block
124*cdf0e10cSrcweir 	  >> nDataFATSize				// 40 # of data FATpages
125*cdf0e10cSrcweir 	  >> nMasterChain 				// 44 chain to the next master block
126*cdf0e10cSrcweir 	  >> nMaster;					// 48 # of additional master blocks
127*cdf0e10cSrcweir 	for( short i = 0; i < 109; i++ )
128*cdf0e10cSrcweir 		r >> nMasterFAT[ i ];
129*cdf0e10cSrcweir     return r.GetErrorCode() == ERRCODE_NONE;
130*cdf0e10cSrcweir }
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir sal_Bool StgHeader::Store( StgIo& rIo )
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir 	if( !bDirty )
135*cdf0e10cSrcweir 		return sal_True;
136*cdf0e10cSrcweir 	SvStream& r = *rIo.GetStrm();
137*cdf0e10cSrcweir 	r.Seek( 0L );
138*cdf0e10cSrcweir     r.Write( cSignature, 8 + 16 );
139*cdf0e10cSrcweir 	r << nVersion 					// 1A version number
140*cdf0e10cSrcweir 	  << nByteOrder 				// 1C Unicode byte order indicator
141*cdf0e10cSrcweir 	  << nPageSize 					// 1E 1 << nPageSize = block size
142*cdf0e10cSrcweir 	  << nDataPageSize 				// 20 1 << this size == data block size
143*cdf0e10cSrcweir 	  << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int16) 0
144*cdf0e10cSrcweir 	  << nFATSize					// 2C total number of FAT pages
145*cdf0e10cSrcweir 	  << nTOCstrm 					// 30 starting page for the TOC stream
146*cdf0e10cSrcweir 	  << nReserved 					// 34
147*cdf0e10cSrcweir 	  << nThreshold  				// 38 minimum file size for big data
148*cdf0e10cSrcweir 	  << nDataFAT 					// 3C page # of 1st data FAT block
149*cdf0e10cSrcweir 	  << nDataFATSize				// 40 # of data FAT pages
150*cdf0e10cSrcweir 	  << nMasterChain 				// 44 chain to the next master block
151*cdf0e10cSrcweir 	  << nMaster;					// 48 # of additional master blocks
152*cdf0e10cSrcweir 	for( short i = 0; i < 109; i++ )
153*cdf0e10cSrcweir 		r << nMasterFAT[ i ];
154*cdf0e10cSrcweir 	bDirty = !rIo.Good();
155*cdf0e10cSrcweir 	return sal_Bool( !bDirty );
156*cdf0e10cSrcweir }
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir static bool lcl_wontoverflow(short shift)
159*cdf0e10cSrcweir {
160*cdf0e10cSrcweir     return shift >= 0 && shift < (short)sizeof(short) * 8 - 1;
161*cdf0e10cSrcweir }
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir // Perform thorough checks also on unknown variables
164*cdf0e10cSrcweir sal_Bool StgHeader::Check()
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir     return sal_Bool( memcmp( cSignature, cStgSignature, 8 ) == 0
167*cdf0e10cSrcweir             && (short) ( nVersion >> 16 ) == 3 )
168*cdf0e10cSrcweir             && lcl_wontoverflow(nPageSize)
169*cdf0e10cSrcweir             && lcl_wontoverflow(nDataPageSize);
170*cdf0e10cSrcweir }
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir sal_Int32 StgHeader::GetFATPage( short n ) const
173*cdf0e10cSrcweir {
174*cdf0e10cSrcweir     if( n >= 0 && n < 109 )
175*cdf0e10cSrcweir         return nMasterFAT[ n ];
176*cdf0e10cSrcweir     else
177*cdf0e10cSrcweir         return STG_EOF;
178*cdf0e10cSrcweir }
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir void StgHeader::SetFATPage( short n, sal_Int32 nb )
181*cdf0e10cSrcweir {
182*cdf0e10cSrcweir     if( n >= 0 && n < 109 )
183*cdf0e10cSrcweir 	{
184*cdf0e10cSrcweir 		if( nMasterFAT[ n ] != nb )
185*cdf0e10cSrcweir         	bDirty = sal_True, nMasterFAT[ n ] = nb;
186*cdf0e10cSrcweir 	}
187*cdf0e10cSrcweir }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir void StgHeader::SetClassId( const ClsId& r )
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir 	if( memcmp( &aClsId, &r, sizeof( ClsId ) ) )
192*cdf0e10cSrcweir 		bDirty = sal_True, memcpy( &aClsId, &r, sizeof( ClsId ) );
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir void StgHeader::SetTOCStart( sal_Int32 n )
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir 	if( n != nTOCstrm ) bDirty = sal_True, nTOCstrm = n;
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir void StgHeader::SetDataFATStart( sal_Int32 n )
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir 	if( n != nDataFAT ) bDirty = sal_True, nDataFAT = n;
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir void StgHeader::SetDataFATSize( sal_Int32 n )
206*cdf0e10cSrcweir {
207*cdf0e10cSrcweir 	if( n != nDataFATSize ) bDirty = sal_True, nDataFATSize = n;
208*cdf0e10cSrcweir }
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir void StgHeader::SetFATSize( sal_Int32 n )
211*cdf0e10cSrcweir {
212*cdf0e10cSrcweir 	if( n != nFATSize ) bDirty = sal_True, nFATSize = n;
213*cdf0e10cSrcweir }
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir void StgHeader::SetFATChain( sal_Int32 n )
216*cdf0e10cSrcweir {
217*cdf0e10cSrcweir 	if( n != nMasterChain )
218*cdf0e10cSrcweir 		bDirty = sal_True, nMasterChain = n;
219*cdf0e10cSrcweir }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir void StgHeader::SetMasters( sal_Int32 n )
222*cdf0e10cSrcweir {
223*cdf0e10cSrcweir 	if( n != nMaster ) bDirty = sal_True, nMaster = n;
224*cdf0e10cSrcweir }
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir ///////////////////////////// class StgEntry /////////////////////////////
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir // This class is only a wrapper around teh dir entry structure
229*cdf0e10cSrcweir // which retrieves and sets data.
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir // The name must be smaller than 32 chars. Conversion into Unicode
232*cdf0e10cSrcweir // is easy, since the 1st 256 characters of the Windows ANSI set
233*cdf0e10cSrcweir // equal the 1st 256 Unicode characters.
234*cdf0e10cSrcweir /*
235*cdf0e10cSrcweir void ToUnicode_Impl( String& rName )
236*cdf0e10cSrcweir {
237*cdf0e10cSrcweir 	rName.Erase( 32 );
238*cdf0e10cSrcweir 	rName.Convert( ::GetSystemCharSet(), CHARSET_ANSI );
239*cdf0e10cSrcweir 	// brute force is OK
240*cdf0e10cSrcweir 	sal_uInt8* p = (sal_uInt8*) rName.GetCharStr();
241*cdf0e10cSrcweir     for( sal_uInt16 i = 0; i < rName.Len(); i++, p++ )
242*cdf0e10cSrcweir     {
243*cdf0e10cSrcweir         // check each character and substitute blanks for illegal ones
244*cdf0e10cSrcweir         sal_uInt8 cChar = *p;
245*cdf0e10cSrcweir         if( cChar == '!' || cChar == ':' || cChar == '\\' || cChar == '/' )
246*cdf0e10cSrcweir 			*p = ' ';
247*cdf0e10cSrcweir     }
248*cdf0e10cSrcweir }
249*cdf0e10cSrcweir */
250*cdf0e10cSrcweir /*
251*cdf0e10cSrcweir static void FromUnicode( String& rName )
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir 	rName.Convert( CHARSET_ANSI, ::GetSystemCharSet() );
254*cdf0e10cSrcweir }
255*cdf0e10cSrcweir */
256*cdf0e10cSrcweir sal_Bool StgEntry::Init()
257*cdf0e10cSrcweir {
258*cdf0e10cSrcweir     memset( this, 0, sizeof (StgEntry) - sizeof( String ) );
259*cdf0e10cSrcweir     SetLeaf( STG_LEFT,  STG_FREE );
260*cdf0e10cSrcweir     SetLeaf( STG_RIGHT, STG_FREE );
261*cdf0e10cSrcweir     SetLeaf( STG_CHILD, STG_FREE );
262*cdf0e10cSrcweir     SetLeaf( STG_DATA,  STG_EOF );
263*cdf0e10cSrcweir     return sal_True;
264*cdf0e10cSrcweir }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir static String ToUpperUnicode( const String & rStr )
267*cdf0e10cSrcweir {
268*cdf0e10cSrcweir 	// I don't know the locale, so en_US is hopefully fine
269*cdf0e10cSrcweir 	/*
270*cdf0e10cSrcweir 	com.sun.star.lang.Locale aLocale;
271*cdf0e10cSrcweir 	aLocale.Language = OUString::createFromAscii( "en" );
272*cdf0e10cSrcweir 	aLocale.Country  = OUString::createFromAscii( "US" );
273*cdf0e10cSrcweir 	*/
274*cdf0e10cSrcweir 	static rtl::OUString aEN=rtl::OUString::createFromAscii( "en" );
275*cdf0e10cSrcweir 	static rtl::OUString aUS=rtl::OUString::createFromAscii( "US" );
276*cdf0e10cSrcweir 	static CharClass aCC( com::sun::star::lang::Locale( aEN, aUS, rtl::OUString() ) );
277*cdf0e10cSrcweir 	return aCC.toUpper( rStr, 0, rStr.Len() );
278*cdf0e10cSrcweir }
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir sal_Bool StgEntry::SetName( const String& rName )
282*cdf0e10cSrcweir {
283*cdf0e10cSrcweir     // I don't know the locale, so en_US is hopefully fine
284*cdf0e10cSrcweir     aName = ToUpperUnicode( rName );
285*cdf0e10cSrcweir     aName.Erase( 31 );
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir     int i;
288*cdf0e10cSrcweir     for( i = 0; i < aName.Len() && i < 32; i++ )
289*cdf0e10cSrcweir         nName[ i ] = rName.GetChar( sal_uInt16( i ));
290*cdf0e10cSrcweir     while( i < 32 )
291*cdf0e10cSrcweir         nName[ i++ ] = 0;
292*cdf0e10cSrcweir     nNameLen = ( aName.Len() + 1 ) << 1;
293*cdf0e10cSrcweir     return sal_True;
294*cdf0e10cSrcweir }
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir sal_Int32 StgEntry::GetLeaf( StgEntryRef eRef ) const
297*cdf0e10cSrcweir {
298*cdf0e10cSrcweir     sal_Int32 n = -1;
299*cdf0e10cSrcweir     switch( eRef )
300*cdf0e10cSrcweir     {
301*cdf0e10cSrcweir         case STG_LEFT:  n = nLeft;  break;
302*cdf0e10cSrcweir         case STG_RIGHT: n = nRight; break;
303*cdf0e10cSrcweir         case STG_CHILD: n = nChild; break;
304*cdf0e10cSrcweir         case STG_DATA:  n = nPage1; break;
305*cdf0e10cSrcweir     }
306*cdf0e10cSrcweir     return n;
307*cdf0e10cSrcweir }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir void StgEntry::SetLeaf( StgEntryRef eRef, sal_Int32 nPage )
310*cdf0e10cSrcweir {
311*cdf0e10cSrcweir     switch( eRef )
312*cdf0e10cSrcweir     {
313*cdf0e10cSrcweir         case STG_LEFT:  nLeft  = nPage; break;
314*cdf0e10cSrcweir         case STG_RIGHT: nRight = nPage; break;
315*cdf0e10cSrcweir         case STG_CHILD: nChild = nPage; break;
316*cdf0e10cSrcweir         case STG_DATA:  nPage1 = nPage; break;
317*cdf0e10cSrcweir     }
318*cdf0e10cSrcweir }
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir const sal_Int32* StgEntry::GetTime( StgEntryTime eTime ) const
321*cdf0e10cSrcweir {
322*cdf0e10cSrcweir     return( eTime == STG_MODIFIED ) ? nMtime : nAtime;
323*cdf0e10cSrcweir }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir void StgEntry::SetTime( StgEntryTime eTime, sal_Int32* pTime )
326*cdf0e10cSrcweir {
327*cdf0e10cSrcweir     if( eTime == STG_MODIFIED )
328*cdf0e10cSrcweir         nMtime[ 0 ] = *pTime++, nMtime[ 1 ] = *pTime;
329*cdf0e10cSrcweir     else
330*cdf0e10cSrcweir         nAtime[ 0 ] = *pTime++, nAtime[ 1 ] = *pTime;
331*cdf0e10cSrcweir }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir void StgEntry::SetClassId( const ClsId& r )
334*cdf0e10cSrcweir {
335*cdf0e10cSrcweir 	memcpy( &aClsId, &r, sizeof( ClsId ) );
336*cdf0e10cSrcweir }
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir void StgEntry::GetName( String& rName ) const
339*cdf0e10cSrcweir {
340*cdf0e10cSrcweir     sal_uInt16 n = nNameLen;
341*cdf0e10cSrcweir     if( n )
342*cdf0e10cSrcweir         n = ( n >> 1 ) - 1;
343*cdf0e10cSrcweir 	rName = String( nName, n );
344*cdf0e10cSrcweir }
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir // Compare two entries. Do this case-insensitive.
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir short StgEntry::Compare( const StgEntry& r ) const
349*cdf0e10cSrcweir {
350*cdf0e10cSrcweir 	/*
351*cdf0e10cSrcweir     short nRes = r.nNameLen - nNameLen;
352*cdf0e10cSrcweir     if( !nRes ) return strcmp( r.aName, aName );
353*cdf0e10cSrcweir 	else return nRes;
354*cdf0e10cSrcweir 	*/
355*cdf0e10cSrcweir     sal_Int32 nRes = r.nNameLen - nNameLen;
356*cdf0e10cSrcweir     if( !nRes )
357*cdf0e10cSrcweir 		nRes = r.aName.CompareTo( aName );
358*cdf0e10cSrcweir 	return (short)nRes;
359*cdf0e10cSrcweir 	//return aName.CompareTo( r.aName );
360*cdf0e10cSrcweir }
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir // These load/store operations are a bit more complicated,
363*cdf0e10cSrcweir // since they have to copy their contents into a packed structure.
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir sal_Bool StgEntry::Load( const void* pFrom )
366*cdf0e10cSrcweir {
367*cdf0e10cSrcweir 	SvMemoryStream r( (sal_Char*) pFrom, 128, STREAM_READ );
368*cdf0e10cSrcweir 	for( short i = 0; i < 32; i++ )
369*cdf0e10cSrcweir 		r >> nName[ i ];			// 00 name as WCHAR
370*cdf0e10cSrcweir 	r >> nNameLen 					// 40 size of name in bytes including 00H
371*cdf0e10cSrcweir 	  >> cType 						// 42 entry type
372*cdf0e10cSrcweir 	  >> cFlags						// 43 0 or 1 (tree balance?)
373*cdf0e10cSrcweir 	  >> nLeft						// 44 left node entry
374*cdf0e10cSrcweir 	  >> nRight						// 48 right node entry
375*cdf0e10cSrcweir 	  >> nChild						// 4C 1st child entry if storage
376*cdf0e10cSrcweir 	  >> aClsId						// 50 class ID (optional)
377*cdf0e10cSrcweir 	  >> nFlags						// 60 state flags(?)
378*cdf0e10cSrcweir 	  >> nMtime[ 0 ]				// 64 modification time
379*cdf0e10cSrcweir 	  >> nMtime[ 1 ]				// 64 modification time
380*cdf0e10cSrcweir 	  >> nAtime[ 0 ] 				// 6C creation and access time
381*cdf0e10cSrcweir 	  >> nAtime[ 1 ] 				// 6C creation and access time
382*cdf0e10cSrcweir 	  >> nPage1						// 74 starting block (either direct or translated)
383*cdf0e10cSrcweir 	  >> nSize 						// 78 file size
384*cdf0e10cSrcweir 	  >> nUnknown;					// 7C unknown
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir     sal_uInt16 n = nNameLen;
387*cdf0e10cSrcweir     if( n )
388*cdf0e10cSrcweir 		n = ( n >> 1 ) - 1;
389*cdf0e10cSrcweir 	if( n > 31 || (nSize < 0 && cType != STG_STORAGE) )
390*cdf0e10cSrcweir     {
391*cdf0e10cSrcweir         // the size makes no sence for the substorage
392*cdf0e10cSrcweir         // TODO/LATER: actually the size should be an unsigned value, but in this case it would mean a stream of more than 2Gb
393*cdf0e10cSrcweir 		return sal_False;
394*cdf0e10cSrcweir     }
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir 	aName = String( nName, n );
397*cdf0e10cSrcweir 	// I don't know the locale, so en_US is hopefully fine
398*cdf0e10cSrcweir 	aName = ToUpperUnicode( aName );
399*cdf0e10cSrcweir 	aName.Erase( 31 );
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir 	return sal_True;
402*cdf0e10cSrcweir }
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir void StgEntry::Store( void* pTo )
405*cdf0e10cSrcweir {
406*cdf0e10cSrcweir 	SvMemoryStream r( (sal_Char *)pTo, 128, STREAM_WRITE );
407*cdf0e10cSrcweir 	for( short i = 0; i < 32; i++ )
408*cdf0e10cSrcweir 		r << nName[ i ];			// 00 name as WCHAR
409*cdf0e10cSrcweir 	r << nNameLen 					// 40 size of name in bytes including 00H
410*cdf0e10cSrcweir 	  << cType 						// 42 entry type
411*cdf0e10cSrcweir 	  << cFlags						// 43 0 or 1 (tree balance?)
412*cdf0e10cSrcweir 	  << nLeft						// 44 left node entry
413*cdf0e10cSrcweir 	  << nRight						// 48 right node entry
414*cdf0e10cSrcweir 	  << nChild						// 4C 1st child entry if storage;
415*cdf0e10cSrcweir 	  << aClsId						// 50 class ID (optional)
416*cdf0e10cSrcweir 	  << nFlags						// 60 state flags(?)
417*cdf0e10cSrcweir 	  << nMtime[ 0 ]				// 64 modification time
418*cdf0e10cSrcweir 	  << nMtime[ 1 ]				// 64 modification time
419*cdf0e10cSrcweir 	  << nAtime[ 0 ] 				// 6C creation and access time
420*cdf0e10cSrcweir 	  << nAtime[ 1 ] 				// 6C creation and access time
421*cdf0e10cSrcweir 	  << nPage1						// 74 starting block (either direct or translated)
422*cdf0e10cSrcweir 	  << nSize 						// 78 file size
423*cdf0e10cSrcweir 	  << nUnknown;					// 7C unknown
424*cdf0e10cSrcweir }
425*cdf0e10cSrcweir 
426