1/*
2 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.font;
27
28import java.nio.CharBuffer;
29import java.nio.ByteBuffer;
30import java.nio.charset.*;
31import sun.nio.cs.*;
32import static sun.nio.cs.CharsetMapping.*;
33
34public class X11GB2312 extends Charset {
35    public X11GB2312 () {
36        super("X11GB2312", null);
37    }
38    public CharsetEncoder newEncoder() {
39        return new Encoder(this);
40    }
41    public CharsetDecoder newDecoder() {
42        return new Decoder(this);
43    }
44
45    public boolean contains(Charset cs) {
46        return cs instanceof X11GB2312;
47    }
48
49    private class Encoder extends CharsetEncoder {
50        private DoubleByte.Encoder enc = (DoubleByte.Encoder)new EUC_CN().newEncoder();
51
52        public Encoder(Charset cs) {
53            super(cs, 2.0f, 2.0f);
54        }
55
56        public boolean canEncode(char c) {
57            if (c <= 0x7F) {
58                return false;
59            }
60            return enc.canEncode(c);
61        }
62
63        protected int encodeDouble(char c) {
64            return enc.encodeChar(c);
65        }
66
67        protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
68            char[] sa = src.array();
69            int sp = src.arrayOffset() + src.position();
70            int sl = src.arrayOffset() + src.limit();
71
72            byte[] da = dst.array();
73            int dp = dst.arrayOffset() + dst.position();
74            int dl = dst.arrayOffset() + dst.limit();
75
76            try {
77                while (sp < sl) {
78                    char c = sa[sp];
79                    if (c <= '\u007f')
80                        return CoderResult.unmappableForLength(1);
81                    int ncode = encodeDouble(c);
82                    if (ncode != 0 && c != '\u0000' ) {
83                        da[dp++] = (byte) ((ncode  >> 8) & 0x7f);
84                        da[dp++] = (byte) (ncode & 0x7f);
85                        sp++;
86                        continue;
87                    }
88                    return CoderResult.unmappableForLength(1);
89                }
90                return CoderResult.UNDERFLOW;
91            } finally {
92                src.position(sp - src.arrayOffset());
93                dst.position(dp - dst.arrayOffset());
94            }
95        }
96        public boolean isLegalReplacement(byte[] repl) {
97            return true;
98        }
99    }
100
101    private class Decoder extends  CharsetDecoder {
102        private DoubleByte.Decoder dec = (DoubleByte.Decoder)new EUC_CN().newDecoder();
103
104        public Decoder(Charset cs) {
105            super(cs, 0.5f, 1.0f);
106        }
107
108        protected char decodeDouble(int b1, int b2) {
109            return dec.decodeDouble(b1, b2);
110        }
111
112        protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
113            byte[] sa = src.array();
114            int sp = src.arrayOffset() + src.position();
115            int sl = src.arrayOffset() + src.limit();
116            assert (sp <= sl);
117            sp = (sp <= sl ? sp : sl);
118            char[] da = dst.array();
119            int dp = dst.arrayOffset() + dst.position();
120            int dl = dst.arrayOffset() + dst.limit();
121            assert (dp <= dl);
122            dp = (dp <= dl ? dp : dl);
123
124            try {
125                while (sp < sl) {
126                    if ( sl - sp < 2) {
127                        return CoderResult.UNDERFLOW;
128                    }
129                    int b1 = sa[sp] & 0xFF | 0x80;
130                    int b2 = sa[sp + 1] & 0xFF | 0x80;
131                    char c = decodeDouble(b1, b2);
132                    if (c == UNMAPPABLE_DECODING) {
133                        return CoderResult.unmappableForLength(2);
134                    }
135                    if (dl - dp < 1)
136                        return CoderResult.OVERFLOW;
137                    da[dp++] = c;
138                    sp +=2;
139                }
140                return CoderResult.UNDERFLOW;
141            } finally {
142                src.position(sp - src.arrayOffset());
143                dst.position(dp - dst.arrayOffset());
144            }
145
146        }
147    }
148
149}
150