Back to index

lightning-sunbird  0.9+nobinonly
nsBinaryStream.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00053 #include <string.h>
00054 #include "nsBinaryStream.h"
00055 #include "nsCRT.h"
00056 #include "nsIStreamBufferAccess.h"
00057 #include "nsMemory.h"
00058 #include "prlong.h"
00059 #include "nsGenericFactory.h"
00060 #include "nsString.h"
00061 
00062 NS_IMPL_ISUPPORTS3(nsBinaryOutputStream, nsIObjectOutputStream, nsIBinaryOutputStream, nsIOutputStream)
00063 
00064 NS_IMETHODIMP
00065 nsBinaryOutputStream::Flush() { return mOutputStream->Flush(); }
00066 
00067 NS_IMETHODIMP
00068 nsBinaryOutputStream::Close() { return mOutputStream->Close(); }
00069 
00070 NS_IMETHODIMP
00071 nsBinaryOutputStream::Write(const char *aBuf, PRUint32 aCount, PRUint32 *aActualBytes)
00072 {
00073     return mOutputStream->Write(aBuf, aCount, aActualBytes);
00074 }
00075 
00076 NS_IMETHODIMP
00077 nsBinaryOutputStream::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
00078 {
00079     NS_NOTREACHED("WriteFrom");
00080     return NS_ERROR_NOT_IMPLEMENTED;
00081 }
00082 
00083 NS_IMETHODIMP
00084 nsBinaryOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
00085 {
00086     NS_NOTREACHED("WriteSegments");
00087     return NS_ERROR_NOT_IMPLEMENTED;
00088 }
00089 
00090 NS_IMETHODIMP
00091 nsBinaryOutputStream::IsNonBlocking(PRBool *aNonBlocking)
00092 {
00093     return mOutputStream->IsNonBlocking(aNonBlocking);
00094 }
00095 
00096 nsresult
00097 nsBinaryOutputStream::WriteFully(const char *aBuf, PRUint32 aCount)
00098 {
00099     nsresult rv;
00100     PRUint32 bytesWritten;
00101 
00102     rv = mOutputStream->Write(aBuf, aCount, &bytesWritten);
00103     if (NS_FAILED(rv)) return rv;
00104     if (bytesWritten != aCount)
00105         return NS_ERROR_FAILURE;
00106     return NS_OK;
00107 }
00108 
00109 NS_IMETHODIMP
00110 nsBinaryOutputStream::SetOutputStream(nsIOutputStream *aOutputStream)
00111 {
00112     NS_ENSURE_ARG_POINTER(aOutputStream);
00113     mOutputStream = aOutputStream;
00114     mBufferAccess = do_QueryInterface(aOutputStream);
00115     return NS_OK;
00116 }
00117 
00118 NS_IMETHODIMP
00119 nsBinaryOutputStream::WriteBoolean(PRBool aBoolean)
00120 {
00121     return Write8(aBoolean);
00122 }
00123 
00124 NS_IMETHODIMP
00125 nsBinaryOutputStream::Write8(PRUint8 aByte)
00126 {
00127     return WriteFully((const char*)&aByte, sizeof aByte);
00128 }
00129 
00130 NS_IMETHODIMP
00131 nsBinaryOutputStream::Write16(PRUint16 a16)
00132 {
00133     a16 = NS_SWAP16(a16);
00134     return WriteFully((const char*)&a16, sizeof a16);
00135 }
00136 
00137 NS_IMETHODIMP
00138 nsBinaryOutputStream::Write32(PRUint32 a32)
00139 {
00140     a32 = NS_SWAP32(a32);
00141     return WriteFully((const char*)&a32, sizeof a32);
00142 }
00143 
00144 NS_IMETHODIMP
00145 nsBinaryOutputStream::Write64(PRUint64 a64)
00146 {
00147     nsresult rv;
00148     PRUint32 bytesWritten;
00149 
00150     a64 = NS_SWAP64(a64);
00151     rv = Write(NS_REINTERPRET_CAST(char*, &a64), sizeof a64, &bytesWritten);
00152     if (NS_FAILED(rv)) return rv;
00153     if (bytesWritten != sizeof a64)
00154         return NS_ERROR_FAILURE;
00155     return rv;
00156 }
00157 
00158 NS_IMETHODIMP
00159 nsBinaryOutputStream::WriteFloat(float aFloat)
00160 {
00161     NS_ASSERTION(sizeof(float) == sizeof (PRUint32),
00162                  "False assumption about sizeof(float)");
00163     return Write32(*NS_REINTERPRET_CAST(PRUint32*, &aFloat));
00164 }
00165 
00166 NS_IMETHODIMP
00167 nsBinaryOutputStream::WriteDouble(double aDouble)
00168 {
00169     NS_ASSERTION(sizeof(double) == sizeof(PRUint64),
00170                  "False assumption about sizeof(double)");
00171     return Write64(*NS_REINTERPRET_CAST(PRUint64*, &aDouble));
00172 }
00173 
00174 NS_IMETHODIMP
00175 nsBinaryOutputStream::WriteStringZ(const char *aString)
00176 {
00177     PRUint32 length;
00178     nsresult rv;
00179 
00180     length = strlen(aString);
00181     rv = Write32(length);
00182     if (NS_FAILED(rv)) return rv;
00183     return WriteFully(aString, length);
00184 }
00185 
00186 NS_IMETHODIMP
00187 nsBinaryOutputStream::WriteWStringZ(const PRUnichar* aString)
00188 {
00189     PRUint32 length, byteCount;
00190     nsresult rv;
00191 
00192     length = nsCRT::strlen(aString);
00193     rv = Write32(length);
00194     if (NS_FAILED(rv)) return rv;
00195 
00196     if (length == 0)
00197         return NS_OK;
00198     byteCount = length * sizeof(PRUnichar);
00199 
00200 #ifdef IS_BIG_ENDIAN
00201     rv = WriteBytes(NS_REINTERPRET_CAST(const char*, aString), byteCount);
00202 #else
00203     // XXX use WriteSegments here to avoid copy!
00204     PRUnichar *copy, temp[64];
00205     if (length <= 64) {
00206         copy = temp;
00207     } else {
00208         copy = NS_REINTERPRET_CAST(PRUnichar*, nsMemory::Alloc(byteCount));
00209         if (!copy)
00210             return NS_ERROR_OUT_OF_MEMORY;
00211     }
00212     NS_ASSERTION((PRUptrdiff(aString) & 0x1) == 0, "aString not properly aligned");
00213     for (PRUint32 i = 0; i < length; i++)
00214         copy[i] = NS_SWAP16(aString[i]);
00215     rv = WriteBytes(NS_REINTERPRET_CAST(const char*, copy), byteCount);
00216     if (copy != temp)
00217         nsMemory::Free(copy);
00218 #endif
00219 
00220     return rv;
00221 }
00222 
00223 NS_IMETHODIMP
00224 nsBinaryOutputStream::WriteUtf8Z(const PRUnichar* aString)
00225 {
00226     return WriteStringZ(NS_ConvertUTF16toUTF8(aString).get());
00227 }
00228 
00229 NS_IMETHODIMP
00230 nsBinaryOutputStream::WriteBytes(const char *aString, PRUint32 aLength)
00231 {
00232     nsresult rv;
00233     PRUint32 bytesWritten;
00234 
00235     rv = Write(aString, aLength, &bytesWritten);
00236     if (NS_FAILED(rv)) return rv;
00237     if (bytesWritten != aLength)
00238         return NS_ERROR_FAILURE;
00239     return rv;
00240 }
00241 
00242 NS_IMETHODIMP
00243 nsBinaryOutputStream::WriteByteArray(PRUint8 *aBytes, PRUint32 aLength)
00244 {
00245     return WriteBytes(NS_REINTERPRET_CAST(char *, aBytes), aLength);
00246 }
00247 
00248 NS_IMETHODIMP
00249 nsBinaryOutputStream::WriteObject(nsISupports* aObject, PRBool aIsStrongRef)
00250 {
00251     NS_NOTREACHED("WriteObject");
00252     return NS_ERROR_NOT_IMPLEMENTED;
00253 }
00254 
00255 NS_IMETHODIMP
00256 nsBinaryOutputStream::WriteSingleRefObject(nsISupports* aObject)
00257 {
00258     NS_NOTREACHED("WriteSingleRefObject");
00259     return NS_ERROR_NOT_IMPLEMENTED;
00260 }
00261 
00262 NS_IMETHODIMP
00263 nsBinaryOutputStream::WriteCompoundObject(nsISupports* aObject,
00264                                           const nsIID& aIID,
00265                                           PRBool aIsStrongRef)
00266 {
00267     NS_NOTREACHED("WriteCompoundObject");
00268     return NS_ERROR_NOT_IMPLEMENTED;
00269 }
00270 
00271 NS_IMETHODIMP
00272 nsBinaryOutputStream::WriteID(const nsIID& aIID)
00273 {
00274     NS_NOTREACHED("WriteID");
00275     return NS_ERROR_NOT_IMPLEMENTED;
00276 }
00277 
00278 NS_IMETHODIMP_(char*)
00279 nsBinaryOutputStream::GetBuffer(PRUint32 aLength, PRUint32 aAlignMask)
00280 {
00281     if (mBufferAccess)
00282         return mBufferAccess->GetBuffer(aLength, aAlignMask);
00283     return nsnull;
00284 }
00285 
00286 NS_IMETHODIMP_(void)
00287 nsBinaryOutputStream::PutBuffer(char* aBuffer, PRUint32 aLength)
00288 {
00289     if (mBufferAccess)
00290         mBufferAccess->PutBuffer(aBuffer, aLength);
00291 }
00292 
00293 NS_IMPL_ISUPPORTS3(nsBinaryInputStream, nsIObjectInputStream, nsIBinaryInputStream, nsIInputStream)
00294 
00295 NS_IMETHODIMP
00296 nsBinaryInputStream::Available(PRUint32* aResult)
00297 {
00298     return mInputStream->Available(aResult);
00299 }
00300 
00301 NS_IMETHODIMP
00302 nsBinaryInputStream::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead)
00303 {
00304     return mInputStream->Read(aBuffer, aCount, aNumRead);
00305 }
00306 
00307 
00308 // when forwarding ReadSegments to mInputStream, we need to make sure
00309 // 'this' is being passed to the writer each time. To do this, we need
00310 // a thunking function which keeps the real input stream around.
00311 
00312 // the closure wrapper
00313 struct ReadSegmentsClosure {
00314     nsIInputStream* mRealInputStream;
00315     void* mRealClosure;
00316     nsWriteSegmentFun mRealWriter;
00317 };
00318 
00319 // the thunking function
00320 static NS_METHOD
00321 ReadSegmentForwardingThunk(nsIInputStream* aStream,
00322                            void *aClosure,
00323                            const char* aFromSegment,
00324                            PRUint32 aToOffset,
00325                            PRUint32 aCount,
00326                            PRUint32 *aWriteCount)
00327 {
00328     ReadSegmentsClosure* thunkClosure =
00329         NS_REINTERPRET_CAST(ReadSegmentsClosure*, aClosure);
00330 
00331     return thunkClosure->mRealWriter(thunkClosure->mRealInputStream,
00332                                      thunkClosure->mRealClosure,
00333                                      aFromSegment, aToOffset,
00334                                      aCount, aWriteCount);
00335 }
00336 
00337 
00338 NS_IMETHODIMP
00339 nsBinaryInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
00340 {
00341     ReadSegmentsClosure thunkClosure = { this, closure, writer };
00342     
00343     return mInputStream->ReadSegments(ReadSegmentForwardingThunk, &thunkClosure, count, _retval);
00344 }
00345 
00346 NS_IMETHODIMP
00347 nsBinaryInputStream::IsNonBlocking(PRBool *aNonBlocking)
00348 {
00349     return mInputStream->IsNonBlocking(aNonBlocking);
00350 }
00351 
00352 NS_IMETHODIMP
00353 nsBinaryInputStream::Close() { return mInputStream->Close(); }
00354 
00355 NS_IMETHODIMP
00356 nsBinaryInputStream::SetInputStream(nsIInputStream *aInputStream)
00357 {
00358     NS_ENSURE_ARG_POINTER(aInputStream);
00359     mInputStream = aInputStream;
00360     mBufferAccess = do_QueryInterface(aInputStream);
00361     return NS_OK;
00362 }
00363 
00364 NS_IMETHODIMP
00365 nsBinaryInputStream::ReadBoolean(PRBool* aBoolean)
00366 {
00367     PRUint8 byteResult;
00368     nsresult rv = Read8(&byteResult);
00369     *aBoolean = byteResult;
00370     return rv;
00371 }
00372 
00373 NS_IMETHODIMP
00374 nsBinaryInputStream::Read8(PRUint8* aByte)
00375 {
00376     nsresult rv;
00377     PRUint32 bytesRead;
00378 
00379     rv = Read(NS_REINTERPRET_CAST(char*, aByte), sizeof(*aByte), &bytesRead);
00380     if (NS_FAILED(rv)) return rv;
00381     if (bytesRead != 1)
00382         return NS_ERROR_FAILURE;
00383     return rv;
00384 }
00385 
00386 NS_IMETHODIMP
00387 nsBinaryInputStream::Read16(PRUint16* a16)
00388 {
00389     nsresult rv;
00390     PRUint32 bytesRead;
00391 
00392     rv = Read(NS_REINTERPRET_CAST(char*, a16), sizeof *a16, &bytesRead);
00393     if (NS_FAILED(rv)) return rv;
00394     if (bytesRead != sizeof *a16)
00395         return NS_ERROR_FAILURE;
00396     *a16 = NS_SWAP16(*a16);
00397     return rv;
00398 }
00399 
00400 NS_IMETHODIMP
00401 nsBinaryInputStream::Read32(PRUint32* a32)
00402 {
00403     nsresult rv;
00404     PRUint32 bytesRead;
00405 
00406     rv = Read(NS_REINTERPRET_CAST(char*, a32), sizeof *a32, &bytesRead);
00407     if (NS_FAILED(rv)) return rv;
00408     if (bytesRead != sizeof *a32)
00409         return NS_ERROR_FAILURE;
00410     *a32 = NS_SWAP32(*a32);
00411     return rv;
00412 }
00413 
00414 NS_IMETHODIMP
00415 nsBinaryInputStream::Read64(PRUint64* a64)
00416 {
00417     nsresult rv;
00418     PRUint32 bytesRead;
00419 
00420     rv = Read(NS_REINTERPRET_CAST(char*, a64), sizeof *a64, &bytesRead);
00421     if (NS_FAILED(rv)) return rv;
00422     if (bytesRead != sizeof *a64)
00423         return NS_ERROR_FAILURE;
00424     *a64 = NS_SWAP64(*a64);
00425     return rv;
00426 }
00427 
00428 NS_IMETHODIMP
00429 nsBinaryInputStream::ReadFloat(float* aFloat)
00430 {
00431     NS_ASSERTION(sizeof(float) == sizeof (PRUint32),
00432                  "False assumption about sizeof(float)");
00433     return Read32(NS_REINTERPRET_CAST(PRUint32*, aFloat));
00434 }
00435 
00436 NS_IMETHODIMP
00437 nsBinaryInputStream::ReadDouble(double* aDouble)
00438 {
00439     NS_ASSERTION(sizeof(double) == sizeof(PRUint64),
00440                  "False assumption about sizeof(double)");
00441     return Read64(NS_REINTERPRET_CAST(PRUint64*, aDouble));
00442 }
00443 
00444 static NS_METHOD
00445 WriteSegmentToCString(nsIInputStream* aStream,
00446                       void *aClosure,
00447                       const char* aFromSegment,
00448                       PRUint32 aToOffset,
00449                       PRUint32 aCount,
00450                       PRUint32 *aWriteCount)
00451 {
00452     nsACString* outString = NS_STATIC_CAST(nsACString*,aClosure);
00453 
00454     outString->Append(aFromSegment, aCount);
00455 
00456     *aWriteCount = aCount;
00457     
00458     return NS_OK;
00459 }
00460 
00461 NS_IMETHODIMP
00462 nsBinaryInputStream::ReadCString(nsACString& aString)
00463 {
00464     nsresult rv;
00465     PRUint32 length, bytesRead;
00466 
00467     rv = Read32(&length);
00468     if (NS_FAILED(rv)) return rv;
00469 
00470     aString.Truncate();
00471     rv = ReadSegments(WriteSegmentToCString, &aString, length, &bytesRead);
00472     if (NS_FAILED(rv)) return rv;
00473     
00474     if (bytesRead != length)
00475         return NS_ERROR_FAILURE;
00476 
00477     return NS_OK;
00478 }
00479 
00480 
00481 // sometimes, WriteSegmentToString will be handed an odd-number of
00482 // bytes, which means we only have half of the last PRUnichar
00483 struct WriteStringClosure {
00484     PRUnichar *mWriteCursor;
00485     PRPackedBool mHasCarryoverByte;
00486     char mCarryoverByte;
00487 };
00488 
00489 // there are a few cases we have to account for here:
00490 // * even length buffer, no carryover - easy, just append
00491 // * odd length buffer, no carryover - the last byte needs to be saved
00492 //                                     for carryover
00493 // * odd length buffer, with carryover - first byte needs to be used
00494 //                              with the carryover byte, and
00495 //                              the rest of the even length
00496 //                              buffer is appended as normal
00497 // * even length buffer, with carryover - the first byte needs to be
00498 //                              used with the previous carryover byte.
00499 //                              this gives you an odd length buffer,
00500 //                              so you have to save the last byte for
00501 //                              the next carryover
00502 
00503 
00504 // same version of the above, but with correct casting and endian swapping
00505 static NS_METHOD
00506 WriteSegmentToString(nsIInputStream* aStream,
00507                      void *aClosure,
00508                      const char* aFromSegment,
00509                      PRUint32 aToOffset,
00510                      PRUint32 aCount,
00511                      PRUint32 *aWriteCount)
00512 {
00513     NS_PRECONDITION(aCount > 0, "Why are we being told to write 0 bytes?");
00514     NS_PRECONDITION(sizeof(PRUnichar) == 2, "We can't handle other sizes!");
00515 
00516     WriteStringClosure* closure = NS_STATIC_CAST(WriteStringClosure*,aClosure);
00517     PRUnichar *cursor = closure->mWriteCursor;
00518 
00519     // we're always going to consume the whole buffer no matter what
00520     // happens, so take care of that right now.. that allows us to
00521     // tweak aCount later. Do NOT move this!
00522     *aWriteCount = aCount;
00523 
00524     // if the last Write had an odd-number of bytes read, then 
00525     if (closure->mHasCarryoverByte) {
00526         // re-create the two-byte sequence we want to work with
00527         char bytes[2] = { closure->mCarryoverByte, *aFromSegment };
00528         *cursor = *(PRUnichar*)bytes;
00529         // Now the little endianness dance
00530 #ifdef IS_LITTLE_ENDIAN
00531         *cursor = (PRUnichar) NS_SWAP16(*cursor);
00532 #endif
00533         ++cursor;
00534         
00535         // now skip past the first byte of the buffer.. code from here
00536         // can assume normal operations, but should not assume aCount
00537         // is relative to the ORIGINAL buffer
00538         ++aFromSegment;
00539         --aCount;
00540 
00541         closure->mHasCarryoverByte = PR_FALSE;
00542     }
00543     
00544     // this array is possibly unaligned... be careful how we access it!
00545     const PRUnichar *unicodeSegment =
00546         NS_REINTERPRET_CAST(const PRUnichar*, aFromSegment);
00547 
00548     // calculate number of full characters in segment (aCount could be odd!)
00549     PRUint32 segmentLength = aCount / sizeof(PRUnichar);
00550 
00551     // copy all data into our aligned buffer.  byte swap if necessary.
00552     memcpy(cursor, unicodeSegment, segmentLength * sizeof(PRUnichar));
00553     PRUnichar *end = cursor + segmentLength;
00554 #ifdef IS_LITTLE_ENDIAN
00555     for (; cursor < end; ++cursor)
00556         *cursor = (PRUnichar) NS_SWAP16(*cursor);
00557 #endif
00558     closure->mWriteCursor = end;
00559 
00560     // remember this is the modifed aCount and aFromSegment,
00561     // so that will take into account the fact that we might have
00562     // skipped the first byte in the buffer
00563     if (aCount % sizeof(PRUnichar) != 0) {
00564         // we must have had a carryover byte, that we'll need the next
00565         // time around
00566         closure->mCarryoverByte = aFromSegment[aCount - 1];
00567         closure->mHasCarryoverByte = PR_TRUE;
00568     }
00569     
00570     return NS_OK;
00571 }
00572 
00573 
00574 NS_IMETHODIMP
00575 nsBinaryInputStream::ReadString(nsAString& aString)
00576 {
00577     nsresult rv;
00578     PRUint32 length, bytesRead;
00579 
00580     rv = Read32(&length);
00581     if (NS_FAILED(rv)) return rv;
00582 
00583     // pre-allocate output buffer, and get direct access to buffer...
00584     if (!EnsureStringLength(aString, length))
00585         return NS_ERROR_OUT_OF_MEMORY;
00586 
00587     nsAString::iterator start;
00588     aString.BeginWriting(start);
00589     
00590     WriteStringClosure closure;
00591     closure.mWriteCursor = start.get();
00592     closure.mHasCarryoverByte = PR_FALSE;
00593     
00594     rv = ReadSegments(WriteSegmentToString, &closure,
00595                       length*sizeof(PRUnichar), &bytesRead);
00596     if (NS_FAILED(rv)) return rv;
00597 
00598     NS_ASSERTION(!closure.mHasCarryoverByte, "some strange stream corruption!");
00599     
00600     if (bytesRead != length*sizeof(PRUnichar))
00601         return NS_ERROR_FAILURE;
00602 
00603     return NS_OK;
00604 }
00605 
00606 NS_IMETHODIMP
00607 nsBinaryInputStream::ReadBytes(PRUint32 aLength, char* *_rval)
00608 {
00609     nsresult rv;
00610     PRUint32 bytesRead;
00611     char* s;
00612 
00613     s = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(aLength));
00614     if (!s)
00615         return NS_ERROR_OUT_OF_MEMORY;
00616 
00617     rv = Read(s, aLength, &bytesRead);
00618     if (NS_FAILED(rv)) {
00619         nsMemory::Free(s);
00620         return rv;
00621     }
00622     if (bytesRead != aLength) {
00623         nsMemory::Free(s);
00624         return NS_ERROR_FAILURE;
00625     }
00626 
00627     *_rval = s;
00628     return NS_OK;
00629 }
00630 
00631 NS_IMETHODIMP
00632 nsBinaryInputStream::ReadByteArray(PRUint32 aLength, PRUint8* *_rval)
00633 {
00634     return ReadBytes(aLength, NS_REINTERPRET_CAST(char **, _rval));
00635 }
00636 
00637 NS_IMETHODIMP
00638 nsBinaryInputStream::ReadObject(PRBool aIsStrongRef, nsISupports* *aObject)
00639 {
00640     NS_NOTREACHED("ReadObject");
00641     return NS_ERROR_NOT_IMPLEMENTED;
00642 }
00643 
00644 NS_IMETHODIMP
00645 nsBinaryInputStream::ReadID(nsID *aResult)
00646 {
00647     NS_NOTREACHED("ReadID");
00648     return NS_ERROR_NOT_IMPLEMENTED;
00649 }
00650 
00651 NS_IMETHODIMP_(char*)
00652 nsBinaryInputStream::GetBuffer(PRUint32 aLength, PRUint32 aAlignMask)
00653 {
00654     if (mBufferAccess)
00655         return mBufferAccess->GetBuffer(aLength, aAlignMask);
00656     return nsnull;
00657 }
00658 
00659 NS_IMETHODIMP_(void)
00660 nsBinaryInputStream::PutBuffer(char* aBuffer, PRUint32 aLength)
00661 {
00662     if (mBufferAccess)
00663         mBufferAccess->PutBuffer(aBuffer, aLength);
00664 }
00665