intl/uconv/util/nsUCSupport.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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 "nsUCSupport.h"
michael@0 7 #include "nsUnicodeDecodeHelper.h"
michael@0 8 #include "nsUnicodeEncodeHelper.h"
michael@0 9 #include <algorithm>
michael@0 10
michael@0 11 #define DEFAULT_BUFFER_CAPACITY 16
michael@0 12
michael@0 13 // XXX review the buffer growth limitation code
michael@0 14
michael@0 15 //----------------------------------------------------------------------
michael@0 16 // Class nsBasicDecoderSupport [implementation]
michael@0 17
michael@0 18 nsBasicDecoderSupport::nsBasicDecoderSupport()
michael@0 19 : mErrBehavior(kOnError_Recover)
michael@0 20 {
michael@0 21 }
michael@0 22
michael@0 23 nsBasicDecoderSupport::~nsBasicDecoderSupport()
michael@0 24 {
michael@0 25 }
michael@0 26
michael@0 27 //----------------------------------------------------------------------
michael@0 28 // Interface nsISupports [implementation]
michael@0 29
michael@0 30 #ifdef DEBUG
michael@0 31 NS_IMPL_ISUPPORTS(nsBasicDecoderSupport,
michael@0 32 nsIUnicodeDecoder,
michael@0 33 nsIBasicDecoder)
michael@0 34 #else
michael@0 35 NS_IMPL_ISUPPORTS(nsBasicDecoderSupport, nsIUnicodeDecoder)
michael@0 36 #endif
michael@0 37
michael@0 38 //----------------------------------------------------------------------
michael@0 39 // Interface nsIUnicodeDecoder [implementation]
michael@0 40
michael@0 41 void
michael@0 42 nsBasicDecoderSupport::SetInputErrorBehavior(int32_t aBehavior)
michael@0 43 {
michael@0 44 NS_ABORT_IF_FALSE(aBehavior == kOnError_Recover || aBehavior == kOnError_Signal,
michael@0 45 "Unknown behavior for SetInputErrorBehavior");
michael@0 46 mErrBehavior = aBehavior;
michael@0 47 }
michael@0 48
michael@0 49 char16_t
michael@0 50 nsBasicDecoderSupport::GetCharacterForUnMapped()
michael@0 51 {
michael@0 52 return char16_t(0xfffd); // Unicode REPLACEMENT CHARACTER
michael@0 53 }
michael@0 54
michael@0 55 //----------------------------------------------------------------------
michael@0 56 // Class nsBufferDecoderSupport [implementation]
michael@0 57
michael@0 58 nsBufferDecoderSupport::nsBufferDecoderSupport(uint32_t aMaxLengthFactor)
michael@0 59 : nsBasicDecoderSupport(),
michael@0 60 mMaxLengthFactor(aMaxLengthFactor)
michael@0 61 {
michael@0 62 mBufferCapacity = DEFAULT_BUFFER_CAPACITY;
michael@0 63 mBuffer = new char[mBufferCapacity];
michael@0 64
michael@0 65 Reset();
michael@0 66 }
michael@0 67
michael@0 68 nsBufferDecoderSupport::~nsBufferDecoderSupport()
michael@0 69 {
michael@0 70 delete [] mBuffer;
michael@0 71 }
michael@0 72
michael@0 73 void nsBufferDecoderSupport::FillBuffer(const char ** aSrc, int32_t aSrcLength)
michael@0 74 {
michael@0 75 int32_t bcr = std::min(mBufferCapacity - mBufferLength, aSrcLength);
michael@0 76 memcpy(mBuffer + mBufferLength, *aSrc, bcr);
michael@0 77 mBufferLength += bcr;
michael@0 78 (*aSrc) += bcr;
michael@0 79 }
michael@0 80
michael@0 81 //----------------------------------------------------------------------
michael@0 82 // Subclassing of nsBasicDecoderSupport class [implementation]
michael@0 83
michael@0 84 NS_IMETHODIMP nsBufferDecoderSupport::Convert(const char * aSrc,
michael@0 85 int32_t * aSrcLength,
michael@0 86 char16_t * aDest,
michael@0 87 int32_t * aDestLength)
michael@0 88 {
michael@0 89 // we do all operations using pointers internally
michael@0 90 const char * src = aSrc;
michael@0 91 const char * srcEnd = aSrc + *aSrcLength;
michael@0 92 char16_t * dest = aDest;
michael@0 93 char16_t * destEnd = aDest + *aDestLength;
michael@0 94
michael@0 95 int32_t bcr, bcw; // byte counts for read & write;
michael@0 96 nsresult res = NS_OK;
michael@0 97
michael@0 98 // do we have some residual data from the last conversion?
michael@0 99 if (mBufferLength > 0) {
michael@0 100 if (dest == destEnd) {
michael@0 101 res = NS_OK_UDEC_MOREOUTPUT;
michael@0 102 } else {
michael@0 103 for (;;) {
michael@0 104 // we need new data to add to the buffer
michael@0 105 if (src == srcEnd) {
michael@0 106 res = NS_OK_UDEC_MOREINPUT;
michael@0 107 break;
michael@0 108 }
michael@0 109
michael@0 110 // fill that buffer
michael@0 111 int32_t buffLen = mBufferLength; // initial buffer length
michael@0 112 FillBuffer(&src, srcEnd - src);
michael@0 113
michael@0 114 // convert that buffer
michael@0 115 bcr = mBufferLength;
michael@0 116 bcw = destEnd - dest;
michael@0 117 res = ConvertNoBuff(mBuffer, &bcr, dest, &bcw);
michael@0 118 dest += bcw;
michael@0 119
michael@0 120 // Detect invalid input character
michael@0 121 if (res == NS_ERROR_ILLEGAL_INPUT && mErrBehavior == kOnError_Signal) {
michael@0 122 break;
michael@0 123 }
michael@0 124
michael@0 125 if ((res == NS_OK_UDEC_MOREINPUT) && (bcw == 0)) {
michael@0 126 res = NS_ERROR_UNEXPECTED;
michael@0 127 #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
michael@0 128 NS_ERROR("This should not happen. Internal buffer may be corrupted.");
michael@0 129 #endif
michael@0 130 break;
michael@0 131 } else {
michael@0 132 if (bcr < buffLen) {
michael@0 133 // we didn't convert that residual data - unfill the buffer
michael@0 134 src -= mBufferLength - buffLen;
michael@0 135 mBufferLength = buffLen;
michael@0 136 #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
michael@0 137 NS_ERROR("This should not happen. Internal buffer may be corrupted.");
michael@0 138 #endif
michael@0 139 } else {
michael@0 140 // the buffer and some extra data was converted - unget the rest
michael@0 141 src -= mBufferLength - bcr;
michael@0 142 mBufferLength = 0;
michael@0 143 res = NS_OK;
michael@0 144 }
michael@0 145 break;
michael@0 146 }
michael@0 147 }
michael@0 148 }
michael@0 149 }
michael@0 150
michael@0 151 if (res == NS_OK) {
michael@0 152 bcr = srcEnd - src;
michael@0 153 bcw = destEnd - dest;
michael@0 154 res = ConvertNoBuff(src, &bcr, dest, &bcw);
michael@0 155 src += bcr;
michael@0 156 dest += bcw;
michael@0 157
michael@0 158 // if we have partial input, store it in our internal buffer.
michael@0 159 if (res == NS_OK_UDEC_MOREINPUT) {
michael@0 160 bcr = srcEnd - src;
michael@0 161 // make sure buffer is large enough
michael@0 162 if (bcr > mBufferCapacity) {
michael@0 163 // somehow we got into an error state and the buffer is growing out
michael@0 164 // of control
michael@0 165 res = NS_ERROR_UNEXPECTED;
michael@0 166 } else {
michael@0 167 FillBuffer(&src, bcr);
michael@0 168 }
michael@0 169 }
michael@0 170 }
michael@0 171
michael@0 172 *aSrcLength -= srcEnd - src;
michael@0 173 *aDestLength -= destEnd - dest;
michael@0 174 return res;
michael@0 175 }
michael@0 176
michael@0 177 NS_IMETHODIMP nsBufferDecoderSupport::Reset()
michael@0 178 {
michael@0 179 mBufferLength = 0;
michael@0 180 return NS_OK;
michael@0 181 }
michael@0 182
michael@0 183 NS_IMETHODIMP nsBufferDecoderSupport::GetMaxLength(const char* aSrc,
michael@0 184 int32_t aSrcLength,
michael@0 185 int32_t* aDestLength)
michael@0 186 {
michael@0 187 NS_ASSERTION(mMaxLengthFactor != 0, "Must override GetMaxLength!");
michael@0 188 *aDestLength = aSrcLength * mMaxLengthFactor;
michael@0 189 return NS_OK;
michael@0 190 }
michael@0 191
michael@0 192 //----------------------------------------------------------------------
michael@0 193 // Class nsTableDecoderSupport [implementation]
michael@0 194
michael@0 195 nsTableDecoderSupport::nsTableDecoderSupport(uScanClassID aScanClass,
michael@0 196 uShiftInTable * aShiftInTable,
michael@0 197 uMappingTable * aMappingTable,
michael@0 198 uint32_t aMaxLengthFactor)
michael@0 199 : nsBufferDecoderSupport(aMaxLengthFactor)
michael@0 200 {
michael@0 201 mScanClass = aScanClass;
michael@0 202 mShiftInTable = aShiftInTable;
michael@0 203 mMappingTable = aMappingTable;
michael@0 204 }
michael@0 205
michael@0 206 nsTableDecoderSupport::~nsTableDecoderSupport()
michael@0 207 {
michael@0 208 }
michael@0 209
michael@0 210 //----------------------------------------------------------------------
michael@0 211 // Subclassing of nsBufferDecoderSupport class [implementation]
michael@0 212
michael@0 213 NS_IMETHODIMP nsTableDecoderSupport::ConvertNoBuff(const char * aSrc,
michael@0 214 int32_t * aSrcLength,
michael@0 215 char16_t * aDest,
michael@0 216 int32_t * aDestLength)
michael@0 217 {
michael@0 218 return nsUnicodeDecodeHelper::ConvertByTable(aSrc, aSrcLength,
michael@0 219 aDest, aDestLength,
michael@0 220 mScanClass,
michael@0 221 mShiftInTable, mMappingTable,
michael@0 222 mErrBehavior == kOnError_Signal);
michael@0 223 }
michael@0 224
michael@0 225 //----------------------------------------------------------------------
michael@0 226 // Class nsMultiTableDecoderSupport [implementation]
michael@0 227
michael@0 228 nsMultiTableDecoderSupport::nsMultiTableDecoderSupport(
michael@0 229 int32_t aTableCount,
michael@0 230 const uRange * aRangeArray,
michael@0 231 uScanClassID * aScanClassArray,
michael@0 232 uMappingTable ** aMappingTable,
michael@0 233 uint32_t aMaxLengthFactor)
michael@0 234 : nsBufferDecoderSupport(aMaxLengthFactor)
michael@0 235 {
michael@0 236 mTableCount = aTableCount;
michael@0 237 mRangeArray = aRangeArray;
michael@0 238 mScanClassArray = aScanClassArray;
michael@0 239 mMappingTable = aMappingTable;
michael@0 240 }
michael@0 241
michael@0 242 nsMultiTableDecoderSupport::~nsMultiTableDecoderSupport()
michael@0 243 {
michael@0 244 }
michael@0 245
michael@0 246 //----------------------------------------------------------------------
michael@0 247 // Subclassing of nsBufferDecoderSupport class [implementation]
michael@0 248
michael@0 249 NS_IMETHODIMP nsMultiTableDecoderSupport::ConvertNoBuff(const char * aSrc,
michael@0 250 int32_t * aSrcLength,
michael@0 251 char16_t * aDest,
michael@0 252 int32_t * aDestLength)
michael@0 253 {
michael@0 254 return nsUnicodeDecodeHelper::ConvertByMultiTable(aSrc, aSrcLength,
michael@0 255 aDest, aDestLength,
michael@0 256 mTableCount, mRangeArray,
michael@0 257 mScanClassArray,
michael@0 258 mMappingTable,
michael@0 259 mErrBehavior == kOnError_Signal);
michael@0 260 }
michael@0 261
michael@0 262 //----------------------------------------------------------------------
michael@0 263 // Class nsOneByteDecoderSupport [implementation]
michael@0 264
michael@0 265 nsOneByteDecoderSupport::nsOneByteDecoderSupport(
michael@0 266 uMappingTable * aMappingTable)
michael@0 267 : nsBasicDecoderSupport()
michael@0 268 , mMappingTable(aMappingTable)
michael@0 269 , mFastTableCreated(false)
michael@0 270 , mFastTableMutex("nsOneByteDecoderSupport mFastTableMutex")
michael@0 271 {
michael@0 272 }
michael@0 273
michael@0 274 nsOneByteDecoderSupport::~nsOneByteDecoderSupport()
michael@0 275 {
michael@0 276 }
michael@0 277
michael@0 278 //----------------------------------------------------------------------
michael@0 279 // Subclassing of nsBasicDecoderSupport class [implementation]
michael@0 280
michael@0 281 NS_IMETHODIMP nsOneByteDecoderSupport::Convert(const char * aSrc,
michael@0 282 int32_t * aSrcLength,
michael@0 283 char16_t * aDest,
michael@0 284 int32_t * aDestLength)
michael@0 285 {
michael@0 286 if (!mFastTableCreated) {
michael@0 287 // Probably better to make this non-lazy and get rid of the mutex
michael@0 288 mozilla::MutexAutoLock autoLock(mFastTableMutex);
michael@0 289 if (!mFastTableCreated) {
michael@0 290 nsresult res = nsUnicodeDecodeHelper::CreateFastTable(
michael@0 291 mMappingTable, mFastTable, ONE_BYTE_TABLE_SIZE);
michael@0 292 if (NS_FAILED(res)) return res;
michael@0 293 mFastTableCreated = true;
michael@0 294 }
michael@0 295 }
michael@0 296
michael@0 297 return nsUnicodeDecodeHelper::ConvertByFastTable(aSrc, aSrcLength,
michael@0 298 aDest, aDestLength,
michael@0 299 mFastTable,
michael@0 300 ONE_BYTE_TABLE_SIZE,
michael@0 301 mErrBehavior == kOnError_Signal);
michael@0 302 }
michael@0 303
michael@0 304 NS_IMETHODIMP nsOneByteDecoderSupport::GetMaxLength(const char * aSrc,
michael@0 305 int32_t aSrcLength,
michael@0 306 int32_t * aDestLength)
michael@0 307 {
michael@0 308 // single byte to Unicode converter
michael@0 309 *aDestLength = aSrcLength;
michael@0 310 return NS_OK_UDEC_EXACTLENGTH;
michael@0 311 }
michael@0 312
michael@0 313 NS_IMETHODIMP nsOneByteDecoderSupport::Reset()
michael@0 314 {
michael@0 315 // nothing to reset, no internal state in this case
michael@0 316 return NS_OK;
michael@0 317 }
michael@0 318
michael@0 319 //----------------------------------------------------------------------
michael@0 320 // Class nsBasicEncoder [implementation]
michael@0 321 nsBasicEncoder::nsBasicEncoder()
michael@0 322 {
michael@0 323 }
michael@0 324
michael@0 325 nsBasicEncoder::~nsBasicEncoder()
michael@0 326 {
michael@0 327 }
michael@0 328
michael@0 329 //----------------------------------------------------------------------
michael@0 330 // Interface nsISupports [implementation]
michael@0 331
michael@0 332 NS_IMPL_ADDREF(nsBasicEncoder)
michael@0 333 NS_IMPL_RELEASE(nsBasicEncoder)
michael@0 334 #ifdef DEBUG
michael@0 335 NS_IMPL_QUERY_INTERFACE(nsBasicEncoder,
michael@0 336 nsIUnicodeEncoder,
michael@0 337 nsIBasicEncoder)
michael@0 338 #else
michael@0 339 NS_IMPL_QUERY_INTERFACE(nsBasicEncoder,
michael@0 340 nsIUnicodeEncoder)
michael@0 341 #endif
michael@0 342 //----------------------------------------------------------------------
michael@0 343 // Class nsEncoderSupport [implementation]
michael@0 344
michael@0 345 nsEncoderSupport::nsEncoderSupport(uint32_t aMaxLengthFactor) :
michael@0 346 mMaxLengthFactor(aMaxLengthFactor)
michael@0 347 {
michael@0 348 mBufferCapacity = DEFAULT_BUFFER_CAPACITY;
michael@0 349 mBuffer = new char[mBufferCapacity];
michael@0 350
michael@0 351 mErrBehavior = kOnError_Signal;
michael@0 352 mErrChar = 0;
michael@0 353
michael@0 354 Reset();
michael@0 355 }
michael@0 356
michael@0 357 nsEncoderSupport::~nsEncoderSupport()
michael@0 358 {
michael@0 359 delete [] mBuffer;
michael@0 360 }
michael@0 361
michael@0 362 NS_IMETHODIMP nsEncoderSupport::ConvertNoBuff(const char16_t * aSrc,
michael@0 363 int32_t * aSrcLength,
michael@0 364 char * aDest,
michael@0 365 int32_t * aDestLength)
michael@0 366 {
michael@0 367 // we do all operations using pointers internally
michael@0 368 const char16_t * src = aSrc;
michael@0 369 const char16_t * srcEnd = aSrc + *aSrcLength;
michael@0 370 char * dest = aDest;
michael@0 371 char * destEnd = aDest + *aDestLength;
michael@0 372
michael@0 373 int32_t bcr, bcw; // byte counts for read & write;
michael@0 374 nsresult res;
michael@0 375
michael@0 376 for (;;) {
michael@0 377 bcr = srcEnd - src;
michael@0 378 bcw = destEnd - dest;
michael@0 379 res = ConvertNoBuffNoErr(src, &bcr, dest, &bcw);
michael@0 380 src += bcr;
michael@0 381 dest += bcw;
michael@0 382
michael@0 383 if (res == NS_ERROR_UENC_NOMAPPING) {
michael@0 384 if (mErrBehavior == kOnError_Replace) {
michael@0 385 const char16_t buff[] = {mErrChar};
michael@0 386 bcr = 1;
michael@0 387 bcw = destEnd - dest;
michael@0 388 src--; // back the input: maybe the guy won't consume consume anything.
michael@0 389 res = ConvertNoBuffNoErr(buff, &bcr, dest, &bcw);
michael@0 390 src += bcr;
michael@0 391 dest += bcw;
michael@0 392 if (res != NS_OK) break;
michael@0 393 } else if (mErrBehavior == kOnError_CallBack) {
michael@0 394 bcw = destEnd - dest;
michael@0 395 src--;
michael@0 396 res = mErrEncoder->Convert(*src, dest, &bcw);
michael@0 397 dest += bcw;
michael@0 398 // if enought output space then the last char was used
michael@0 399 if (res != NS_OK_UENC_MOREOUTPUT) src++;
michael@0 400 if (res != NS_OK) break;
michael@0 401 } else break;
michael@0 402 }
michael@0 403 else break;
michael@0 404 }
michael@0 405
michael@0 406 *aSrcLength -= srcEnd - src;
michael@0 407 *aDestLength -= destEnd - dest;
michael@0 408 return res;
michael@0 409 }
michael@0 410
michael@0 411 NS_IMETHODIMP nsEncoderSupport::FinishNoBuff(char * aDest,
michael@0 412 int32_t * aDestLength)
michael@0 413 {
michael@0 414 *aDestLength = 0;
michael@0 415 return NS_OK;
michael@0 416 }
michael@0 417
michael@0 418 nsresult nsEncoderSupport::FlushBuffer(char ** aDest, const char * aDestEnd)
michael@0 419 {
michael@0 420 int32_t bcr, bcw; // byte counts for read & write;
michael@0 421 nsresult res = NS_OK;
michael@0 422 char * dest = *aDest;
michael@0 423
michael@0 424 if (mBufferStart < mBufferEnd) {
michael@0 425 bcr = mBufferEnd - mBufferStart;
michael@0 426 bcw = aDestEnd - dest;
michael@0 427 if (bcw < bcr) bcr = bcw;
michael@0 428 memcpy(dest, mBufferStart, bcr);
michael@0 429 dest += bcr;
michael@0 430 mBufferStart += bcr;
michael@0 431
michael@0 432 if (mBufferStart < mBufferEnd) res = NS_OK_UENC_MOREOUTPUT;
michael@0 433 }
michael@0 434
michael@0 435 *aDest = dest;
michael@0 436 return res;
michael@0 437 }
michael@0 438
michael@0 439
michael@0 440 //----------------------------------------------------------------------
michael@0 441 // Interface nsIUnicodeEncoder [implementation]
michael@0 442
michael@0 443 NS_IMETHODIMP nsEncoderSupport::Convert(const char16_t * aSrc,
michael@0 444 int32_t * aSrcLength,
michael@0 445 char * aDest,
michael@0 446 int32_t * aDestLength)
michael@0 447 {
michael@0 448 // we do all operations using pointers internally
michael@0 449 const char16_t * src = aSrc;
michael@0 450 const char16_t * srcEnd = aSrc + *aSrcLength;
michael@0 451 char * dest = aDest;
michael@0 452 char * destEnd = aDest + *aDestLength;
michael@0 453
michael@0 454 int32_t bcr, bcw; // byte counts for read & write;
michael@0 455 nsresult res;
michael@0 456
michael@0 457 res = FlushBuffer(&dest, destEnd);
michael@0 458 if (res == NS_OK_UENC_MOREOUTPUT) goto final;
michael@0 459
michael@0 460 bcr = srcEnd - src;
michael@0 461 bcw = destEnd - dest;
michael@0 462 res = ConvertNoBuff(src, &bcr, dest, &bcw);
michael@0 463 src += bcr;
michael@0 464 dest += bcw;
michael@0 465 if ((res == NS_OK_UENC_MOREOUTPUT) && (dest < destEnd)) {
michael@0 466 // convert exactly one character into the internal buffer
michael@0 467 // at this point, there should be at least a char in the input
michael@0 468 for (;;) {
michael@0 469 bcr = 1;
michael@0 470 bcw = mBufferCapacity;
michael@0 471 res = ConvertNoBuff(src, &bcr, mBuffer, &bcw);
michael@0 472
michael@0 473 if (res == NS_OK_UENC_MOREOUTPUT) {
michael@0 474 delete [] mBuffer;
michael@0 475 mBufferCapacity *= 2;
michael@0 476 mBuffer = new char [mBufferCapacity];
michael@0 477 } else {
michael@0 478 src += bcr;
michael@0 479 mBufferStart = mBufferEnd = mBuffer;
michael@0 480 mBufferEnd += bcw;
michael@0 481 break;
michael@0 482 }
michael@0 483 }
michael@0 484
michael@0 485 res = FlushBuffer(&dest, destEnd);
michael@0 486 }
michael@0 487
michael@0 488 final:
michael@0 489 *aSrcLength -= srcEnd - src;
michael@0 490 *aDestLength -= destEnd - dest;
michael@0 491 return res;
michael@0 492 }
michael@0 493
michael@0 494 NS_IMETHODIMP nsEncoderSupport::Finish(char * aDest, int32_t * aDestLength)
michael@0 495 {
michael@0 496 // we do all operations using pointers internally
michael@0 497 char * dest = aDest;
michael@0 498 char * destEnd = aDest + *aDestLength;
michael@0 499
michael@0 500 int32_t bcw; // byte count for write;
michael@0 501 nsresult res;
michael@0 502
michael@0 503 res = FlushBuffer(&dest, destEnd);
michael@0 504 if (res == NS_OK_UENC_MOREOUTPUT) goto final;
michael@0 505
michael@0 506 // do the finish into the internal buffer.
michael@0 507 for (;;) {
michael@0 508 bcw = mBufferCapacity;
michael@0 509 res = FinishNoBuff(mBuffer, &bcw);
michael@0 510
michael@0 511 if (res == NS_OK_UENC_MOREOUTPUT) {
michael@0 512 delete [] mBuffer;
michael@0 513 mBufferCapacity *= 2;
michael@0 514 mBuffer = new char [mBufferCapacity];
michael@0 515 } else {
michael@0 516 mBufferStart = mBufferEnd = mBuffer;
michael@0 517 mBufferEnd += bcw;
michael@0 518 break;
michael@0 519 }
michael@0 520 }
michael@0 521
michael@0 522 res = FlushBuffer(&dest, destEnd);
michael@0 523
michael@0 524 final:
michael@0 525 *aDestLength -= destEnd - dest;
michael@0 526 return res;
michael@0 527 }
michael@0 528
michael@0 529 NS_IMETHODIMP nsEncoderSupport::Reset()
michael@0 530 {
michael@0 531 mBufferStart = mBufferEnd = mBuffer;
michael@0 532 return NS_OK;
michael@0 533 }
michael@0 534
michael@0 535 NS_IMETHODIMP nsEncoderSupport::SetOutputErrorBehavior(
michael@0 536 int32_t aBehavior,
michael@0 537 nsIUnicharEncoder * aEncoder,
michael@0 538 char16_t aChar)
michael@0 539 {
michael@0 540 if (aBehavior == kOnError_CallBack && !aEncoder)
michael@0 541 return NS_ERROR_NULL_POINTER;
michael@0 542
michael@0 543 mErrEncoder = aEncoder;
michael@0 544 mErrBehavior = aBehavior;
michael@0 545 mErrChar = aChar;
michael@0 546 return NS_OK;
michael@0 547 }
michael@0 548
michael@0 549 NS_IMETHODIMP
michael@0 550 nsEncoderSupport::GetMaxLength(const char16_t * aSrc,
michael@0 551 int32_t aSrcLength,
michael@0 552 int32_t * aDestLength)
michael@0 553 {
michael@0 554 *aDestLength = aSrcLength * mMaxLengthFactor;
michael@0 555 return NS_OK;
michael@0 556 }
michael@0 557
michael@0 558
michael@0 559 //----------------------------------------------------------------------
michael@0 560 // Class nsTableEncoderSupport [implementation]
michael@0 561
michael@0 562 nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass,
michael@0 563 uShiftOutTable * aShiftOutTable,
michael@0 564 uMappingTable * aMappingTable,
michael@0 565 uint32_t aMaxLengthFactor)
michael@0 566 : nsEncoderSupport(aMaxLengthFactor)
michael@0 567 {
michael@0 568 mScanClass = aScanClass;
michael@0 569 mShiftOutTable = aShiftOutTable,
michael@0 570 mMappingTable = aMappingTable;
michael@0 571 }
michael@0 572
michael@0 573 nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass,
michael@0 574 uMappingTable * aMappingTable,
michael@0 575 uint32_t aMaxLengthFactor)
michael@0 576 : nsEncoderSupport(aMaxLengthFactor)
michael@0 577 {
michael@0 578 mScanClass = aScanClass;
michael@0 579 mShiftOutTable = nullptr;
michael@0 580 mMappingTable = aMappingTable;
michael@0 581 }
michael@0 582
michael@0 583 nsTableEncoderSupport::~nsTableEncoderSupport()
michael@0 584 {
michael@0 585 }
michael@0 586
michael@0 587 //----------------------------------------------------------------------
michael@0 588 // Subclassing of nsEncoderSupport class [implementation]
michael@0 589
michael@0 590 NS_IMETHODIMP nsTableEncoderSupport::ConvertNoBuffNoErr(
michael@0 591 const char16_t * aSrc,
michael@0 592 int32_t * aSrcLength,
michael@0 593 char * aDest,
michael@0 594 int32_t * aDestLength)
michael@0 595 {
michael@0 596 return nsUnicodeEncodeHelper::ConvertByTable(aSrc, aSrcLength,
michael@0 597 aDest, aDestLength,
michael@0 598 mScanClass,
michael@0 599 mShiftOutTable, mMappingTable);
michael@0 600 }
michael@0 601
michael@0 602 //----------------------------------------------------------------------
michael@0 603 // Class nsMultiTableEncoderSupport [implementation]
michael@0 604
michael@0 605 nsMultiTableEncoderSupport::nsMultiTableEncoderSupport(
michael@0 606 int32_t aTableCount,
michael@0 607 uScanClassID * aScanClassArray,
michael@0 608 uShiftOutTable ** aShiftOutTable,
michael@0 609 uMappingTable ** aMappingTable,
michael@0 610 uint32_t aMaxLengthFactor)
michael@0 611 : nsEncoderSupport(aMaxLengthFactor)
michael@0 612 {
michael@0 613 mTableCount = aTableCount;
michael@0 614 mScanClassArray = aScanClassArray;
michael@0 615 mShiftOutTable = aShiftOutTable;
michael@0 616 mMappingTable = aMappingTable;
michael@0 617 }
michael@0 618
michael@0 619 nsMultiTableEncoderSupport::~nsMultiTableEncoderSupport()
michael@0 620 {
michael@0 621 }
michael@0 622
michael@0 623 //----------------------------------------------------------------------
michael@0 624 // Subclassing of nsEncoderSupport class [implementation]
michael@0 625
michael@0 626 NS_IMETHODIMP nsMultiTableEncoderSupport::ConvertNoBuffNoErr(
michael@0 627 const char16_t * aSrc,
michael@0 628 int32_t * aSrcLength,
michael@0 629 char * aDest,
michael@0 630 int32_t * aDestLength)
michael@0 631 {
michael@0 632 return nsUnicodeEncodeHelper::ConvertByMultiTable(aSrc, aSrcLength,
michael@0 633 aDest, aDestLength,
michael@0 634 mTableCount,
michael@0 635 mScanClassArray,
michael@0 636 mShiftOutTable,
michael@0 637 mMappingTable);
michael@0 638 }

mercurial