netwerk/streamconv/converters/nsBinHexDecoder.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

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 #include "nsIOService.h"
michael@0 7 #include "nsBinHexDecoder.h"
michael@0 8 #include "nsIServiceManager.h"
michael@0 9 #include "nsIStreamConverterService.h"
michael@0 10 #include "nsCRT.h"
michael@0 11 #include "nsIPipe.h"
michael@0 12 #include "nsMimeTypes.h"
michael@0 13 #include "netCore.h"
michael@0 14 #include "nsXPIDLString.h"
michael@0 15 #include "prnetdb.h"
michael@0 16 #include "nsIURI.h"
michael@0 17 #include "nsIURL.h"
michael@0 18
michael@0 19 #include "nsIMIMEService.h"
michael@0 20 #include "nsMimeTypes.h"
michael@0 21 #include <algorithm>
michael@0 22
michael@0 23 nsBinHexDecoder::nsBinHexDecoder() :
michael@0 24 mState(0), mCRC(0), mFileCRC(0), mOctetin(26),
michael@0 25 mDonePos(3), mInCRC(0), mCount(0), mMarker(0), mPosInbuff(0),
michael@0 26 mPosOutputBuff(0)
michael@0 27 {
michael@0 28 mDataBuffer = nullptr;
michael@0 29 mOutgoingBuffer = nullptr;
michael@0 30
michael@0 31 mOctetBuf.val = 0;
michael@0 32 mHeader.type = 0;
michael@0 33 mHeader.creator = 0;
michael@0 34 mHeader.flags = 0;
michael@0 35 mHeader.dlen = 0;
michael@0 36 mHeader.rlen = 0;
michael@0 37 }
michael@0 38
michael@0 39 nsBinHexDecoder::~nsBinHexDecoder()
michael@0 40 {
michael@0 41 if (mDataBuffer)
michael@0 42 nsMemory::Free(mDataBuffer);
michael@0 43 if (mOutgoingBuffer)
michael@0 44 nsMemory::Free(mOutgoingBuffer);
michael@0 45 }
michael@0 46
michael@0 47 NS_IMPL_ADDREF(nsBinHexDecoder)
michael@0 48 NS_IMPL_RELEASE(nsBinHexDecoder)
michael@0 49
michael@0 50 NS_INTERFACE_MAP_BEGIN(nsBinHexDecoder)
michael@0 51 NS_INTERFACE_MAP_ENTRY(nsIStreamConverter)
michael@0 52 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
michael@0 53 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
michael@0 54 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 55 NS_INTERFACE_MAP_END
michael@0 56
michael@0 57
michael@0 58 // The binhex 4.0 decoder table....
michael@0 59
michael@0 60 static const signed char binhex_decode[256] =
michael@0 61 {
michael@0 62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 63 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 64 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1,
michael@0 65 13, 14, 15, 16, 17, 18, 19, -1, 20, 21, -1, -1, -1, -1, -1, -1,
michael@0 66 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
michael@0 67 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, -1, -1, -1, -1,
michael@0 68 48, 49, 50, 51, 52, 53, 54, -1, 55, 56, 57, 58, 59, 60, -1, -1,
michael@0 69 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 71 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 72 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 73 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 74 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 75 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 76 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 77 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
michael@0 78 };
michael@0 79
michael@0 80 #define BHEXVAL(c) (binhex_decode[(unsigned char) c])
michael@0 81
michael@0 82 //////////////////////////////////////////////////////
michael@0 83 // nsIStreamConverter methods...
michael@0 84 //////////////////////////////////////////////////////
michael@0 85
michael@0 86 NS_IMETHODIMP
michael@0 87 nsBinHexDecoder::Convert(nsIInputStream *aFromStream,
michael@0 88 const char *aFromType,
michael@0 89 const char *aToType,
michael@0 90 nsISupports *aCtxt,
michael@0 91 nsIInputStream **aResultStream)
michael@0 92 {
michael@0 93 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 94 }
michael@0 95
michael@0 96 NS_IMETHODIMP
michael@0 97 nsBinHexDecoder::AsyncConvertData(const char *aFromType,
michael@0 98 const char *aToType,
michael@0 99 nsIStreamListener *aListener,
michael@0 100 nsISupports *aCtxt)
michael@0 101 {
michael@0 102 NS_ASSERTION(aListener && aFromType && aToType,
michael@0 103 "null pointer passed into bin hex converter");
michael@0 104
michael@0 105 // hook up our final listener. this guy gets the various On*() calls we want to throw
michael@0 106 // at him.
michael@0 107 //
michael@0 108 mNextListener = aListener;
michael@0 109 return (aListener) ? NS_OK : NS_ERROR_FAILURE;
michael@0 110 }
michael@0 111
michael@0 112 //////////////////////////////////////////////////////
michael@0 113 // nsIStreamListener methods...
michael@0 114 //////////////////////////////////////////////////////
michael@0 115 NS_IMETHODIMP
michael@0 116 nsBinHexDecoder::OnDataAvailable(nsIRequest* request,
michael@0 117 nsISupports *aCtxt,
michael@0 118 nsIInputStream *aStream,
michael@0 119 uint64_t aSourceOffset,
michael@0 120 uint32_t aCount)
michael@0 121 {
michael@0 122 nsresult rv = NS_OK;
michael@0 123
michael@0 124 if (mOutputStream && mDataBuffer && aCount > 0)
michael@0 125 {
michael@0 126 uint32_t numBytesRead = 0;
michael@0 127 while (aCount > 0) // while we still have bytes to copy...
michael@0 128 {
michael@0 129 aStream->Read(mDataBuffer, std::min(aCount, nsIOService::gDefaultSegmentSize - 1), &numBytesRead);
michael@0 130 if (aCount >= numBytesRead)
michael@0 131 aCount -= numBytesRead; // subtract off the number of bytes we just read
michael@0 132 else
michael@0 133 aCount = 0;
michael@0 134
michael@0 135 // Process this new chunk of bin hex data...
michael@0 136 ProcessNextChunk(request, aCtxt, numBytesRead);
michael@0 137 }
michael@0 138 }
michael@0 139
michael@0 140 return rv;
michael@0 141 }
michael@0 142
michael@0 143 nsresult nsBinHexDecoder::ProcessNextState(nsIRequest * aRequest, nsISupports * aContext)
michael@0 144 {
michael@0 145 nsresult status = NS_OK;
michael@0 146 uint16_t tmpcrc, cval;
michael@0 147 unsigned char ctmp, c = mRlebuf;
michael@0 148
michael@0 149 /* do CRC */
michael@0 150 ctmp = mInCRC ? c : 0;
michael@0 151 cval = mCRC & 0xf000;
michael@0 152 tmpcrc = ((uint16_t) (mCRC << 4) | (ctmp >> 4)) ^ (cval | (cval >> 7) | (cval >> 12));
michael@0 153 cval = tmpcrc & 0xf000;
michael@0 154 mCRC = ((uint16_t) (tmpcrc << 4) | (ctmp & 0x0f)) ^ (cval | (cval >> 7) | (cval >> 12));
michael@0 155
michael@0 156 /* handle state */
michael@0 157 switch (mState)
michael@0 158 {
michael@0 159 case BINHEX_STATE_START:
michael@0 160 mState = BINHEX_STATE_FNAME;
michael@0 161 mCount = 0;
michael@0 162
michael@0 163 // c & 63 returns the length of mName. So if we need the length, that's how
michael@0 164 // you can figure it out....
michael@0 165 mName.SetLength(c & 63);
michael@0 166 if (mName.Length() != (c & 63)) {
michael@0 167 /* XXX ProcessNextState/ProcessNextChunk aren't rv checked */
michael@0 168 mState = BINHEX_STATE_DONE;
michael@0 169 }
michael@0 170 break;
michael@0 171
michael@0 172 case BINHEX_STATE_FNAME:
michael@0 173 mName.BeginWriting()[mCount] = c;
michael@0 174
michael@0 175 if (++mCount > mName.Length())
michael@0 176 {
michael@0 177 // okay we've figured out the file name....set the content type on the channel
michael@0 178 // based on the file name AND issue our delayed on start request....
michael@0 179
michael@0 180 DetectContentType(aRequest, mName);
michael@0 181 // now propagate the on start request
michael@0 182 mNextListener->OnStartRequest(aRequest, aContext);
michael@0 183
michael@0 184 mState = BINHEX_STATE_HEADER;
michael@0 185 mCount = 0;
michael@0 186 }
michael@0 187 break;
michael@0 188
michael@0 189 case BINHEX_STATE_HEADER:
michael@0 190 ((char *) &mHeader)[mCount] = c;
michael@0 191 if (++mCount == 18)
michael@0 192 {
michael@0 193 if (sizeof(binhex_header) != 18) /* fix an alignment problem in some OSes */
michael@0 194 {
michael@0 195 char *p = (char *)&mHeader;
michael@0 196 p += 19;
michael@0 197 for (c = 0; c < 8; c++)
michael@0 198 {
michael@0 199 *p = *(p-2);
michael@0 200 --p;
michael@0 201 }
michael@0 202 }
michael@0 203
michael@0 204 mState = BINHEX_STATE_HCRC;
michael@0 205 mInCRC = 1;
michael@0 206 mCount = 0;
michael@0 207 }
michael@0 208 break;
michael@0 209
michael@0 210 case BINHEX_STATE_DFORK:
michael@0 211 case BINHEX_STATE_RFORK:
michael@0 212 mOutgoingBuffer[mPosOutputBuff++] = c;
michael@0 213 if (--mCount == 0)
michael@0 214 {
michael@0 215 /* only output data fork in the non-mac system. */
michael@0 216 if (mState == BINHEX_STATE_DFORK)
michael@0 217 {
michael@0 218 uint32_t numBytesWritten = 0;
michael@0 219 mOutputStream->Write(mOutgoingBuffer, mPosOutputBuff, &numBytesWritten);
michael@0 220 if (int32_t(numBytesWritten) != mPosOutputBuff)
michael@0 221 status = NS_ERROR_FAILURE;
michael@0 222
michael@0 223 // now propagate the data we just wrote
michael@0 224 mNextListener->OnDataAvailable(aRequest, aContext, mInputStream, 0, numBytesWritten);
michael@0 225 }
michael@0 226 else
michael@0 227 status = NS_OK; /* do nothing for resource fork. */
michael@0 228
michael@0 229 mPosOutputBuff = 0;
michael@0 230
michael@0 231 if (status != NS_OK)
michael@0 232 mState = BINHEX_STATE_DONE;
michael@0 233 else
michael@0 234 ++mState;
michael@0 235
michael@0 236 mInCRC = 1;
michael@0 237 }
michael@0 238 else if (mPosOutputBuff >= (int32_t) nsIOService::gDefaultSegmentSize)
michael@0 239 {
michael@0 240 if (mState == BINHEX_STATE_DFORK)
michael@0 241 {
michael@0 242 uint32_t numBytesWritten = 0;
michael@0 243 mOutputStream->Write(mOutgoingBuffer, mPosOutputBuff, &numBytesWritten);
michael@0 244 if (int32_t(numBytesWritten) != mPosOutputBuff)
michael@0 245 status = NS_ERROR_FAILURE;
michael@0 246
michael@0 247 mNextListener->OnDataAvailable(aRequest, aContext, mInputStream, 0, numBytesWritten);
michael@0 248 mPosOutputBuff = 0;
michael@0 249 }
michael@0 250 }
michael@0 251 break;
michael@0 252
michael@0 253 case BINHEX_STATE_HCRC:
michael@0 254 case BINHEX_STATE_DCRC:
michael@0 255 case BINHEX_STATE_RCRC:
michael@0 256 if (!mCount++)
michael@0 257 mFileCRC = (unsigned short) c << 8;
michael@0 258 else
michael@0 259 {
michael@0 260 if ((mFileCRC | c) != mCRC)
michael@0 261 {
michael@0 262 mState = BINHEX_STATE_DONE;
michael@0 263 break;
michael@0 264 }
michael@0 265
michael@0 266 /* passed the CRC check!!!*/
michael@0 267 mCRC = 0;
michael@0 268 if (++mState == BINHEX_STATE_FINISH)
michael@0 269 {
michael@0 270 // when we reach the finished state...fire an on stop request on the event listener...
michael@0 271 mNextListener->OnStopRequest(aRequest, aContext, NS_OK);
michael@0 272 mNextListener = 0;
michael@0 273
michael@0 274 /* now We are done with everything. */
michael@0 275 ++mState;
michael@0 276 break;
michael@0 277 }
michael@0 278
michael@0 279 if (mState == BINHEX_STATE_DFORK)
michael@0 280 mCount = PR_ntohl(mHeader.dlen);
michael@0 281 else
michael@0 282 {
michael@0 283 // we aren't processing the resurce Fork. uncomment this line if we make this converter
michael@0 284 // smart enough to do this in the future.
michael@0 285 // mCount = PR_ntohl(mHeader.rlen); /* it should in host byte order */
michael@0 286 mCount = 0;
michael@0 287 }
michael@0 288
michael@0 289 if (mCount) {
michael@0 290 mInCRC = 0;
michael@0 291 } else {
michael@0 292 /* nothing inside, so skip to the next state. */
michael@0 293 ++mState;
michael@0 294 }
michael@0 295 }
michael@0 296 break;
michael@0 297 }
michael@0 298
michael@0 299 return NS_OK;
michael@0 300 }
michael@0 301
michael@0 302 nsresult nsBinHexDecoder::ProcessNextChunk(nsIRequest * aRequest, nsISupports * aContext, uint32_t numBytesInBuffer)
michael@0 303 {
michael@0 304 bool foundStart;
michael@0 305 int16_t octetpos, c = 0;
michael@0 306 uint32_t val;
michael@0 307 mPosInDataBuffer = 0; // use member variable.
michael@0 308
michael@0 309 NS_ENSURE_TRUE(numBytesInBuffer > 0, NS_ERROR_FAILURE);
michael@0 310
michael@0 311 // if it is the first time, seek to the right start place.
michael@0 312 if (mState == BINHEX_STATE_START)
michael@0 313 {
michael@0 314 foundStart = false;
michael@0 315 // go through the line, until we get a ':'
michael@0 316 while (mPosInDataBuffer < numBytesInBuffer)
michael@0 317 {
michael@0 318 c = mDataBuffer[mPosInDataBuffer++];
michael@0 319 while (c == nsCRT::CR || c == nsCRT::LF)
michael@0 320 {
michael@0 321 if (mPosInDataBuffer >= numBytesInBuffer)
michael@0 322 break;
michael@0 323
michael@0 324 c = mDataBuffer[mPosInDataBuffer++];
michael@0 325 if (c == ':')
michael@0 326 {
michael@0 327 foundStart = true;
michael@0 328 break;
michael@0 329 }
michael@0 330 }
michael@0 331 if (foundStart) break; /* we got the start point. */
michael@0 332 }
michael@0 333
michael@0 334 if (mPosInDataBuffer >= numBytesInBuffer)
michael@0 335 return NS_OK; /* we meet buff end before we get the start point, wait till next fills. */
michael@0 336
michael@0 337 if (c != ':')
michael@0 338 return NS_ERROR_FAILURE; /* can't find the start character. */
michael@0 339 }
michael@0 340
michael@0 341 while (mState != BINHEX_STATE_DONE)
michael@0 342 {
michael@0 343 /* fill in octetbuf */
michael@0 344 do
michael@0 345 {
michael@0 346 if (mPosInDataBuffer >= numBytesInBuffer)
michael@0 347 return NS_OK; /* end of buff, go on for the nxet calls. */
michael@0 348
michael@0 349 c = GetNextChar(numBytesInBuffer);
michael@0 350 if (c == 0) return NS_OK;
michael@0 351
michael@0 352 if ((val = BHEXVAL(c)) == uint32_t(-1))
michael@0 353 {
michael@0 354 /* we incount an invalid character. */
michael@0 355 if (c)
michael@0 356 {
michael@0 357 /* rolling back. */
michael@0 358 --mDonePos;
michael@0 359 if (mOctetin >= 14)
michael@0 360 --mDonePos;
michael@0 361 if (mOctetin >= 20)
michael@0 362 --mDonePos;
michael@0 363 }
michael@0 364 break;
michael@0 365 }
michael@0 366 mOctetBuf.val |= val << mOctetin;
michael@0 367 }
michael@0 368 while ((mOctetin -= 6) > 2);
michael@0 369
michael@0 370 /* handle decoded characters -- run length encoding (rle) detection */
michael@0 371
michael@0 372 // We put decoded chars into mOctetBuf.val in order from high to low (via
michael@0 373 // bitshifting, above). But we want to byte-address them, so we want the
michael@0 374 // first byte to correspond to the high byte. In other words, we want
michael@0 375 // these bytes to be in network order.
michael@0 376 mOctetBuf.val = PR_htonl(mOctetBuf.val);
michael@0 377
michael@0 378 for (octetpos = 0; octetpos < mDonePos; ++octetpos)
michael@0 379 {
michael@0 380 c = mOctetBuf.c[octetpos];
michael@0 381
michael@0 382 if (c == 0x90 && !mMarker++)
michael@0 383 continue;
michael@0 384
michael@0 385 if (mMarker)
michael@0 386 {
michael@0 387 if (c == 0)
michael@0 388 {
michael@0 389 mRlebuf = 0x90;
michael@0 390 ProcessNextState(aRequest, aContext);
michael@0 391 }
michael@0 392 else
michael@0 393 {
michael@0 394 /* we are in the run length mode */
michael@0 395 while (--c > 0)
michael@0 396 ProcessNextState(aRequest, aContext);
michael@0 397 }
michael@0 398 mMarker = 0;
michael@0 399 }
michael@0 400 else
michael@0 401 {
michael@0 402 mRlebuf = (unsigned char) c;
michael@0 403 ProcessNextState(aRequest, aContext);
michael@0 404 }
michael@0 405
michael@0 406 if (mState >= BINHEX_STATE_DONE)
michael@0 407 break;
michael@0 408 }
michael@0 409
michael@0 410 /* prepare for next 3 characters. */
michael@0 411 if (mDonePos < 3 && mState < BINHEX_STATE_DONE)
michael@0 412 mState = BINHEX_STATE_DONE;
michael@0 413
michael@0 414 mOctetin = 26;
michael@0 415 mOctetBuf.val = 0;
michael@0 416 }
michael@0 417
michael@0 418 return NS_OK;
michael@0 419 }
michael@0 420
michael@0 421 int16_t nsBinHexDecoder::GetNextChar(uint32_t numBytesInBuffer)
michael@0 422 {
michael@0 423 char c = 0;
michael@0 424
michael@0 425 while (mPosInDataBuffer < numBytesInBuffer)
michael@0 426 {
michael@0 427 c = mDataBuffer[mPosInDataBuffer++];
michael@0 428 if (c != nsCRT::LF && c != nsCRT::CR)
michael@0 429 break;
michael@0 430 }
michael@0 431 return (c == nsCRT::LF || c == nsCRT::CR) ? 0 : (int) c;
michael@0 432 }
michael@0 433
michael@0 434 //////////////////////////////////////////////////////
michael@0 435 // nsIRequestObserver methods...
michael@0 436 //////////////////////////////////////////////////////
michael@0 437
michael@0 438 NS_IMETHODIMP
michael@0 439 nsBinHexDecoder::OnStartRequest(nsIRequest* request, nsISupports *aCtxt)
michael@0 440 {
michael@0 441 nsresult rv = NS_OK;
michael@0 442
michael@0 443 NS_ENSURE_TRUE(mNextListener, NS_ERROR_FAILURE);
michael@0 444
michael@0 445 mDataBuffer = (char *) moz_malloc((sizeof(char) * nsIOService::gDefaultSegmentSize));
michael@0 446 mOutgoingBuffer = (char *) moz_malloc((sizeof(char) * nsIOService::gDefaultSegmentSize));
michael@0 447 if (!mDataBuffer || !mOutgoingBuffer) return NS_ERROR_FAILURE; // out of memory;
michael@0 448
michael@0 449 // now we want to create a pipe which we'll use to write our converted data...
michael@0 450 rv = NS_NewPipe(getter_AddRefs(mInputStream), getter_AddRefs(mOutputStream),
michael@0 451 nsIOService::gDefaultSegmentSize,
michael@0 452 nsIOService::gDefaultSegmentSize,
michael@0 453 true, true);
michael@0 454
michael@0 455 // don't propagate the on start request to mNextListener until we have determined the content type.
michael@0 456 return rv;
michael@0 457 }
michael@0 458
michael@0 459 // Given the fileName we discovered inside the bin hex decoding, figure out the
michael@0 460 // content type and set it on the channel associated with the request. If the
michael@0 461 // filename tells us nothing useful, just report an unknown type and let the
michael@0 462 // unknown decoder handle things.
michael@0 463 nsresult nsBinHexDecoder::DetectContentType(nsIRequest* aRequest,
michael@0 464 const nsAFlatCString &aFilename)
michael@0 465 {
michael@0 466 if (aFilename.IsEmpty()) {
michael@0 467 // Nothing to do here.
michael@0 468 return NS_OK;
michael@0 469 }
michael@0 470
michael@0 471 nsresult rv;
michael@0 472 nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest, &rv));
michael@0 473 NS_ENSURE_SUCCESS(rv, rv);
michael@0 474
michael@0 475 nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
michael@0 476 NS_ENSURE_SUCCESS(rv, rv);
michael@0 477
michael@0 478 nsAutoCString contentType;
michael@0 479
michael@0 480 // extract the extension from aFilename and look it up.
michael@0 481 const char * fileExt = strrchr(aFilename.get(), '.');
michael@0 482 if (!fileExt) {
michael@0 483 return NS_OK;
michael@0 484 }
michael@0 485
michael@0 486 mimeService->GetTypeFromExtension(nsDependentCString(fileExt), contentType);
michael@0 487
michael@0 488 // Only set the type if it's not empty and, to prevent recursive loops, not the binhex type
michael@0 489 if (!contentType.IsEmpty() && !contentType.Equals(APPLICATION_BINHEX)) {
michael@0 490 channel->SetContentType(contentType);
michael@0 491 } else {
michael@0 492 channel->SetContentType(NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE));
michael@0 493 }
michael@0 494
michael@0 495 return NS_OK;
michael@0 496 }
michael@0 497
michael@0 498
michael@0 499 NS_IMETHODIMP
michael@0 500 nsBinHexDecoder::OnStopRequest(nsIRequest* request, nsISupports *aCtxt,
michael@0 501 nsresult aStatus)
michael@0 502 {
michael@0 503 nsresult rv = NS_OK;
michael@0 504
michael@0 505 if (!mNextListener) return NS_ERROR_FAILURE;
michael@0 506 // don't do anything here...we'll fire our own on stop request when we are done
michael@0 507 // processing the data....
michael@0 508
michael@0 509 return rv;
michael@0 510 }

mercurial