1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
---|
2 | /* ***** BEGIN LICENSE BLOCK *****
|
---|
3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
4 | *
|
---|
5 | * The contents of this file are subject to the Mozilla Public License Version
|
---|
6 | * 1.1 (the "License"); you may not use this file except in compliance with
|
---|
7 | * the License. You may obtain a copy of the License at
|
---|
8 | * http://www.mozilla.org/MPL/
|
---|
9 | *
|
---|
10 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
12 | * for the specific language governing rights and limitations under the
|
---|
13 | * License.
|
---|
14 | *
|
---|
15 | * The Original Code is Mozilla FastLoad code.
|
---|
16 | *
|
---|
17 | * The Initial Developer of the Original Code is
|
---|
18 | * Netscape Communications Corporation.
|
---|
19 | * Portions created by the Initial Developer are Copyright (C) 2001
|
---|
20 | * the Initial Developer. All Rights Reserved.
|
---|
21 | *
|
---|
22 | * Contributor(s):
|
---|
23 | * Brendan Eich <brendan@mozilla.org> (original author)
|
---|
24 | *
|
---|
25 | * Alternatively, the contents of this file may be used under the terms of
|
---|
26 | * either of the GNU General Public License Version 2 or later (the "GPL"),
|
---|
27 | * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
---|
28 | * in which case the provisions of the GPL or the LGPL are applicable instead
|
---|
29 | * of those above. If you wish to allow use of your version of this file only
|
---|
30 | * under the terms of either the GPL or the LGPL, and not to allow others to
|
---|
31 | * use your version of this file under the terms of the MPL, indicate your
|
---|
32 | * decision by deleting the provisions above and replace them with the notice
|
---|
33 | * and other provisions required by the GPL or the LGPL. If you do not delete
|
---|
34 | * the provisions above, a recipient may use your version of this file under
|
---|
35 | * the terms of any one of the MPL, the GPL or the LGPL.
|
---|
36 | *
|
---|
37 | * ***** END LICENSE BLOCK ***** */
|
---|
38 |
|
---|
39 | #ifndef nsFastLoadFile_h___
|
---|
40 | #define nsFastLoadFile_h___
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * Mozilla FastLoad file format and helper types.
|
---|
44 | */
|
---|
45 |
|
---|
46 | #include "prtypes.h"
|
---|
47 | #include "pldhash.h"
|
---|
48 |
|
---|
49 | #include "nsBinaryStream.h"
|
---|
50 | #include "nsCOMPtr.h"
|
---|
51 | #include "nsDebug.h"
|
---|
52 | #include "nsID.h"
|
---|
53 | #include "nsMemory.h"
|
---|
54 | #include "nsVoidArray.h"
|
---|
55 |
|
---|
56 | #include "nsIFastLoadFileControl.h"
|
---|
57 | #include "nsIFastLoadService.h"
|
---|
58 | #include "nsISeekableStream.h"
|
---|
59 | #include "nsISupportsArray.h"
|
---|
60 |
|
---|
61 | /**
|
---|
62 | * FastLoad file Object ID (OID) is an identifier for multiply and cyclicly
|
---|
63 | * connected objects in the serialized graph of all reachable objects.
|
---|
64 | *
|
---|
65 | * Holy Mixed Metaphors: JS, after Common Lisp, uses #n= to define a "sharp
|
---|
66 | * variable" naming an object that's multiply or cyclicly connected, and #n#
|
---|
67 | * to stand for a connection to an already-defined object. We too call any
|
---|
68 | * object with multiple references "sharp", and (here it comes) any object
|
---|
69 | * with only one reference "dull".
|
---|
70 | *
|
---|
71 | * Note that only sharp objects require a mapping from OID to FastLoad file
|
---|
72 | * offset and other information. Dull objects can be serialized _in situ_
|
---|
73 | * (where they are referenced) and deserialized when their (singular, shared)
|
---|
74 | * OID is scanned.
|
---|
75 | *
|
---|
76 | * We also compress 16-byte XPCOM IDs into 32-bit dense identifiers to save
|
---|
77 | * space. See nsFastLoadFooter, below, for the mapping data structure used to
|
---|
78 | * compute an nsID given an NSFastLoadID.
|
---|
79 | */
|
---|
80 | typedef PRUint32 NSFastLoadID; // nsFastLoadFooter::mIDMap index
|
---|
81 | typedef PRUint32 NSFastLoadOID; // nsFastLoadFooter::mObjectMap index
|
---|
82 |
|
---|
83 | /**
|
---|
84 | * A Mozilla FastLoad file is an untagged (in general) stream of objects and
|
---|
85 | * primitive-type data. Small integers are fairly common, and could easily be
|
---|
86 | * confused for NSFastLoadIDs and NSFastLoadOIDs. To help catch bugs where
|
---|
87 | * reader and writer code fail to match, we XOR unlikely 32-bit numbers with
|
---|
88 | * NSFastLoad*IDs when storing and fetching. The following unlikely values are
|
---|
89 | * irrational numbers ((sqrt(5)-1)/2, sqrt(2)-1) represented in fixed point.
|
---|
90 | *
|
---|
91 | * The reader XORs, converts the ID to an index, and bounds-checks all array
|
---|
92 | * accesses that use the index. Array access code asserts that the index is in
|
---|
93 | * bounds, and returns a dummy array element if it isn't.
|
---|
94 | */
|
---|
95 | #define MFL_ID_XOR_KEY 0x9E3779B9 // key XOR'd with ID when serialized
|
---|
96 | #define MFL_OID_XOR_KEY 0x6A09E667 // key XOR'd with OID when serialized
|
---|
97 |
|
---|
98 | /**
|
---|
99 | * An OID can be tagged to introduce the serialized definition of the object,
|
---|
100 | * or to stand for a strong or weak reference to that object. Thus the high
|
---|
101 | * 29 bits actually identify the object, and the low three bits tell whether
|
---|
102 | * the object is being defined or just referenced -- and via what inheritance
|
---|
103 | * chain or inner object, if necessary.
|
---|
104 | *
|
---|
105 | * The MFL_QUERY_INTERFACE_TAG bit helps us cope with aggregation and multiple
|
---|
106 | * inheritance: object identity follows the XPCOM rule, but a deserializer may
|
---|
107 | * need to query for an interface not on the primary inheritance chain ending
|
---|
108 | * in the nsISupports whose address uniquely identifies the XPCOM object being
|
---|
109 | * referenced or defined.
|
---|
110 | */
|
---|
111 | #define MFL_OBJECT_TAG_BITS 3
|
---|
112 | #define MFL_OBJECT_TAG_MASK PR_BITMASK(MFL_OBJECT_TAG_BITS)
|
---|
113 |
|
---|
114 | #define MFL_OBJECT_DEF_TAG 1U // object definition follows this OID
|
---|
115 | #define MFL_WEAK_REF_TAG 2U // OID weakly refers to a prior object
|
---|
116 | // NB: do not confuse with nsWeakPtr!
|
---|
117 | #define MFL_QUERY_INTERFACE_TAG 4U // QI object to the ID follows this OID
|
---|
118 | // NB: an NSFastLoadID, not an nsIID!
|
---|
119 |
|
---|
120 | /**
|
---|
121 | * The dull object identifier introduces the definition of all objects that
|
---|
122 | * have only one (necessarily strong) ref in the serialization. The definition
|
---|
123 | * appears at the point of reference.
|
---|
124 | */
|
---|
125 | #define MFL_DULL_OBJECT_OID MFL_OBJECT_DEF_TAG
|
---|
126 |
|
---|
127 | /**
|
---|
128 | * Convert an OID to an index into nsFastLoadFooter::mObjectMap.
|
---|
129 | */
|
---|
130 | #define MFL_OID_TO_SHARP_INDEX(oid) (((oid) >> MFL_OBJECT_TAG_BITS) - 1)
|
---|
131 | #define MFL_SHARP_INDEX_TO_OID(index) (((index) + 1) << MFL_OBJECT_TAG_BITS)
|
---|
132 |
|
---|
133 | /**
|
---|
134 | * Magic "number" at start of a FastLoad file. Inspired by the PNG "magic"
|
---|
135 | * string, which inspired XPCOM's typelib (.xpt) file magic. Guaranteed to be
|
---|
136 | * corrupted by FTP-as-ASCII and other likely errors, meaningful to clued-in
|
---|
137 | * humans, and ending in ^Z to terminate erroneous text input on Windows.
|
---|
138 | */
|
---|
139 | #define MFL_FILE_MAGIC "XPCOM\nMozFASL\r\n\032"
|
---|
140 | #define MFL_FILE_MAGIC_SIZE 16
|
---|
141 |
|
---|
142 | #define MFL_FILE_VERSION_0 0
|
---|
143 | #define MFL_FILE_VERSION_1 1000
|
---|
144 | #define MFL_FILE_VERSION 4 // fix to note singletons in object map
|
---|
145 |
|
---|
146 | /**
|
---|
147 | * Compute Fletcher's 16-bit checksum over aLength bytes starting at aBuffer,
|
---|
148 | * with the initial accumulators seeded from *aChecksum, and final checksum
|
---|
149 | * returned in *aChecksum. The return value is the number of unchecked bytes,
|
---|
150 | * which may be non-zero if aBuffer is misaligned or aLength is odd. Callers
|
---|
151 | * should copy any remaining bytes to the front of the next buffer.
|
---|
152 | *
|
---|
153 | * If aLastBuffer is false, do not check any bytes remaining due to misaligned
|
---|
154 | * aBuffer or odd aLength, instead returning the remaining byte count. But if
|
---|
155 | * aLastBuffer is true, treat aBuffer as the last buffer in the file and check
|
---|
156 | * every byte, returning 0. Here's a read-loop checksumming sketch:
|
---|
157 | *
|
---|
158 | * char buf[BUFSIZE];
|
---|
159 | * PRUint32 len, rem = 0;
|
---|
160 | * PRUint32 checksum = 0;
|
---|
161 | *
|
---|
162 | * while (NS_SUCCEEDED(rv = Read(buf + rem, sizeof buf - rem, &len)) && len) {
|
---|
163 | * len += rem;
|
---|
164 | * rem = NS_AccumulateFastLoadChecksum(&checksum,
|
---|
165 | * NS_REINTERPRET_CAST(PRUint8*, buf),
|
---|
166 | * len,
|
---|
167 | * PR_FALSE);
|
---|
168 | * if (rem)
|
---|
169 | * memcpy(buf, buf + len - rem, rem);
|
---|
170 | * }
|
---|
171 | *
|
---|
172 | * if (rem) {
|
---|
173 | * NS_AccumulateFastLoadChecksum(&checksum,
|
---|
174 | * NS_REINTERPRET_CAST(PRUint8*, buf),
|
---|
175 | * rem,
|
---|
176 | * PR_TRUE);
|
---|
177 | * }
|
---|
178 | *
|
---|
179 | * After this, if NS_SUCCEEDED(rv), checksum contains a valid FastLoad sum.
|
---|
180 | */
|
---|
181 | PR_EXTERN(PRUint32)
|
---|
182 | NS_AccumulateFastLoadChecksum(PRUint32 *aChecksum,
|
---|
183 | const PRUint8* aBuffer,
|
---|
184 | PRUint32 aLength,
|
---|
185 | PRBool aLastBuffer);
|
---|
186 |
|
---|
187 | PR_EXTERN(PRUint32)
|
---|
188 | NS_AddFastLoadChecksums(PRUint32 sum1, PRUint32 sum2, PRUint32 sum2ByteCount);
|
---|
189 |
|
---|
190 | /**
|
---|
191 | * Header at the start of a FastLoad file.
|
---|
192 | */
|
---|
193 | struct nsFastLoadHeader {
|
---|
194 | char mMagic[MFL_FILE_MAGIC_SIZE];
|
---|
195 | PRUint32 mChecksum;
|
---|
196 | PRUint32 mVersion;
|
---|
197 | PRUint32 mFooterOffset;
|
---|
198 | PRUint32 mFileSize;
|
---|
199 | };
|
---|
200 |
|
---|
201 | /**
|
---|
202 | * Footer prefix structure (footer header, ugh), after which come arrays of
|
---|
203 | * structures or strings counted by these members.
|
---|
204 | */
|
---|
205 | struct nsFastLoadFooterPrefix {
|
---|
206 | PRUint32 mNumIDs;
|
---|
207 | PRUint32 mNumSharpObjects;
|
---|
208 | PRUint32 mNumMuxedDocuments;
|
---|
209 | PRUint32 mNumDependencies;
|
---|
210 | };
|
---|
211 |
|
---|
212 | struct nsFastLoadSharpObjectInfo {
|
---|
213 | PRUint32 mCIDOffset; // offset of object's NSFastLoadID and data
|
---|
214 | PRUint16 mStrongRefCnt;
|
---|
215 | PRUint16 mWeakRefCnt; // high bit is singleton flag, see below
|
---|
216 | };
|
---|
217 |
|
---|
218 | #define MFL_SINGLETON_FLAG 0x8000
|
---|
219 | #define MFL_WEAK_REFCNT_MASK 0x7fff
|
---|
220 |
|
---|
221 | #define MFL_GET_SINGLETON_FLAG(ip) ((ip)->mWeakRefCnt & MFL_SINGLETON_FLAG)
|
---|
222 | #define MFL_GET_WEAK_REFCNT(ip) ((ip)->mWeakRefCnt & MFL_WEAK_REFCNT_MASK)
|
---|
223 |
|
---|
224 | #define MFL_SET_SINGLETON_FLAG(ip) \
|
---|
225 | ((ip)->mWeakRefCnt |= MFL_SINGLETON_FLAG)
|
---|
226 | #define MFL_SET_WEAK_REFCNT(ip,rc) \
|
---|
227 | ((ip)->mWeakRefCnt = (((ip)->mWeakRefCnt & MFL_SINGLETON_FLAG) | (rc)))
|
---|
228 |
|
---|
229 | #define MFL_BUMP_WEAK_REFCNT(ip) (++(ip)->mWeakRefCnt)
|
---|
230 | #define MFL_DROP_WEAK_REFCNT(ip) (--(ip)->mWeakRefCnt)
|
---|
231 |
|
---|
232 | struct nsFastLoadMuxedDocumentInfo {
|
---|
233 | const char* mURISpec;
|
---|
234 | PRUint32 mInitialSegmentOffset;
|
---|
235 | };
|
---|
236 |
|
---|
237 | // forward declarations of opaque types defined in nsFastLoadFile.cpp
|
---|
238 | struct nsDocumentMapReadEntry;
|
---|
239 | struct nsDocumentMapWriteEntry;
|
---|
240 |
|
---|
241 | // So nsFastLoadFileUpdater can verify that its nsIObjectInputStream parameter
|
---|
242 | // is an nsFastLoadFileReader.
|
---|
243 | #define NS_FASTLOADFILEREADER_IID \
|
---|
244 | {0x7d37d1bb,0xcef3,0x4c5f,{0x97,0x68,0x0f,0x89,0x7f,0x1a,0xe1,0x40}}
|
---|
245 |
|
---|
246 | struct nsIFastLoadFileReader : public nsISupports {
|
---|
247 | NS_DEFINE_STATIC_IID_ACCESSOR(NS_FASTLOADFILEREADER_IID)
|
---|
248 | };
|
---|
249 |
|
---|
250 | /**
|
---|
251 | * Inherit from the concrete class nsBinaryInputStream, which inherits from
|
---|
252 | * abstract nsIObjectInputStream but does not implement its direct methods.
|
---|
253 | * Though the names are not as clear as I'd like, this seems to be the best
|
---|
254 | * way to share nsBinaryStream.cpp code.
|
---|
255 | */
|
---|
256 | class nsFastLoadFileReader
|
---|
257 | : public nsBinaryInputStream,
|
---|
258 | public nsIFastLoadReadControl,
|
---|
259 | public nsISeekableStream,
|
---|
260 | public nsIFastLoadFileReader
|
---|
261 | {
|
---|
262 | public:
|
---|
263 | nsFastLoadFileReader(nsIInputStream *aStream)
|
---|
264 | : mCurrentDocumentMapEntry(nsnull) {
|
---|
265 | SetInputStream(aStream);
|
---|
266 | MOZ_COUNT_CTOR(nsFastLoadFileReader);
|
---|
267 | }
|
---|
268 |
|
---|
269 | virtual ~nsFastLoadFileReader() {
|
---|
270 | MOZ_COUNT_DTOR(nsFastLoadFileReader);
|
---|
271 | }
|
---|
272 |
|
---|
273 | private:
|
---|
274 | // nsISupports methods
|
---|
275 | NS_DECL_ISUPPORTS_INHERITED
|
---|
276 |
|
---|
277 | // overridden nsIObjectInputStream methods
|
---|
278 | NS_IMETHOD ReadObject(PRBool aIsStrongRef, nsISupports* *_retval);
|
---|
279 | NS_IMETHOD ReadID(nsID *aResult);
|
---|
280 |
|
---|
281 | // nsIFastLoadFileControl methods
|
---|
282 | NS_DECL_NSIFASTLOADFILECONTROL
|
---|
283 |
|
---|
284 | // nsIFastLoadReadControl methods
|
---|
285 | NS_DECL_NSIFASTLOADREADCONTROL
|
---|
286 |
|
---|
287 | // nsISeekableStream methods
|
---|
288 | NS_DECL_NSISEEKABLESTREAM
|
---|
289 |
|
---|
290 | // Override Read so we can demultiplex a document interleaved with others.
|
---|
291 | NS_IMETHOD Read(char* aBuffer, PRUint32 aCount, PRUint32 *aBytesRead);
|
---|
292 |
|
---|
293 | // Override ReadSegments too, as nsBinaryInputStream::ReadSegments does
|
---|
294 | // not call through our overridden Read method -- it calls directly into
|
---|
295 | // the underlying input stream.
|
---|
296 | NS_IMETHODIMP ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
---|
297 | PRUint32 aCount, PRUint32 *aResult);
|
---|
298 |
|
---|
299 | nsresult ReadHeader(nsFastLoadHeader *aHeader);
|
---|
300 |
|
---|
301 | /**
|
---|
302 | * In-memory representation of an indexed nsFastLoadSharpObjectInfo record.
|
---|
303 | */
|
---|
304 | struct nsObjectMapEntry : public nsFastLoadSharpObjectInfo {
|
---|
305 | nsCOMPtr<nsISupports> mReadObject;
|
---|
306 | PRInt64 mSkipOffset;
|
---|
307 | PRUint16 mSaveStrongRefCnt; // saved for an Update
|
---|
308 | PRUint16 mSaveWeakRefCnt; // after a Read
|
---|
309 | };
|
---|
310 |
|
---|
311 | /**
|
---|
312 | * In-memory representation of the FastLoad file footer.
|
---|
313 | */
|
---|
314 | struct nsFastLoadFooter : public nsFastLoadFooterPrefix {
|
---|
315 | nsFastLoadFooter()
|
---|
316 | : mIDMap(nsnull),
|
---|
317 | mObjectMap(nsnull) {
|
---|
318 | mDocumentMap.ops = mURIMap.ops = nsnull;
|
---|
319 | }
|
---|
320 |
|
---|
321 | ~nsFastLoadFooter() {
|
---|
322 | delete[] mIDMap;
|
---|
323 | delete[] mObjectMap;
|
---|
324 | if (mDocumentMap.ops)
|
---|
325 | PL_DHashTableFinish(&mDocumentMap);
|
---|
326 | if (mURIMap.ops)
|
---|
327 | PL_DHashTableFinish(&mURIMap);
|
---|
328 | }
|
---|
329 |
|
---|
330 | // These can't be static within GetID and GetSharpObjectEntry or the
|
---|
331 | // toolchains on HP-UX 10.20's, RH 7.0, and Mac OS X all barf at link
|
---|
332 | // time ("common symbols not allowed with MY_DHLIB output format", to
|
---|
333 | // quote the OS X rev of gcc).
|
---|
334 | static nsID gDummyID;
|
---|
335 | static nsObjectMapEntry gDummySharpObjectEntry;
|
---|
336 |
|
---|
337 | const nsID& GetID(NSFastLoadID aFastId) const {
|
---|
338 | PRUint32 index = aFastId - 1;
|
---|
339 | NS_ASSERTION(index < mNumIDs, "aFastId out of range");
|
---|
340 | if (index >= mNumIDs)
|
---|
341 | return gDummyID;
|
---|
342 | return mIDMap[index];
|
---|
343 | }
|
---|
344 |
|
---|
345 | nsObjectMapEntry&
|
---|
346 | GetSharpObjectEntry(NSFastLoadOID aOID) const {
|
---|
347 | PRUint32 index = MFL_OID_TO_SHARP_INDEX(aOID);
|
---|
348 | NS_ASSERTION(index < mNumSharpObjects, "aOID out of range");
|
---|
349 | if (index >= mNumSharpObjects)
|
---|
350 | return gDummySharpObjectEntry;
|
---|
351 | return mObjectMap[index];
|
---|
352 | }
|
---|
353 |
|
---|
354 | // Map from dense, zero-based, uint32 NSFastLoadID to 16-byte nsID.
|
---|
355 | nsID* mIDMap;
|
---|
356 |
|
---|
357 | // Map from dense, zero-based MFL_OID_TO_SHARP_INDEX(oid) to sharp
|
---|
358 | // object offset and refcnt information.
|
---|
359 | nsObjectMapEntry* mObjectMap;
|
---|
360 |
|
---|
361 | // Map from URI spec string to nsDocumentMapReadEntry, which helps us
|
---|
362 | // demultiplex a document's objects from among the interleaved object
|
---|
363 | // stream segments in the FastLoad file.
|
---|
364 | PLDHashTable mDocumentMap;
|
---|
365 |
|
---|
366 | // Fast mapping from URI object pointer to mDocumentMap entry, valid
|
---|
367 | // only while the muxed document is loading.
|
---|
368 | PLDHashTable mURIMap;
|
---|
369 |
|
---|
370 | // List of source filename dependencies that should trigger regeneration
|
---|
371 | // of the FastLoad file.
|
---|
372 | nsCOMPtr<nsISupportsArray> mDependencies;
|
---|
373 | };
|
---|
374 |
|
---|
375 | nsresult ReadFooter(nsFastLoadFooter *aFooter);
|
---|
376 | nsresult ReadFooterPrefix(nsFastLoadFooterPrefix *aFooterPrefix);
|
---|
377 | nsresult ReadSlowID(nsID *aID);
|
---|
378 | nsresult ReadFastID(NSFastLoadID *aID);
|
---|
379 | nsresult ReadSharpObjectInfo(nsFastLoadSharpObjectInfo *aInfo);
|
---|
380 | nsresult ReadMuxedDocumentInfo(nsFastLoadMuxedDocumentInfo *aInfo);
|
---|
381 | nsresult DeserializeObject(nsISupports* *aObject);
|
---|
382 |
|
---|
383 | nsresult Open();
|
---|
384 | NS_IMETHOD Close();
|
---|
385 |
|
---|
386 | protected:
|
---|
387 | nsFastLoadHeader mHeader;
|
---|
388 | nsFastLoadFooter mFooter;
|
---|
389 |
|
---|
390 | nsDocumentMapReadEntry* mCurrentDocumentMapEntry;
|
---|
391 |
|
---|
392 | friend class nsFastLoadFileUpdater;
|
---|
393 | };
|
---|
394 |
|
---|
395 | NS_COM nsresult
|
---|
396 | NS_NewFastLoadFileReader(nsIObjectInputStream* *aResult,
|
---|
397 | nsIInputStream* aSrcStream);
|
---|
398 |
|
---|
399 | /**
|
---|
400 | * Inherit from the concrete class nsBinaryInputStream, which inherits from
|
---|
401 | * abstract nsIObjectInputStream but does not implement its direct methods.
|
---|
402 | * Though the names are not as clear as I'd like, this seems to be the best
|
---|
403 | * way to share nsBinaryStream.cpp code.
|
---|
404 | */
|
---|
405 | class nsFastLoadFileWriter
|
---|
406 | : public nsBinaryOutputStream,
|
---|
407 | public nsIFastLoadWriteControl,
|
---|
408 | public nsISeekableStream
|
---|
409 | {
|
---|
410 | public:
|
---|
411 | nsFastLoadFileWriter(nsIOutputStream *aStream, nsIFastLoadFileIO* aFileIO)
|
---|
412 | : mCurrentDocumentMapEntry(nsnull),
|
---|
413 | mFileIO(aFileIO)
|
---|
414 | {
|
---|
415 | SetOutputStream(aStream);
|
---|
416 | mHeader.mChecksum = 0;
|
---|
417 | mIDMap.ops = mObjectMap.ops = mDocumentMap.ops = mURIMap.ops = nsnull;
|
---|
418 | mDependencyMap.ops = nsnull;
|
---|
419 | MOZ_COUNT_CTOR(nsFastLoadFileWriter);
|
---|
420 | }
|
---|
421 |
|
---|
422 | virtual ~nsFastLoadFileWriter()
|
---|
423 | {
|
---|
424 | if (mIDMap.ops)
|
---|
425 | PL_DHashTableFinish(&mIDMap);
|
---|
426 | if (mObjectMap.ops)
|
---|
427 | PL_DHashTableFinish(&mObjectMap);
|
---|
428 | if (mDocumentMap.ops)
|
---|
429 | PL_DHashTableFinish(&mDocumentMap);
|
---|
430 | if (mURIMap.ops)
|
---|
431 | PL_DHashTableFinish(&mURIMap);
|
---|
432 | if (mDependencyMap.ops)
|
---|
433 | PL_DHashTableFinish(&mDependencyMap);
|
---|
434 | MOZ_COUNT_DTOR(nsFastLoadFileWriter);
|
---|
435 | }
|
---|
436 |
|
---|
437 | private:
|
---|
438 | // nsISupports methods
|
---|
439 | NS_DECL_ISUPPORTS_INHERITED
|
---|
440 |
|
---|
441 | // overridden nsIObjectOutputStream methods
|
---|
442 | NS_IMETHOD WriteObject(nsISupports* aObject, PRBool aIsStrongRef);
|
---|
443 | NS_IMETHOD WriteSingleRefObject(nsISupports* aObject);
|
---|
444 | NS_IMETHOD WriteCompoundObject(nsISupports* aObject,
|
---|
445 | const nsIID& aIID,
|
---|
446 | PRBool aIsStrongRef);
|
---|
447 | NS_IMETHOD WriteID(const nsID& aID);
|
---|
448 |
|
---|
449 | // nsIFastLoadFileControl methods
|
---|
450 | NS_DECL_NSIFASTLOADFILECONTROL
|
---|
451 |
|
---|
452 | // nsIFastLoadWriteControl methods
|
---|
453 | NS_DECL_NSIFASTLOADWRITECONTROL
|
---|
454 |
|
---|
455 | // nsISeekableStream methods
|
---|
456 | NS_DECL_NSISEEKABLESTREAM
|
---|
457 |
|
---|
458 | nsresult MapID(const nsID& aSlowID, NSFastLoadID *aResult);
|
---|
459 |
|
---|
460 | nsresult WriteHeader(nsFastLoadHeader *aHeader);
|
---|
461 | nsresult WriteFooter();
|
---|
462 | nsresult WriteFooterPrefix(const nsFastLoadFooterPrefix& aFooterPrefix);
|
---|
463 | nsresult WriteSlowID(const nsID& aID);
|
---|
464 | nsresult WriteFastID(NSFastLoadID aID);
|
---|
465 | nsresult WriteSharpObjectInfo(const nsFastLoadSharpObjectInfo& aInfo);
|
---|
466 | nsresult WriteMuxedDocumentInfo(const nsFastLoadMuxedDocumentInfo& aInfo);
|
---|
467 |
|
---|
468 | nsresult Init();
|
---|
469 | nsresult Open();
|
---|
470 | NS_IMETHOD Close();
|
---|
471 |
|
---|
472 | nsresult WriteObjectCommon(nsISupports* aObject,
|
---|
473 | PRBool aIsStrongRef,
|
---|
474 | PRUint32 aQITag);
|
---|
475 |
|
---|
476 | static PLDHashOperator PR_CALLBACK
|
---|
477 | IDMapEnumerate(PLDHashTable *aTable,
|
---|
478 | PLDHashEntryHdr *aHdr,
|
---|
479 | PRUint32 aNumber,
|
---|
480 | void *aData);
|
---|
481 |
|
---|
482 | static PLDHashOperator PR_CALLBACK
|
---|
483 | ObjectMapEnumerate(PLDHashTable *aTable,
|
---|
484 | PLDHashEntryHdr *aHdr,
|
---|
485 | PRUint32 aNumber,
|
---|
486 | void *aData);
|
---|
487 |
|
---|
488 | static PLDHashOperator PR_CALLBACK
|
---|
489 | DocumentMapEnumerate(PLDHashTable *aTable,
|
---|
490 | PLDHashEntryHdr *aHdr,
|
---|
491 | PRUint32 aNumber,
|
---|
492 | void *aData);
|
---|
493 |
|
---|
494 | static PLDHashOperator PR_CALLBACK
|
---|
495 | DependencyMapEnumerate(PLDHashTable *aTable,
|
---|
496 | PLDHashEntryHdr *aHdr,
|
---|
497 | PRUint32 aNumber,
|
---|
498 | void *aData);
|
---|
499 |
|
---|
500 | protected:
|
---|
501 | nsFastLoadHeader mHeader;
|
---|
502 |
|
---|
503 | PLDHashTable mIDMap;
|
---|
504 | PLDHashTable mObjectMap;
|
---|
505 | PLDHashTable mDocumentMap;
|
---|
506 | PLDHashTable mURIMap;
|
---|
507 | PLDHashTable mDependencyMap;
|
---|
508 |
|
---|
509 | nsDocumentMapWriteEntry* mCurrentDocumentMapEntry;
|
---|
510 | nsCOMPtr<nsIFastLoadFileIO> mFileIO;
|
---|
511 | };
|
---|
512 |
|
---|
513 | NS_COM nsresult
|
---|
514 | NS_NewFastLoadFileWriter(nsIObjectOutputStream* *aResult,
|
---|
515 | nsIOutputStream* aDestStream,
|
---|
516 | nsIFastLoadFileIO* aFileIO);
|
---|
517 |
|
---|
518 | /**
|
---|
519 | * Subclass of nsFastLoadFileWriter, friend of nsFastLoadFileReader which it
|
---|
520 | * wraps when a FastLoad file needs to be updated. The wrapped reader can be
|
---|
521 | * used to demulitplex data for documents already in the FastLoad file, while
|
---|
522 | * the updater writes new data over the old footer, then writes a new footer
|
---|
523 | * that maps all data on Close.
|
---|
524 | */
|
---|
525 | class nsFastLoadFileUpdater
|
---|
526 | : public nsFastLoadFileWriter,
|
---|
527 | nsIFastLoadFileIO
|
---|
528 | {
|
---|
529 | public:
|
---|
530 | nsFastLoadFileUpdater(nsIOutputStream* aOutputStream)
|
---|
531 | : nsFastLoadFileWriter(aOutputStream, nsnull) {
|
---|
532 | MOZ_COUNT_CTOR(nsFastLoadFileUpdater);
|
---|
533 | }
|
---|
534 |
|
---|
535 | virtual ~nsFastLoadFileUpdater() {
|
---|
536 | MOZ_COUNT_DTOR(nsFastLoadFileUpdater);
|
---|
537 | }
|
---|
538 |
|
---|
539 | private:
|
---|
540 | // nsISupports methods
|
---|
541 | NS_DECL_ISUPPORTS_INHERITED
|
---|
542 |
|
---|
543 | // nsIFastLoadFileIO methods
|
---|
544 | NS_DECL_NSIFASTLOADFILEIO
|
---|
545 |
|
---|
546 | nsresult Open(nsFastLoadFileReader* aReader);
|
---|
547 | NS_IMETHOD Close();
|
---|
548 |
|
---|
549 | static PLDHashOperator PR_CALLBACK
|
---|
550 | CopyReadDocumentMapEntryToUpdater(PLDHashTable *aTable,
|
---|
551 | PLDHashEntryHdr *aHdr,
|
---|
552 | PRUint32 aNumber,
|
---|
553 | void *aData);
|
---|
554 |
|
---|
555 | friend class nsFastLoadFileReader;
|
---|
556 |
|
---|
557 | protected:
|
---|
558 | nsCOMPtr<nsIInputStream> mInputStream;
|
---|
559 | };
|
---|
560 |
|
---|
561 | NS_COM nsresult
|
---|
562 | NS_NewFastLoadFileUpdater(nsIObjectOutputStream* *aResult,
|
---|
563 | nsIOutputStream* aOutputStream,
|
---|
564 | nsIObjectInputStream* aReaderAsStream);
|
---|
565 |
|
---|
566 | #endif // nsFastLoadFile_h___
|
---|