зеркало из https://github.com/mozilla/pjs.git
Created helper class nsZipRead to hold read state information. That way
one nsJAR can support multiple input streams. r=norris
This commit is contained in:
Родитель
209ec05bae
Коммит
6bf8a92a61
|
@ -43,13 +43,11 @@
|
|||
nsJAR::nsJAR()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mInputStream = nsnull;
|
||||
}
|
||||
|
||||
|
||||
nsJAR::~nsJAR()
|
||||
{
|
||||
NS_IF_RELEASE(mInputStream);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsJAR, nsIZip, nsIJAR);
|
||||
|
@ -98,12 +96,8 @@ nsJAR::GetInputStream(const char *aFilename, nsIInputStream **_retval)
|
|||
rv = is->Init(&mZip, aFilename);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
NS_IF_RELEASE(mInputStream);
|
||||
mInputStream = (nsIInputStream*)is;
|
||||
NS_ADDREF(mInputStream); // because this holds a reference to the InputStream
|
||||
|
||||
*_retval = mInputStream;
|
||||
NS_ADDREF(*_retval); // for the reference passed to the caller
|
||||
*_retval = (nsIInputStream*)is;
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,10 +60,6 @@ class nsJAR : public nsIJAR
|
|||
private:
|
||||
|
||||
nsZipArchive mZip;
|
||||
// Need a pointer to the JARInputStream because nsJAR currently supports
|
||||
// only one input stream at a time. We need a reference to enforce this.
|
||||
// When multiple simultaneous input streams are implemented, this can go away.
|
||||
nsIInputStream* mInputStream;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ nsJARInputStream::Available(PRUint32 *_retval)
|
|||
if (mZip == 0)
|
||||
*_retval = 0;
|
||||
else
|
||||
*_retval = mZip->Available();
|
||||
*_retval = mZip->Available(mReadInfo);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ nsJARInputStream::Read(char* buf, PRUint32 count, PRUint32 *_retval)
|
|||
*_retval = 0;
|
||||
else
|
||||
{
|
||||
if( (mZip->Read(buf, count, _retval)) != ZIP_OK )
|
||||
if( (mZip->Read(mReadInfo, buf, count, _retval)) != ZIP_OK )
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,8 @@ nsJARInputStream::Read(char* buf, PRUint32 count, PRUint32 *_retval)
|
|||
NS_IMETHODIMP
|
||||
nsJARInputStream::Close()
|
||||
{
|
||||
// In the future, this should tell mZip to free resources associated with reading
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
delete mReadInfo;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -72,7 +72,8 @@ nsJARInputStream::Init(nsZipArchive* aZip, const char* aFilename)
|
|||
if (aZip == 0 || aFilename == nsnull)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
mZip = aZip;
|
||||
PRInt32 result = mZip->ReadInit(aFilename);
|
||||
PRInt32 result;
|
||||
result = mZip->ReadInit(aFilename, &mReadInfo);
|
||||
if (result != ZIP_OK)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
|
@ -95,15 +96,15 @@ nsJARInputStream::Create(nsISupports* ignored, const nsIID& aIID, void* *aResult
|
|||
// nsJARInputStream constructor and destructor
|
||||
//----------------------------------------------
|
||||
|
||||
nsJARInputStream::nsJARInputStream()
|
||||
nsJARInputStream::nsJARInputStream(): mZip(0), mReadInfo(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mZip = 0;
|
||||
}
|
||||
|
||||
nsJARInputStream::~nsJARInputStream()
|
||||
{
|
||||
// In the future, this should tell mZip to free up resources associated with reading.
|
||||
if (mReadInfo != 0)
|
||||
delete mReadInfo;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ class nsJARInputStream : public nsIInputStream
|
|||
private:
|
||||
|
||||
nsZipArchive* mZip;
|
||||
nsZipRead* mReadInfo;
|
||||
};
|
||||
|
||||
#endif /* nsJAR_h__ */
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#endif /* STANDALONE */
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/stat.h>
|
||||
#elif defined(XP_PC)
|
||||
#include <io.h>
|
||||
|
@ -292,27 +292,33 @@ PRInt32 nsZipArchive::OpenArchive( const char * aArchiveName )
|
|||
//---------------------------------------------
|
||||
// nsZipArchive::ReadInit
|
||||
//---------------------------------------------
|
||||
PRInt32 nsZipArchive::ReadInit( const char* aFilename )
|
||||
PRInt32 nsZipArchive::ReadInit(const char* aFilename, nsZipRead** aRead)
|
||||
{
|
||||
PRInt32 status;
|
||||
//-- Parameter validity check
|
||||
if (aFilename == 0)
|
||||
if (aFilename == 0 || aRead == 0)
|
||||
return ZIP_ERR_PARAM;
|
||||
|
||||
PRInt32 result;
|
||||
|
||||
//-- find item and seek to file position
|
||||
status = ReadInitImpl(aFilename, &mCurItem);
|
||||
if (status != ZIP_OK) return status;
|
||||
mCurPos = 0; // Signifies beginning of item
|
||||
nsZipItem* item;
|
||||
result = ReadInitImpl(aFilename, &item);
|
||||
if (result != ZIP_OK) return result;
|
||||
|
||||
//-- Create nsZipRead object
|
||||
*aRead = new nsZipRead(this, item);
|
||||
if (aRead == 0)
|
||||
return ZIP_ERR_MEMORY;
|
||||
|
||||
//-- If file is deflated, do the inflation now.
|
||||
// We save the complete inflated item in mInflatedFileBuffer
|
||||
// to be copied later.
|
||||
if (mCurItem->compression == DEFLATED)
|
||||
if (item->compression == DEFLATED)
|
||||
{
|
||||
PR_FREEIF(mInflatedFileBuffer);
|
||||
mInflatedFileBuffer = (char*)PR_Malloc(mCurItem->realsize);
|
||||
status = InflateItem( mCurItem, 0, mInflatedFileBuffer);
|
||||
if (status != ZIP_OK) return status;
|
||||
char* buf = (char*)PR_Malloc(item->realsize);
|
||||
result = InflateItem(item, 0, buf);
|
||||
if (result != ZIP_OK) return result;
|
||||
(*aRead)->mInflatedFileBuffer = buf;
|
||||
}
|
||||
|
||||
return ZIP_OK;
|
||||
|
@ -322,32 +328,30 @@ PRInt32 nsZipArchive::ReadInit( const char* aFilename )
|
|||
//---------------------------------------------
|
||||
// nsZipArchive::Read
|
||||
//---------------------------------------------
|
||||
PRInt32 nsZipArchive::Read(char* aBuf,
|
||||
PRInt32 nsZipArchive::Read(nsZipRead* aRead, char* aBuf,
|
||||
PRUint32 aCount, PRUint32* aBytesRead)
|
||||
{
|
||||
//-- Parameter validity check
|
||||
if (aBuf == 0 || aBytesRead == 0)
|
||||
/*
|
||||
* Note the nsZipRead passed in must have been created
|
||||
* by this nsZipArchive.
|
||||
*/
|
||||
if (aBytesRead == 0 || aRead == 0 || aBuf == 0 ||
|
||||
aRead->mArchive != this)
|
||||
return ZIP_ERR_PARAM;
|
||||
|
||||
//-- Make sure we've run ReadInit already
|
||||
if (mCurItem == 0)
|
||||
{
|
||||
*aBytesRead = 0;
|
||||
return ZIP_ERR_GENERAL;
|
||||
}
|
||||
|
||||
//-- extract the file using appropriate method
|
||||
switch( mCurItem->compression )
|
||||
switch( aRead->mItem->compression )
|
||||
{
|
||||
case STORED:
|
||||
//-- Read from the zip file directly into the caller's buffer
|
||||
return ReadItem( mCurItem, aBuf, &mCurPos, aCount, aBytesRead);
|
||||
return ReadItem( aRead->mItem, aBuf, &(aRead->mCurPos), aCount, aBytesRead);
|
||||
|
||||
case DEFLATED:
|
||||
//-- We've already done the inflation; copy from mInflatedFileBuffer
|
||||
// into the caller's buffer
|
||||
return ReadInflatedItem( mCurItem, mInflatedFileBuffer, aBuf,
|
||||
&mCurPos, aCount, aBytesRead);
|
||||
return ReadInflatedItem( aRead->mItem, aRead->mInflatedFileBuffer, aBuf,
|
||||
&(aRead->mCurPos), aCount, aBytesRead);
|
||||
|
||||
default:
|
||||
//-- unsupported compression type
|
||||
|
@ -359,14 +363,17 @@ PRInt32 nsZipArchive::Read(char* aBuf,
|
|||
//---------------------------------------------
|
||||
// nsZipArchive::Available
|
||||
//---------------------------------------------
|
||||
PRUint32 nsZipArchive::Available()
|
||||
PRUint32 nsZipArchive::Available(nsZipRead* aRead)
|
||||
{
|
||||
if (mCurItem == 0)
|
||||
if (aRead == 0)
|
||||
return 0;
|
||||
else if (mCurItem->compression == DEFLATED)
|
||||
return mCurItem->realsize - mCurPos;
|
||||
|
||||
nsZipItem* item = aRead->mItem;
|
||||
|
||||
if (item->compression == DEFLATED)
|
||||
return item->realsize - aRead->mCurPos;
|
||||
else
|
||||
return mCurItem->size - mCurPos;
|
||||
return item->size - aRead->mCurPos;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
|
@ -655,7 +662,6 @@ PRInt32 nsZipArchive::BuildFileList()
|
|||
{
|
||||
item->name[namelen] = 0;
|
||||
item->namelen = namelen;
|
||||
|
||||
item->headerloc = xtolong( Central.localhdr_offset );
|
||||
|
||||
//-- seek to local header
|
||||
|
@ -793,6 +799,11 @@ PRInt32 nsZipArchive::ReadItem(const nsZipItem* aItem, char* aBuf,
|
|||
PRUint32 chunk;
|
||||
PR_ASSERT(aBuf != 0 && aItem != 0);
|
||||
|
||||
// Seek to position in file
|
||||
if ( PR_Seek( mFd, (PROffset32)(aItem->offset + aCurPos), PR_SEEK_SET ) !=
|
||||
(PROffset32)(aItem->offset + aCurPos) )
|
||||
return ZIP_ERR_CORRUPT;
|
||||
|
||||
//-- Read from file
|
||||
chunk = (aCount <= ((aItem->size) - *aCurPos) ) ? aCount
|
||||
: ((aItem->size) - *aCurPos);
|
||||
|
@ -984,8 +995,8 @@ PRInt32 nsZipArchive::InflateItem( const nsZipItem* aItem, const char* aOutname,
|
|||
//-- copy inflated buffer to our big buffer
|
||||
// Assertion makes sure we don't overflow bigBuf
|
||||
PR_ASSERT( outpos + ZIP_BUFLEN <= bigBufSize);
|
||||
for (PRUint32 c = 0; c < ZIP_BUFLEN; c++)
|
||||
bigBuf[outpos + c] = (char)outbuf[c];
|
||||
char* copyStart = bigBuf + outpos;
|
||||
memcpy(copyStart, outbuf, ZIP_BUFLEN);
|
||||
}
|
||||
outpos = zs.total_out;
|
||||
zs.next_out = outbuf;
|
||||
|
@ -1019,8 +1030,8 @@ PRInt32 nsZipArchive::InflateItem( const nsZipItem* aItem, const char* aOutname,
|
|||
else
|
||||
{
|
||||
PR_ASSERT( (outpos + chunk) <= bigBufSize );
|
||||
for (PRUint32 c = 0; c < chunk; c++)
|
||||
bigBuf[outpos + c] = (char)outbuf[c];
|
||||
char* copyStart = bigBuf + outpos;
|
||||
memcpy(copyStart, outbuf, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1064,13 +1075,11 @@ PRInt32 nsZipArchive::ReadInflatedItem( nsZipItem* aItem,
|
|||
//-- Set up the copy
|
||||
PRUint32 bigBufSize = aItem->realsize;
|
||||
PRUint32 c = ((*aCurPos + count) < bigBufSize) ? count : bigBufSize - *aCurPos;
|
||||
*actual = c;
|
||||
char* src = inflatedBuf + (*aCurPos);
|
||||
char* dest = outbuf;
|
||||
|
||||
//-- Do the copy and record number of bytes copied
|
||||
for( ; c; dest++, src++, c-- )
|
||||
*dest = *src;
|
||||
memcpy(outbuf, src, c);
|
||||
*actual = c;
|
||||
*aCurPos += *actual;
|
||||
|
||||
return ZIP_OK;
|
||||
|
@ -1089,10 +1098,6 @@ nsZipArchive::nsZipArchive()
|
|||
mFiles[i] = 0;
|
||||
}
|
||||
|
||||
// initialize internal state
|
||||
mCurItem = 0;
|
||||
mInflatedFileBuffer = 0;
|
||||
mCurPos = 0;
|
||||
}
|
||||
|
||||
nsZipArchive::~nsZipArchive()
|
||||
|
@ -1114,9 +1119,6 @@ nsZipArchive::~nsZipArchive()
|
|||
pItem = mFiles[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Free inflated file buffer if necessary
|
||||
PR_FREEIF(mInflatedFileBuffer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1134,8 +1136,21 @@ nsZipItem::~nsZipItem()
|
|||
delete [] name;
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
// nsZipRead constructor and destructor
|
||||
//------------------------------------------
|
||||
|
||||
nsZipRead::nsZipRead( nsZipArchive* aZipArchive, nsZipItem* aZipItem )
|
||||
: mArchive(aZipArchive),
|
||||
mItem(aZipItem),
|
||||
mCurPos(0),
|
||||
mInflatedFileBuffer(0)
|
||||
{}
|
||||
|
||||
nsZipRead::~nsZipRead()
|
||||
{
|
||||
PR_FREEIF(mInflatedFileBuffer);
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
// nsZipFind constructor and destructor
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
|
||||
class nsZipFind;
|
||||
class nsZipRead;
|
||||
|
||||
/**
|
||||
* nsZipItem -- a helper class for nsZipArchive
|
||||
|
@ -106,9 +107,10 @@ public:
|
|||
* before any calls to Read or Available
|
||||
*
|
||||
* @param aFilename name of item in file
|
||||
* @param (out) a structure used by Read and Available
|
||||
* @return status code
|
||||
*/
|
||||
PRInt32 ReadInit( const char* aFilename );
|
||||
PRInt32 ReadInit( const char* aFilename, nsZipRead** aRead);
|
||||
|
||||
/**
|
||||
* Read
|
||||
|
@ -116,22 +118,24 @@ public:
|
|||
* Read from the item specified to ReadInit. ReadInit must be
|
||||
* called first.
|
||||
*
|
||||
* @param aRead the structure returned by ReadInit
|
||||
* @param buf buffer to write data into.
|
||||
* @param count number of bytes to read
|
||||
* @param actual (out) number of bytes read
|
||||
* @return status code
|
||||
*/
|
||||
PRInt32 Read(char* buf, PRUint32 count, PRUint32* actual );
|
||||
PRInt32 Read(nsZipRead* aRead, char* buf, PRUint32 count, PRUint32* actual );
|
||||
|
||||
/**
|
||||
* Available
|
||||
*
|
||||
* Returns the number of bytes left to be read from the
|
||||
* item specified to ReadInit. ReadInit must be called first,
|
||||
* otherwise Available returns zero.
|
||||
* item specified to ReadInit. ReadInit must be called first.
|
||||
*
|
||||
* @param aRead the structure returned by ReadInit
|
||||
* @return the number of bytes still to be read
|
||||
*/
|
||||
PRUint32 Available();
|
||||
PRUint32 Available(nsZipRead* aRead);
|
||||
|
||||
/**
|
||||
* ExtractFile
|
||||
|
@ -169,10 +173,7 @@ private:
|
|||
|
||||
PRFileDesc *mFd;
|
||||
nsZipItem* mFiles[ZIP_TABSIZE];
|
||||
PRUint32 mCurPos; // Used by ReadInit,Read, and Available
|
||||
nsZipItem* mCurItem;
|
||||
char* mInflatedFileBuffer; // Filled by InflateItem, read by ReadInflatedItem
|
||||
|
||||
|
||||
//--- private methods ---
|
||||
|
||||
nsZipArchive& operator=(const nsZipArchive& rhs); // prevent assignments
|
||||
|
@ -184,7 +185,7 @@ private:
|
|||
|
||||
PRInt32 ReadInitImpl(const char* aFilename, nsZipItem** aItem);
|
||||
PRInt32 ReadItem( const nsZipItem* aItem, char* buf,
|
||||
PRUint32* aCurPos,PRUint32 count, PRUint32* actual );
|
||||
PRUint32* aCurPos, PRUint32 count, PRUint32* actual );
|
||||
PRInt32 CopyItemToDisk( const nsZipItem* aItem, const char* aOutname );
|
||||
PRInt32 InflateItem( const nsZipItem* aItem,
|
||||
const char* aOutname,
|
||||
|
@ -194,7 +195,30 @@ private:
|
|||
PRUint32* aCurPos, PRUint32 count, PRUint32* actual);
|
||||
};
|
||||
|
||||
/**
|
||||
* nsZipRead
|
||||
*
|
||||
* a helper class for nsZipArchive, representing a read in progress
|
||||
*/
|
||||
class nsZipRead
|
||||
{
|
||||
friend class nsZipArchive;
|
||||
|
||||
public:
|
||||
|
||||
nsZipRead( nsZipArchive* aZip, nsZipItem* item );
|
||||
~nsZipRead();
|
||||
|
||||
private:
|
||||
nsZipArchive* mArchive;
|
||||
nsZipItem* mItem;
|
||||
PRUint32 mCurPos;
|
||||
char* mInflatedFileBuffer;
|
||||
|
||||
//-- prevent copies and assignments
|
||||
nsZipRead& operator=(const nsZipRead& rhs);
|
||||
nsZipRead(const nsZipFind& rhs);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче