Back to index

lightning-sunbird  0.9+nobinonly
nsFileStream.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037  
00038 //     First checked in on 98/12/08 by John R. McMullen.
00039 //  Since nsFileStream.h is entirely templates, common code (such as open())
00040 //  which does not actually depend on the charT, can be placed here.
00041 
00042 #include "nsFileStream.h"
00043 #include "nsFileSpec.h"
00044 #include "nsIFileSpec.h"
00045 #include "nsIStringStream.h"
00046 #include "nsInt64.h"
00047 #include <string.h>
00048 #include <stdio.h>
00049 
00050 
00051 //========================================================================================
00052 //          nsInputStream
00053 //========================================================================================
00054 
00055 //----------------------------------------------------------------------------------------
00056 nsInputStream::~nsInputStream()
00057 //----------------------------------------------------------------------------------------
00058 {
00059 }
00060 
00061 //----------------------------------------------------------------------------------------
00062 char nsInputStream::get()
00063 //----------------------------------------------------------------------------------------
00064 {
00065        char c;
00066     if (read(&c, sizeof(c)) == sizeof(c))
00067         return c;
00068     return 0;
00069 }
00070 
00071 //----------------------------------------------------------------------------------------
00072 PRInt32 nsInputStream::read(void* s, PRInt32 n)
00073 //----------------------------------------------------------------------------------------
00074 {
00075   if (!mInputStream)
00076       return 0;
00077   PRInt32 result = 0;
00078   PRInt32 status = mInputStream->Read((char*)s, n, (PRUint32*)&result);
00079   if (result == 0)
00080       set_at_eof(PR_TRUE);
00081   if (status < 0) 
00082       return (status); 
00083   return result;
00084 } // nsInputStream::read
00085 
00086 //----------------------------------------------------------------------------------------
00087 static void TidyEndOfLine(char*& cp)
00088 // Assumes that cp is pointing at \n or \r.  Nulls out the character, checks for
00089 // a second terminator (of the opposite persuasion), and returns cp pointing past the
00090 // entire eol construct (one or two characters).
00091 //----------------------------------------------------------------------------------------
00092 {
00093     char ch = *cp;
00094     *cp++ = '\0'; // terminate at the newline, then skip past it
00095     if ((ch == '\n' && *cp == '\r') || (ch == '\r' && *cp == '\n'))
00096         cp++; // possibly a pair.
00097 }
00098 
00099 //----------------------------------------------------------------------------------------
00100 nsInputStream& nsInputStream::operator >> (char& c)
00101 //----------------------------------------------------------------------------------------
00102 {
00103        c = get();
00104        return *this;
00105 }
00106 
00107 //========================================================================================
00108 //          nsOutputStream
00109 //========================================================================================
00110 
00111 //----------------------------------------------------------------------------------------
00112 nsOutputStream::~nsOutputStream()
00113 //----------------------------------------------------------------------------------------
00114 {
00115 }
00116 
00117 //----------------------------------------------------------------------------------------
00118 void nsOutputStream::put(char c)
00119 //----------------------------------------------------------------------------------------
00120 {
00121     write(&c, sizeof(c));
00122 }
00123 
00124 //----------------------------------------------------------------------------------------
00125 PRInt32 nsOutputStream::write(const void* s, PRInt32 n)
00126 //----------------------------------------------------------------------------------------
00127 {
00128   if (!mOutputStream)
00129       return 0;
00130   PRInt32 result = 0;
00131   mWriteStatus = mOutputStream->Write((char*)s, n, (PRUint32*)&result);
00132   return result;
00133 } // nsOutputStream::write
00134 
00135 //----------------------------------------------------------------------------------------
00136 nsresult nsOutputStream::flush()
00137 //----------------------------------------------------------------------------------------
00138 {
00139   return NS_OK;
00140 }
00141 
00142 //----------------------------------------------------------------------------------------
00143 nsresult nsOutputStream::lastWriteStatus()
00144 //----------------------------------------------------------------------------------------
00145 {
00146   return mWriteStatus;
00147 }
00148 
00149 //----------------------------------------------------------------------------------------
00150 nsOutputStream& nsOutputStream::operator << (char c)
00151 //----------------------------------------------------------------------------------------
00152 {
00153        put(c);
00154        return *this;
00155 }
00156 
00157 //----------------------------------------------------------------------------------------
00158 nsOutputStream& nsOutputStream::operator << (const char* s)
00159 //----------------------------------------------------------------------------------------
00160 {
00161        if (s)
00162               write(s, strlen(s));
00163        return *this;
00164 }
00165 
00166 //----------------------------------------------------------------------------------------
00167 nsOutputStream& nsOutputStream::operator << (short val)
00168 //----------------------------------------------------------------------------------------
00169 {
00170        char buf[30];
00171        sprintf(buf, "%hd", val);
00172        return (*this << buf);
00173 }
00174 
00175 //----------------------------------------------------------------------------------------
00176 nsOutputStream& nsOutputStream::operator << (unsigned short val)
00177 //----------------------------------------------------------------------------------------
00178 {
00179        char buf[30];
00180        sprintf(buf, "%hu", val);
00181        return (*this << buf);
00182 }
00183 
00184 //----------------------------------------------------------------------------------------
00185 nsOutputStream& nsOutputStream::operator << (long val)
00186 //----------------------------------------------------------------------------------------
00187 {
00188        char buf[30];
00189        sprintf(buf, "%ld", val);
00190        return (*this << buf);
00191 }
00192 
00193 //----------------------------------------------------------------------------------------
00194 nsOutputStream& nsOutputStream::operator << (unsigned long val)
00195 //----------------------------------------------------------------------------------------
00196 {
00197        char buf[30];
00198        sprintf(buf, "%lu", val);
00199        return (*this << buf);
00200 }
00201 
00202 //----------------------------------------------------------------------------------------
00203 nsOutputStream& nsOutputStream::operator << (int val)
00204 //----------------------------------------------------------------------------------------
00205 {
00206        char buf[30];
00207        sprintf(buf, "%d", val);
00208        return (*this << buf);
00209 }
00210 
00211 //----------------------------------------------------------------------------------------
00212 nsOutputStream& nsOutputStream::operator << (unsigned int val)
00213 //----------------------------------------------------------------------------------------
00214 {
00215        char buf[30];
00216        sprintf(buf, "%u", val);
00217        return (*this << buf);
00218 }
00219 
00220 //========================================================================================
00221 //          nsRandomAccessInputStream
00222 //========================================================================================
00223 
00224 //----------------------------------------------------------------------------------------
00225 PRBool nsRandomAccessInputStream::readline(char* s, PRInt32 n)
00226 // This will truncate if the buffer is too small.  Result will always be null-terminated.
00227 //----------------------------------------------------------------------------------------
00228 {
00229     PRBool bufferLargeEnough = PR_TRUE; // result
00230     if (!s || !n)
00231         return PR_TRUE;
00232 
00233     nsInt64 position = tell();
00234     const nsInt64 zero(0);
00235     if (position < zero)
00236         return PR_FALSE;
00237     PRInt32 bytesRead = read(s, n - 1);
00238     if (failed())
00239         return PR_FALSE;
00240     s[bytesRead] = '\0'; // always terminate at the end of the buffer
00241     char* tp = strpbrk(s, "\n\r");
00242     if (tp)
00243     {
00244         TidyEndOfLine(tp);
00245         bytesRead = (tp - s);
00246     }
00247     else if (!eof() && n-1 == bytesRead)
00248         bufferLargeEnough = PR_FALSE;
00249     position += bytesRead;
00250     seek(position);
00251     return bufferLargeEnough;
00252 } // nsRandomAccessInputStream::readline
00253 
00254 //========================================================================================
00255 //          nsInputStringStream
00256 //========================================================================================
00257 
00258 //----------------------------------------------------------------------------------------
00259 nsInputStringStream::nsInputStringStream(const char* stringToRead)
00260 //----------------------------------------------------------------------------------------
00261 {
00262        nsCOMPtr<nsIInputStream> stream;
00263        if (NS_FAILED(NS_NewCharInputStream(getter_AddRefs(stream), stringToRead)))
00264               return;
00265        mInputStream = stream;
00266        mStore = do_QueryInterface(stream);
00267 }
00268 
00269 //----------------------------------------------------------------------------------------
00270 nsInputStringStream::nsInputStringStream(const nsString& stringToRead)
00271 //----------------------------------------------------------------------------------------
00272 {
00273        if (NS_FAILED(NS_NewStringInputStream(getter_AddRefs(mInputStream), stringToRead)))
00274               return;
00275        mStore = do_QueryInterface(mInputStream);
00276 }
00277 
00278 
00279 //========================================================================================
00280 //          nsInputFileStream
00281 //========================================================================================
00282 
00283 //----------------------------------------------------------------------------------------
00284 nsInputFileStream::nsInputFileStream(
00285        const nsFileSpec& inFile,
00286        int nsprMode,
00287        PRIntn accessMode)
00288 //----------------------------------------------------------------------------------------
00289 {
00290        nsISupports* stream;
00291        if (NS_FAILED(NS_NewIOFileStream(&stream, inFile, nsprMode, accessMode)))
00292         return;
00293        AssignFrom(stream);
00294        NS_RELEASE(stream);
00295 } // nsInputFileStream::nsInputFileStream
00296 
00297 //----------------------------------------------------------------------------------------
00298 nsInputFileStream::nsInputFileStream(nsIFileSpec* inSpec)
00299 //----------------------------------------------------------------------------------------
00300 {
00301        nsIInputStream* stream;
00302        if (NS_FAILED(inSpec->GetInputStream(&stream)))
00303         return;
00304        AssignFrom(stream);
00305        NS_RELEASE(stream);
00306 } // nsInputFileStream::nsInputFileStream
00307 
00308 //----------------------------------------------------------------------------------------
00309 nsInputFileStream::~nsInputFileStream()
00310 //----------------------------------------------------------------------------------------
00311 {
00312 //    if (is_open())
00313 //      close();
00314 }
00315 
00316 //----------------------------------------------------------------------------------------
00317 void nsInputFileStream::AssignFrom(nsISupports* stream)
00318 //----------------------------------------------------------------------------------------
00319 {
00320        mFile = do_QueryInterface(stream);
00321        mInputStream = do_QueryInterface(stream);
00322        mStore = do_QueryInterface(stream);
00323        mFileInputStream = do_QueryInterface(stream);
00324 }
00325 
00326 //========================================================================================
00327 //          nsOutputFileStream
00328 //========================================================================================
00329 
00330 //----------------------------------------------------------------------------------------
00331 nsOutputFileStream::nsOutputFileStream(nsIFileSpec* inSpec)
00332 //----------------------------------------------------------------------------------------
00333 {
00334        if (!inSpec)
00335               return;
00336        nsIOutputStream* stream;
00337        if (NS_FAILED(inSpec->GetOutputStream(&stream)))
00338          return;
00339        AssignFrom(stream);
00340        NS_RELEASE(stream);
00341 }
00342 
00343 //----------------------------------------------------------------------------------------
00344 nsOutputFileStream::~nsOutputFileStream()
00345 //----------------------------------------------------------------------------------------
00346 {
00347 //    if (is_open())
00348 //      close();
00349 }
00350 //----------------------------------------------------------------------------------------
00351 void nsOutputFileStream::AssignFrom(nsISupports* stream)
00352 //----------------------------------------------------------------------------------------
00353 {
00354     mFile = do_QueryInterface(stream);
00355     mOutputStream = do_QueryInterface(stream);
00356     mStore = do_QueryInterface(stream);
00357     mFileOutputStream = do_QueryInterface(stream);
00358 }
00359 
00360 //----------------------------------------------------------------------------------------
00361 nsresult nsOutputFileStream::flush()
00362 //----------------------------------------------------------------------------------------
00363 {
00364        if (mFileOutputStream)
00365               mFileOutputStream->Flush();
00366     return error();
00367 }
00368 
00369 //----------------------------------------------------------------------------------------
00370 void nsOutputFileStream::abort()
00371 //----------------------------------------------------------------------------------------
00372 {
00373        mResult = NS_FILE_FAILURE;
00374        close();
00375 }
00376 
00377 //========================================================================================
00378 //        Manipulators
00379 //========================================================================================
00380 
00381 //----------------------------------------------------------------------------------------
00382 nsOutputStream& nsEndl(nsOutputStream& os)
00383 //----------------------------------------------------------------------------------------
00384 {
00385 #if defined(XP_WIN) || defined(XP_OS2)
00386     os.write("\r\n", 2);
00387 #elif defined (XP_MAC)
00388     os.put('\r');
00389 #else
00390     os.put('\n');
00391 #endif
00392     //os.flush();
00393     return os;
00394 } // nsEndl