Back to index

lightning-sunbird  0.9+nobinonly
nsBinHexDecoder.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Scott MacGregor <mscott@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 // A decoder for Mac Bin Hex 4.0.
00040 
00041 // This decoder is currently only intended to be used on NON-Mac platforms. It isn't hooked up to 
00042 // code which would actually save the file to disk. As a result, we can't leverage the resource fork.
00043 // This makes this decoder most unhelpful for the Mac. Our assumption is that if you save a bin hex file
00044 // on the mac and try to open it, stuffit or some other tool is already going to be on the Mac which knows how
00045 // to handle bin hex. On windows and unix, that's not the case. We need client code to strip out the data fork. 
00046 // So this decoder currently just strips out the data fork. 
00047 
00048 // Note: it's possible that we can eventually turn this decoder into both a decoder and into a file stream (much
00049 // like the apple double decoder) so on the Mac, if we are saving to disk, we can invoke the decoder as a file stream
00050 // and it will process the resource fork and do the right magic. 
00051 
00052 #ifndef nsBinHexDecoder_h__
00053 #define nsBinHexDecoder_h__
00054 
00055 #include "nsIStreamConverter.h"
00056 #include "nsIChannel.h"
00057 #include "nsIOutputStream.h"
00058 #include "nsIInputStream.h"
00059 
00060 #include "nsCOMPtr.h"
00061 #include "nsString.h"
00062 
00063 #define NS_BINHEXDECODER_CID                        \
00064 { /* 301DEA42-6850-4cda-8945-81F7DBC2186B */         \
00065     0x301dea42, 0x6850, 0x4cda,                      \
00066     { 0x89, 0x45, 0x81, 0xf7, 0xdb, 0xc2, 0x18, 0x6b } \
00067 }
00068 
00069 typedef struct _binhex_header
00070 {
00071        PRUint32      type, creator;
00072        PRUint16  flags;
00073        PRInt32       dlen, rlen;
00074 } binhex_header;
00075 
00076 typedef union 
00077 {
00078        unsigned char c[4];
00079        PRUint32        val;
00080 } longbuf;
00081 
00082 #define BINHEX_STATE_START         0
00083 #define BINHEX_STATE_FNAME         1
00084 #define BINHEX_STATE_HEADER        2
00085 #define BINHEX_STATE_HCRC          3
00086 #define BINHEX_STATE_DFORK         4
00087 #define BINHEX_STATE_DCRC          5
00088 #define BINHEX_STATE_RFORK         6
00089 #define BINHEX_STATE_RCRC          7
00090 #define BINHEX_STATE_FINISH        8
00091 #define BINHEX_STATE_DONE          9
00092 /* #define BINHEX_STATE_ERROR             10 */
00093 
00094 class nsBinHexDecoder : public nsIStreamConverter
00095 {
00096 public:
00097   // nsISupports methods
00098   NS_DECL_ISUPPORTS
00099 
00100   // nsIStreamConverter methods
00101   NS_DECL_NSISTREAMCONVERTER
00102 
00103   // nsIStreamListener methods
00104   NS_DECL_NSISTREAMLISTENER
00105 
00106   // nsIRequestObserver methods
00107   NS_DECL_NSIREQUESTOBSERVER
00108 
00109   nsBinHexDecoder();
00110 
00111 protected:
00112   virtual ~nsBinHexDecoder();
00113 
00114   PRInt16  GetNextChar(PRUint32 numBytesInBuffer);
00115   nsresult ProcessNextChunk(nsIRequest * aRequest, nsISupports * aContext, PRUint32 numBytesInBuffer);
00116   nsresult ProcessNextState(nsIRequest * aRequest, nsISupports * aContext);
00117   nsresult SetContentType(nsIRequest * aRequest, const char * fileName);
00118 
00119 protected:
00120   nsCOMPtr<nsIStreamListener> mNextListener;
00121 
00122   // the input and output streams form a pipe...they need to be passed around together..
00123   nsCOMPtr<nsIOutputStream>     mOutputStream;     // output stream
00124   nsCOMPtr<nsIInputStream>      mInputStream;
00125 
00126   PRInt16   mState;                /* current state */
00127   PRUint16  mCRC; /* cumulative CRC */
00128        PRUint16  mFileCRC;         /* CRC value from file */
00129   longbuf   mOctetBuf;             /* buffer for decoded 6-bit values               */
00130        PRInt16       mOctetin;            /* current input position in octetbuf */
00131        PRInt16       mDonePos;            /* ending position in octetbuf */
00132        PRInt16       mInCRC;                     /* flag set when reading a CRC */
00133 
00134   // Bin Hex Header Information
00135   binhex_header mHeader;
00136   char        mName[64];           /* fsspec for the output file */
00137 
00138   // unfortunately we are going to need 2 8K buffers here. One for the data we are currently digesting. Another
00139   // for the outgoing decoded data. I tried getting them to share a buffer but things didn't work out so nicely.
00140   char * mDataBuffer; // temporary holding pen for the incoming data.
00141   char * mOutgoingBuffer; // temporary holding pen for the incoming data.
00142   PRUint32 mPosInDataBuffer;
00143 
00144        unsigned char mRlebuf;      /* buffer for last run length encoding value */
00145 
00146        PRInt32 mCount;                      /* generic counter */
00147   PRInt16 mMarker;                 /* flag indicating maker */
00148        
00149        PRInt32       mPosInbuff;             /* the index of the inbuff.     */
00150        PRInt32 mPosOutputBuff; /* the position of the out buff.              */
00151 };
00152 
00153 #endif /* nsBinHexDecoder_h__ */