32 #include "kmime_codec_uuencode.h"
38 using namespace KMime;
43 class UUDecoder :
public Decoder {
45 uchar mAnnouncedOctetCount;
46 uchar mCurrentOctetCount;
48 bool mLastWasCRLF : 1;
50 uint mIntoBeginLine : 3;
52 uint mIntoEndLine : 2;
54 void searchForBegin(
const char* & scursor,
const char *
const send );
58 UUDecoder(
bool withCRLF=
false )
59 :
Decoder( withCRLF ), mStepNo(0),
60 mAnnouncedOctetCount(0), mCurrentOctetCount(0),
61 mOutbits(0), mLastWasCRLF(true),
62 mSawBegin(false), mIntoBeginLine(0),
63 mSawEnd(false), mIntoEndLine(0) {}
66 virtual ~UUDecoder() {}
68 bool decode(
const char* & scursor,
const char *
const send,
69 char* & dcursor,
const char *
const dend );
71 bool finish(
char* & ,
const char *
const ) {
return true; }
76 Encoder * UUCodec::makeEncoder(
bool )
const {
80 Decoder * UUCodec::makeDecoder(
bool withCRLF )
const {
81 return new UUDecoder( withCRLF );
91 void UUDecoder::searchForBegin(
const char* & scursor,
const char *
const send ) {
92 static const char begin[] =
"begin\n";
93 static const uint beginLength = 5;
95 assert( !mSawBegin || mIntoBeginLine > 0 );
97 while ( scursor != send ) {
98 uchar ch = *scursor++;
99 if ( ch == begin[mIntoBeginLine] ) {
100 if ( mIntoBeginLine < beginLength ) {
103 if ( mIntoBeginLine == beginLength )
111 }
else if ( mSawBegin ) {
114 kdWarning() <<
"UUDecoder: garbage before \"begin\", resetting parser"
125 static inline uchar uuDecode( uchar c ) {
131 bool UUDecoder::decode(
const char* & scursor,
const char *
const send,
132 char* & dcursor,
const char *
const dend )
135 if ( !mSawBegin || mIntoBeginLine != 0 )
136 searchForBegin( scursor, send );
138 else if ( mSawEnd ) {
143 while ( dcursor != dend && scursor != send ) {
144 uchar ch = *scursor++;
148 if ( mIntoEndLine > 0 ) {
149 static const char end[] =
"end";
150 static const uint endLength = 3;
152 if ( ch == end[mIntoEndLine] ) {
154 if ( mIntoEndLine == endLength ) {
161 kdWarning() <<
"UUDecoder: invalid line octet count looks like \"end\" (mIntoEndLine = " << mIntoEndLine <<
" )!" << endl;
171 if ( mLastWasCRLF ) {
173 mLastWasCRLF =
false;
174 mCurrentOctetCount = 0;
179 else if ( ch > 0x60 )
182 mAnnouncedOctetCount = uuDecode( ch );
183 else if ( ch ==
'\n' )
193 value = uuDecode( ch );
194 else if ( ch ==
'\n' ) {
203 mOutbits = value << 2;
206 if ( mCurrentOctetCount < mAnnouncedOctetCount )
207 *dcursor++ = (char)(mOutbits | value >> 4);
208 ++mCurrentOctetCount;
209 mOutbits = value << 4;
212 if ( mCurrentOctetCount < mAnnouncedOctetCount )
213 *dcursor++ = (char)(mOutbits | value >> 2);
214 ++mCurrentOctetCount;
215 mOutbits = value << 6;
218 if ( mCurrentOctetCount < mAnnouncedOctetCount )
219 *dcursor++ = (char)(mOutbits | value);
220 ++mCurrentOctetCount;
226 mStepNo = (mStepNo + 1) % 4;
229 kdWarning( mCurrentOctetCount == mAnnouncedOctetCount + 1 )
230 <<
"UUDecoder: mismatch between announced ("
231 << mAnnouncedOctetCount <<
") and actual line octet count!" << endl;
236 return (scursor == send);
Stateful decoder class, modelled after TQTextDecoder.
Stateful encoder class, modelled after TQTextEncoder.