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