Wed, 31 Dec 2014 06:55:46 +0100
Added tag TORBROWSER_REPLICA for changeset 6474c204b198
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | // A decoder for Mac Bin Hex 4.0. |
michael@0 | 7 | |
michael@0 | 8 | // This decoder is currently only intended to be used on NON-Mac platforms. It isn't hooked up to |
michael@0 | 9 | // code which would actually save the file to disk. As a result, we can't leverage the resource fork. |
michael@0 | 10 | // This makes this decoder most unhelpful for the Mac. Our assumption is that if you save a bin hex file |
michael@0 | 11 | // on the mac and try to open it, stuffit or some other tool is already going to be on the Mac which knows how |
michael@0 | 12 | // to handle bin hex. On windows and unix, that's not the case. We need client code to strip out the data fork. |
michael@0 | 13 | // So this decoder currently just strips out the data fork. |
michael@0 | 14 | |
michael@0 | 15 | // Note: it's possible that we can eventually turn this decoder into both a decoder and into a file stream (much |
michael@0 | 16 | // like the apple double decoder) so on the Mac, if we are saving to disk, we can invoke the decoder as a file stream |
michael@0 | 17 | // and it will process the resource fork and do the right magic. |
michael@0 | 18 | |
michael@0 | 19 | #ifndef nsBinHexDecoder_h__ |
michael@0 | 20 | #define nsBinHexDecoder_h__ |
michael@0 | 21 | |
michael@0 | 22 | #include "nsIStreamConverter.h" |
michael@0 | 23 | #include "nsIChannel.h" |
michael@0 | 24 | #include "nsIOutputStream.h" |
michael@0 | 25 | #include "nsIInputStream.h" |
michael@0 | 26 | |
michael@0 | 27 | #include "nsCOMPtr.h" |
michael@0 | 28 | #include "nsString.h" |
michael@0 | 29 | |
michael@0 | 30 | #define NS_BINHEXDECODER_CID \ |
michael@0 | 31 | { /* 301DEA42-6850-4cda-8945-81F7DBC2186B */ \ |
michael@0 | 32 | 0x301dea42, 0x6850, 0x4cda, \ |
michael@0 | 33 | { 0x89, 0x45, 0x81, 0xf7, 0xdb, 0xc2, 0x18, 0x6b } \ |
michael@0 | 34 | } |
michael@0 | 35 | |
michael@0 | 36 | typedef struct _binhex_header |
michael@0 | 37 | { |
michael@0 | 38 | uint32_t type, creator; |
michael@0 | 39 | uint16_t flags; |
michael@0 | 40 | int32_t dlen, rlen; |
michael@0 | 41 | } binhex_header; |
michael@0 | 42 | |
michael@0 | 43 | typedef union |
michael@0 | 44 | { |
michael@0 | 45 | unsigned char c[4]; |
michael@0 | 46 | uint32_t val; |
michael@0 | 47 | } longbuf; |
michael@0 | 48 | |
michael@0 | 49 | #define BINHEX_STATE_START 0 |
michael@0 | 50 | #define BINHEX_STATE_FNAME 1 |
michael@0 | 51 | #define BINHEX_STATE_HEADER 2 |
michael@0 | 52 | #define BINHEX_STATE_HCRC 3 |
michael@0 | 53 | #define BINHEX_STATE_DFORK 4 |
michael@0 | 54 | #define BINHEX_STATE_DCRC 5 |
michael@0 | 55 | #define BINHEX_STATE_RFORK 6 |
michael@0 | 56 | #define BINHEX_STATE_RCRC 7 |
michael@0 | 57 | #define BINHEX_STATE_FINISH 8 |
michael@0 | 58 | #define BINHEX_STATE_DONE 9 |
michael@0 | 59 | /* #define BINHEX_STATE_ERROR 10 */ |
michael@0 | 60 | |
michael@0 | 61 | class nsBinHexDecoder : public nsIStreamConverter |
michael@0 | 62 | { |
michael@0 | 63 | public: |
michael@0 | 64 | // nsISupports methods |
michael@0 | 65 | NS_DECL_ISUPPORTS |
michael@0 | 66 | |
michael@0 | 67 | // nsIStreamConverter methods |
michael@0 | 68 | NS_DECL_NSISTREAMCONVERTER |
michael@0 | 69 | |
michael@0 | 70 | // nsIStreamListener methods |
michael@0 | 71 | NS_DECL_NSISTREAMLISTENER |
michael@0 | 72 | |
michael@0 | 73 | // nsIRequestObserver methods |
michael@0 | 74 | NS_DECL_NSIREQUESTOBSERVER |
michael@0 | 75 | |
michael@0 | 76 | nsBinHexDecoder(); |
michael@0 | 77 | |
michael@0 | 78 | protected: |
michael@0 | 79 | virtual ~nsBinHexDecoder(); |
michael@0 | 80 | |
michael@0 | 81 | int16_t GetNextChar(uint32_t numBytesInBuffer); |
michael@0 | 82 | nsresult ProcessNextChunk(nsIRequest * aRequest, nsISupports * aContext, uint32_t numBytesInBuffer); |
michael@0 | 83 | nsresult ProcessNextState(nsIRequest * aRequest, nsISupports * aContext); |
michael@0 | 84 | nsresult DetectContentType(nsIRequest * aRequest, const nsAFlatCString &aFilename); |
michael@0 | 85 | |
michael@0 | 86 | protected: |
michael@0 | 87 | nsCOMPtr<nsIStreamListener> mNextListener; |
michael@0 | 88 | |
michael@0 | 89 | // the input and output streams form a pipe...they need to be passed around together.. |
michael@0 | 90 | nsCOMPtr<nsIOutputStream> mOutputStream; // output stream |
michael@0 | 91 | nsCOMPtr<nsIInputStream> mInputStream; |
michael@0 | 92 | |
michael@0 | 93 | int16_t mState; /* current state */ |
michael@0 | 94 | uint16_t mCRC; /* cumulative CRC */ |
michael@0 | 95 | uint16_t mFileCRC; /* CRC value from file */ |
michael@0 | 96 | longbuf mOctetBuf; /* buffer for decoded 6-bit values */ |
michael@0 | 97 | int16_t mOctetin; /* current input position in octetbuf */ |
michael@0 | 98 | int16_t mDonePos; /* ending position in octetbuf */ |
michael@0 | 99 | int16_t mInCRC; /* flag set when reading a CRC */ |
michael@0 | 100 | |
michael@0 | 101 | // Bin Hex Header Information |
michael@0 | 102 | binhex_header mHeader; |
michael@0 | 103 | nsCString mName; /* fsspec for the output file */ |
michael@0 | 104 | |
michael@0 | 105 | // unfortunately we are going to need 2 8K buffers here. One for the data we are currently digesting. Another |
michael@0 | 106 | // for the outgoing decoded data. I tried getting them to share a buffer but things didn't work out so nicely. |
michael@0 | 107 | char * mDataBuffer; // temporary holding pen for the incoming data. |
michael@0 | 108 | char * mOutgoingBuffer; // temporary holding pen for the incoming data. |
michael@0 | 109 | uint32_t mPosInDataBuffer; |
michael@0 | 110 | |
michael@0 | 111 | unsigned char mRlebuf; /* buffer for last run length encoding value */ |
michael@0 | 112 | |
michael@0 | 113 | uint32_t mCount; /* generic counter */ |
michael@0 | 114 | int16_t mMarker; /* flag indicating maker */ |
michael@0 | 115 | |
michael@0 | 116 | int32_t mPosInbuff; /* the index of the inbuff. */ |
michael@0 | 117 | int32_t mPosOutputBuff; /* the position of the out buff. */ |
michael@0 | 118 | }; |
michael@0 | 119 | |
michael@0 | 120 | #endif /* nsBinHexDecoder_h__ */ |