001: /**
002: *******************************************************************************
003: * Copyright (C) 2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: *
007: *******************************************************************************
008: */package com.ibm.icu.charset;
009:
010: import java.nio.ByteBuffer;
011: import java.nio.CharBuffer;
012: import java.nio.IntBuffer;
013: import java.nio.charset.CharsetDecoder;
014: import java.nio.charset.CharsetEncoder;
015: import java.nio.charset.CoderResult;
016:
017: import com.ibm.icu.lang.UCharacter;
018: import com.ibm.icu.text.UTF16;
019:
020: class Charset88591 extends CharsetICU {
021: protected byte[] fromUSubstitution = new byte[] { (byte) 0x1a };
022:
023: public Charset88591(String icuCanonicalName,
024: String javaCanonicalName, String[] aliases) {
025: super (icuCanonicalName, javaCanonicalName, aliases);
026: maxBytesPerChar = 1;
027: minBytesPerChar = 1;
028: maxCharsPerByte = 1;
029: }
030:
031: class CharsetDecoder88591 extends CharsetDecoderICU {
032:
033: public CharsetDecoder88591(CharsetICU cs) {
034: super (cs);
035: }
036:
037: protected CoderResult decodeLoop(ByteBuffer source,
038: CharBuffer target, IntBuffer offsets, boolean flush) {
039: CoderResult cr = CoderResult.UNDERFLOW;
040: if (!source.hasRemaining() && toUnicodeStatus == 0) {
041: /* no input, nothing to do */
042: return cr;
043: }
044: if (!target.hasRemaining()) {
045: return CoderResult.OVERFLOW;
046: }
047:
048: int sourceArrayIndex = source.position(), count = 0;
049: int sourceIndex = 0;
050: char c = 0;
051: int oldTarget = target.position();
052: /* conversion loop */
053: c = 0;
054: while (sourceArrayIndex < source.limit()
055: && (c = (char) (source.get(sourceArrayIndex) & 0xFF)) <= 0xff
056: && target.hasRemaining()) {
057: target.put(c);
058: sourceArrayIndex++;
059: }
060:
061: if (c > 0xff) {
062: /* callback(illegal); copy the current bytes to toUBytes[] */
063: toUBytesArray[0] = (byte) c;
064: toULength = 1;
065: cr = CoderResult.malformedForLength(toULength);
066: } else if (sourceArrayIndex < source.limit()
067: && !target.hasRemaining()) {
068: /* target is full */
069: cr = CoderResult.OVERFLOW;
070: }
071:
072: /* set offsets since the start */
073: if (offsets != null) {
074: count = target.position() - oldTarget;
075: while (count > 0) {
076: offsets.put(sourceIndex++);
077: --count;
078: }
079: }
080:
081: source.position(sourceArrayIndex);
082: return cr;
083: }
084:
085: }
086:
087: class CharsetEncoder88591 extends CharsetEncoderICU {
088:
089: public CharsetEncoder88591(CharsetICU cs) {
090: super (cs, fromUSubstitution);
091: implReset();
092: }
093:
094: private final static int NEED_TO_WRITE_BOM = 1;
095:
096: protected void implReset() {
097: super .implReset();
098: fromUnicodeStatus = NEED_TO_WRITE_BOM;
099: }
100:
101: protected CoderResult encodeLoop(CharBuffer source,
102: ByteBuffer target, IntBuffer offsets, boolean flush) {
103: CoderResult cr = CoderResult.UNDERFLOW;
104: if (!source.hasRemaining()) {
105: /* no input, nothing to do */
106: return cr;
107: }
108:
109: if (!target.hasRemaining()) {
110: return CoderResult.OVERFLOW;
111: }
112:
113: int sourceArrayIndex = source.position(), count = 0;
114: int sourceIndex = 0;
115: int ch = 0;
116: int oldTarget = target.position();
117: boolean doloop = true;
118:
119: if (fromUChar32 != 0 && target.hasRemaining()) {
120: ch = fromUChar32;
121: fromUChar32 = 0;
122:
123: if (sourceArrayIndex < source.limit()) {
124: /* test the following code unit */
125: char trail = source.get(sourceArrayIndex);
126: if (UTF16.isTrailSurrogate(trail)) {
127: ++sourceArrayIndex;
128: ch = UCharacter.getCodePoint((char) ch, trail);
129: /* convert this supplementary code point */
130: cr = CoderResult
131: .unmappableForLength(sourceArrayIndex);
132: doloop = false;
133: } else {
134: /* this is an unmatched lead code unit (1st surrogate) */
135: /* callback(illegal) */
136: fromUChar32 = (int) ch;
137: cr = CoderResult
138: .malformedForLength(sourceArrayIndex);
139: doloop = false;
140: }
141: } else {
142: /* no more input */
143: fromUChar32 = (int) ch;
144: doloop = false;
145: }
146: }
147: if (doloop) {
148: /* conversion loop */
149: ch = 0;
150: int ch2 = 0;
151: while (sourceArrayIndex < source.limit()) {
152: ch = source.get(sourceArrayIndex++);
153: if (ch <= 0xff) {
154: if (target.hasRemaining()) {
155: target.put((byte) ch);
156: } else {
157: cr = CoderResult.OVERFLOW;
158: break;
159: }
160: } else {
161: if (UTF16.isSurrogate((char) ch)) {
162: if (UTF16.isLeadSurrogate((char) ch)) {
163: //lowsurogate:
164: if (sourceArrayIndex < source.limit()) {
165: ch2 = source.get(sourceArrayIndex);
166: if (UTF16
167: .isTrailSurrogate((char) ch2)) {
168: ch = ((ch - UConverterSharedData.SURROGATE_HIGH_START) << UConverterSharedData.HALF_SHIFT)
169: + ch2
170: + UConverterSharedData.SURROGATE_LOW_BASE;
171: sourceArrayIndex++;
172: } else {
173: /* this is an unmatched trail code unit (2nd surrogate) */
174: /* callback(illegal) */
175: fromUChar32 = ch;
176: cr = CoderResult.OVERFLOW;
177: break;
178: }
179: } else {
180: /* ran out of source */
181: fromUChar32 = ch;
182: if (flush) {
183: /* this is an unmatched trail code unit (2nd surrogate) */
184: /* callback(illegal) */
185: cr = CoderResult
186: .malformedForLength(sourceArrayIndex);
187: }
188: break;
189: }
190: }
191: }
192: fromUChar32 = ch;
193: cr = CoderResult
194: .malformedForLength(sourceArrayIndex);
195: break;
196: }
197: }
198: }
199: /* set offsets since the start */
200: if (offsets != null) {
201: count = target.position() - oldTarget;
202: while (count > 0) {
203: offsets.put(sourceIndex++);
204: --count;
205: }
206: }
207:
208: source.position(sourceArrayIndex);
209: return cr;
210: }
211: }
212:
213: public CharsetDecoder newDecoder() {
214: return new CharsetDecoder88591(this );
215: }
216:
217: public CharsetEncoder newEncoder() {
218: return new CharsetEncoder88591(this);
219: }
220:
221: }
|