VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadFile.h@ 6542

Last change on this file since 6542 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.5 KB
Line 
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 <[email protected]> (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 */
80typedef PRUint32 NSFastLoadID; // nsFastLoadFooter::mIDMap index
81typedef 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 */
181PR_EXTERN(PRUint32)
182NS_AccumulateFastLoadChecksum(PRUint32 *aChecksum,
183 const PRUint8* aBuffer,
184 PRUint32 aLength,
185 PRBool aLastBuffer);
186
187PR_EXTERN(PRUint32)
188NS_AddFastLoadChecksums(PRUint32 sum1, PRUint32 sum2, PRUint32 sum2ByteCount);
189
190/**
191 * Header at the start of a FastLoad file.
192 */
193struct 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 */
205struct nsFastLoadFooterPrefix {
206 PRUint32 mNumIDs;
207 PRUint32 mNumSharpObjects;
208 PRUint32 mNumMuxedDocuments;
209 PRUint32 mNumDependencies;
210};
211
212struct 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
232struct nsFastLoadMuxedDocumentInfo {
233 const char* mURISpec;
234 PRUint32 mInitialSegmentOffset;
235};
236
237// forward declarations of opaque types defined in nsFastLoadFile.cpp
238struct nsDocumentMapReadEntry;
239struct 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
246struct 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 */
256class 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
395NS_COM nsresult
396NS_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 */
405class 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
513NS_COM nsresult
514NS_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 */
525class 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
561NS_COM nsresult
562NS_NewFastLoadFileUpdater(nsIObjectOutputStream* *aResult,
563 nsIOutputStream* aOutputStream,
564 nsIObjectInputStream* aReaderAsStream);
565
566#endif // nsFastLoadFile_h___
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette