Files
tubestation/modules/libjar/nsJARInputStream.h
Mike Hommey 3b0b47d020 Bug 1355661 - Add support for brotli streams in Jar archives. r=aklotz
Modern compression algorithms are better than zlib both in terms of
space and time. The jar format, used for e.g. omni.ja, addons, etc.
could benefit from using such modern algorithms, but the format only
allows a limited set of compression algorithms.

However, the format in itself is flexible, in that it can be extended
with arbitrary compression algorithms. This breaks compatibility with
programs like unzip, obviously, but we've never promised the files
shipped with Firefox will always remain "valid" zips (which they already
aren't, but they currently work with most zip readers).

With this change, we allow those archives to contain brotli streams,
using an arbitrary large value for the compression type in the Zip local
file header. This only allows to read such archives, but not to produce
them, and, for now, support for brotli streams is kept Nightly-only,
until everything is pieced together and we're happy to ship it.
2017-04-07 14:48:25 +09:00

92 lines
2.8 KiB
C++

/* nsJARInputStream.h
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsJARINPUTSTREAM_h__
#define nsJARINPUTSTREAM_h__
#include "nsIInputStream.h"
#include "nsJAR.h"
#include "nsTArray.h"
#include "mozilla/Attributes.h"
#ifdef MOZ_JAR_BROTLI
struct BrotliStateStruct;
#endif
/*-------------------------------------------------------------------------
* Class nsJARInputStream declaration. This class defines the type of the
* object returned by calls to nsJAR::GetInputStream(filename) for the
* purpose of reading a file item out of a JAR file.
*------------------------------------------------------------------------*/
class nsJARInputStream final : public nsIInputStream
{
public:
nsJARInputStream()
: mOutSize(0)
, mInCrc(0)
, mOutCrc(0)
#ifdef MOZ_JAR_BROTLI
, mBrotliState(nullptr)
#endif
, mNameLen(0)
, mCurPos(0)
, mArrPos(0)
, mMode(MODE_NOTINITED)
{
memset(&mZs, 0, sizeof(z_stream));
}
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
// takes ownership of |fd|, even on failure
nsresult InitFile(nsJAR *aJar, nsZipItem *item);
nsresult InitDirectory(nsJAR *aJar,
const nsACString& aJarDirSpec,
const char* aDir);
private:
~nsJARInputStream() { Close(); }
RefPtr<nsZipHandle> mFd; // handle for reading
uint32_t mOutSize; // inflated size
uint32_t mInCrc; // CRC as provided by the zipentry
uint32_t mOutCrc; // CRC as calculated by me
z_stream mZs; // zip data structure
#ifdef MOZ_JAR_BROTLI
BrotliStateStruct* mBrotliState; // Brotli decoder state
#endif
/* For directory reading */
RefPtr<nsJAR> mJar; // string reference to zipreader
uint32_t mNameLen; // length of dirname
nsCString mBuffer; // storage for generated text of stream
uint32_t mCurPos; // Current position in buffer
uint32_t mArrPos; // current position within mArray
nsTArray<nsCString> mArray; // array of names in (zip) directory
typedef enum {
MODE_NOTINITED,
MODE_CLOSED,
MODE_DIRECTORY,
MODE_INFLATE,
#ifdef MOZ_JAR_BROTLI
MODE_BROTLI,
#endif
MODE_COPY
} JISMode;
JISMode mMode; // Modus of the stream
nsresult ContinueInflate(char* aBuf, uint32_t aCount, uint32_t* aBytesRead);
nsresult ReadDirectory(char* aBuf, uint32_t aCount, uint32_t* aBytesRead);
uint32_t CopyDataToBuffer(char* &aBuffer, uint32_t &aCount);
};
#endif /* nsJARINPUTSTREAM_h__ */