1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_sot.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include <string.h> // memcpy()
28*b1cdbd2cSJim Jagielski
29*b1cdbd2cSJim Jagielski #include "sot/stg.hxx"
30*b1cdbd2cSJim Jagielski #include "stgelem.hxx"
31*b1cdbd2cSJim Jagielski #include "stgcache.hxx"
32*b1cdbd2cSJim Jagielski #include "stgstrms.hxx"
33*b1cdbd2cSJim Jagielski #include "stgdir.hxx"
34*b1cdbd2cSJim Jagielski #include "stgio.hxx"
35*b1cdbd2cSJim Jagielski
36*b1cdbd2cSJim Jagielski
37*b1cdbd2cSJim Jagielski //////////////////////////// class StgDirEntry /////////////////////////////
38*b1cdbd2cSJim Jagielski
39*b1cdbd2cSJim Jagielski // This class holds the dir entry data and maintains dirty flags for both
40*b1cdbd2cSJim Jagielski // the entry and the data.
41*b1cdbd2cSJim Jagielski
42*b1cdbd2cSJim Jagielski // Transacted mode for streams: On the first write, a temp stream pTmpStrm
43*b1cdbd2cSJim Jagielski // is created and operated on. A commit moves pTmpStrm to pCurStrm, which
44*b1cdbd2cSJim Jagielski // is used for subsequent reads. A new write creates a new copy of pTmpStrm
45*b1cdbd2cSJim Jagielski // based on pCurStrm. Reverting throws away pTmpStrm.
46*b1cdbd2cSJim Jagielski // Transacted mode for storages: A copy of the dir ents is kept in aSave.
47*b1cdbd2cSJim Jagielski // Committing means copying aEntry to aSave. Reverting means to copy aSave
48*b1cdbd2cSJim Jagielski // to aEntry, delete newly created entries and to reactivate removed entries.
49*b1cdbd2cSJim Jagielski
50*b1cdbd2cSJim Jagielski // Problem der Implementation: Keine Hierarchischen commits. Daher nur
51*b1cdbd2cSJim Jagielski // insgesamt transaktionsorientert oder direkt.
52*b1cdbd2cSJim Jagielski
StgDirEntry(const void * pBuffer,sal_uInt32 nBufferLen,sal_Bool * pbOk)53*b1cdbd2cSJim Jagielski StgDirEntry::StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, sal_Bool * pbOk ) : StgAvlNode()
54*b1cdbd2cSJim Jagielski {
55*b1cdbd2cSJim Jagielski *pbOk = aEntry.Load( pBuffer, nBufferLen );
56*b1cdbd2cSJim Jagielski
57*b1cdbd2cSJim Jagielski InitMembers();
58*b1cdbd2cSJim Jagielski }
59*b1cdbd2cSJim Jagielski
StgDirEntry(const StgEntry & r)60*b1cdbd2cSJim Jagielski StgDirEntry::StgDirEntry( const StgEntry& r ) : StgAvlNode(), aEntry( r )
61*b1cdbd2cSJim Jagielski {
62*b1cdbd2cSJim Jagielski InitMembers();
63*b1cdbd2cSJim Jagielski }
64*b1cdbd2cSJim Jagielski
65*b1cdbd2cSJim Jagielski // Helper for all ctors
66*b1cdbd2cSJim Jagielski
InitMembers()67*b1cdbd2cSJim Jagielski void StgDirEntry::InitMembers()
68*b1cdbd2cSJim Jagielski {
69*b1cdbd2cSJim Jagielski aSave = aEntry;
70*b1cdbd2cSJim Jagielski pUp =
71*b1cdbd2cSJim Jagielski pDown = NULL;
72*b1cdbd2cSJim Jagielski ppRoot = NULL;
73*b1cdbd2cSJim Jagielski pStgStrm = NULL;
74*b1cdbd2cSJim Jagielski pCurStrm =
75*b1cdbd2cSJim Jagielski pTmpStrm = NULL;
76*b1cdbd2cSJim Jagielski nPos =
77*b1cdbd2cSJim Jagielski nEntry =
78*b1cdbd2cSJim Jagielski nRefCnt = 0;
79*b1cdbd2cSJim Jagielski nMode = STREAM_READ;
80*b1cdbd2cSJim Jagielski bDirect = sal_True;
81*b1cdbd2cSJim Jagielski bInvalid =
82*b1cdbd2cSJim Jagielski bCreated =
83*b1cdbd2cSJim Jagielski bRenamed =
84*b1cdbd2cSJim Jagielski bRemoved =
85*b1cdbd2cSJim Jagielski bTemp =
86*b1cdbd2cSJim Jagielski bDirty =
87*b1cdbd2cSJim Jagielski bZombie = sal_False;
88*b1cdbd2cSJim Jagielski }
89*b1cdbd2cSJim Jagielski
~StgDirEntry()90*b1cdbd2cSJim Jagielski StgDirEntry::~StgDirEntry()
91*b1cdbd2cSJim Jagielski {
92*b1cdbd2cSJim Jagielski Close();
93*b1cdbd2cSJim Jagielski delete pCurStrm;
94*b1cdbd2cSJim Jagielski delete pStgStrm;
95*b1cdbd2cSJim Jagielski delete pDown;
96*b1cdbd2cSJim Jagielski }
97*b1cdbd2cSJim Jagielski
98*b1cdbd2cSJim Jagielski // Comparison function
99*b1cdbd2cSJim Jagielski
Compare(const StgAvlNode * p) const100*b1cdbd2cSJim Jagielski short StgDirEntry::Compare( const StgAvlNode* p ) const
101*b1cdbd2cSJim Jagielski {
102*b1cdbd2cSJim Jagielski short nResult = -1;
103*b1cdbd2cSJim Jagielski if ( p )
104*b1cdbd2cSJim Jagielski {
105*b1cdbd2cSJim Jagielski const StgDirEntry* pEntry = (const StgDirEntry*) p;
106*b1cdbd2cSJim Jagielski nResult = aEntry.Compare( pEntry->aEntry );
107*b1cdbd2cSJim Jagielski }
108*b1cdbd2cSJim Jagielski return nResult;
109*b1cdbd2cSJim Jagielski }
110*b1cdbd2cSJim Jagielski
111*b1cdbd2cSJim Jagielski // Enumerate the entry numbers.
112*b1cdbd2cSJim Jagielski // n is incremented to show the total # of entries.
113*b1cdbd2cSJim Jagielski // These number are later used as page numbers when storing
114*b1cdbd2cSJim Jagielski // the TOC tree into the TOC stream. Remember that aSave is
115*b1cdbd2cSJim Jagielski // stored, not aEntry.
116*b1cdbd2cSJim Jagielski
Enum(sal_Int32 & n)117*b1cdbd2cSJim Jagielski void StgDirEntry::Enum( sal_Int32& n )
118*b1cdbd2cSJim Jagielski {
119*b1cdbd2cSJim Jagielski sal_Int32 nLeft = STG_FREE, nRight = STG_FREE, nDown = STG_FREE;
120*b1cdbd2cSJim Jagielski nEntry = n++;
121*b1cdbd2cSJim Jagielski if( pLeft )
122*b1cdbd2cSJim Jagielski {
123*b1cdbd2cSJim Jagielski ((StgDirEntry*) pLeft)->Enum( n ); nLeft = ((StgDirEntry*) pLeft)->nEntry;
124*b1cdbd2cSJim Jagielski }
125*b1cdbd2cSJim Jagielski if( pRight )
126*b1cdbd2cSJim Jagielski {
127*b1cdbd2cSJim Jagielski ((StgDirEntry*) pRight)->Enum( n ); nRight = ((StgDirEntry*) pRight)->nEntry;
128*b1cdbd2cSJim Jagielski }
129*b1cdbd2cSJim Jagielski if( pDown )
130*b1cdbd2cSJim Jagielski {
131*b1cdbd2cSJim Jagielski pDown->Enum( n ); nDown = pDown->nEntry;
132*b1cdbd2cSJim Jagielski }
133*b1cdbd2cSJim Jagielski aSave.SetLeaf( STG_LEFT, nLeft );
134*b1cdbd2cSJim Jagielski aSave.SetLeaf( STG_RIGHT, nRight );
135*b1cdbd2cSJim Jagielski aSave.SetLeaf( STG_CHILD, nDown );
136*b1cdbd2cSJim Jagielski }
137*b1cdbd2cSJim Jagielski
138*b1cdbd2cSJim Jagielski // Delete all temporary entries before writing the TOC stream.
139*b1cdbd2cSJim Jagielski // Until now Deltem is never called with bForce True
140*b1cdbd2cSJim Jagielski
DelTemp(sal_Bool bForce)141*b1cdbd2cSJim Jagielski void StgDirEntry::DelTemp( sal_Bool bForce )
142*b1cdbd2cSJim Jagielski {
143*b1cdbd2cSJim Jagielski if( pLeft )
144*b1cdbd2cSJim Jagielski ((StgDirEntry*) pLeft)->DelTemp( sal_False );
145*b1cdbd2cSJim Jagielski if( pRight )
146*b1cdbd2cSJim Jagielski ((StgDirEntry*) pRight)->DelTemp( sal_False );
147*b1cdbd2cSJim Jagielski if( pDown )
148*b1cdbd2cSJim Jagielski {
149*b1cdbd2cSJim Jagielski // If the storage is dead, of course all elements are dead, too
150*b1cdbd2cSJim Jagielski if( bInvalid && aEntry.GetType() == STG_STORAGE )
151*b1cdbd2cSJim Jagielski bForce = sal_True;
152*b1cdbd2cSJim Jagielski pDown->DelTemp( bForce );
153*b1cdbd2cSJim Jagielski }
154*b1cdbd2cSJim Jagielski if( ( bForce || bInvalid )
155*b1cdbd2cSJim Jagielski && ( aEntry.GetType() != STG_ROOT ) /* && ( nRefCnt <= 1 ) */ )
156*b1cdbd2cSJim Jagielski {
157*b1cdbd2cSJim Jagielski Close();
158*b1cdbd2cSJim Jagielski if( pUp )
159*b1cdbd2cSJim Jagielski {
160*b1cdbd2cSJim Jagielski // this deletes the element if refcnt == 0!
161*b1cdbd2cSJim Jagielski sal_Bool bDel = nRefCnt == 0;
162*b1cdbd2cSJim Jagielski StgAvlNode::Remove( (StgAvlNode**) &pUp->pDown, this, bDel );
163*b1cdbd2cSJim Jagielski if( !bDel )
164*b1cdbd2cSJim Jagielski {
165*b1cdbd2cSJim Jagielski pLeft = pRight = pDown = 0;
166*b1cdbd2cSJim Jagielski bInvalid = bZombie = sal_True;
167*b1cdbd2cSJim Jagielski }
168*b1cdbd2cSJim Jagielski }
169*b1cdbd2cSJim Jagielski }
170*b1cdbd2cSJim Jagielski }
171*b1cdbd2cSJim Jagielski
172*b1cdbd2cSJim Jagielski // Save the tree into the given dir stream
173*b1cdbd2cSJim Jagielski
Store(StgDirStrm & rStrm)174*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::Store( StgDirStrm& rStrm )
175*b1cdbd2cSJim Jagielski {
176*b1cdbd2cSJim Jagielski void* pEntry = rStrm.GetEntry( nEntry, sal_True );
177*b1cdbd2cSJim Jagielski if( !pEntry )
178*b1cdbd2cSJim Jagielski return sal_False;
179*b1cdbd2cSJim Jagielski // Do not store the current (maybe not commited) entry
180*b1cdbd2cSJim Jagielski aSave.Store( pEntry );
181*b1cdbd2cSJim Jagielski if( pLeft )
182*b1cdbd2cSJim Jagielski if( !((StgDirEntry*) pLeft)->Store( rStrm ) )
183*b1cdbd2cSJim Jagielski return sal_False;
184*b1cdbd2cSJim Jagielski if( pRight )
185*b1cdbd2cSJim Jagielski if( !((StgDirEntry*) pRight)->Store( rStrm ) )
186*b1cdbd2cSJim Jagielski return sal_False;
187*b1cdbd2cSJim Jagielski if( pDown )
188*b1cdbd2cSJim Jagielski if( !pDown->Store( rStrm ) )
189*b1cdbd2cSJim Jagielski return sal_False;
190*b1cdbd2cSJim Jagielski return sal_True;
191*b1cdbd2cSJim Jagielski }
192*b1cdbd2cSJim Jagielski
StoreStream(StgIo & rIo)193*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::StoreStream( StgIo& rIo )
194*b1cdbd2cSJim Jagielski {
195*b1cdbd2cSJim Jagielski if( aEntry.GetType() == STG_STREAM || aEntry.GetType() == STG_ROOT )
196*b1cdbd2cSJim Jagielski {
197*b1cdbd2cSJim Jagielski if( bInvalid )
198*b1cdbd2cSJim Jagielski {
199*b1cdbd2cSJim Jagielski // Delete the stream if needed
200*b1cdbd2cSJim Jagielski if( !pStgStrm )
201*b1cdbd2cSJim Jagielski {
202*b1cdbd2cSJim Jagielski OpenStream( rIo );
203*b1cdbd2cSJim Jagielski delete pStgStrm, pStgStrm = NULL;
204*b1cdbd2cSJim Jagielski }
205*b1cdbd2cSJim Jagielski else
206*b1cdbd2cSJim Jagielski pStgStrm->SetSize( 0 );
207*b1cdbd2cSJim Jagielski }
208*b1cdbd2cSJim Jagielski // or write the data stream
209*b1cdbd2cSJim Jagielski else if( !Tmp2Strm() )
210*b1cdbd2cSJim Jagielski return sal_False;
211*b1cdbd2cSJim Jagielski }
212*b1cdbd2cSJim Jagielski return sal_True;
213*b1cdbd2cSJim Jagielski }
214*b1cdbd2cSJim Jagielski
215*b1cdbd2cSJim Jagielski // Save all dirty streams
216*b1cdbd2cSJim Jagielski
StoreStreams(StgIo & rIo)217*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::StoreStreams( StgIo& rIo )
218*b1cdbd2cSJim Jagielski {
219*b1cdbd2cSJim Jagielski if( !StoreStream( rIo ) )
220*b1cdbd2cSJim Jagielski return sal_False;
221*b1cdbd2cSJim Jagielski if( pLeft )
222*b1cdbd2cSJim Jagielski if( !((StgDirEntry*) pLeft)->StoreStreams( rIo ) )
223*b1cdbd2cSJim Jagielski return sal_False;
224*b1cdbd2cSJim Jagielski if( pRight )
225*b1cdbd2cSJim Jagielski if( !((StgDirEntry*) pRight)->StoreStreams( rIo ) )
226*b1cdbd2cSJim Jagielski return sal_False;
227*b1cdbd2cSJim Jagielski if( pDown )
228*b1cdbd2cSJim Jagielski if( !pDown->StoreStreams( rIo ) )
229*b1cdbd2cSJim Jagielski return sal_False;
230*b1cdbd2cSJim Jagielski return sal_True;
231*b1cdbd2cSJim Jagielski }
232*b1cdbd2cSJim Jagielski
233*b1cdbd2cSJim Jagielski // Revert all directory entries after failure to write the TOC stream
234*b1cdbd2cSJim Jagielski
RevertAll()235*b1cdbd2cSJim Jagielski void StgDirEntry::RevertAll()
236*b1cdbd2cSJim Jagielski {
237*b1cdbd2cSJim Jagielski aEntry = aSave;
238*b1cdbd2cSJim Jagielski if( pLeft )
239*b1cdbd2cSJim Jagielski ((StgDirEntry*) pLeft)->RevertAll();
240*b1cdbd2cSJim Jagielski if( pRight )
241*b1cdbd2cSJim Jagielski ((StgDirEntry*) pRight)->RevertAll();
242*b1cdbd2cSJim Jagielski if( pDown )
243*b1cdbd2cSJim Jagielski pDown->RevertAll();
244*b1cdbd2cSJim Jagielski }
245*b1cdbd2cSJim Jagielski
246*b1cdbd2cSJim Jagielski // Look if any element of the tree is dirty
247*b1cdbd2cSJim Jagielski
IsDirty()248*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::IsDirty()
249*b1cdbd2cSJim Jagielski {
250*b1cdbd2cSJim Jagielski if( bDirty || bInvalid )
251*b1cdbd2cSJim Jagielski return sal_True;
252*b1cdbd2cSJim Jagielski if( pLeft && ((StgDirEntry*) pLeft)->IsDirty() )
253*b1cdbd2cSJim Jagielski return sal_True;
254*b1cdbd2cSJim Jagielski if( pRight && ((StgDirEntry*) pRight)->IsDirty() )
255*b1cdbd2cSJim Jagielski return sal_True;
256*b1cdbd2cSJim Jagielski if( pDown && pDown->IsDirty() )
257*b1cdbd2cSJim Jagielski return sal_True;
258*b1cdbd2cSJim Jagielski return sal_False;
259*b1cdbd2cSJim Jagielski }
260*b1cdbd2cSJim Jagielski
261*b1cdbd2cSJim Jagielski // Set up a stream.
262*b1cdbd2cSJim Jagielski
OpenStream(StgIo & rIo,sal_Bool bForceBig)263*b1cdbd2cSJim Jagielski void StgDirEntry::OpenStream( StgIo& rIo, sal_Bool bForceBig )
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski sal_Int32 nThreshold = (sal_uInt16) rIo.aHdr.GetThreshold();
266*b1cdbd2cSJim Jagielski delete pStgStrm;
267*b1cdbd2cSJim Jagielski if( !bForceBig && aEntry.GetSize() < nThreshold )
268*b1cdbd2cSJim Jagielski pStgStrm = new StgSmallStrm( rIo, *this );
269*b1cdbd2cSJim Jagielski else
270*b1cdbd2cSJim Jagielski pStgStrm = new StgDataStrm( rIo, *this );
271*b1cdbd2cSJim Jagielski if( bInvalid && aEntry.GetSize() )
272*b1cdbd2cSJim Jagielski {
273*b1cdbd2cSJim Jagielski // This entry has invalid data, so delete that data
274*b1cdbd2cSJim Jagielski SetSize( 0L );
275*b1cdbd2cSJim Jagielski // bRemoved = bInvalid = sal_False;
276*b1cdbd2cSJim Jagielski }
277*b1cdbd2cSJim Jagielski nPos = 0;
278*b1cdbd2cSJim Jagielski }
279*b1cdbd2cSJim Jagielski
280*b1cdbd2cSJim Jagielski // Close the open stream without committing. If the entry is marked as
281*b1cdbd2cSJim Jagielski // temporary, delete it.
282*b1cdbd2cSJim Jagielski // Do not delete pCurStrm here!
283*b1cdbd2cSJim Jagielski // (TLX:??? Zumindest pStgStrm muss deleted werden.)
284*b1cdbd2cSJim Jagielski
Close()285*b1cdbd2cSJim Jagielski void StgDirEntry::Close()
286*b1cdbd2cSJim Jagielski {
287*b1cdbd2cSJim Jagielski delete pTmpStrm;
288*b1cdbd2cSJim Jagielski pTmpStrm = NULL;
289*b1cdbd2cSJim Jagielski // nRefCnt = 0;
290*b1cdbd2cSJim Jagielski bInvalid = bTemp;
291*b1cdbd2cSJim Jagielski }
292*b1cdbd2cSJim Jagielski
293*b1cdbd2cSJim Jagielski // Get the current stream size
294*b1cdbd2cSJim Jagielski
GetSize()295*b1cdbd2cSJim Jagielski sal_Int32 StgDirEntry::GetSize()
296*b1cdbd2cSJim Jagielski {
297*b1cdbd2cSJim Jagielski sal_Int32 n;
298*b1cdbd2cSJim Jagielski if( pTmpStrm )
299*b1cdbd2cSJim Jagielski n = pTmpStrm->GetSize();
300*b1cdbd2cSJim Jagielski else if( pCurStrm )
301*b1cdbd2cSJim Jagielski n = pCurStrm->GetSize();
302*b1cdbd2cSJim Jagielski else n = aEntry.GetSize();
303*b1cdbd2cSJim Jagielski return n;
304*b1cdbd2cSJim Jagielski }
305*b1cdbd2cSJim Jagielski
306*b1cdbd2cSJim Jagielski // Set the stream size. This means also creating a temp stream.
307*b1cdbd2cSJim Jagielski
SetSize(sal_Int32 nNewSize)308*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::SetSize( sal_Int32 nNewSize )
309*b1cdbd2cSJim Jagielski {
310*b1cdbd2cSJim Jagielski if (
311*b1cdbd2cSJim Jagielski !( nMode & STREAM_WRITE ) ||
312*b1cdbd2cSJim Jagielski (!bDirect && !pTmpStrm && !Strm2Tmp())
313*b1cdbd2cSJim Jagielski )
314*b1cdbd2cSJim Jagielski {
315*b1cdbd2cSJim Jagielski return sal_False;
316*b1cdbd2cSJim Jagielski }
317*b1cdbd2cSJim Jagielski
318*b1cdbd2cSJim Jagielski if( nNewSize < nPos )
319*b1cdbd2cSJim Jagielski nPos = nNewSize;
320*b1cdbd2cSJim Jagielski if( pTmpStrm )
321*b1cdbd2cSJim Jagielski {
322*b1cdbd2cSJim Jagielski pTmpStrm->SetSize( nNewSize );
323*b1cdbd2cSJim Jagielski pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
324*b1cdbd2cSJim Jagielski return sal_Bool( pTmpStrm->GetError() == SVSTREAM_OK );
325*b1cdbd2cSJim Jagielski }
326*b1cdbd2cSJim Jagielski else
327*b1cdbd2cSJim Jagielski {
328*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
329*b1cdbd2cSJim Jagielski if ( !pStgStrm )
330*b1cdbd2cSJim Jagielski return sal_False;
331*b1cdbd2cSJim Jagielski
332*b1cdbd2cSJim Jagielski sal_Bool bRes = sal_False;
333*b1cdbd2cSJim Jagielski StgIo& rIo = pStgStrm->GetIo();
334*b1cdbd2cSJim Jagielski sal_Int32 nThreshold = rIo.aHdr.GetThreshold();
335*b1cdbd2cSJim Jagielski // ensure the correct storage stream!
336*b1cdbd2cSJim Jagielski StgStrm* pOld = NULL;
337*b1cdbd2cSJim Jagielski sal_uInt16 nOldSize = 0;
338*b1cdbd2cSJim Jagielski if( nNewSize >= nThreshold && pStgStrm->IsSmallStrm() )
339*b1cdbd2cSJim Jagielski {
340*b1cdbd2cSJim Jagielski pOld = pStgStrm;
341*b1cdbd2cSJim Jagielski nOldSize = (sal_uInt16) pOld->GetSize();
342*b1cdbd2cSJim Jagielski pStgStrm = new StgDataStrm( rIo, STG_EOF, 0 );
343*b1cdbd2cSJim Jagielski }
344*b1cdbd2cSJim Jagielski else if( nNewSize < nThreshold && !pStgStrm->IsSmallStrm() )
345*b1cdbd2cSJim Jagielski {
346*b1cdbd2cSJim Jagielski pOld = pStgStrm;
347*b1cdbd2cSJim Jagielski nOldSize = (sal_uInt16) nNewSize;
348*b1cdbd2cSJim Jagielski pStgStrm = new StgSmallStrm( rIo, STG_EOF, 0 );
349*b1cdbd2cSJim Jagielski }
350*b1cdbd2cSJim Jagielski // now set the new size
351*b1cdbd2cSJim Jagielski if( pStgStrm->SetSize( nNewSize ) )
352*b1cdbd2cSJim Jagielski {
353*b1cdbd2cSJim Jagielski // did we create a new stream?
354*b1cdbd2cSJim Jagielski if( pOld )
355*b1cdbd2cSJim Jagielski {
356*b1cdbd2cSJim Jagielski // if so, we probably need to copy the old data
357*b1cdbd2cSJim Jagielski if( nOldSize )
358*b1cdbd2cSJim Jagielski {
359*b1cdbd2cSJim Jagielski void* pBuf = new sal_uInt8[ nOldSize ];
360*b1cdbd2cSJim Jagielski pOld->Pos2Page( 0L );
361*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( 0L );
362*b1cdbd2cSJim Jagielski if( pOld->Read( pBuf, nOldSize )
363*b1cdbd2cSJim Jagielski && pStgStrm->Write( pBuf, nOldSize ) )
364*b1cdbd2cSJim Jagielski bRes = sal_True;
365*b1cdbd2cSJim Jagielski delete[] static_cast<sal_uInt8*>(pBuf);
366*b1cdbd2cSJim Jagielski }
367*b1cdbd2cSJim Jagielski else
368*b1cdbd2cSJim Jagielski bRes = sal_True;
369*b1cdbd2cSJim Jagielski if( bRes )
370*b1cdbd2cSJim Jagielski {
371*b1cdbd2cSJim Jagielski pOld->SetSize( 0 );
372*b1cdbd2cSJim Jagielski delete pOld;
373*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( nPos );
374*b1cdbd2cSJim Jagielski pStgStrm->SetEntry( *this );
375*b1cdbd2cSJim Jagielski }
376*b1cdbd2cSJim Jagielski else
377*b1cdbd2cSJim Jagielski {
378*b1cdbd2cSJim Jagielski pStgStrm->SetSize( 0 );
379*b1cdbd2cSJim Jagielski delete pStgStrm;
380*b1cdbd2cSJim Jagielski pStgStrm = pOld;
381*b1cdbd2cSJim Jagielski }
382*b1cdbd2cSJim Jagielski }
383*b1cdbd2cSJim Jagielski else
384*b1cdbd2cSJim Jagielski {
385*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( nPos );
386*b1cdbd2cSJim Jagielski bRes = sal_True;
387*b1cdbd2cSJim Jagielski }
388*b1cdbd2cSJim Jagielski }
389*b1cdbd2cSJim Jagielski return bRes;
390*b1cdbd2cSJim Jagielski }
391*b1cdbd2cSJim Jagielski }
392*b1cdbd2cSJim Jagielski
393*b1cdbd2cSJim Jagielski // Seek. On negative values, seek to EOF.
394*b1cdbd2cSJim Jagielski
Seek(sal_Int32 nNew)395*b1cdbd2cSJim Jagielski sal_Int32 StgDirEntry::Seek( sal_Int32 nNew )
396*b1cdbd2cSJim Jagielski {
397*b1cdbd2cSJim Jagielski if( pTmpStrm )
398*b1cdbd2cSJim Jagielski {
399*b1cdbd2cSJim Jagielski if( nNew < 0 )
400*b1cdbd2cSJim Jagielski nNew = pTmpStrm->GetSize();
401*b1cdbd2cSJim Jagielski nNew = pTmpStrm->Seek( nNew );
402*b1cdbd2cSJim Jagielski }
403*b1cdbd2cSJim Jagielski else if( pCurStrm )
404*b1cdbd2cSJim Jagielski {
405*b1cdbd2cSJim Jagielski if( nNew < 0 )
406*b1cdbd2cSJim Jagielski nNew = pCurStrm->GetSize();
407*b1cdbd2cSJim Jagielski nNew = pCurStrm->Seek( nNew );
408*b1cdbd2cSJim Jagielski }
409*b1cdbd2cSJim Jagielski else
410*b1cdbd2cSJim Jagielski {
411*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
412*b1cdbd2cSJim Jagielski if ( !pStgStrm )
413*b1cdbd2cSJim Jagielski return nPos;
414*b1cdbd2cSJim Jagielski
415*b1cdbd2cSJim Jagielski sal_Int32 nSize = aEntry.GetSize();
416*b1cdbd2cSJim Jagielski
417*b1cdbd2cSJim Jagielski if( nNew < 0 )
418*b1cdbd2cSJim Jagielski nNew = nSize;
419*b1cdbd2cSJim Jagielski
420*b1cdbd2cSJim Jagielski // try to enlarge, the readonly streams should not allow this
421*b1cdbd2cSJim Jagielski if( nNew > nSize )
422*b1cdbd2cSJim Jagielski {
423*b1cdbd2cSJim Jagielski if ( !( nMode & STREAM_WRITE ) || !SetSize( nNew ) )
424*b1cdbd2cSJim Jagielski {
425*b1cdbd2cSJim Jagielski OSL_ENSURE( nMode & STREAM_WRITE, "Trying to resize readonly stream by seeking, could be a wrong offset!" );
426*b1cdbd2cSJim Jagielski return nPos;
427*b1cdbd2cSJim Jagielski }
428*b1cdbd2cSJim Jagielski else
429*b1cdbd2cSJim Jagielski return Seek( nNew );
430*b1cdbd2cSJim Jagielski }
431*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( nNew );
432*b1cdbd2cSJim Jagielski nNew = pStgStrm->GetPos();
433*b1cdbd2cSJim Jagielski }
434*b1cdbd2cSJim Jagielski
435*b1cdbd2cSJim Jagielski return nPos = nNew;
436*b1cdbd2cSJim Jagielski }
437*b1cdbd2cSJim Jagielski
438*b1cdbd2cSJim Jagielski // Read
439*b1cdbd2cSJim Jagielski
Read(void * p,sal_Int32 nLen)440*b1cdbd2cSJim Jagielski sal_Int32 StgDirEntry::Read( void* p, sal_Int32 nLen )
441*b1cdbd2cSJim Jagielski {
442*b1cdbd2cSJim Jagielski if( nLen <= 0 )
443*b1cdbd2cSJim Jagielski return 0;
444*b1cdbd2cSJim Jagielski if( pTmpStrm )
445*b1cdbd2cSJim Jagielski nLen = pTmpStrm->Read( p, nLen );
446*b1cdbd2cSJim Jagielski else if( pCurStrm )
447*b1cdbd2cSJim Jagielski nLen = pCurStrm->Read( p, nLen );
448*b1cdbd2cSJim Jagielski else
449*b1cdbd2cSJim Jagielski {
450*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
451*b1cdbd2cSJim Jagielski if ( !pStgStrm )
452*b1cdbd2cSJim Jagielski return 0;
453*b1cdbd2cSJim Jagielski
454*b1cdbd2cSJim Jagielski nLen = pStgStrm->Read( p, nLen );
455*b1cdbd2cSJim Jagielski }
456*b1cdbd2cSJim Jagielski
457*b1cdbd2cSJim Jagielski nPos += nLen;
458*b1cdbd2cSJim Jagielski return nLen;
459*b1cdbd2cSJim Jagielski }
460*b1cdbd2cSJim Jagielski
461*b1cdbd2cSJim Jagielski // Write
462*b1cdbd2cSJim Jagielski
Write(const void * p,sal_Int32 nLen)463*b1cdbd2cSJim Jagielski sal_Int32 StgDirEntry::Write( const void* p, sal_Int32 nLen )
464*b1cdbd2cSJim Jagielski {
465*b1cdbd2cSJim Jagielski if( nLen <= 0 || !( nMode & STREAM_WRITE ) )
466*b1cdbd2cSJim Jagielski return 0;
467*b1cdbd2cSJim Jagielski
468*b1cdbd2cSJim Jagielski // Was this stream committed internally and reopened in direct mode?
469*b1cdbd2cSJim Jagielski if( bDirect && ( pCurStrm || pTmpStrm ) && !Tmp2Strm() )
470*b1cdbd2cSJim Jagielski return 0;
471*b1cdbd2cSJim Jagielski // Is this stream opened in transacted mode? Do we have to make a copy?
472*b1cdbd2cSJim Jagielski if( !bDirect && !pTmpStrm && !Strm2Tmp() )
473*b1cdbd2cSJim Jagielski return 0;
474*b1cdbd2cSJim Jagielski
475*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
476*b1cdbd2cSJim Jagielski if ( !pStgStrm )
477*b1cdbd2cSJim Jagielski return 0;
478*b1cdbd2cSJim Jagielski
479*b1cdbd2cSJim Jagielski if( pTmpStrm )
480*b1cdbd2cSJim Jagielski {
481*b1cdbd2cSJim Jagielski nLen = pTmpStrm->Write( p, nLen );
482*b1cdbd2cSJim Jagielski pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
483*b1cdbd2cSJim Jagielski }
484*b1cdbd2cSJim Jagielski else
485*b1cdbd2cSJim Jagielski {
486*b1cdbd2cSJim Jagielski sal_Int32 nNew = nPos + nLen;
487*b1cdbd2cSJim Jagielski if( nNew > pStgStrm->GetSize() )
488*b1cdbd2cSJim Jagielski {
489*b1cdbd2cSJim Jagielski if( !SetSize( nNew ) )
490*b1cdbd2cSJim Jagielski return 0L;
491*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( nPos );
492*b1cdbd2cSJim Jagielski }
493*b1cdbd2cSJim Jagielski nLen = pStgStrm->Write( p, nLen );
494*b1cdbd2cSJim Jagielski }
495*b1cdbd2cSJim Jagielski nPos += nLen;
496*b1cdbd2cSJim Jagielski return nLen;
497*b1cdbd2cSJim Jagielski }
498*b1cdbd2cSJim Jagielski
499*b1cdbd2cSJim Jagielski // Copy the data of one entry into another entry.
500*b1cdbd2cSJim Jagielski
Copy(StgDirEntry & rDest)501*b1cdbd2cSJim Jagielski void StgDirEntry::Copy( StgDirEntry& rDest )
502*b1cdbd2cSJim Jagielski {
503*b1cdbd2cSJim Jagielski sal_Int32 n = GetSize();
504*b1cdbd2cSJim Jagielski if( rDest.SetSize( n ) && n )
505*b1cdbd2cSJim Jagielski {
506*b1cdbd2cSJim Jagielski sal_uInt8 aTempBytes[ 4096 ];
507*b1cdbd2cSJim Jagielski void* p = static_cast<void*>( aTempBytes );
508*b1cdbd2cSJim Jagielski Seek( 0L );
509*b1cdbd2cSJim Jagielski rDest.Seek( 0L );
510*b1cdbd2cSJim Jagielski while( n )
511*b1cdbd2cSJim Jagielski {
512*b1cdbd2cSJim Jagielski sal_Int32 nn = n;
513*b1cdbd2cSJim Jagielski if( nn > 4096 )
514*b1cdbd2cSJim Jagielski nn = 4096;
515*b1cdbd2cSJim Jagielski if( Read( p, nn ) != nn )
516*b1cdbd2cSJim Jagielski break;
517*b1cdbd2cSJim Jagielski if( rDest.Write( p, nn ) != nn )
518*b1cdbd2cSJim Jagielski break;
519*b1cdbd2cSJim Jagielski n -= nn;
520*b1cdbd2cSJim Jagielski }
521*b1cdbd2cSJim Jagielski }
522*b1cdbd2cSJim Jagielski }
523*b1cdbd2cSJim Jagielski
Copy(BaseStorageStream & rDest)524*b1cdbd2cSJim Jagielski void StgDirEntry::Copy( BaseStorageStream& rDest )
525*b1cdbd2cSJim Jagielski {
526*b1cdbd2cSJim Jagielski sal_Int32 n = GetSize();
527*b1cdbd2cSJim Jagielski if( rDest.SetSize( n ) && n )
528*b1cdbd2cSJim Jagielski {
529*b1cdbd2cSJim Jagielski sal_uLong Pos = rDest.Tell();
530*b1cdbd2cSJim Jagielski sal_uInt8 aTempBytes[ 4096 ];
531*b1cdbd2cSJim Jagielski void* p = static_cast<void*>( aTempBytes );
532*b1cdbd2cSJim Jagielski Seek( 0L );
533*b1cdbd2cSJim Jagielski rDest.Seek( 0L );
534*b1cdbd2cSJim Jagielski while( n )
535*b1cdbd2cSJim Jagielski {
536*b1cdbd2cSJim Jagielski sal_Int32 nn = n;
537*b1cdbd2cSJim Jagielski if( nn > 4096 )
538*b1cdbd2cSJim Jagielski nn = 4096;
539*b1cdbd2cSJim Jagielski if( Read( p, nn ) != nn )
540*b1cdbd2cSJim Jagielski break;
541*b1cdbd2cSJim Jagielski if( sal::static_int_cast<sal_Int32>(rDest.Write( p, nn )) != nn )
542*b1cdbd2cSJim Jagielski break;
543*b1cdbd2cSJim Jagielski n -= nn;
544*b1cdbd2cSJim Jagielski }
545*b1cdbd2cSJim Jagielski rDest.Seek( Pos ); // ?! Seems to be undocumented !
546*b1cdbd2cSJim Jagielski }
547*b1cdbd2cSJim Jagielski }
548*b1cdbd2cSJim Jagielski
549*b1cdbd2cSJim Jagielski // Commit this entry
550*b1cdbd2cSJim Jagielski
Commit()551*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::Commit()
552*b1cdbd2cSJim Jagielski {
553*b1cdbd2cSJim Jagielski // OSL_ENSURE( nMode & STREAM_WRITE, "Trying to commit readonly stream!" );
554*b1cdbd2cSJim Jagielski
555*b1cdbd2cSJim Jagielski aSave = aEntry;
556*b1cdbd2cSJim Jagielski sal_Bool bRes = sal_True;
557*b1cdbd2cSJim Jagielski if( aEntry.GetType() == STG_STREAM )
558*b1cdbd2cSJim Jagielski {
559*b1cdbd2cSJim Jagielski if( pTmpStrm )
560*b1cdbd2cSJim Jagielski delete pCurStrm, pCurStrm = pTmpStrm, pTmpStrm = NULL;
561*b1cdbd2cSJim Jagielski if( bRemoved )
562*b1cdbd2cSJim Jagielski // Delete the stream if needed
563*b1cdbd2cSJim Jagielski if( pStgStrm )
564*b1cdbd2cSJim Jagielski pStgStrm->SetSize( 0 );
565*b1cdbd2cSJim Jagielski }
566*b1cdbd2cSJim Jagielski else if( aEntry.GetType() == STG_STORAGE && bDirect && bRes )
567*b1cdbd2cSJim Jagielski {
568*b1cdbd2cSJim Jagielski StgIterator aIter( *this );
569*b1cdbd2cSJim Jagielski for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
570*b1cdbd2cSJim Jagielski bRes = p->Commit();
571*b1cdbd2cSJim Jagielski }
572*b1cdbd2cSJim Jagielski return bRes;
573*b1cdbd2cSJim Jagielski }
574*b1cdbd2cSJim Jagielski
575*b1cdbd2cSJim Jagielski // Revert the entry
576*b1cdbd2cSJim Jagielski
Revert()577*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::Revert()
578*b1cdbd2cSJim Jagielski {
579*b1cdbd2cSJim Jagielski aEntry = aSave;
580*b1cdbd2cSJim Jagielski switch( aEntry.GetType() )
581*b1cdbd2cSJim Jagielski {
582*b1cdbd2cSJim Jagielski case STG_STREAM:
583*b1cdbd2cSJim Jagielski if( pCurStrm )
584*b1cdbd2cSJim Jagielski delete pTmpStrm, pTmpStrm = pCurStrm, pCurStrm = NULL;
585*b1cdbd2cSJim Jagielski break;
586*b1cdbd2cSJim Jagielski case STG_STORAGE:
587*b1cdbd2cSJim Jagielski {
588*b1cdbd2cSJim Jagielski sal_Bool bSomeRenamed = sal_False;
589*b1cdbd2cSJim Jagielski StgIterator aOIter( *this );
590*b1cdbd2cSJim Jagielski StgDirEntry* op = aOIter.First();
591*b1cdbd2cSJim Jagielski while( op )
592*b1cdbd2cSJim Jagielski {
593*b1cdbd2cSJim Jagielski op->aEntry = op->aSave;
594*b1cdbd2cSJim Jagielski op->bDirty = sal_False;
595*b1cdbd2cSJim Jagielski bSomeRenamed = sal_Bool( bSomeRenamed | op->bRenamed );
596*b1cdbd2cSJim Jagielski // Remove any new entries
597*b1cdbd2cSJim Jagielski if( op->bCreated )
598*b1cdbd2cSJim Jagielski {
599*b1cdbd2cSJim Jagielski op->bCreated = sal_False;
600*b1cdbd2cSJim Jagielski op->Close();
601*b1cdbd2cSJim Jagielski op->bInvalid = sal_True;
602*b1cdbd2cSJim Jagielski }
603*b1cdbd2cSJim Jagielski // Reactivate any removed entries
604*b1cdbd2cSJim Jagielski else if( op->bRemoved )
605*b1cdbd2cSJim Jagielski op->bRemoved = op->bInvalid = op->bTemp = sal_False;
606*b1cdbd2cSJim Jagielski op = aOIter.Next();
607*b1cdbd2cSJim Jagielski }
608*b1cdbd2cSJim Jagielski // Resort all renamed entries
609*b1cdbd2cSJim Jagielski if( bSomeRenamed )
610*b1cdbd2cSJim Jagielski {
611*b1cdbd2cSJim Jagielski StgIterator aIter( *this );
612*b1cdbd2cSJim Jagielski StgDirEntry* p = aIter.First();
613*b1cdbd2cSJim Jagielski while( p )
614*b1cdbd2cSJim Jagielski {
615*b1cdbd2cSJim Jagielski if( p->bRenamed )
616*b1cdbd2cSJim Jagielski {
617*b1cdbd2cSJim Jagielski StgAvlNode::Move
618*b1cdbd2cSJim Jagielski ( (StgAvlNode**) &p->pUp->pDown,
619*b1cdbd2cSJim Jagielski (StgAvlNode**) &p->pUp->pDown, p );
620*b1cdbd2cSJim Jagielski p->bRenamed = sal_False;
621*b1cdbd2cSJim Jagielski }
622*b1cdbd2cSJim Jagielski p = aIter.Next();
623*b1cdbd2cSJim Jagielski }
624*b1cdbd2cSJim Jagielski }
625*b1cdbd2cSJim Jagielski DelTemp( sal_False );
626*b1cdbd2cSJim Jagielski break;
627*b1cdbd2cSJim Jagielski }
628*b1cdbd2cSJim Jagielski case STG_EMPTY:
629*b1cdbd2cSJim Jagielski case STG_LOCKBYTES:
630*b1cdbd2cSJim Jagielski case STG_PROPERTY:
631*b1cdbd2cSJim Jagielski case STG_ROOT:
632*b1cdbd2cSJim Jagielski break;
633*b1cdbd2cSJim Jagielski }
634*b1cdbd2cSJim Jagielski return sal_True;
635*b1cdbd2cSJim Jagielski }
636*b1cdbd2cSJim Jagielski
637*b1cdbd2cSJim Jagielski // Copy the stg stream to the temp stream
638*b1cdbd2cSJim Jagielski
Strm2Tmp()639*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::Strm2Tmp()
640*b1cdbd2cSJim Jagielski {
641*b1cdbd2cSJim Jagielski if( !pTmpStrm )
642*b1cdbd2cSJim Jagielski {
643*b1cdbd2cSJim Jagielski sal_uLong n = 0;
644*b1cdbd2cSJim Jagielski if( pCurStrm )
645*b1cdbd2cSJim Jagielski {
646*b1cdbd2cSJim Jagielski // It was already commited once
647*b1cdbd2cSJim Jagielski pTmpStrm = new StgTmpStrm;
648*b1cdbd2cSJim Jagielski if( pTmpStrm->GetError() == SVSTREAM_OK && pTmpStrm->Copy( *pCurStrm ) )
649*b1cdbd2cSJim Jagielski return sal_True;
650*b1cdbd2cSJim Jagielski n = 1; // indicates error
651*b1cdbd2cSJim Jagielski }
652*b1cdbd2cSJim Jagielski else
653*b1cdbd2cSJim Jagielski {
654*b1cdbd2cSJim Jagielski n = aEntry.GetSize();
655*b1cdbd2cSJim Jagielski pTmpStrm = new StgTmpStrm( n );
656*b1cdbd2cSJim Jagielski if( pTmpStrm->GetError() == SVSTREAM_OK )
657*b1cdbd2cSJim Jagielski {
658*b1cdbd2cSJim Jagielski if( n )
659*b1cdbd2cSJim Jagielski {
660*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
661*b1cdbd2cSJim Jagielski if ( !pStgStrm )
662*b1cdbd2cSJim Jagielski return sal_False;
663*b1cdbd2cSJim Jagielski
664*b1cdbd2cSJim Jagielski sal_uInt8 aTempBytes[ 4096 ];
665*b1cdbd2cSJim Jagielski void* p = static_cast<void*>( aTempBytes );
666*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( 0L );
667*b1cdbd2cSJim Jagielski while( n )
668*b1cdbd2cSJim Jagielski {
669*b1cdbd2cSJim Jagielski sal_uLong nn = n;
670*b1cdbd2cSJim Jagielski if( nn > 4096 )
671*b1cdbd2cSJim Jagielski nn = 4096;
672*b1cdbd2cSJim Jagielski if( (sal_uLong) pStgStrm->Read( p, nn ) != nn )
673*b1cdbd2cSJim Jagielski break;
674*b1cdbd2cSJim Jagielski if( pTmpStrm->Write( p, nn ) != nn )
675*b1cdbd2cSJim Jagielski break;
676*b1cdbd2cSJim Jagielski n -= nn;
677*b1cdbd2cSJim Jagielski }
678*b1cdbd2cSJim Jagielski pStgStrm->Pos2Page( nPos );
679*b1cdbd2cSJim Jagielski pTmpStrm->Seek( nPos );
680*b1cdbd2cSJim Jagielski }
681*b1cdbd2cSJim Jagielski }
682*b1cdbd2cSJim Jagielski else
683*b1cdbd2cSJim Jagielski n = 1;
684*b1cdbd2cSJim Jagielski }
685*b1cdbd2cSJim Jagielski
686*b1cdbd2cSJim Jagielski if( n )
687*b1cdbd2cSJim Jagielski {
688*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
689*b1cdbd2cSJim Jagielski if ( pStgStrm )
690*b1cdbd2cSJim Jagielski pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
691*b1cdbd2cSJim Jagielski
692*b1cdbd2cSJim Jagielski delete pTmpStrm;
693*b1cdbd2cSJim Jagielski pTmpStrm = NULL;
694*b1cdbd2cSJim Jagielski return sal_False;
695*b1cdbd2cSJim Jagielski }
696*b1cdbd2cSJim Jagielski }
697*b1cdbd2cSJim Jagielski return sal_True;
698*b1cdbd2cSJim Jagielski }
699*b1cdbd2cSJim Jagielski
700*b1cdbd2cSJim Jagielski // Copy the temp stream to the stg stream during the final commit
701*b1cdbd2cSJim Jagielski
Tmp2Strm()702*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::Tmp2Strm()
703*b1cdbd2cSJim Jagielski {
704*b1cdbd2cSJim Jagielski // We did commit once, but have not written since then
705*b1cdbd2cSJim Jagielski if( !pTmpStrm )
706*b1cdbd2cSJim Jagielski pTmpStrm = pCurStrm, pCurStrm = NULL;
707*b1cdbd2cSJim Jagielski if( pTmpStrm )
708*b1cdbd2cSJim Jagielski {
709*b1cdbd2cSJim Jagielski OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
710*b1cdbd2cSJim Jagielski if ( !pStgStrm )
711*b1cdbd2cSJim Jagielski return sal_False;
712*b1cdbd2cSJim Jagielski sal_uLong n = pTmpStrm->GetSize();
713*b1cdbd2cSJim Jagielski StgStrm* pNewStrm;
714*b1cdbd2cSJim Jagielski StgIo& rIo = pStgStrm->GetIo();
715*b1cdbd2cSJim Jagielski sal_uLong nThreshold = (sal_uLong) rIo.aHdr.GetThreshold();
716*b1cdbd2cSJim Jagielski if( n < nThreshold )
717*b1cdbd2cSJim Jagielski pNewStrm = new StgSmallStrm( rIo, STG_EOF, 0 );
718*b1cdbd2cSJim Jagielski else
719*b1cdbd2cSJim Jagielski pNewStrm = new StgDataStrm( rIo, STG_EOF, 0 );
720*b1cdbd2cSJim Jagielski if( pNewStrm->SetSize( n ) )
721*b1cdbd2cSJim Jagielski {
722*b1cdbd2cSJim Jagielski sal_uInt8 p[ 4096 ];
723*b1cdbd2cSJim Jagielski pTmpStrm->Seek( 0L );
724*b1cdbd2cSJim Jagielski while( n )
725*b1cdbd2cSJim Jagielski {
726*b1cdbd2cSJim Jagielski sal_uLong nn = n;
727*b1cdbd2cSJim Jagielski if( nn > 4096 )
728*b1cdbd2cSJim Jagielski nn = 4096;
729*b1cdbd2cSJim Jagielski if( pTmpStrm->Read( p, nn ) != nn )
730*b1cdbd2cSJim Jagielski break;
731*b1cdbd2cSJim Jagielski if( (sal_uLong) pNewStrm->Write( p, nn ) != nn )
732*b1cdbd2cSJim Jagielski break;
733*b1cdbd2cSJim Jagielski n -= nn;
734*b1cdbd2cSJim Jagielski }
735*b1cdbd2cSJim Jagielski if( n )
736*b1cdbd2cSJim Jagielski {
737*b1cdbd2cSJim Jagielski pTmpStrm->Seek( nPos );
738*b1cdbd2cSJim Jagielski pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
739*b1cdbd2cSJim Jagielski delete pNewStrm;
740*b1cdbd2cSJim Jagielski return sal_False;
741*b1cdbd2cSJim Jagielski }
742*b1cdbd2cSJim Jagielski else
743*b1cdbd2cSJim Jagielski {
744*b1cdbd2cSJim Jagielski pStgStrm->SetSize( 0L );
745*b1cdbd2cSJim Jagielski delete pStgStrm;
746*b1cdbd2cSJim Jagielski pStgStrm = pNewStrm;
747*b1cdbd2cSJim Jagielski pNewStrm->SetEntry( *this );
748*b1cdbd2cSJim Jagielski pNewStrm->Pos2Page( nPos );
749*b1cdbd2cSJim Jagielski delete pTmpStrm;
750*b1cdbd2cSJim Jagielski delete pCurStrm;
751*b1cdbd2cSJim Jagielski pTmpStrm = pCurStrm = NULL;
752*b1cdbd2cSJim Jagielski aSave = aEntry;
753*b1cdbd2cSJim Jagielski }
754*b1cdbd2cSJim Jagielski }
755*b1cdbd2cSJim Jagielski }
756*b1cdbd2cSJim Jagielski return sal_True;
757*b1cdbd2cSJim Jagielski }
758*b1cdbd2cSJim Jagielski
759*b1cdbd2cSJim Jagielski // Check if the given entry is contained in this entry
760*b1cdbd2cSJim Jagielski
IsContained(StgDirEntry * pStg)761*b1cdbd2cSJim Jagielski sal_Bool StgDirEntry::IsContained( StgDirEntry* pStg )
762*b1cdbd2cSJim Jagielski {
763*b1cdbd2cSJim Jagielski if( aEntry.GetType() == STG_STORAGE )
764*b1cdbd2cSJim Jagielski {
765*b1cdbd2cSJim Jagielski StgIterator aIter( *this );
766*b1cdbd2cSJim Jagielski StgDirEntry* p = aIter.First();
767*b1cdbd2cSJim Jagielski while( p )
768*b1cdbd2cSJim Jagielski {
769*b1cdbd2cSJim Jagielski if( !p->aEntry.Compare( pStg->aEntry ) )
770*b1cdbd2cSJim Jagielski return sal_False;
771*b1cdbd2cSJim Jagielski if( p->aEntry.GetType() == STG_STORAGE )
772*b1cdbd2cSJim Jagielski if( !p->IsContained( pStg ) )
773*b1cdbd2cSJim Jagielski return sal_False;
774*b1cdbd2cSJim Jagielski p = aIter.Next();
775*b1cdbd2cSJim Jagielski }
776*b1cdbd2cSJim Jagielski }
777*b1cdbd2cSJim Jagielski return sal_True;
778*b1cdbd2cSJim Jagielski }
779*b1cdbd2cSJim Jagielski
780*b1cdbd2cSJim Jagielski // Invalidate all open entries by setting the RefCount to 0. If the bDel
781*b1cdbd2cSJim Jagielski // flag is set, also set the invalid flag to indicate deletion during the
782*b1cdbd2cSJim Jagielski // next dir stream flush.
783*b1cdbd2cSJim Jagielski
Invalidate(sal_Bool bDel)784*b1cdbd2cSJim Jagielski void StgDirEntry::Invalidate( sal_Bool bDel )
785*b1cdbd2cSJim Jagielski {
786*b1cdbd2cSJim Jagielski // nRefCnt = 0;
787*b1cdbd2cSJim Jagielski if( bDel )
788*b1cdbd2cSJim Jagielski bRemoved = bInvalid = sal_True;
789*b1cdbd2cSJim Jagielski switch( aEntry.GetType() )
790*b1cdbd2cSJim Jagielski {
791*b1cdbd2cSJim Jagielski case STG_STORAGE:
792*b1cdbd2cSJim Jagielski case STG_ROOT:
793*b1cdbd2cSJim Jagielski {
794*b1cdbd2cSJim Jagielski StgIterator aIter( *this );
795*b1cdbd2cSJim Jagielski for( StgDirEntry* p = aIter.First(); p; p = aIter.Next() )
796*b1cdbd2cSJim Jagielski p->Invalidate( bDel );
797*b1cdbd2cSJim Jagielski break;
798*b1cdbd2cSJim Jagielski }
799*b1cdbd2cSJim Jagielski default:
800*b1cdbd2cSJim Jagielski break;
801*b1cdbd2cSJim Jagielski }
802*b1cdbd2cSJim Jagielski }
803*b1cdbd2cSJim Jagielski
804*b1cdbd2cSJim Jagielski ///////////////////////////// class StgDirStrm ////////////////////////////
805*b1cdbd2cSJim Jagielski
806*b1cdbd2cSJim Jagielski // This specialized stream is the maintenance stream for the directory tree.
807*b1cdbd2cSJim Jagielski
StgDirStrm(StgIo & r)808*b1cdbd2cSJim Jagielski StgDirStrm::StgDirStrm( StgIo& r )
809*b1cdbd2cSJim Jagielski : StgDataStrm( r, r.aHdr.GetTOCStart(), -1 )
810*b1cdbd2cSJim Jagielski , pRoot( NULL )
811*b1cdbd2cSJim Jagielski , nEntries( 0 )
812*b1cdbd2cSJim Jagielski {
813*b1cdbd2cSJim Jagielski if( r.GetError() )
814*b1cdbd2cSJim Jagielski return;
815*b1cdbd2cSJim Jagielski nEntries = nPageSize / STGENTRY_SIZE;
816*b1cdbd2cSJim Jagielski if( nStart == STG_EOF )
817*b1cdbd2cSJim Jagielski {
818*b1cdbd2cSJim Jagielski StgEntry aRoot;
819*b1cdbd2cSJim Jagielski aRoot.Init();
820*b1cdbd2cSJim Jagielski aRoot.SetName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Root Entry" ) ) );
821*b1cdbd2cSJim Jagielski aRoot.SetType( STG_ROOT );
822*b1cdbd2cSJim Jagielski pRoot = new StgDirEntry( aRoot );
823*b1cdbd2cSJim Jagielski pRoot->SetDirty();
824*b1cdbd2cSJim Jagielski }
825*b1cdbd2cSJim Jagielski else
826*b1cdbd2cSJim Jagielski {
827*b1cdbd2cSJim Jagielski // temporarily use this instance as owner, so
828*b1cdbd2cSJim Jagielski // the TOC pages can be removed.
829*b1cdbd2cSJim Jagielski pEntry = (StgDirEntry*) this; // just for a bit pattern
830*b1cdbd2cSJim Jagielski SetupEntry(0, pRoot, nSize/STGENTRY_SIZE, 0);
831*b1cdbd2cSJim Jagielski rIo.Revert( pEntry );
832*b1cdbd2cSJim Jagielski pEntry = NULL;
833*b1cdbd2cSJim Jagielski }
834*b1cdbd2cSJim Jagielski }
835*b1cdbd2cSJim Jagielski
~StgDirStrm()836*b1cdbd2cSJim Jagielski StgDirStrm::~StgDirStrm()
837*b1cdbd2cSJim Jagielski {
838*b1cdbd2cSJim Jagielski delete pRoot;
839*b1cdbd2cSJim Jagielski }
840*b1cdbd2cSJim Jagielski
841*b1cdbd2cSJim Jagielski // Recursively parse the directory tree during reading the TOC stream
842*b1cdbd2cSJim Jagielski
SetupEntry(const sal_Int32 n,StgDirEntry * pUpper,const sal_Int32 nEntryCount,const sal_Int32 nDepth)843*b1cdbd2cSJim Jagielski void StgDirStrm::SetupEntry (
844*b1cdbd2cSJim Jagielski const sal_Int32 n,
845*b1cdbd2cSJim Jagielski StgDirEntry* pUpper,
846*b1cdbd2cSJim Jagielski const sal_Int32 nEntryCount,
847*b1cdbd2cSJim Jagielski const sal_Int32 nDepth)
848*b1cdbd2cSJim Jagielski {
849*b1cdbd2cSJim Jagielski if (nDepth > nEntryCount)
850*b1cdbd2cSJim Jagielski {
851*b1cdbd2cSJim Jagielski // Tree grew higher than there are different nodes. Looks like
852*b1cdbd2cSJim Jagielski // something is wrong with the file. Return now to avoid
853*b1cdbd2cSJim Jagielski // infinite recursion.
854*b1cdbd2cSJim Jagielski return;
855*b1cdbd2cSJim Jagielski }
856*b1cdbd2cSJim Jagielski else if (n>=nEntryCount || (n<0 && n!=STG_FREE))
857*b1cdbd2cSJim Jagielski {
858*b1cdbd2cSJim Jagielski // n has an invalid value. Don't access the corresponding
859*b1cdbd2cSJim Jagielski // stream content.
860*b1cdbd2cSJim Jagielski return;
861*b1cdbd2cSJim Jagielski }
862*b1cdbd2cSJim Jagielski
863*b1cdbd2cSJim Jagielski void* p = ( n == STG_FREE ) ? NULL : GetEntry( n );
864*b1cdbd2cSJim Jagielski if( p )
865*b1cdbd2cSJim Jagielski {
866*b1cdbd2cSJim Jagielski sal_Bool bOk(sal_False);
867*b1cdbd2cSJim Jagielski StgDirEntry* pCur = new StgDirEntry( p, STGENTRY_SIZE, &bOk );
868*b1cdbd2cSJim Jagielski
869*b1cdbd2cSJim Jagielski if( !bOk )
870*b1cdbd2cSJim Jagielski {
871*b1cdbd2cSJim Jagielski delete pCur;
872*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_GENERALERROR );
873*b1cdbd2cSJim Jagielski // an error occured
874*b1cdbd2cSJim Jagielski return;
875*b1cdbd2cSJim Jagielski }
876*b1cdbd2cSJim Jagielski
877*b1cdbd2cSJim Jagielski // better it is
878*b1cdbd2cSJim Jagielski if( !pUpper )
879*b1cdbd2cSJim Jagielski pCur->aEntry.SetType( STG_ROOT );
880*b1cdbd2cSJim Jagielski
881*b1cdbd2cSJim Jagielski sal_Int32 nLeft = pCur->aEntry.GetLeaf( STG_LEFT );
882*b1cdbd2cSJim Jagielski sal_Int32 nRight = pCur->aEntry.GetLeaf( STG_RIGHT );
883*b1cdbd2cSJim Jagielski // substorage?
884*b1cdbd2cSJim Jagielski sal_Int32 nLeaf = STG_FREE;
885*b1cdbd2cSJim Jagielski if( pCur->aEntry.GetType() == STG_STORAGE || pCur->aEntry.GetType() == STG_ROOT )
886*b1cdbd2cSJim Jagielski {
887*b1cdbd2cSJim Jagielski nLeaf = pCur->aEntry.GetLeaf( STG_CHILD );
888*b1cdbd2cSJim Jagielski if (nLeaf != STG_FREE && nLeaf == n)
889*b1cdbd2cSJim Jagielski {
890*b1cdbd2cSJim Jagielski delete pCur;
891*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_GENERALERROR );
892*b1cdbd2cSJim Jagielski return;
893*b1cdbd2cSJim Jagielski }
894*b1cdbd2cSJim Jagielski }
895*b1cdbd2cSJim Jagielski
896*b1cdbd2cSJim Jagielski if( nLeaf != 0 && nLeft != 0 && nRight != 0 )
897*b1cdbd2cSJim Jagielski {
898*b1cdbd2cSJim Jagielski if( StgAvlNode::Insert
899*b1cdbd2cSJim Jagielski ( (StgAvlNode**) ( pUpper ? &pUpper->pDown : &pRoot ), pCur ) )
900*b1cdbd2cSJim Jagielski {
901*b1cdbd2cSJim Jagielski pCur->pUp = pUpper;
902*b1cdbd2cSJim Jagielski pCur->ppRoot = &pRoot;
903*b1cdbd2cSJim Jagielski }
904*b1cdbd2cSJim Jagielski else
905*b1cdbd2cSJim Jagielski {
906*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_CANNOT_MAKE );
907*b1cdbd2cSJim Jagielski delete pCur; pCur = NULL;
908*b1cdbd2cSJim Jagielski return;
909*b1cdbd2cSJim Jagielski }
910*b1cdbd2cSJim Jagielski SetupEntry( nLeft, pUpper, nEntryCount, nDepth+1);
911*b1cdbd2cSJim Jagielski SetupEntry( nRight, pUpper, nEntryCount, nDepth+1);
912*b1cdbd2cSJim Jagielski SetupEntry( nLeaf, pCur, nEntryCount, nDepth+1);
913*b1cdbd2cSJim Jagielski }
914*b1cdbd2cSJim Jagielski }
915*b1cdbd2cSJim Jagielski }
916*b1cdbd2cSJim Jagielski
917*b1cdbd2cSJim Jagielski // Extend or shrink the directory stream.
918*b1cdbd2cSJim Jagielski
SetSize(sal_Int32 nBytes)919*b1cdbd2cSJim Jagielski sal_Bool StgDirStrm::SetSize( sal_Int32 nBytes )
920*b1cdbd2cSJim Jagielski {
921*b1cdbd2cSJim Jagielski // Always allocate full pages
922*b1cdbd2cSJim Jagielski if ( nBytes < 0 )
923*b1cdbd2cSJim Jagielski nBytes = 0;
924*b1cdbd2cSJim Jagielski
925*b1cdbd2cSJim Jagielski nBytes = ( ( nBytes + nPageSize - 1 ) / nPageSize ) * nPageSize;
926*b1cdbd2cSJim Jagielski return StgStrm::SetSize( nBytes );
927*b1cdbd2cSJim Jagielski }
928*b1cdbd2cSJim Jagielski
929*b1cdbd2cSJim Jagielski // Save the TOC stream into a new substream after saving all data streams
930*b1cdbd2cSJim Jagielski
Store()931*b1cdbd2cSJim Jagielski sal_Bool StgDirStrm::Store()
932*b1cdbd2cSJim Jagielski {
933*b1cdbd2cSJim Jagielski if( !pRoot || !pRoot->IsDirty() )
934*b1cdbd2cSJim Jagielski return sal_True;
935*b1cdbd2cSJim Jagielski if( !pRoot->StoreStreams( rIo ) )
936*b1cdbd2cSJim Jagielski return sal_False;
937*b1cdbd2cSJim Jagielski // After writing all streams, the data FAT stream has changed,
938*b1cdbd2cSJim Jagielski // so we have to commit the root again
939*b1cdbd2cSJim Jagielski pRoot->Commit();
940*b1cdbd2cSJim Jagielski // We want a completely new stream, so fake an empty stream
941*b1cdbd2cSJim Jagielski sal_Int32 nOldStart = nStart; // save for later deletion
942*b1cdbd2cSJim Jagielski sal_Int32 nOldSize = nSize;
943*b1cdbd2cSJim Jagielski nStart = nPage = STG_EOF;
944*b1cdbd2cSJim Jagielski nSize = nPos = 0;
945*b1cdbd2cSJim Jagielski nOffset = 0;
946*b1cdbd2cSJim Jagielski // Delete all temporary entries
947*b1cdbd2cSJim Jagielski pRoot->DelTemp( sal_False );
948*b1cdbd2cSJim Jagielski // set the entry numbers
949*b1cdbd2cSJim Jagielski sal_Int32 n = 0;
950*b1cdbd2cSJim Jagielski pRoot->Enum( n );
951*b1cdbd2cSJim Jagielski if( !SetSize( n * STGENTRY_SIZE ) )
952*b1cdbd2cSJim Jagielski {
953*b1cdbd2cSJim Jagielski nStart = nOldStart; nSize = nOldSize;
954*b1cdbd2cSJim Jagielski pRoot->RevertAll();
955*b1cdbd2cSJim Jagielski return sal_False;
956*b1cdbd2cSJim Jagielski }
957*b1cdbd2cSJim Jagielski // set up the cache elements for the new stream
958*b1cdbd2cSJim Jagielski if( !Copy( STG_FREE, nSize ) )
959*b1cdbd2cSJim Jagielski {
960*b1cdbd2cSJim Jagielski pRoot->RevertAll();
961*b1cdbd2cSJim Jagielski return sal_False;
962*b1cdbd2cSJim Jagielski }
963*b1cdbd2cSJim Jagielski // Write the data to the new stream
964*b1cdbd2cSJim Jagielski if( !pRoot->Store( *this ) )
965*b1cdbd2cSJim Jagielski {
966*b1cdbd2cSJim Jagielski pRoot->RevertAll();
967*b1cdbd2cSJim Jagielski return sal_False;
968*b1cdbd2cSJim Jagielski }
969*b1cdbd2cSJim Jagielski // fill any remaining entries with empty data
970*b1cdbd2cSJim Jagielski sal_Int32 ne = nSize / STGENTRY_SIZE;
971*b1cdbd2cSJim Jagielski StgEntry aEmpty;
972*b1cdbd2cSJim Jagielski aEmpty.Init();
973*b1cdbd2cSJim Jagielski while( n < ne )
974*b1cdbd2cSJim Jagielski {
975*b1cdbd2cSJim Jagielski void* p = GetEntry( n++, sal_True );
976*b1cdbd2cSJim Jagielski if( !p )
977*b1cdbd2cSJim Jagielski {
978*b1cdbd2cSJim Jagielski pRoot->RevertAll();
979*b1cdbd2cSJim Jagielski return sal_False;
980*b1cdbd2cSJim Jagielski }
981*b1cdbd2cSJim Jagielski aEmpty.Store( p );
982*b1cdbd2cSJim Jagielski }
983*b1cdbd2cSJim Jagielski // Now we can release the old stream
984*b1cdbd2cSJim Jagielski pFat->FreePages( nOldStart, sal_True );
985*b1cdbd2cSJim Jagielski rIo.aHdr.SetTOCStart( nStart );
986*b1cdbd2cSJim Jagielski return sal_True;
987*b1cdbd2cSJim Jagielski }
988*b1cdbd2cSJim Jagielski
989*b1cdbd2cSJim Jagielski // Get a dir entry.
990*b1cdbd2cSJim Jagielski
GetEntry(sal_Int32 n,sal_Bool bDirty)991*b1cdbd2cSJim Jagielski void* StgDirStrm::GetEntry( sal_Int32 n, sal_Bool bDirty )
992*b1cdbd2cSJim Jagielski {
993*b1cdbd2cSJim Jagielski if( n < 0 )
994*b1cdbd2cSJim Jagielski return NULL;
995*b1cdbd2cSJim Jagielski
996*b1cdbd2cSJim Jagielski n *= STGENTRY_SIZE;
997*b1cdbd2cSJim Jagielski if( n < 0 && n >= nSize )
998*b1cdbd2cSJim Jagielski return NULL;
999*b1cdbd2cSJim Jagielski return GetPtr( n, sal_True, bDirty );
1000*b1cdbd2cSJim Jagielski }
1001*b1cdbd2cSJim Jagielski
1002*b1cdbd2cSJim Jagielski // Find a dir entry.
1003*b1cdbd2cSJim Jagielski
Find(StgDirEntry & rStg,const String & rName)1004*b1cdbd2cSJim Jagielski StgDirEntry* StgDirStrm::Find( StgDirEntry& rStg, const String& rName )
1005*b1cdbd2cSJim Jagielski {
1006*b1cdbd2cSJim Jagielski if( rStg.pDown )
1007*b1cdbd2cSJim Jagielski {
1008*b1cdbd2cSJim Jagielski StgEntry aEntry;
1009*b1cdbd2cSJim Jagielski aEntry.Init();
1010*b1cdbd2cSJim Jagielski if( !aEntry.SetName( rName ) )
1011*b1cdbd2cSJim Jagielski {
1012*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_GENERALERROR );
1013*b1cdbd2cSJim Jagielski return NULL;
1014*b1cdbd2cSJim Jagielski }
1015*b1cdbd2cSJim Jagielski // Look in the directory attached to the entry
1016*b1cdbd2cSJim Jagielski StgDirEntry aTest( aEntry );
1017*b1cdbd2cSJim Jagielski return (StgDirEntry*) rStg.pDown->Find( &aTest );
1018*b1cdbd2cSJim Jagielski }
1019*b1cdbd2cSJim Jagielski else
1020*b1cdbd2cSJim Jagielski return NULL;
1021*b1cdbd2cSJim Jagielski }
1022*b1cdbd2cSJim Jagielski
1023*b1cdbd2cSJim Jagielski // Create a new entry.
1024*b1cdbd2cSJim Jagielski
Create(StgDirEntry & rStg,const String & rName,StgEntryType eType)1025*b1cdbd2cSJim Jagielski StgDirEntry* StgDirStrm::Create
1026*b1cdbd2cSJim Jagielski ( StgDirEntry& rStg, const String& rName, StgEntryType eType )
1027*b1cdbd2cSJim Jagielski {
1028*b1cdbd2cSJim Jagielski StgEntry aEntry;
1029*b1cdbd2cSJim Jagielski aEntry.Init();
1030*b1cdbd2cSJim Jagielski aEntry.SetType( eType );
1031*b1cdbd2cSJim Jagielski if( !aEntry.SetName( rName ) )
1032*b1cdbd2cSJim Jagielski {
1033*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_GENERALERROR );
1034*b1cdbd2cSJim Jagielski return NULL;
1035*b1cdbd2cSJim Jagielski }
1036*b1cdbd2cSJim Jagielski StgDirEntry* pRes = Find( rStg, rName );
1037*b1cdbd2cSJim Jagielski if( pRes )
1038*b1cdbd2cSJim Jagielski {
1039*b1cdbd2cSJim Jagielski if( !pRes->bInvalid )
1040*b1cdbd2cSJim Jagielski {
1041*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_CANNOT_MAKE );
1042*b1cdbd2cSJim Jagielski return NULL;
1043*b1cdbd2cSJim Jagielski }
1044*b1cdbd2cSJim Jagielski pRes->bInvalid =
1045*b1cdbd2cSJim Jagielski pRes->bRemoved =
1046*b1cdbd2cSJim Jagielski pRes->bTemp = sal_False;
1047*b1cdbd2cSJim Jagielski pRes->bCreated =
1048*b1cdbd2cSJim Jagielski pRes->bDirty = sal_True;
1049*b1cdbd2cSJim Jagielski }
1050*b1cdbd2cSJim Jagielski else
1051*b1cdbd2cSJim Jagielski {
1052*b1cdbd2cSJim Jagielski pRes = new StgDirEntry( aEntry );
1053*b1cdbd2cSJim Jagielski if( StgAvlNode::Insert( (StgAvlNode**) &rStg.pDown, pRes ) )
1054*b1cdbd2cSJim Jagielski {
1055*b1cdbd2cSJim Jagielski pRes->pUp = &rStg;
1056*b1cdbd2cSJim Jagielski pRes->ppRoot = &pRoot;
1057*b1cdbd2cSJim Jagielski pRes->bCreated =
1058*b1cdbd2cSJim Jagielski pRes->bDirty = sal_True;
1059*b1cdbd2cSJim Jagielski }
1060*b1cdbd2cSJim Jagielski else
1061*b1cdbd2cSJim Jagielski {
1062*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_CANNOT_MAKE );
1063*b1cdbd2cSJim Jagielski delete pRes; pRes = NULL;
1064*b1cdbd2cSJim Jagielski }
1065*b1cdbd2cSJim Jagielski }
1066*b1cdbd2cSJim Jagielski return pRes;
1067*b1cdbd2cSJim Jagielski }
1068*b1cdbd2cSJim Jagielski
1069*b1cdbd2cSJim Jagielski // Rename the given entry.
1070*b1cdbd2cSJim Jagielski
Rename(StgDirEntry & rStg,const String & rOld,const String & rNew)1071*b1cdbd2cSJim Jagielski sal_Bool StgDirStrm::Rename( StgDirEntry& rStg, const String& rOld, const String& rNew )
1072*b1cdbd2cSJim Jagielski {
1073*b1cdbd2cSJim Jagielski StgDirEntry* p = Find( rStg, rOld );
1074*b1cdbd2cSJim Jagielski if( p )
1075*b1cdbd2cSJim Jagielski {
1076*b1cdbd2cSJim Jagielski
1077*b1cdbd2cSJim Jagielski if( !StgAvlNode::Remove( (StgAvlNode**) &rStg.pDown, p, sal_False ) )
1078*b1cdbd2cSJim Jagielski return sal_False;
1079*b1cdbd2cSJim Jagielski p->aEntry.SetName( rNew );
1080*b1cdbd2cSJim Jagielski if( !StgAvlNode::Insert( (StgAvlNode**) &rStg.pDown, p ) )
1081*b1cdbd2cSJim Jagielski return sal_False;
1082*b1cdbd2cSJim Jagielski p->bRenamed = p->bDirty = sal_True;
1083*b1cdbd2cSJim Jagielski return sal_True;
1084*b1cdbd2cSJim Jagielski }
1085*b1cdbd2cSJim Jagielski else
1086*b1cdbd2cSJim Jagielski {
1087*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_FILE_NOT_FOUND );
1088*b1cdbd2cSJim Jagielski return sal_False;
1089*b1cdbd2cSJim Jagielski }
1090*b1cdbd2cSJim Jagielski }
1091*b1cdbd2cSJim Jagielski
1092*b1cdbd2cSJim Jagielski // Move the given entry to a different storage.
1093*b1cdbd2cSJim Jagielski
Move(StgDirEntry & rStg1,StgDirEntry & rStg2,const String & rName)1094*b1cdbd2cSJim Jagielski sal_Bool StgDirStrm::Move( StgDirEntry& rStg1, StgDirEntry& rStg2, const String& rName )
1095*b1cdbd2cSJim Jagielski {
1096*b1cdbd2cSJim Jagielski StgDirEntry* p = Find( rStg1, rName );
1097*b1cdbd2cSJim Jagielski if( p )
1098*b1cdbd2cSJim Jagielski {
1099*b1cdbd2cSJim Jagielski if( !StgAvlNode::Move
1100*b1cdbd2cSJim Jagielski ( (StgAvlNode**) &rStg1.pDown, (StgAvlNode**) &rStg2.pDown, p ) )
1101*b1cdbd2cSJim Jagielski return sal_False;
1102*b1cdbd2cSJim Jagielski p->bDirty = sal_True;
1103*b1cdbd2cSJim Jagielski return sal_True;
1104*b1cdbd2cSJim Jagielski }
1105*b1cdbd2cSJim Jagielski else
1106*b1cdbd2cSJim Jagielski {
1107*b1cdbd2cSJim Jagielski rIo.SetError( SVSTREAM_FILE_NOT_FOUND );
1108*b1cdbd2cSJim Jagielski return sal_False;
1109*b1cdbd2cSJim Jagielski }
1110*b1cdbd2cSJim Jagielski }
1111*b1cdbd2cSJim Jagielski
1112