1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Pierre Phaneuf <pp@ludusdesign.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "pratom.h"
40 : #include "nsAlgorithm.h"
41 : #include "nsIComponentManager.h"
42 : #include "nsUCSupport.h"
43 : #include "nsUnicodeDecodeHelper.h"
44 : #include "nsUnicodeEncodeHelper.h"
45 :
46 : #define DEFAULT_BUFFER_CAPACITY 16
47 :
48 : // XXX review the buffer growth limitation code
49 :
50 : //----------------------------------------------------------------------
51 : // Class nsBasicDecoderSupport [implementation]
52 :
53 15552 : nsBasicDecoderSupport::nsBasicDecoderSupport()
54 15552 : : mErrBehavior(kOnError_Recover)
55 : {
56 15552 : }
57 :
58 15552 : nsBasicDecoderSupport::~nsBasicDecoderSupport()
59 : {
60 31104 : }
61 :
62 : //----------------------------------------------------------------------
63 : // Interface nsISupports [implementation]
64 :
65 : #ifdef NS_DEBUG
66 171045 : NS_IMPL_THREADSAFE_ISUPPORTS2(nsBasicDecoderSupport,
67 : nsIUnicodeDecoder,
68 : nsIBasicDecoder)
69 : #else
70 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsBasicDecoderSupport, nsIUnicodeDecoder)
71 : #endif
72 :
73 : //----------------------------------------------------------------------
74 : // Interface nsIUnicodeDecoder [implementation]
75 :
76 : void
77 3878 : nsBasicDecoderSupport::SetInputErrorBehavior(PRInt32 aBehavior)
78 : {
79 3878 : NS_ABORT_IF_FALSE(aBehavior == kOnError_Recover || aBehavior == kOnError_Signal,
80 : "Unknown behavior for SetInputErrorBehavior");
81 3878 : mErrBehavior = aBehavior;
82 3878 : }
83 :
84 : PRUnichar
85 0 : nsBasicDecoderSupport::GetCharacterForUnMapped()
86 : {
87 0 : return PRUnichar(0xfffd); // Unicode REPLACEMENT CHARACTER
88 : }
89 :
90 : //----------------------------------------------------------------------
91 : // Class nsBufferDecoderSupport [implementation]
92 :
93 8886 : nsBufferDecoderSupport::nsBufferDecoderSupport(PRUint32 aMaxLengthFactor)
94 : : nsBasicDecoderSupport(),
95 8886 : mMaxLengthFactor(aMaxLengthFactor)
96 : {
97 8886 : mBufferCapacity = DEFAULT_BUFFER_CAPACITY;
98 17772 : mBuffer = new char[mBufferCapacity];
99 :
100 8886 : Reset();
101 8886 : }
102 :
103 17772 : nsBufferDecoderSupport::~nsBufferDecoderSupport()
104 : {
105 8886 : delete [] mBuffer;
106 17772 : }
107 :
108 2374 : void nsBufferDecoderSupport::FillBuffer(const char ** aSrc, PRInt32 aSrcLength)
109 : {
110 2374 : PRInt32 bcr = NS_MIN(mBufferCapacity - mBufferLength, aSrcLength);
111 2374 : memcpy(mBuffer + mBufferLength, *aSrc, bcr);
112 2374 : mBufferLength += bcr;
113 2374 : (*aSrc) += bcr;
114 2374 : }
115 :
116 : //----------------------------------------------------------------------
117 : // Subclassing of nsBasicDecoderSupport class [implementation]
118 :
119 400611 : NS_IMETHODIMP nsBufferDecoderSupport::Convert(const char * aSrc,
120 : PRInt32 * aSrcLength,
121 : PRUnichar * aDest,
122 : PRInt32 * aDestLength)
123 : {
124 : // we do all operations using pointers internally
125 400611 : const char * src = aSrc;
126 400611 : const char * srcEnd = aSrc + *aSrcLength;
127 400611 : PRUnichar * dest = aDest;
128 400611 : PRUnichar * destEnd = aDest + *aDestLength;
129 :
130 : PRInt32 bcr, bcw; // byte counts for read & write;
131 400611 : nsresult res = NS_OK;
132 :
133 : // do we have some residual data from the last conversion?
134 400611 : if (mBufferLength > 0) {
135 1243 : if (dest == destEnd) {
136 0 : res = NS_OK_UDEC_MOREOUTPUT;
137 : } else {
138 : for (;;) {
139 : // we need new data to add to the buffer
140 1243 : if (src == srcEnd) {
141 0 : res = NS_OK_UDEC_MOREINPUT;
142 0 : break;
143 : }
144 :
145 : // fill that buffer
146 1243 : PRInt32 buffLen = mBufferLength; // initial buffer length
147 1243 : FillBuffer(&src, srcEnd - src);
148 :
149 : // convert that buffer
150 1243 : bcr = mBufferLength;
151 1243 : bcw = destEnd - dest;
152 1243 : res = ConvertNoBuff(mBuffer, &bcr, dest, &bcw);
153 1243 : dest += bcw;
154 :
155 : // Detect invalid input character
156 1243 : if (res == NS_ERROR_ILLEGAL_INPUT && mErrBehavior == kOnError_Signal) {
157 0 : break;
158 : }
159 :
160 1243 : if ((res == NS_OK_UDEC_MOREINPUT) && (bcw == 0)) {
161 2 : res = NS_ERROR_UNEXPECTED;
162 : #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
163 : NS_ERROR("This should not happen. Internal buffer may be corrupted.");
164 : #endif
165 2 : break;
166 : } else {
167 1241 : if (bcr < buffLen) {
168 : // we didn't convert that residual data - unfill the buffer
169 111 : src -= mBufferLength - buffLen;
170 111 : mBufferLength = buffLen;
171 : #if defined(DEBUG_yokoyama) || defined(DEBUG_ftang)
172 : NS_ERROR("This should not happen. Internal buffer may be corrupted.");
173 : #endif
174 : } else {
175 : // the buffer and some extra data was converted - unget the rest
176 1130 : src -= mBufferLength - bcr;
177 1130 : mBufferLength = 0;
178 1130 : res = NS_OK;
179 : }
180 1241 : break;
181 : }
182 : }
183 : }
184 : }
185 :
186 400611 : if (res == NS_OK) {
187 400498 : bcr = srcEnd - src;
188 400498 : bcw = destEnd - dest;
189 400498 : res = ConvertNoBuff(src, &bcr, dest, &bcw);
190 400498 : src += bcr;
191 400498 : dest += bcw;
192 :
193 : // if we have partial input, store it in our internal buffer.
194 400498 : if (res == NS_OK_UDEC_MOREINPUT) {
195 1131 : bcr = srcEnd - src;
196 : // make sure buffer is large enough
197 1131 : if (bcr > mBufferCapacity) {
198 : // somehow we got into an error state and the buffer is growing out
199 : // of control
200 0 : res = NS_ERROR_UNEXPECTED;
201 : } else {
202 1131 : FillBuffer(&src, bcr);
203 : }
204 : }
205 : }
206 :
207 400611 : *aSrcLength -= srcEnd - src;
208 400611 : *aDestLength -= destEnd - dest;
209 400611 : return res;
210 : }
211 :
212 9161 : NS_IMETHODIMP nsBufferDecoderSupport::Reset()
213 : {
214 9161 : mBufferLength = 0;
215 9161 : return NS_OK;
216 : }
217 :
218 400268 : NS_IMETHODIMP nsBufferDecoderSupport::GetMaxLength(const char* aSrc,
219 : PRInt32 aSrcLength,
220 : PRInt32* aDestLength)
221 : {
222 400268 : NS_ASSERTION(mMaxLengthFactor != 0, "Must override GetMaxLength!");
223 400268 : *aDestLength = aSrcLength * mMaxLengthFactor;
224 400268 : return NS_OK;
225 : }
226 :
227 : //----------------------------------------------------------------------
228 : // Class nsTableDecoderSupport [implementation]
229 :
230 2 : nsTableDecoderSupport::nsTableDecoderSupport(uScanClassID aScanClass,
231 : uShiftInTable * aShiftInTable,
232 : uMappingTable * aMappingTable,
233 : PRUint32 aMaxLengthFactor)
234 2 : : nsBufferDecoderSupport(aMaxLengthFactor)
235 : {
236 2 : mScanClass = aScanClass;
237 2 : mShiftInTable = aShiftInTable;
238 2 : mMappingTable = aMappingTable;
239 2 : }
240 :
241 2 : nsTableDecoderSupport::~nsTableDecoderSupport()
242 : {
243 4 : }
244 :
245 : //----------------------------------------------------------------------
246 : // Subclassing of nsBufferDecoderSupport class [implementation]
247 :
248 263 : NS_IMETHODIMP nsTableDecoderSupport::ConvertNoBuff(const char * aSrc,
249 : PRInt32 * aSrcLength,
250 : PRUnichar * aDest,
251 : PRInt32 * aDestLength)
252 : {
253 : return nsUnicodeDecodeHelper::ConvertByTable(aSrc, aSrcLength,
254 : aDest, aDestLength,
255 : mScanClass,
256 : mShiftInTable, mMappingTable,
257 263 : mErrBehavior == kOnError_Signal);
258 : }
259 :
260 : //----------------------------------------------------------------------
261 : // Class nsMultiTableDecoderSupport [implementation]
262 :
263 8852 : nsMultiTableDecoderSupport::nsMultiTableDecoderSupport(
264 : PRInt32 aTableCount,
265 : const uRange * aRangeArray,
266 : uScanClassID * aScanClassArray,
267 : uMappingTable ** aMappingTable,
268 : PRUint32 aMaxLengthFactor)
269 8852 : : nsBufferDecoderSupport(aMaxLengthFactor)
270 : {
271 8852 : mTableCount = aTableCount;
272 8852 : mRangeArray = aRangeArray;
273 8852 : mScanClassArray = aScanClassArray;
274 8852 : mMappingTable = aMappingTable;
275 8852 : }
276 :
277 17704 : nsMultiTableDecoderSupport::~nsMultiTableDecoderSupport()
278 : {
279 35408 : }
280 :
281 : //----------------------------------------------------------------------
282 : // Subclassing of nsBufferDecoderSupport class [implementation]
283 :
284 270081 : NS_IMETHODIMP nsMultiTableDecoderSupport::ConvertNoBuff(const char * aSrc,
285 : PRInt32 * aSrcLength,
286 : PRUnichar * aDest,
287 : PRInt32 * aDestLength)
288 : {
289 : return nsUnicodeDecodeHelper::ConvertByMultiTable(aSrc, aSrcLength,
290 : aDest, aDestLength,
291 : mTableCount, mRangeArray,
292 : mScanClassArray,
293 : mMappingTable,
294 270081 : mErrBehavior == kOnError_Signal);
295 : }
296 :
297 : //----------------------------------------------------------------------
298 : // Class nsOneByteDecoderSupport [implementation]
299 :
300 1279 : nsOneByteDecoderSupport::nsOneByteDecoderSupport(
301 : uMappingTable * aMappingTable)
302 : : nsBasicDecoderSupport()
303 : , mMappingTable(aMappingTable)
304 : , mFastTableCreated(false)
305 1279 : , mFastTableMutex("nsOneByteDecoderSupport mFastTableMutex")
306 : {
307 1279 : }
308 :
309 2558 : nsOneByteDecoderSupport::~nsOneByteDecoderSupport()
310 : {
311 5116 : }
312 :
313 : //----------------------------------------------------------------------
314 : // Subclassing of nsBasicDecoderSupport class [implementation]
315 :
316 98705 : NS_IMETHODIMP nsOneByteDecoderSupport::Convert(const char * aSrc,
317 : PRInt32 * aSrcLength,
318 : PRUnichar * aDest,
319 : PRInt32 * aDestLength)
320 : {
321 98705 : if (!mFastTableCreated) {
322 : // Probably better to make this non-lazy and get rid of the mutex
323 1814 : mozilla::MutexAutoLock autoLock(mFastTableMutex);
324 907 : if (!mFastTableCreated) {
325 : nsresult res = nsUnicodeDecodeHelper::CreateFastTable(
326 907 : mMappingTable, mFastTable, ONE_BYTE_TABLE_SIZE);
327 907 : if (NS_FAILED(res)) return res;
328 907 : mFastTableCreated = true;
329 : }
330 : }
331 :
332 : return nsUnicodeDecodeHelper::ConvertByFastTable(aSrc, aSrcLength,
333 : aDest, aDestLength,
334 : mFastTable,
335 : ONE_BYTE_TABLE_SIZE,
336 98705 : mErrBehavior == kOnError_Signal);
337 : }
338 :
339 7790 : NS_IMETHODIMP nsOneByteDecoderSupport::GetMaxLength(const char * aSrc,
340 : PRInt32 aSrcLength,
341 : PRInt32 * aDestLength)
342 : {
343 : // single byte to Unicode converter
344 7790 : *aDestLength = aSrcLength;
345 7790 : return NS_OK_UDEC_EXACTLENGTH;
346 : }
347 :
348 0 : NS_IMETHODIMP nsOneByteDecoderSupport::Reset()
349 : {
350 : // nothing to reset, no internal state in this case
351 0 : return NS_OK;
352 : }
353 :
354 : //----------------------------------------------------------------------
355 : // Class nsBasicEncoder [implementation]
356 9929 : nsBasicEncoder::nsBasicEncoder()
357 : {
358 9929 : }
359 :
360 9929 : nsBasicEncoder::~nsBasicEncoder()
361 : {
362 19858 : }
363 :
364 : //----------------------------------------------------------------------
365 : // Interface nsISupports [implementation]
366 :
367 49645 : NS_IMPL_ADDREF(nsBasicEncoder)
368 49645 : NS_IMPL_RELEASE(nsBasicEncoder)
369 : #ifdef NS_DEBUG
370 29787 : NS_IMPL_QUERY_INTERFACE2(nsBasicEncoder,
371 : nsIUnicodeEncoder,
372 : nsIBasicEncoder)
373 : #else
374 : NS_IMPL_QUERY_INTERFACE1(nsBasicEncoder,
375 : nsIUnicodeEncoder)
376 : #endif
377 : //----------------------------------------------------------------------
378 : // Class nsEncoderSupport [implementation]
379 :
380 9892 : nsEncoderSupport::nsEncoderSupport(PRUint32 aMaxLengthFactor) :
381 9892 : mMaxLengthFactor(aMaxLengthFactor)
382 : {
383 9892 : mBufferCapacity = DEFAULT_BUFFER_CAPACITY;
384 19784 : mBuffer = new char[mBufferCapacity];
385 :
386 9892 : mErrBehavior = kOnError_Signal;
387 9892 : mErrChar = 0;
388 :
389 9892 : Reset();
390 9892 : }
391 :
392 19784 : nsEncoderSupport::~nsEncoderSupport()
393 : {
394 9892 : delete [] mBuffer;
395 19784 : }
396 :
397 171846 : NS_IMETHODIMP nsEncoderSupport::ConvertNoBuff(const PRUnichar * aSrc,
398 : PRInt32 * aSrcLength,
399 : char * aDest,
400 : PRInt32 * aDestLength)
401 : {
402 : // we do all operations using pointers internally
403 171846 : const PRUnichar * src = aSrc;
404 171846 : const PRUnichar * srcEnd = aSrc + *aSrcLength;
405 171846 : char * dest = aDest;
406 171846 : char * destEnd = aDest + *aDestLength;
407 :
408 : PRInt32 bcr, bcw; // byte counts for read & write;
409 : nsresult res;
410 :
411 119 : for (;;) {
412 171965 : bcr = srcEnd - src;
413 171965 : bcw = destEnd - dest;
414 171965 : res = ConvertNoBuffNoErr(src, &bcr, dest, &bcw);
415 171965 : src += bcr;
416 171965 : dest += bcw;
417 :
418 171965 : if (res == NS_ERROR_UENC_NOMAPPING) {
419 12073 : if (mErrBehavior == kOnError_Replace) {
420 119 : const PRUnichar buff[] = {mErrChar};
421 119 : bcr = 1;
422 119 : bcw = destEnd - dest;
423 119 : src--; // back the input: maybe the guy won't consume consume anything.
424 119 : res = ConvertNoBuffNoErr(buff, &bcr, dest, &bcw);
425 119 : src += bcr;
426 119 : dest += bcw;
427 119 : if (res != NS_OK) break;
428 11954 : } else if (mErrBehavior == kOnError_CallBack) {
429 0 : bcw = destEnd - dest;
430 0 : src--;
431 0 : res = mErrEncoder->Convert(*src, dest, &bcw);
432 0 : dest += bcw;
433 : // if enought output space then the last char was used
434 0 : if (res != NS_OK_UENC_MOREOUTPUT) src++;
435 0 : if (res != NS_OK) break;
436 11954 : } else break;
437 : }
438 159892 : else break;
439 : }
440 :
441 171846 : *aSrcLength -= srcEnd - src;
442 171846 : *aDestLength -= destEnd - dest;
443 171846 : return res;
444 : }
445 :
446 538137 : NS_IMETHODIMP nsEncoderSupport::FinishNoBuff(char * aDest,
447 : PRInt32 * aDestLength)
448 : {
449 538137 : *aDestLength = 0;
450 538137 : return NS_OK;
451 : }
452 :
453 1378477 : nsresult nsEncoderSupport::FlushBuffer(char ** aDest, const char * aDestEnd)
454 : {
455 : PRInt32 bcr, bcw; // byte counts for read & write;
456 1378477 : nsresult res = NS_OK;
457 1378477 : char * dest = *aDest;
458 :
459 1378477 : if (mBufferStart < mBufferEnd) {
460 6 : bcr = mBufferEnd - mBufferStart;
461 6 : bcw = aDestEnd - dest;
462 6 : if (bcw < bcr) bcr = bcw;
463 6 : memcpy(dest, mBufferStart, bcr);
464 6 : dest += bcr;
465 6 : mBufferStart += bcr;
466 :
467 6 : if (mBufferStart < mBufferEnd) res = NS_OK_UENC_MOREOUTPUT;
468 : }
469 :
470 1378477 : *aDest = dest;
471 1378477 : return res;
472 : }
473 :
474 :
475 : //----------------------------------------------------------------------
476 : // Interface nsIUnicodeEncoder [implementation]
477 :
478 171855 : NS_IMETHODIMP nsEncoderSupport::Convert(const PRUnichar * aSrc,
479 : PRInt32 * aSrcLength,
480 : char * aDest,
481 : PRInt32 * aDestLength)
482 : {
483 : // we do all operations using pointers internally
484 171855 : const PRUnichar * src = aSrc;
485 171855 : const PRUnichar * srcEnd = aSrc + *aSrcLength;
486 171855 : char * dest = aDest;
487 171855 : char * destEnd = aDest + *aDestLength;
488 :
489 : PRInt32 bcr, bcw; // byte counts for read & write;
490 : nsresult res;
491 :
492 171855 : res = FlushBuffer(&dest, destEnd);
493 171855 : if (res == NS_OK_UENC_MOREOUTPUT) goto final;
494 :
495 171855 : bcr = srcEnd - src;
496 171855 : bcw = destEnd - dest;
497 171855 : res = ConvertNoBuff(src, &bcr, dest, &bcw);
498 171855 : src += bcr;
499 171855 : dest += bcw;
500 171855 : if ((res == NS_OK_UENC_MOREOUTPUT) && (dest < destEnd)) {
501 : // convert exactly one character into the internal buffer
502 : // at this point, there should be at least a char in the input
503 0 : for (;;) {
504 0 : bcr = 1;
505 0 : bcw = mBufferCapacity;
506 0 : res = ConvertNoBuff(src, &bcr, mBuffer, &bcw);
507 :
508 0 : if (res == NS_OK_UENC_MOREOUTPUT) {
509 0 : delete [] mBuffer;
510 0 : mBufferCapacity *= 2;
511 0 : mBuffer = new char [mBufferCapacity];
512 : } else {
513 0 : src += bcr;
514 0 : mBufferStart = mBufferEnd = mBuffer;
515 0 : mBufferEnd += bcw;
516 : break;
517 : }
518 : }
519 :
520 0 : res = FlushBuffer(&dest, destEnd);
521 : }
522 :
523 : final:
524 171855 : *aSrcLength -= srcEnd - src;
525 171855 : *aDestLength -= destEnd - dest;
526 171855 : return res;
527 : }
528 :
529 603311 : NS_IMETHODIMP nsEncoderSupport::Finish(char * aDest, PRInt32 * aDestLength)
530 : {
531 : // we do all operations using pointers internally
532 603311 : char * dest = aDest;
533 603311 : char * destEnd = aDest + *aDestLength;
534 :
535 : PRInt32 bcw; // byte count for write;
536 : nsresult res;
537 :
538 603311 : res = FlushBuffer(&dest, destEnd);
539 603311 : if (res == NS_OK_UENC_MOREOUTPUT) goto final;
540 :
541 : // do the finish into the internal buffer.
542 0 : for (;;) {
543 603311 : bcw = mBufferCapacity;
544 603311 : res = FinishNoBuff(mBuffer, &bcw);
545 :
546 603311 : if (res == NS_OK_UENC_MOREOUTPUT) {
547 0 : delete [] mBuffer;
548 0 : mBufferCapacity *= 2;
549 0 : mBuffer = new char [mBufferCapacity];
550 : } else {
551 603311 : mBufferStart = mBufferEnd = mBuffer;
552 603311 : mBufferEnd += bcw;
553 : break;
554 : }
555 : }
556 :
557 603311 : res = FlushBuffer(&dest, destEnd);
558 :
559 : final:
560 603311 : *aDestLength -= destEnd - dest;
561 603311 : return res;
562 : }
563 :
564 9928 : NS_IMETHODIMP nsEncoderSupport::Reset()
565 : {
566 9928 : mBufferStart = mBufferEnd = mBuffer;
567 9928 : return NS_OK;
568 : }
569 :
570 9885 : NS_IMETHODIMP nsEncoderSupport::SetOutputErrorBehavior(
571 : PRInt32 aBehavior,
572 : nsIUnicharEncoder * aEncoder,
573 : PRUnichar aChar)
574 : {
575 9885 : if (aBehavior == kOnError_CallBack && aEncoder == nsnull)
576 0 : return NS_ERROR_NULL_POINTER;
577 :
578 9885 : mErrEncoder = aEncoder;
579 9885 : mErrBehavior = aBehavior;
580 9885 : mErrChar = aChar;
581 9885 : return NS_OK;
582 : }
583 :
584 : NS_IMETHODIMP
585 1180 : nsEncoderSupport::GetMaxLength(const PRUnichar * aSrc,
586 : PRInt32 aSrcLength,
587 : PRInt32 * aDestLength)
588 : {
589 1180 : *aDestLength = aSrcLength * mMaxLengthFactor;
590 1180 : return NS_OK;
591 : }
592 :
593 :
594 : //----------------------------------------------------------------------
595 : // Class nsTableEncoderSupport [implementation]
596 :
597 987 : nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass,
598 : uShiftOutTable * aShiftOutTable,
599 : uMappingTable * aMappingTable,
600 : PRUint32 aMaxLengthFactor)
601 987 : : nsEncoderSupport(aMaxLengthFactor)
602 : {
603 987 : mScanClass = aScanClass;
604 : mShiftOutTable = aShiftOutTable,
605 987 : mMappingTable = aMappingTable;
606 987 : }
607 :
608 0 : nsTableEncoderSupport::nsTableEncoderSupport(uScanClassID aScanClass,
609 : uMappingTable * aMappingTable,
610 : PRUint32 aMaxLengthFactor)
611 0 : : nsEncoderSupport(aMaxLengthFactor)
612 : {
613 0 : mScanClass = aScanClass;
614 0 : mShiftOutTable = nsnull;
615 0 : mMappingTable = aMappingTable;
616 0 : }
617 :
618 1974 : nsTableEncoderSupport::~nsTableEncoderSupport()
619 : {
620 3948 : }
621 :
622 : //----------------------------------------------------------------------
623 : // Subclassing of nsEncoderSupport class [implementation]
624 :
625 172041 : NS_IMETHODIMP nsTableEncoderSupport::ConvertNoBuffNoErr(
626 : const PRUnichar * aSrc,
627 : PRInt32 * aSrcLength,
628 : char * aDest,
629 : PRInt32 * aDestLength)
630 : {
631 : return nsUnicodeEncodeHelper::ConvertByTable(aSrc, aSrcLength,
632 : aDest, aDestLength,
633 : mScanClass,
634 172041 : mShiftOutTable, mMappingTable);
635 : }
636 :
637 : //----------------------------------------------------------------------
638 : // Class nsMultiTableEncoderSupport [implementation]
639 :
640 8851 : nsMultiTableEncoderSupport::nsMultiTableEncoderSupport(
641 : PRInt32 aTableCount,
642 : uScanClassID * aScanClassArray,
643 : uShiftOutTable ** aShiftOutTable,
644 : uMappingTable ** aMappingTable,
645 : PRUint32 aMaxLengthFactor)
646 8851 : : nsEncoderSupport(aMaxLengthFactor)
647 : {
648 8851 : mTableCount = aTableCount;
649 8851 : mScanClassArray = aScanClassArray;
650 8851 : mShiftOutTable = aShiftOutTable;
651 8851 : mMappingTable = aMappingTable;
652 8851 : }
653 :
654 17702 : nsMultiTableEncoderSupport::~nsMultiTableEncoderSupport()
655 : {
656 35404 : }
657 :
658 : //----------------------------------------------------------------------
659 : // Subclassing of nsEncoderSupport class [implementation]
660 :
661 7 : NS_IMETHODIMP nsMultiTableEncoderSupport::ConvertNoBuffNoErr(
662 : const PRUnichar * aSrc,
663 : PRInt32 * aSrcLength,
664 : char * aDest,
665 : PRInt32 * aDestLength)
666 : {
667 : return nsUnicodeEncodeHelper::ConvertByMultiTable(aSrc, aSrcLength,
668 : aDest, aDestLength,
669 : mTableCount,
670 : mScanClassArray,
671 : mShiftOutTable,
672 7 : mMappingTable);
673 : }
|