1/*
2 * Copyright (c) 2015, 2016, 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 */
25package jdk.incubator.http.internal.hpack;
26
27import java.io.IOException;
28import java.io.UncheckedIOException;
29import java.nio.ByteBuffer;
30
31//
32// Custom implementation of ISO/IEC 8859-1:1998
33//
34// The rationale behind this is not to deal with CharsetEncoder/CharsetDecoder,
35// basically because it would require wrapping every single CharSequence into a
36// CharBuffer and then copying it back.
37//
38// But why not to give a CharBuffer instead of Appendable? Because I can choose
39// an Appendable (e.g. StringBuilder) that adjusts its length when needed and
40// therefore not to deal with pre-sized CharBuffers or copying.
41//
42// The encoding is simple and well known: 1 byte <-> 1 char
43//
44final class ISO_8859_1 {
45
46    private ISO_8859_1() { }
47
48    public static final class Reader {
49
50        public void read(ByteBuffer source, Appendable destination) {
51            for (int i = 0, len = source.remaining(); i < len; i++) {
52                char c = (char) (source.get() & 0xff);
53                try {
54                    destination.append(c);
55                } catch (IOException e) {
56                    throw new UncheckedIOException
57                            ("Error appending to the destination", e);
58                }
59            }
60        }
61
62        public Reader reset() {
63            return this;
64        }
65    }
66
67    public static final class Writer {
68
69        private CharSequence source;
70        private int pos;
71        private int end;
72
73        public Writer configure(CharSequence source, int start, int end) {
74            this.source = source;
75            this.pos = start;
76            this.end = end;
77            return this;
78        }
79
80        public boolean write(ByteBuffer destination) {
81            for (; pos < end; pos++) {
82                char c = source.charAt(pos);
83                if (c > '\u00FF') {
84                    throw new IllegalArgumentException(
85                            "Illegal ISO-8859-1 char: " + (int) c);
86                }
87                if (destination.hasRemaining()) {
88                    destination.put((byte) c);
89                } else {
90                    return false;
91                }
92            }
93            return true;
94        }
95
96        public Writer reset() {
97            source = null;
98            pos = -1;
99            end = -1;
100            return this;
101        }
102    }
103}
104