KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > schlichtherle > nio > charset > OctetCharset


1 /*
2  * OctetCharset.java
3  *
4  * Created on 13. Dezember 2005, 16:39
5  */

6 /*
7  * Copyright 2005 Schlichtherle IT Services
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package de.schlichtherle.nio.charset;
23
24 import java.nio.ByteBuffer JavaDoc;
25 import java.nio.CharBuffer JavaDoc;
26 import java.nio.charset.Charset JavaDoc;
27 import java.nio.charset.CharsetDecoder JavaDoc;
28 import java.nio.charset.CharsetEncoder JavaDoc;
29 import java.nio.charset.CoderResult JavaDoc;
30 import java.util.Arrays JavaDoc;
31
32 /**
33  * A memory efficient base class for simple 8 bit (octet) character sets.
34  *
35  * @author Christian Schlichtherle
36  * @version @version@
37  */

38 public abstract class OctetCharset extends Charset JavaDoc {
39
40     /**
41      * Use this character in the lookup table provided to the constructor for
42      * every character that does not have a replacement in 16 bit Unicode.
43      */

44     protected static final char REPLACEMENT = '\uFFFD';
45
46     private final char[] byte2char;
47     private final char[][] char2byte;
48
49     protected OctetCharset(String JavaDoc cname, String JavaDoc[] aliases, char[] byte2char) {
50         super(cname, aliases);
51
52         // Construct sparse inverse lookup table.
53
final char[][] char2byte = new char[256][];
54         for (char i = 0; i < 256; i++) {
55             final char c = byte2char[i];
56             if (c == REPLACEMENT)
57                 continue;
58
59             final int high = c >> 8; // char is unsigned!
60
char[] table = char2byte[high];
61             if (table == null) {
62                 table = new char[256];
63                 Arrays.fill(table, REPLACEMENT);
64                 char2byte[high] = table;
65             }
66             table[c & 0xFF] = i;
67         }
68
69         this.byte2char = byte2char;
70         this.char2byte = char2byte;
71     }
72
73     public boolean contains(Charset JavaDoc cs) {
74         return this.getClass().isInstance(cs);
75     }
76
77     public CharsetEncoder JavaDoc newEncoder() {
78         return new Encoder JavaDoc();
79     }
80
81     protected class Encoder extends CharsetEncoder JavaDoc {
82
83         protected Encoder() {
84             super(OctetCharset.this, 1, 1);
85         }
86
87         protected CoderResult JavaDoc encodeLoop(CharBuffer JavaDoc in, ByteBuffer JavaDoc out) {
88             final char[][] c2b = char2byte;
89             while (in.hasRemaining()) {
90                 if (!out.hasRemaining())
91                     return CoderResult.OVERFLOW;
92                 final char c = in.get();
93                 final char[] table = c2b[c >> 8]; // char is unsigned!
94
final char b;
95                 if (table == null || (b = table[c & 0xFF]) == REPLACEMENT) {
96                     in.position(in.position() - 1); // push back
97
return CoderResult.unmappableForLength(1);
98                 }
99                 out.put((byte)(b & 0xFF));
100             }
101             return CoderResult.UNDERFLOW;
102         }
103     }
104
105     public CharsetDecoder JavaDoc newDecoder() {
106         return new Decoder JavaDoc();
107     }
108
109     protected class Decoder extends CharsetDecoder JavaDoc {
110
111         protected Decoder() {
112             super(OctetCharset.this, 1, 1);
113         }
114
115         protected CoderResult JavaDoc decodeLoop(ByteBuffer JavaDoc in, CharBuffer JavaDoc out) {
116             final char[] b2c = byte2char;
117             while (in.hasRemaining()) {
118                 if (!out.hasRemaining())
119                     return CoderResult.OVERFLOW;
120                 final char c = b2c[in.get() & 0xFF];
121                 if (c == REPLACEMENT) {
122                     in.position(in.position() - 1); // push back
123
return CoderResult.unmappableForLength(1);
124                 }
125                 out.put(c);
126             }
127             return CoderResult.UNDERFLOW;
128         }
129     }
130 }
131
Popular Tags