49 private final int shift; |
49 private final int shift; |
50 |
50 |
51 private final Surrogate.Parser sgp = new Surrogate.Parser(); |
51 private final Surrogate.Parser sgp = new Surrogate.Parser(); |
52 |
52 |
53 protected SingleByteEncoder(Charset cs, |
53 protected SingleByteEncoder(Charset cs, |
54 short[] index1, String index2, |
54 short[] index1, String index2, |
55 int mask1, int mask2, int shift) |
55 int mask1, int mask2, int shift) |
56 { |
56 { |
57 super(cs, 1.0f, 1.0f); |
57 super(cs, 1.0f, 1.0f); |
58 this.index1 = index1; |
58 this.index1 = index1; |
59 this.index2 = index2; |
59 this.index2 = index2; |
60 this.mask1 = mask1; |
60 this.mask1 = mask1; |
61 this.mask2 = mask2; |
61 this.mask2 = mask2; |
62 this.shift = shift; |
62 this.shift = shift; |
63 } |
63 } |
64 |
64 |
65 public boolean canEncode(char c) { |
65 public boolean canEncode(char c) { |
66 char testEncode; |
66 char testEncode; |
67 testEncode = index2.charAt(index1[(c & mask1) >> shift] |
67 testEncode = index2.charAt(index1[(c & mask1) >> shift] |
68 + (c & mask2)); |
68 + (c & mask2)); |
69 if (testEncode == '\u0000') |
69 if (testEncode == '\u0000') |
70 return false; |
70 return false; |
71 else |
71 else |
72 return true; |
72 return true; |
73 } |
73 } |
74 |
74 |
75 private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) { |
75 private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) { |
76 char[] sa = src.array(); |
76 char[] sa = src.array(); |
77 int sp = src.arrayOffset() + src.position(); |
77 int sp = src.arrayOffset() + src.position(); |
78 int sl = src.arrayOffset() + src.limit(); |
78 int sl = src.arrayOffset() + src.limit(); |
79 sp = (sp <= sl ? sp : sl); |
79 sp = (sp <= sl ? sp : sl); |
80 byte[] da = dst.array(); |
80 byte[] da = dst.array(); |
81 int dp = dst.arrayOffset() + dst.position(); |
81 int dp = dst.arrayOffset() + dst.position(); |
82 int dl = dst.arrayOffset() + dst.limit(); |
82 int dl = dst.arrayOffset() + dst.limit(); |
83 dp = (dp <= dl ? dp : dl); |
83 dp = (dp <= dl ? dp : dl); |
84 |
84 |
85 try { |
85 try { |
86 while (sp < sl) { |
86 while (sp < sl) { |
87 char c = sa[sp]; |
87 char c = sa[sp]; |
88 if (Surrogate.is(c)) { |
88 if (Surrogate.is(c)) { |
89 if (sgp.parse(c, sa, sp, sl) < 0) |
89 if (sgp.parse(c, sa, sp, sl) < 0) |
90 return sgp.error(); |
90 return sgp.error(); |
91 return sgp.unmappableResult(); |
91 return sgp.unmappableResult(); |
92 } |
92 } |
93 if (c >= '\uFFFE') |
93 if (c >= '\uFFFE') |
94 return CoderResult.unmappableForLength(1); |
94 return CoderResult.unmappableForLength(1); |
95 if (dl - dp < 1) |
95 if (dl - dp < 1) |
96 return CoderResult.OVERFLOW; |
96 return CoderResult.OVERFLOW; |
97 |
97 |
98 char e = index2.charAt(index1[(c & mask1) >> shift] |
98 char e = index2.charAt(index1[(c & mask1) >> shift] |
99 + (c & mask2)); |
99 + (c & mask2)); |
100 |
100 |
101 // If output byte is zero because input char is zero |
101 // If output byte is zero because input char is zero |
102 // then character is mappable, o.w. fail |
102 // then character is mappable, o.w. fail |
103 if (e == '\u0000' && c != '\u0000') |
103 if (e == '\u0000' && c != '\u0000') |
104 return CoderResult.unmappableForLength(1); |
104 return CoderResult.unmappableForLength(1); |
105 |
105 |
106 sp++; |
106 sp++; |
107 da[dp++] = (byte)e; |
107 da[dp++] = (byte)e; |
108 } |
108 } |
109 return CoderResult.UNDERFLOW; |
109 return CoderResult.UNDERFLOW; |
110 } finally { |
110 } finally { |
111 src.position(sp - src.arrayOffset()); |
111 src.position(sp - src.arrayOffset()); |
112 dst.position(dp - dst.arrayOffset()); |
112 dst.position(dp - dst.arrayOffset()); |
113 } |
113 } |
114 } |
114 } |
115 |
115 |
116 private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) { |
116 private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) { |
117 int mark = src.position(); |
117 int mark = src.position(); |
118 try { |
118 try { |
119 while (src.hasRemaining()) { |
119 while (src.hasRemaining()) { |
120 char c = src.get(); |
120 char c = src.get(); |
121 if (Surrogate.is(c)) { |
121 if (Surrogate.is(c)) { |
122 if (sgp.parse(c, src) < 0) |
122 if (sgp.parse(c, src) < 0) |
123 return sgp.error(); |
123 return sgp.error(); |
124 return sgp.unmappableResult(); |
124 return sgp.unmappableResult(); |
125 } |
125 } |
126 if (c >= '\uFFFE') |
126 if (c >= '\uFFFE') |
127 return CoderResult.unmappableForLength(1); |
127 return CoderResult.unmappableForLength(1); |
128 if (!dst.hasRemaining()) |
128 if (!dst.hasRemaining()) |
129 return CoderResult.OVERFLOW; |
129 return CoderResult.OVERFLOW; |
130 |
130 |
131 char e = index2.charAt(index1[(c & mask1) >> shift] |
131 char e = index2.charAt(index1[(c & mask1) >> shift] |
132 + (c & mask2)); |
132 + (c & mask2)); |
133 |
133 |
134 // If output byte is zero because input char is zero |
134 // If output byte is zero because input char is zero |
135 // then character is mappable, o.w. fail |
135 // then character is mappable, o.w. fail |
136 if (e == '\u0000' && c != '\u0000') |
136 if (e == '\u0000' && c != '\u0000') |
137 return CoderResult.unmappableForLength(1); |
137 return CoderResult.unmappableForLength(1); |
138 |
138 |
139 mark++; |
139 mark++; |
140 dst.put((byte)e); |
140 dst.put((byte)e); |
141 } |
141 } |
142 return CoderResult.UNDERFLOW; |
142 return CoderResult.UNDERFLOW; |
143 } finally { |
143 } finally { |
144 src.position(mark); |
144 src.position(mark); |
145 } |
145 } |
146 } |
146 } |
147 |
147 |
148 protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { |
148 protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { |
149 if (true && src.hasArray() && dst.hasArray()) |
149 if (true && src.hasArray() && dst.hasArray()) |
150 return encodeArrayLoop(src, dst); |
150 return encodeArrayLoop(src, dst); |
151 else |
151 else |
152 return encodeBufferLoop(src, dst); |
152 return encodeBufferLoop(src, dst); |
153 } |
153 } |
154 |
154 |
155 public byte encode(char inputChar) { |
155 public byte encode(char inputChar) { |
156 return (byte)index2.charAt(index1[(inputChar & mask1) >> shift] + |
156 return (byte)index2.charAt(index1[(inputChar & mask1) >> shift] + |
157 (inputChar & mask2)); |
157 (inputChar & mask2)); |
158 } |
158 } |
159 } |
159 } |