src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/hpack/StringReader.java
changeset 47216 71c04702a3d5
parent 42460 7133f144981a
child 48083 b1c1b4ef4be2
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     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  */
       
    25 package jdk.incubator.http.internal.hpack;
       
    26 
       
    27 import java.nio.ByteBuffer;
       
    28 import java.util.Arrays;
       
    29 
       
    30 //
       
    31 //          0   1   2   3   4   5   6   7
       
    32 //        +---+---+---+---+---+---+---+---+
       
    33 //        | H |    String Length (7+)     |
       
    34 //        +---+---------------------------+
       
    35 //        |  String Data (Length octets)  |
       
    36 //        +-------------------------------+
       
    37 //
       
    38 final class StringReader {
       
    39 
       
    40     private static final int NEW             = 0;
       
    41     private static final int FIRST_BYTE_READ = 1;
       
    42     private static final int LENGTH_READ     = 2;
       
    43     private static final int DONE            = 4;
       
    44 
       
    45     private final IntegerReader intReader = new IntegerReader();
       
    46     private final Huffman.Reader huffmanReader = new Huffman.Reader();
       
    47     private final ISO_8859_1.Reader plainReader = new ISO_8859_1.Reader();
       
    48 
       
    49     private int state = NEW;
       
    50 
       
    51     private boolean huffman;
       
    52     private int remainingLength;
       
    53 
       
    54     boolean read(ByteBuffer input, Appendable output) {
       
    55         if (state == DONE) {
       
    56             return true;
       
    57         }
       
    58         if (!input.hasRemaining()) {
       
    59             return false;
       
    60         }
       
    61         if (state == NEW) {
       
    62             int p = input.position();
       
    63             huffman = (input.get(p) & 0b10000000) != 0;
       
    64             state = FIRST_BYTE_READ;
       
    65             intReader.configure(7);
       
    66         }
       
    67         if (state == FIRST_BYTE_READ) {
       
    68             boolean lengthRead = intReader.read(input);
       
    69             if (!lengthRead) {
       
    70                 return false;
       
    71             }
       
    72             remainingLength = intReader.get();
       
    73             state = LENGTH_READ;
       
    74         }
       
    75         if (state == LENGTH_READ) {
       
    76             boolean isLast = input.remaining() >= remainingLength;
       
    77             int oldLimit = input.limit();
       
    78             if (isLast) {
       
    79                 input.limit(input.position() + remainingLength);
       
    80             }
       
    81             remainingLength -= Math.min(input.remaining(), remainingLength);
       
    82             if (huffman) {
       
    83                 huffmanReader.read(input, output, isLast);
       
    84             } else {
       
    85                 plainReader.read(input, output);
       
    86             }
       
    87             if (isLast) {
       
    88                 input.limit(oldLimit);
       
    89                 state = DONE;
       
    90             }
       
    91             return isLast;
       
    92         }
       
    93         throw new InternalError(Arrays.toString(
       
    94                 new Object[]{state, huffman, remainingLength}));
       
    95     }
       
    96 
       
    97     boolean isHuffmanEncoded() {
       
    98         if (state < FIRST_BYTE_READ) {
       
    99             throw new IllegalStateException("Has not been fully read yet");
       
   100         }
       
   101         return huffman;
       
   102     }
       
   103 
       
   104     void reset() {
       
   105         if (huffman) {
       
   106             huffmanReader.reset();
       
   107         } else {
       
   108             plainReader.reset();
       
   109         }
       
   110         intReader.reset();
       
   111         state = NEW;
       
   112     }
       
   113 }