1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 // First checked in on 98/11/20 by John R. McMullen in the wrong directory.
39 // Checked in again 98/12/04.
40 // Polished version 98/12/08.
41 // Completely rewritten to integrate with nsIInputStream and nsIOutputStream (the
42 // xpcom stream objects.
44 //========================================================================================
48 // nsInputStream, nsOutputStream
49 // These are the lightweight STATICALLY LINKED wrappers for
50 // the xpcom objects nsIInputStream and nsIOutputstream.
52 // If you are implementing a function that accepts one of these xpcom
53 // streams, just make one of these little jobbies on the stack, and
54 // the handy << or >> notation can be yours.
56 // nsInputFileStream, nsOutputFileStream
57 // These are the STATICALLY LINKED wrappers for the file-related
58 // versions of the above.
60 // An input and output file stream attached to the same file.
62 // This suite provide the following services:
64 // 1. Encapsulates all platform-specific file details, so that file i/o
65 // can be done correctly without any platform #ifdefs
67 // 2. Uses NSPR file services (NOT ansi file I/O), in order to get best
68 // native performance. This performance difference is especially large on
71 // 3. Allows all the power of the ansi stream syntax.
75 // nsFileSpec myPath("/Development/iotest.txt");
77 // nsOutputFileStream testStream(myPath);
78 // testStream << "Hello World" << nsEndl;
80 // 4. Requires streams to be constructed using typesafe nsFileSpec specifier
81 // (not the notorious and bug prone const char*), namely nsFileSpec. See
82 // nsFileSpec.h for more details.
84 // 5. Fixes a bug that have been there for a long time, and
85 // is inevitable if you use NSPR alone:
87 // The problem on platforms (Macintosh) in which a path does not fully
88 // specify a file, because two volumes can have the same name.
92 // Endian-awareness for reading and writing crossplatform binary files. At this
93 // time there seems to be no demand for this.
95 //========================================================================================
97 #ifndef _FILESTREAM_H_
98 #define _FILESTREAM_H_
100 #include "xpcomobsolete.h"
101 #include "nsStringFwd.h"
105 #include "nsCOMPtr.h"
106 #include "nsIFileStream.h"
110 class nsIInputStream
;
111 class nsIOutputStream
;
114 //========================================================================================
115 // Compiler-specific macros, as needed
116 //========================================================================================
117 #if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(_MSC_VER))
118 #define NS_USING_NAMESPACE
121 #ifdef NS_USING_NAMESPACE
123 #define NS_NAMESPACE_PROTOTYPE
124 #define NS_NAMESPACE namespace
125 #define NS_NAMESPACE_END
129 #define NS_NAMESPACE_PROTOTYPE static
130 #define NS_NAMESPACE struct
131 #define NS_NAMESPACE_END ;
133 #endif // NS_USING_NAMESPACE
136 // PR_STDOUT and PR_STDIN are fatal on Macintosh. So for console i/o, we must use the std
137 // stream stuff instead. However, we have to require that cout and cin are passed in
138 // to the constructor because in the current build, there is a copy in the base.shlb,
139 // and another in the caller's file. Passing it in as a parameter ensures that the
140 // caller and this library are using the same global object. Groan.
142 // Unix currently does not support iostreams at all. Their compilers do not support
143 // ANSI C++, or even ARM C++.
145 // Windows supports them, but only if you turn on the -GX (VC5-VC7.x) or -EHsc (VC8+)
146 // compile flag, to support exceptions.
149 #define NS_USE_PR_STDIO
152 #ifdef NS_USE_PR_STDIO
156 #define CONSOLE_OUT 0
161 #define CONSOLE_IN &std::cin
162 #define CONSOLE_OUT &std::cout
165 //=========================== End Compiler-specific macros ===============================
167 //========================================================================================
168 class NS_COM_OBSOLETE nsInputStream
169 // This is a convenience class, for use on the STACK ("new" junkies: get detoxed first).
170 // Given a COM-style stream, this allows you to use the >> operators. It also acquires and
171 // reference counts its stream.
172 // Please read the comments at the top of this file
173 //========================================================================================
176 nsInputStream(nsIInputStream
* inStream
)
177 : mInputStream(do_QueryInterface(inStream
))
180 virtual ~nsInputStream();
182 nsCOMPtr
<nsIInputStream
> GetIStream() const
186 PRBool
eof() const { return get_at_eof(); }
190 NS_ASSERTION(mInputStream
, "mInputStream is null!");
192 return mInputStream
->Close();
196 PRInt32
read(void* s
, PRInt32 n
);
198 // Input streamers. Add more as needed (int&, unsigned int& etc). (but you have to
199 // add delegators to the derived classes, too, because these operators don't inherit).
200 nsInputStream
& operator >> (char& ch
);
202 // Support manipulators
203 nsInputStream
& operator >> (nsInputStream
& (*pf
)(nsInputStream
&))
210 // These certainly need to be overridden, they give the best shot we can at detecting
211 // eof in a simple nsIInputStream.
212 virtual void set_at_eof(PRBool atEnd
)
216 virtual PRBool
get_at_eof() const
222 nsInputStream
& operator >> (char* buf
); // TOO DANGEROUS. DON'T DEFINE.
224 // private and unimplemented to disallow copies and assigns
225 nsInputStream(const nsInputStream
& rhs
);
226 nsInputStream
& operator=(const nsInputStream
& rhs
);
230 nsCOMPtr
<nsIInputStream
> mInputStream
;
232 }; // class nsInputStream
234 typedef nsInputStream nsBasicInStream
; // historic support for this name
236 //========================================================================================
237 class NS_COM_OBSOLETE nsOutputStream
238 // This is a convenience class, for use on the STACK ("new" junkies, get detoxed first).
239 // Given a COM-style stream, this allows you to use the << operators. It also acquires and
240 // reference counts its stream.
241 // Please read the comments at the top of this file
242 //========================================================================================
246 nsOutputStream(nsIOutputStream
* inStream
)
247 : mOutputStream(do_QueryInterface(inStream
))
250 virtual ~nsOutputStream();
252 nsCOMPtr
<nsIOutputStream
> GetIStream() const
254 return mOutputStream
;
259 return mOutputStream
->Close();
263 PRInt32
write(const void* s
, PRInt32 n
);
264 virtual nsresult
flush();
265 nsresult
lastWriteStatus();
267 // Output streamers. Add more as needed (but you have to add delegators to the derived
268 // classes, too, because these operators don't inherit).
269 nsOutputStream
& operator << (const char* buf
);
270 nsOutputStream
& operator << (char ch
);
271 nsOutputStream
& operator << (short val
);
272 nsOutputStream
& operator << (unsigned short val
);
273 nsOutputStream
& operator << (long val
);
274 nsOutputStream
& operator << (unsigned long val
);
275 nsOutputStream
& operator << (int val
);
276 nsOutputStream
& operator << (unsigned int val
);
278 // Support manipulators
279 nsOutputStream
& operator << (nsOutputStream
& (*pf
)(nsOutputStream
&))
286 // private and unimplemented to disallow copies and assigns
287 nsOutputStream(const nsOutputStream
& rhs
);
288 nsOutputStream
& operator=(const nsOutputStream
& rhs
);
290 nsresult mWriteStatus
;
294 nsCOMPtr
<nsIOutputStream
> mOutputStream
;
295 }; // class nsOutputStream
297 typedef nsOutputStream nsBasicOutStream
; // Historic support for this name
299 //========================================================================================
300 class NS_COM_OBSOLETE nsErrorProne
301 // Common (virtual) base class for remembering errors on demand
302 //========================================================================================
305 nsErrorProne() // for delayed opening
309 PRBool
failed() const
311 return NS_FAILED(mResult
);
313 nsresult
error() const
321 }; // class nsErrorProne
323 //========================================================================================
324 class NS_COM_OBSOLETE nsFileClient
325 // Because COM does not allow us to write functions which return a boolean value etc,
326 // this class is here to take care of the tedious "declare variable then call with
327 // the address of the variable" chores.
328 //========================================================================================
329 : public virtual nsErrorProne
332 nsFileClient(const nsCOMPtr
<nsIOpenFile
>& inFile
)
333 : mFile(do_QueryInterface(inFile
))
336 virtual ~nsFileClient() {}
339 const nsFileSpec
& inFile
,
344 mResult
= mFile
->Open(inFile
, nsprMode
, accessMode
);
346 PRBool
is_open() const
348 PRBool result
= PR_FALSE
;
350 mFile
->GetIsOpen(&result
);
353 PRBool
is_file() const
355 return mFile
? PR_TRUE
: PR_FALSE
;
360 nsFileClient() // for delayed opening
365 nsCOMPtr
<nsIOpenFile
> mFile
;
366 }; // class nsFileClient
368 //========================================================================================
369 class NS_COM_OBSOLETE nsRandomAccessStoreClient
370 // Because COM does not allow us to write functions which return a boolean value etc,
371 // this class is here to take care of the tedious "declare variable then call with
372 // the address of the variable" chores.
373 //========================================================================================
374 : public virtual nsErrorProne
377 nsRandomAccessStoreClient() // for delayed opening
380 nsRandomAccessStoreClient(const nsCOMPtr
<nsIRandomAccessStore
>& inStore
)
381 : mStore(do_QueryInterface(inStore
))
384 virtual ~nsRandomAccessStoreClient() {}
386 void seek(PRInt64 offset
)
388 seek(PR_SEEK_SET
, offset
);
391 void seek(PRSeekWhence whence
, PRInt64 offset
)
393 set_at_eof(PR_FALSE
);
395 mResult
= mStore
->Seek(whence
, offset
);
402 mResult
= mStore
->Tell(&result
);
408 virtual PRBool
get_at_eof() const
410 PRBool result
= PR_TRUE
;
412 mStore
->GetAtEOF(&result
);
416 virtual void set_at_eof(PRBool atEnd
)
419 mStore
->SetAtEOF(atEnd
);
424 // private and unimplemented to disallow copies and assigns
425 nsRandomAccessStoreClient(const nsRandomAccessStoreClient
& rhs
);
426 nsRandomAccessStoreClient
& operator=(const nsRandomAccessStoreClient
& rhs
);
430 nsCOMPtr
<nsIRandomAccessStore
> mStore
;
431 }; // class nsRandomAccessStoreClient
433 //========================================================================================
434 class NS_COM_OBSOLETE nsRandomAccessInputStream
435 // Please read the comments at the top of this file
436 //========================================================================================
437 : public nsRandomAccessStoreClient
438 , public nsInputStream
441 nsRandomAccessInputStream(nsIInputStream
* inStream
)
442 : nsRandomAccessStoreClient(do_QueryInterface(inStream
))
443 , nsInputStream(inStream
)
446 PRBool
readline(char* s
, PRInt32 n
);
447 // Result always null-terminated.
448 // Check eof() before each call.
449 // CAUTION: false result only indicates line was truncated
450 // to fit buffer, or an error occurred (OTHER THAN eof).
452 // Input streamers. Unfortunately, they don't inherit!
453 nsInputStream
& operator >> (char& ch
)
454 { return nsInputStream::operator >>(ch
); }
455 nsInputStream
& operator >> (nsInputStream
& (*pf
)(nsInputStream
&))
456 { return nsInputStream::operator >>(pf
); }
459 nsRandomAccessInputStream()
460 : nsInputStream(nsnull
)
464 virtual PRBool
get_at_eof() const
466 return nsRandomAccessStoreClient::get_at_eof();
469 virtual void set_at_eof(PRBool atEnd
)
471 nsRandomAccessStoreClient::set_at_eof(atEnd
);
476 // private and unimplemented to disallow copies and assigns
477 nsRandomAccessInputStream(const nsRandomAccessInputStream
& rhs
);
478 nsRandomAccessInputStream
& operator=(const nsRandomAccessInputStream
& rhs
);
480 }; // class nsRandomAccessInputStream
482 //========================================================================================
483 class NS_COM_OBSOLETE nsInputFileStream
484 // Please read the comments at the top of this file
485 //========================================================================================
486 : public nsRandomAccessInputStream
487 , public nsFileClient
490 enum { kDefaultMode
= PR_RDONLY
};
491 nsInputFileStream(nsIInputStream
* inStream
)
492 : nsRandomAccessInputStream(inStream
)
493 , nsFileClient(do_QueryInterface(inStream
))
494 , mFileInputStream(do_QueryInterface(inStream
))
498 const nsFileSpec
& inFile
,
499 int nsprMode
= kDefaultMode
,
500 PRIntn accessMode
= 00666);
501 nsInputFileStream(nsIFileSpec
* inFile
);
502 virtual ~nsInputFileStream();
505 const nsFileSpec
& inFile
,
506 int nsprMode
= kDefaultMode
,
507 PRIntn accessMode
= 00666)
510 mFile
->Open(inFile
, nsprMode
, accessMode
);
513 // Input streamers. Unfortunately, they don't inherit!
514 nsInputStream
& operator >> (char& ch
)
515 { return nsInputStream::operator >>(ch
); }
516 nsInputStream
& operator >> (nsInputStream
& (*pf
)(nsInputStream
&))
517 { return nsInputStream::operator >>(pf
); }
520 void AssignFrom(nsISupports
* stream
);
524 // private and unimplemented to disallow copies and assigns
525 nsInputFileStream(const nsInputFileStream
& rhs
);
526 nsInputFileStream
& operator=(const nsInputFileStream
& rhs
);
530 nsCOMPtr
<nsIFileSpecInputStream
> mFileInputStream
;
531 }; // class nsInputFileStream
533 //========================================================================================
534 class NS_COM_OBSOLETE nsRandomAccessOutputStream
535 // Please read the comments at the top of this file
536 //========================================================================================
537 : public nsRandomAccessStoreClient
538 , public nsOutputStream
541 nsRandomAccessOutputStream(nsIOutputStream
* inStream
)
542 : nsRandomAccessStoreClient(do_QueryInterface(inStream
))
543 , nsOutputStream(inStream
)
547 // Output streamers. Unfortunately, they don't inherit!
548 nsOutputStream
& operator << (const char* buf
)
549 { return nsOutputStream::operator << (buf
); }
550 nsOutputStream
& operator << (char ch
)
551 { return nsOutputStream::operator << (ch
); }
552 nsOutputStream
& operator << (short val
)
553 { return nsOutputStream::operator << (val
); }
554 nsOutputStream
& operator << (unsigned short val
)
555 { return nsOutputStream::operator << (val
); }
556 nsOutputStream
& operator << (long val
)
557 { return nsOutputStream::operator << (val
); }
558 nsOutputStream
& operator << (unsigned long val
)
559 { return nsOutputStream::operator << (val
); }
560 nsOutputStream
& operator << (int val
)
561 { return nsOutputStream::operator << (val
); }
562 nsOutputStream
& operator << (unsigned int val
)
563 { return nsOutputStream::operator << (val
); }
564 nsOutputStream
& operator << (nsOutputStream
& (*pf
)(nsOutputStream
&))
565 { return nsOutputStream::operator << (pf
); }
568 nsRandomAccessOutputStream()
569 : nsOutputStream(nsnull
)
575 // private and unimplemented to disallow copies and assigns
576 nsRandomAccessOutputStream(const nsRandomAccessOutputStream
& rhs
);
577 nsRandomAccessOutputStream
& operator=(const nsRandomAccessOutputStream
& rhs
);
579 }; // class nsRandomAccessOutputStream
581 //========================================================================================
582 class NS_COM_OBSOLETE nsOutputFileStream
583 // Please read the comments at the top of this file
584 //========================================================================================
585 : public nsRandomAccessOutputStream
586 , public nsFileClient
589 enum { kDefaultMode
= (PR_WRONLY
| PR_CREATE_FILE
| PR_TRUNCATE
) };
591 nsOutputFileStream() {}
592 nsOutputFileStream(nsIOutputStream
* inStream
)
594 AssignFrom(inStream
);
597 const nsFileSpec
& inFile
,
598 int nsprMode
= kDefaultMode
,
599 PRIntn accessMode
= 00666)
602 if (NS_FAILED(NS_NewIOFileStream(
604 inFile
, nsprMode
, accessMode
)))
609 nsOutputFileStream(nsIFileSpec
* inFile
);
610 virtual ~nsOutputFileStream();
612 virtual nsresult
flush();
613 virtual void abort();
615 // Output streamers. Unfortunately, they don't inherit!
616 nsOutputStream
& operator << (const char* buf
)
617 { return nsOutputStream::operator << (buf
); }
618 nsOutputStream
& operator << (char ch
)
619 { return nsOutputStream::operator << (ch
); }
620 nsOutputStream
& operator << (short val
)
621 { return nsOutputStream::operator << (val
); }
622 nsOutputStream
& operator << (unsigned short val
)
623 { return nsOutputStream::operator << (val
); }
624 nsOutputStream
& operator << (long val
)
625 { return nsOutputStream::operator << (val
); }
626 nsOutputStream
& operator << (unsigned long val
)
627 { return nsOutputStream::operator << (val
); }
628 nsOutputStream
& operator << (int val
)
629 { return nsOutputStream::operator << (val
); }
630 nsOutputStream
& operator << (unsigned int val
)
631 { return nsOutputStream::operator << (val
); }
632 nsOutputStream
& operator << (nsOutputStream
& (*pf
)(nsOutputStream
&))
633 { return nsOutputStream::operator << (pf
); }
636 void AssignFrom(nsISupports
* stream
);
640 // private and unimplemented to disallow copies and assigns
641 nsOutputFileStream(const nsOutputFileStream
& rhs
);
642 nsOutputFileStream
& operator=(const nsOutputFileStream
& rhs
);
646 nsCOMPtr
<nsIFileSpecOutputStream
> mFileOutputStream
;
647 }; // class nsOutputFileStream
650 //========================================================================================
652 // Please read the comments at the top of this file
653 //========================================================================================
654 : public nsInputFileStream
655 , public nsOutputStream
658 enum { kDefaultMode
= (PR_RDWR
| PR_CREATE_FILE
) };
661 nsIInputStream
* inInputStream
662 , nsIOutputStream
* inOutputStream
)
663 : nsInputFileStream(inInputStream
)
664 , nsOutputStream(inOutputStream
)
665 , mFileOutputStream(do_QueryInterface(inOutputStream
))
669 const nsFileSpec
& inFile
,
670 int nsprMode
= kDefaultMode
,
671 PRIntn accessMode
= 00666)
672 : nsInputFileStream((nsIInputStream
*)nsnull
)
673 , nsOutputStream(nsnull
)
676 if (NS_FAILED(NS_NewIOFileStream(
678 inFile
, nsprMode
, accessMode
)))
680 mFile
= do_QueryInterface(stream
);
681 mStore
= do_QueryInterface(stream
);
682 mInputStream
= do_QueryInterface(stream
);
683 mOutputStream
= do_QueryInterface(stream
);
684 mFileInputStream
= do_QueryInterface(stream
);
685 mFileOutputStream
= do_QueryInterface(stream
);
689 virtual nsresult
close()
691 // Doesn't matter which of the two we close:
692 // they're hooked up to the same file.
693 return nsInputFileStream::close();
696 // Output streamers. Unfortunately, they don't inherit!
697 nsOutputStream
& operator << (const char* buf
)
698 { return nsOutputStream::operator << (buf
); }
699 nsOutputStream
& operator << (char ch
)
700 { return nsOutputStream::operator << (ch
); }
701 nsOutputStream
& operator << (short val
)
702 { return nsOutputStream::operator << (val
); }
703 nsOutputStream
& operator << (unsigned short val
)
704 { return nsOutputStream::operator << (val
); }
705 nsOutputStream
& operator << (long val
)
706 { return nsOutputStream::operator << (val
); }
707 nsOutputStream
& operator << (unsigned long val
)
708 { return nsOutputStream::operator << (val
); }
709 nsOutputStream
& operator << (int val
)
710 { return nsOutputStream::operator << (val
); }
711 nsOutputStream
& operator << (unsigned int val
)
712 { return nsOutputStream::operator << (val
); }
713 nsOutputStream
& operator << (nsOutputStream
& (*pf
)(nsOutputStream
&))
714 { return nsOutputStream::operator << (pf
); }
716 // Input streamers. Unfortunately, they don't inherit!
717 nsInputStream
& operator >> (char& ch
)
718 { return nsInputStream::operator >>(ch
); }
719 nsInputStream
& operator >> (nsInputStream
& (*pf
)(nsInputStream
&))
720 { return nsInputStream::operator >>(pf
); }
722 virtual nsresult
flush() {if (mFileOutputStream
) mFileOutputStream
->Flush(); return error(); }
727 // private and unimplemented to disallow copies and assigns
728 nsIOFileStream(const nsIOFileStream
& rhs
);
729 nsIOFileStream
& operator=(const nsIOFileStream
& rhs
);
733 nsCOMPtr
<nsIFileSpecOutputStream
> mFileOutputStream
;
734 }; // class nsIOFileStream
736 //========================================================================================
738 //========================================================================================
740 NS_COM_OBSOLETE nsOutputStream
& nsEndl(nsOutputStream
& os
); // outputs and FLUSHES.
742 //========================================================================================
743 #endif /* _FILESTREAM_H_ */