Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions
FileImpl Class Reference
Inheritance diagram for FileImpl:
Inheritance graph
[legend]
Collaboration diagram for FileImpl:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 FileImpl (PRFileDesc *inDesc)
 FileImpl (const nsFileSpec &inFile, int nsprMode, PRIntn accessMode)
NS_DECL_ISUPPORTS NS_IMETHOD Open (const nsFileSpec &inFile, int nsprMode, PRIntn accessMode)
NS_IMETHOD Close ()
NS_IMETHOD GetIsOpen (PRBool *outOpen)
NS_IMETHOD Available (PRUint32 *aLength)
NS_IMETHOD Read (char *aBuf, PRUint32 aCount, PRUint32 *aReadCount)
NS_IMETHOD ReadSegments (nsWriteSegmentFun writer, void *closure, PRUint32 count, PRUint32 *_retval)
NS_IMETHOD IsNonBlocking (PRBool *aNonBlocking)
NS_IMETHOD Write (const char *aBuf, PRUint32 aCount, PRUint32 *aWriteCount)
NS_IMETHOD Flush ()
NS_IMETHOD WriteFrom (nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
NS_IMETHOD WriteSegments (nsReadSegmentFun reader, void *closure, PRUint32 count, PRUint32 *_retval)
NS_DECL_NSISEEKABLESTREAM
NS_IMETHOD 
GetAtEOF (PRBool *outAtEOF)
NS_IMETHOD SetAtEOF (PRBool inAtEOF)
void seek (in long whence, in long long offset)
 seek
long long tell ()
 tell
void setEOF ()
 setEOF
void close ()
 Close the stream.
void flush ()
 Flush the stream.
unsigned long write (in string aBuf, in unsigned long aCount)
 Write data into the stream.
unsigned long writeFrom (in nsIInputStream aFromStream, in unsigned long aCount)
 Writes data into the stream from an input stream.
unsigned long writeSegments (in nsReadSegmentFun aReader, in voidPtr aClosure, in unsigned long aCount)
 Low-level write method that has access to the stream's underlying buffer.
boolean isNonBlocking ()
void close ()
 Close the stream.
unsigned long available ()
unsigned long read (in charPtr aBuf, in unsigned long aCount)
 Read data from the stream.
unsigned long readSegments (in nsWriteSegmentFun aWriter, in voidPtr aClosure, in unsigned long aCount)
 Low-level read method that has access to the stream's underlying buffer.
boolean isNonBlocking ()

Public Attributes

const PRInt32 NS_SEEK_SET = 0
const PRInt32 NS_SEEK_CUR = 1
const PRInt32 NS_SEEK_END = 2

Protected Types

enum  { kOuputBufferSegmentSize = 4096, kOuputBufferMaxSize = 4096 }

Protected Member Functions

nsresult InternalFlush (PRBool syncFile)
nsresult AllocateBuffers (PRUint32 segmentSize, PRUint32 maxSize)

Protected Attributes

PRFileDescmFileDesc
int mNSPRMode
PRBool mFailed
PRBool mEOF
PRInt32 mLength
PRBool mGotBuffers
nsSegmentedBuffer mOutBuffer
char * mWriteCursor
char * mWriteLimit

Private Member Functions

 ~FileImpl ()

Detailed Description

Definition at line 60 of file nsIFileStream.cpp.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
kOuputBufferSegmentSize 
kOuputBufferMaxSize 

Definition at line 102 of file nsIFileStream.cpp.


Constructor & Destructor Documentation

Definition at line 138 of file nsIFileStream.cpp.

FileImpl::FileImpl ( const nsFileSpec inFile,
int  nsprMode,
PRIntn  accessMode 
)

Definition at line 153 of file nsIFileStream.cpp.

: mFileDesc(nsnull)
, mNSPRMode(-1)
, mEOF(PR_FALSE)
, mLength(-1)
, mGotBuffers(PR_FALSE)
{
    mWriteCursor = nsnull;
    mWriteLimit  = nsnull;

    nsresult rv = Open(inFile, nsprMode, accessMode);          // this sets nsprMode
    
    if (NS_FAILED(rv))
    {
        mFailed = PR_TRUE;
#if DEBUG
        char *fileName = inFile.GetLeafName();
        printf("Opening file %s failed\n", fileName);
        nsCRT::free(fileName);
#endif
    }
    else
    {
        mFailed = PR_FALSE;
    }
}

Here is the call graph for this function:

FileImpl::~FileImpl ( ) [private]

Definition at line 182 of file nsIFileStream.cpp.

{
    nsresult  rv = Close();
    NS_ASSERTION(NS_SUCCEEDED(rv), "Close failed");
}

Here is the call graph for this function:


Member Function Documentation

nsresult FileImpl::AllocateBuffers ( PRUint32  segmentSize,
PRUint32  maxSize 
) [protected]

Definition at line 557 of file nsIFileStream.cpp.

{
    nsresult rv = mOutBuffer.Init(segmentSize, maxBufSize);
    if (NS_SUCCEEDED(rv))
      mGotBuffers = PR_TRUE;

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 301 of file nsIFileStream.cpp.

{
    NS_PRECONDITION(aLength != nsnull, "null ptr");
    if (!aLength)
        return NS_ERROR_NULL_POINTER;
    if (mLength < 0)
        return NS_ERROR_UNEXPECTED;
    *aLength = mLength;
    return NS_OK;
}
unsigned long nsIInputStream::available ( ) [inherited]
Returns:
number of bytes currently available in the stream

Definition at line 507 of file nsIFileStream.cpp.

{
    if ((mNSPRMode & PR_RDONLY) == 0)
        InternalFlush(PR_FALSE);

    if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc) 
       return NS_OK;
    if (PR_Close(mFileDesc) == PR_SUCCESS)
        mFileDesc = 0;
    else
        return NS_FILE_RESULT(PR_GetError());
    return NS_OK;
} // FileImpl::close

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIInputStream::close ( ) [inherited]

Close the stream.

void nsIOutputStream::close ( ) [inherited]

Close the stream.

Forces the output stream to flush any buffered data.

Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif unable to flush without blocking the calling thread (non-blocking mode only)

Definition at line 523 of file nsIFileStream.cpp.

{
  // for external callers, this will do a Sync as well as flush buffers.
  return InternalFlush(PR_TRUE);
} // FileImpl::flush

Here is the call graph for this function:

void nsIOutputStream::flush ( ) [inherited]

Flush the stream.

Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif unable to flush without blocking the calling thread (non-blocking mode only)
NS_IMETHODIMP FileImpl::GetAtEOF ( PRBool outAtEOF) [virtual]

Implements nsIRandomAccessStore.

Definition at line 532 of file nsIFileStream.cpp.

{
  *outAtEOF = mEOF;
  return NS_OK;
}
NS_IMETHODIMP FileImpl::GetIsOpen ( PRBool outOpen) [virtual]

Implements nsIOpenFile.

Definition at line 314 of file nsIFileStream.cpp.

{
    *outOpen = (mFileDesc != nsnull && !mFailed);
    return NS_OK;
}

Here is the caller graph for this function:

nsresult FileImpl::InternalFlush ( PRBool  syncFile) [protected]

Definition at line 569 of file nsIFileStream.cpp.

{
#ifdef XP_MAC
    if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
    {
        std::cout.flush();
        return NS_OK;
    }
#endif
    if (!mFileDesc) 
        return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
    
    PRInt32 segCount = mOutBuffer.GetSegmentCount();
    PRUint32 segSize = mOutBuffer.GetSegmentSize();

    for (PRInt32 i = 0; i < segCount; i++) 
    {
        char* seg = mOutBuffer.GetSegment(i);

        // if it is the last buffer, it may not be completely full.  
        if(i == (segCount-1))
            segSize = (mWriteCursor - seg);

        PRInt32 bytesWrit = PR_Write(mFileDesc, seg, segSize);
        if (bytesWrit != (PRInt32)segSize)
        {
          mFailed = PR_TRUE;
          return NS_FILE_RESULT(PR_GetError());
        }
    }

    if (mGotBuffers)
        mOutBuffer.Empty();
    mWriteCursor = nsnull;
    mWriteLimit  = nsnull;

    // On unix, it seems to fail always.
    if (syncFile && PR_Sync(mFileDesc) != PR_SUCCESS)
        mFailed = PR_TRUE;
                                                
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 490 of file nsIFileStream.cpp.

{
    *aNonBlocking = PR_FALSE;
    return NS_OK;
}
Returns:
true if stream is non-blocking
Returns:
true if stream is non-blocking

NOTE: writing to a blocking output stream will block the calling thread until all given data can be consumed by the stream.

NS_IMETHODIMP FileImpl::Open ( const nsFileSpec inFile,
int  nsprMode,
PRIntn  accessMode 
) [virtual]

Implements nsIOpenFile.

Definition at line 191 of file nsIFileStream.cpp.

{
    if (mFileDesc)
        if ((nsprMode & mNSPRMode) == nsprMode)
            return NS_OK;
        else
            return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
        
    const int nspr_modes[]={
        PR_WRONLY | PR_CREATE_FILE,
        PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
        PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
        PR_RDONLY,
        PR_RDONLY | PR_APPEND,
        PR_RDWR | PR_CREATE_FILE,
        PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
//      "wb",
//      "ab", 
//      "wb",
//      "rb",
//      "r+b",
//      "w+b",
        0 };
    const int* currentLegalMode = nspr_modes;
    while (*currentLegalMode && nsprMode != *currentLegalMode)
        ++currentLegalMode;
    if (!*currentLegalMode) 
        return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);

#ifdef XP_MAC
     // Use the file spec to open the file, because one path can be common to
     // several files on the Macintosh (you can have several volumes with the
     // same name, see).
    mFileDesc = 0;
    OSErr err = inFile.Error();
    if (err != noErr)
      if (err != fnfErr || !(nsprMode & PR_CREATE_FILE))
          return NS_FILE_RESULT(inFile.Error());
    err = noErr;
#if DEBUG
    const OSType kCreator = 'CWIE';
#else
    const OSType kCreator = 'MOSS';
#endif
    // Resolve the alias to the original file.
    nsFileSpec original = inFile;
    PRBool ignoredResult;
    original.ResolveSymlink(ignoredResult);
    const FSSpec& spec = original.operator const FSSpec&();
    if (nsprMode & PR_CREATE_FILE) {
        // In order to get the right file type/creator, do it with an nsILocalFileMac
        // Don't propagate any errors in doing this. If any error, just use FSpCreate.
        FSSpec nonConstSpec = spec;
        nsCOMPtr<nsILocalFileMac> macFile;
        nsresult res = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_FALSE, getter_AddRefs(macFile));
        if (NS_SUCCEEDED(res)) {
            nsCOMPtr<nsIFile> asFile(do_QueryInterface(macFile, &res));
            if (NS_SUCCEEDED(res)) {
                res = asFile->Create(nsIFile::NORMAL_FILE_TYPE, 0);
                if (res == NS_ERROR_FILE_ALREADY_EXISTS)
                    res = NS_OK;
            }
        }
        if (NS_FAILED(res))
            err = FSpCreate(&spec, kCreator, 'TEXT', 0);
    }

    if (err == dupFNErr)
        err = noErr;
    if (err != noErr)
        return NS_FILE_RESULT(err);
    
    SInt8 perm;
    if (nsprMode & PR_RDWR)
       perm = fsRdWrPerm;
    else if (nsprMode & PR_WRONLY)
       perm = fsWrPerm;
    else
       perm = fsRdPerm;

    short refnum;
    err = FSpOpenDF(&spec, perm, &refnum);

    if (err == noErr && (nsprMode & PR_TRUNCATE))
        err = ::SetEOF(refnum, 0);
    if (err == noErr && (nsprMode & PR_APPEND))
        err = SetFPos(refnum, fsFromLEOF, 0);
    if (err != noErr)
        return NS_FILE_RESULT(err);

    if ((mFileDesc = PR_ImportFile(refnum)) == 0)
        return NS_FILE_RESULT(PR_GetError());
#else
    //    Platforms other than Macintosh...
    //  Another bug in NSPR: Mac PR_Open assumes a unix style path, but Win PR_Open assumes
    //  a windows path.
    if ((mFileDesc = PR_Open((const char*)nsFileSpec(inFile), nsprMode, accessMode)) == 0)
        return NS_FILE_RESULT(PR_GetError());
#endif
     mNSPRMode = nsprMode;
     mLength = PR_Available(mFileDesc);
     return NS_OK;
} // FileImpl::Open

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP FileImpl::Read ( char *  aBuf,
PRUint32  aCount,
PRUint32 aReadCount 
)

Definition at line 361 of file nsIFileStream.cpp.

{
    NS_PRECONDITION(aBuf != nsnull, "null ptr");
    if (!aBuf)
        return NS_ERROR_NULL_POINTER;
    NS_PRECONDITION(aReadCount != nsnull, "null ptr");
    if (!aReadCount)
        return NS_ERROR_NULL_POINTER;
    if (!mFileDesc)
        return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
    if (mFailed)
        return NS_ERROR_FAILURE;
    PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount);
    if (bytesRead < 0)
    {
        *aReadCount = 0;
        mFailed = PR_TRUE;
        return NS_FILE_RESULT(PR_GetError());
    }
    else if (bytesRead == 0)
    {
        mEOF = PR_TRUE;
    }
    *aReadCount = bytesRead;
    return NS_OK;
}
unsigned long nsIInputStream::read ( in charPtr  aBuf,
in unsigned long  aCount 
) [inherited]

Read data from the stream.

Parameters:
aBufthe buffer into which the data is to be read
aCountthe maximum number of bytes to be read
Returns:
number of bytes read (may be less than aCount).
0 if reached end of file
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif reading from the input stream would block the calling thread (non-blocking mode only)
<other-error>on failure
NS_IMETHODIMP FileImpl::ReadSegments ( nsWriteSegmentFun  writer,
void closure,
PRUint32  count,
PRUint32 _retval 
)

Definition at line 390 of file nsIFileStream.cpp.

{
    NS_NOTREACHED("ReadSegments");
    return NS_ERROR_NOT_IMPLEMENTED;
}
unsigned long nsIInputStream::readSegments ( in nsWriteSegmentFun  aWriter,
in voidPtr  aClosure,
in unsigned long  aCount 
) [inherited]

Low-level read method that has access to the stream's underlying buffer.

The writer function may be called multiple times for segmented buffers. ReadSegments is expected to keep calling the writer until either there is nothing left to read or the writer returns an error. ReadSegments should not call the writer with zero bytes to consume.

Parameters:
aWriterthe "consumer" of the data to be read
aClosureopaque parameter passed to writer
aCountthe maximum number of bytes to be read
Returns:
number of bytes read (may be less than aCount)
0 if reached end of file (or if aWriter refused to consume data)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif reading from the input stream would block the calling thread (non-blocking mode only)
<other-error>on failure

NOTE: this function may be unimplemented if a stream has no underlying buffer (e.g., socket input stream).

void nsISeekableStream::seek ( in long  whence,
in long long  offset 
) [inherited]

seek

This method moves the stream offset of the steam implementing this interface.

Parameters:
whencespecifies how to interpret the 'offset' parameter in setting the stream offset associated with the implementing stream.
offsetspecifies a value, in bytes, that is used in conjunction with the 'whence' parameter to set the stream offset of the implementing stream. A negative value causes seeking in the reverse direction.
NS_IMETHODIMP FileImpl::SetAtEOF ( PRBool  inAtEOF) [virtual]

Implements nsIRandomAccessStore.

Definition at line 541 of file nsIFileStream.cpp.

{
    mEOF = inAtEOF;
    return NS_OK;
}

setEOF

This method truncates the stream at the current offset.

tell

This method reports the current offset, in bytes, from the start of the stream.

NS_IMETHODIMP FileImpl::Write ( const char *  aBuf,
PRUint32  aCount,
PRUint32 aWriteCount 
)

Definition at line 397 of file nsIFileStream.cpp.

{
    NS_PRECONDITION(aBuf != nsnull, "null ptr");
    NS_PRECONDITION(aWriteCount != nsnull, "null ptr");
                    
    *aWriteCount = 0;

#ifdef XP_MAC
    // Calling PR_Write on stdout is sure suicide.
    if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
    {
        std::cout.write(aBuf, aCount);
        *aWriteCount = aCount;
        return NS_OK;
    }
#endif
    if (!mFileDesc)
        return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
    if (mFailed)
       return NS_ERROR_FAILURE;

    if (!mGotBuffers)
    {
        nsresult rv = AllocateBuffers(kOuputBufferSegmentSize, kOuputBufferMaxSize);
        if (NS_FAILED(rv))
          return rv;        // try to write non-buffered?
    }
    
    PRUint32 bufOffset = 0;
    PRUint32 currentWrite = 0;
    while (aCount > 0) 
    {
        if (mWriteCursor == nsnull || mWriteCursor == mWriteLimit)
        {
            char* seg = mOutBuffer.AppendNewSegment();
            if (seg == nsnull) 
            {
                // buffer is full, try again
                InternalFlush(PR_FALSE);
                seg = mOutBuffer.AppendNewSegment();
                if (seg == nsnull)
                    return NS_ERROR_OUT_OF_MEMORY;
            }
            mWriteCursor = seg;
            mWriteLimit  = seg + mOutBuffer.GetSegmentSize();
        }
        
        // move
        currentWrite = mWriteLimit - mWriteCursor;
        
        if (aCount < currentWrite)
            currentWrite = aCount;

        memcpy(mWriteCursor, (aBuf + bufOffset), currentWrite);
        
        mWriteCursor += currentWrite;  
        
        aCount    -= currentWrite;
        bufOffset += currentWrite;
        *aWriteCount += currentWrite;
    }
    
    return NS_OK;
}

Here is the call graph for this function:

unsigned long nsIOutputStream::write ( in string  aBuf,
in unsigned long  aCount 
) [inherited]

Write data into the stream.

Parameters:
aBufthe buffer containing the data to be written
aCountthe maximum number of bytes to be written
Returns:
number of bytes written (may be less than aCount)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif writing to the output stream would block the calling thread (non-blocking mode only)
<other-error>on failure
NS_IMETHODIMP FileImpl::WriteFrom ( nsIInputStream inStr,
PRUint32  count,
PRUint32 _retval 
)

Definition at line 476 of file nsIFileStream.cpp.

{
    return inStr->ReadSegments(nsWriteSegmentToFile, nsnull, count, result);
}

Here is the call graph for this function:

unsigned long nsIOutputStream::writeFrom ( in nsIInputStream  aFromStream,
in unsigned long  aCount 
) [inherited]

Writes data into the stream from an input stream.

Parameters:
aFromStreamthe stream containing the data to be written
aCountthe maximum number of bytes to be written
Returns:
number of bytes written (may be less than aCount)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif writing to the output stream would block the calling thread (non-blocking mode only)
<other-error>on failure

NOTE: This method is defined by this interface in order to allow the output stream to efficiently copy the data from the input stream into its internal buffer (if any). If this method was provided as an external facility, a separate char* buffer would need to be used in order to call the output stream's other Write method.

NS_IMETHODIMP FileImpl::WriteSegments ( nsReadSegmentFun  reader,
void closure,
PRUint32  count,
PRUint32 _retval 
)

Definition at line 482 of file nsIFileStream.cpp.

{
    NS_NOTREACHED("WriteSegments");
    return NS_ERROR_NOT_IMPLEMENTED;
}
unsigned long nsIOutputStream::writeSegments ( in nsReadSegmentFun  aReader,
in voidPtr  aClosure,
in unsigned long  aCount 
) [inherited]

Low-level write method that has access to the stream's underlying buffer.

The reader function may be called multiple times for segmented buffers. WriteSegments is expected to keep calling the reader until either there is nothing left to write or the reader returns an error. WriteSegments should not call the reader with zero bytes to provide.

Parameters:
aReaderthe "provider" of the data to be written
aClosureopaque parameter passed to reader
aCountthe maximum number of bytes to be written
Returns:
number of bytes written (may be less than aCount)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif writing to the output stream would block the calling thread (non-blocking mode only)
<other-error>on failure

NOTE: this function may be unimplemented if a stream has no underlying buffer (e.g., socket output stream).


Member Data Documentation

PRBool FileImpl::mEOF [protected]

Definition at line 113 of file nsIFileStream.cpp.

Definition at line 112 of file nsIFileStream.cpp.

Definition at line 110 of file nsIFileStream.cpp.

Definition at line 116 of file nsIFileStream.cpp.

Definition at line 114 of file nsIFileStream.cpp.

int FileImpl::mNSPRMode [protected]

Definition at line 111 of file nsIFileStream.cpp.

Definition at line 117 of file nsIFileStream.cpp.

char* FileImpl::mWriteCursor [protected]

Definition at line 118 of file nsIFileStream.cpp.

char* FileImpl::mWriteLimit [protected]

Definition at line 119 of file nsIFileStream.cpp.

Definition at line 62 of file nsISeekableStream.idl.

Definition at line 68 of file nsISeekableStream.idl.

Definition at line 56 of file nsISeekableStream.idl.


The documentation for this class was generated from the following file: