< prev index next >

test/jdk/java/net/httpclient/http2/jdk.incubator.httpclient/jdk/incubator/http/internal/hpack/HuffmanTest.java

Print this page


   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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package jdk.incubator.http.internal.hpack;
  24 
  25 import org.testng.annotations.Test;
  26 


  27 import java.nio.ByteBuffer;
  28 import java.util.Stack;
  29 import java.util.regex.Matcher;
  30 import java.util.regex.Pattern;
  31 
  32 import static java.lang.Integer.parseInt;
  33 import static org.testng.Assert.*;
  34 
  35 public final class HuffmanTest {
  36 
  37     //
  38     // https://tools.ietf.org/html/rfc7541#appendix-B
  39     //
  40     private static final String SPEC =
  41             // @formatter:off
  42      "                          code as bits                 as hex   len\n" +
  43      "        sym              aligned to MSB                aligned   in\n" +
  44      "                                                       to LSB   bits\n" +
  45      "       (  0)  |11111111|11000                             1ff8  [13]\n" +
  46      "       (  1)  |11111111|11111111|1011000                7fffd8  [23]\n" +


 285      "       (240)  |11111111|11111111|11111010|11           3ffffeb  [26]\n" +
 286      "       (241)  |11111111|11111111|11111100|110          7ffffe6  [27]\n" +
 287      "       (242)  |11111111|11111111|11111011|00           3ffffec  [26]\n" +
 288      "       (243)  |11111111|11111111|11111011|01           3ffffed  [26]\n" +
 289      "       (244)  |11111111|11111111|11111100|111          7ffffe7  [27]\n" +
 290      "       (245)  |11111111|11111111|11111101|000          7ffffe8  [27]\n" +
 291      "       (246)  |11111111|11111111|11111101|001          7ffffe9  [27]\n" +
 292      "       (247)  |11111111|11111111|11111101|010          7ffffea  [27]\n" +
 293      "       (248)  |11111111|11111111|11111101|011          7ffffeb  [27]\n" +
 294      "       (249)  |11111111|11111111|11111111|1110         ffffffe  [28]\n" +
 295      "       (250)  |11111111|11111111|11111101|100          7ffffec  [27]\n" +
 296      "       (251)  |11111111|11111111|11111101|101          7ffffed  [27]\n" +
 297      "       (252)  |11111111|11111111|11111101|110          7ffffee  [27]\n" +
 298      "       (253)  |11111111|11111111|11111101|111          7ffffef  [27]\n" +
 299      "       (254)  |11111111|11111111|11111110|000          7fffff0  [27]\n" +
 300      "       (255)  |11111111|11111111|11111011|10           3ffffee  [26]\n" +
 301      "   EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]";
 302     // @formatter:on
 303 
 304     @Test
 305     public void read_table() {
 306         Pattern line = Pattern.compile(
 307                 "\\(\\s*(?<ascii>\\d+)\\s*\\)\\s*(?<binary>(\\|(0|1)+)+)\\s*" +
 308                         "(?<hex>[0-9a-zA-Z]+)\\s*\\[\\s*(?<len>\\d+)\\s*\\]");
 309         Matcher m = line.matcher(SPEC);
 310         int i = 0;
 311         while (m.find()) {
 312             String ascii = m.group("ascii");
 313             String binary = m.group("binary").replaceAll("\\|", "");
 314             String hex = m.group("hex");
 315             String len = m.group("len");
 316 
 317             // Several sanity checks for the data read from the table, just to
 318             // make sure what we read makes sense
 319             assertEquals(parseInt(len), binary.length());
 320             assertEquals(parseInt(binary, 2), parseInt(hex, 16));
 321 
 322             int expected = parseInt(ascii);
 323 
 324             // TODO: find actual eos, do not hardcode it!
 325             byte[] bytes = intToBytes(0x3fffffff, 30,


 538                 count++;
 539             }
 540         }
 541         assertEquals(count, 257);
 542     }
 543 
 544     @Test
 545     public void cant_encode_outside_byte() {
 546         TestHelper.Block<Object> coding =
 547                 () -> new Huffman.Writer()
 548                         .from(((char) 256) + "", 0, 1)
 549                         .write(ByteBuffer.allocate(1));
 550         RuntimeException e =
 551                 TestHelper.assertVoidThrows(RuntimeException.class, coding);
 552         TestHelper.assertExceptionMessageContains(e, "char");
 553     }
 554 
 555     private static void read(String hexdump, String decoded) {
 556         ByteBuffer source = SpecHelper.toBytes(hexdump);
 557         Appendable actual = new StringBuilder();

 558         new Huffman.Reader().read(source, actual, true);



 559         assertEquals(actual.toString(), decoded);
 560     }
 561 
 562     private static void write(String decoded, String hexdump) {
 563         int n = Huffman.INSTANCE.lengthOf(decoded);
 564         ByteBuffer destination = ByteBuffer.allocate(n); // Extra margin (1) to test having more bytes in the destination than needed is ok
 565         Huffman.Writer writer = new Huffman.Writer();
 566         BuffersTestingKit.forEachSplit(destination, byteBuffers -> {
 567             writer.from(decoded, 0, decoded.length());
 568             boolean written = false;
 569             for (ByteBuffer b : byteBuffers) {
 570                 int pos = b.position();
 571                 written = writer.write(b);
 572                 b.position(pos);
 573             }
 574             assertTrue(written);
 575             ByteBuffer concated = BuffersTestingKit.concat(byteBuffers);
 576             String actual = SpecHelper.toHexdump(concated);
 577             assertEquals(actual, hexdump);
 578             writer.reset();


   1 /*
   2  * Copyright (c) 2015, 2017, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package jdk.incubator.http.internal.hpack;
  24 
  25 import org.testng.annotations.Test;
  26 
  27 import java.io.IOException;
  28 import java.io.UncheckedIOException;
  29 import java.nio.ByteBuffer;
  30 import java.util.Stack;
  31 import java.util.regex.Matcher;
  32 import java.util.regex.Pattern;
  33 
  34 import static java.lang.Integer.parseInt;
  35 import static org.testng.Assert.*;
  36 
  37 public final class HuffmanTest {
  38 
  39     //
  40     // https://tools.ietf.org/html/rfc7541#appendix-B
  41     //
  42     private static final String SPEC =
  43             // @formatter:off
  44      "                          code as bits                 as hex   len\n" +
  45      "        sym              aligned to MSB                aligned   in\n" +
  46      "                                                       to LSB   bits\n" +
  47      "       (  0)  |11111111|11000                             1ff8  [13]\n" +
  48      "       (  1)  |11111111|11111111|1011000                7fffd8  [23]\n" +


 287      "       (240)  |11111111|11111111|11111010|11           3ffffeb  [26]\n" +
 288      "       (241)  |11111111|11111111|11111100|110          7ffffe6  [27]\n" +
 289      "       (242)  |11111111|11111111|11111011|00           3ffffec  [26]\n" +
 290      "       (243)  |11111111|11111111|11111011|01           3ffffed  [26]\n" +
 291      "       (244)  |11111111|11111111|11111100|111          7ffffe7  [27]\n" +
 292      "       (245)  |11111111|11111111|11111101|000          7ffffe8  [27]\n" +
 293      "       (246)  |11111111|11111111|11111101|001          7ffffe9  [27]\n" +
 294      "       (247)  |11111111|11111111|11111101|010          7ffffea  [27]\n" +
 295      "       (248)  |11111111|11111111|11111101|011          7ffffeb  [27]\n" +
 296      "       (249)  |11111111|11111111|11111111|1110         ffffffe  [28]\n" +
 297      "       (250)  |11111111|11111111|11111101|100          7ffffec  [27]\n" +
 298      "       (251)  |11111111|11111111|11111101|101          7ffffed  [27]\n" +
 299      "       (252)  |11111111|11111111|11111101|110          7ffffee  [27]\n" +
 300      "       (253)  |11111111|11111111|11111101|111          7ffffef  [27]\n" +
 301      "       (254)  |11111111|11111111|11111110|000          7fffff0  [27]\n" +
 302      "       (255)  |11111111|11111111|11111011|10           3ffffee  [26]\n" +
 303      "   EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]";
 304     // @formatter:on
 305 
 306     @Test
 307     public void read_table() throws IOException {
 308         Pattern line = Pattern.compile(
 309                 "\\(\\s*(?<ascii>\\d+)\\s*\\)\\s*(?<binary>(\\|(0|1)+)+)\\s*" +
 310                         "(?<hex>[0-9a-zA-Z]+)\\s*\\[\\s*(?<len>\\d+)\\s*\\]");
 311         Matcher m = line.matcher(SPEC);
 312         int i = 0;
 313         while (m.find()) {
 314             String ascii = m.group("ascii");
 315             String binary = m.group("binary").replaceAll("\\|", "");
 316             String hex = m.group("hex");
 317             String len = m.group("len");
 318 
 319             // Several sanity checks for the data read from the table, just to
 320             // make sure what we read makes sense
 321             assertEquals(parseInt(len), binary.length());
 322             assertEquals(parseInt(binary, 2), parseInt(hex, 16));
 323 
 324             int expected = parseInt(ascii);
 325 
 326             // TODO: find actual eos, do not hardcode it!
 327             byte[] bytes = intToBytes(0x3fffffff, 30,


 540                 count++;
 541             }
 542         }
 543         assertEquals(count, 257);
 544     }
 545 
 546     @Test
 547     public void cant_encode_outside_byte() {
 548         TestHelper.Block<Object> coding =
 549                 () -> new Huffman.Writer()
 550                         .from(((char) 256) + "", 0, 1)
 551                         .write(ByteBuffer.allocate(1));
 552         RuntimeException e =
 553                 TestHelper.assertVoidThrows(RuntimeException.class, coding);
 554         TestHelper.assertExceptionMessageContains(e, "char");
 555     }
 556 
 557     private static void read(String hexdump, String decoded) {
 558         ByteBuffer source = SpecHelper.toBytes(hexdump);
 559         Appendable actual = new StringBuilder();
 560         try {
 561             new Huffman.Reader().read(source, actual, true);
 562         } catch (IOException e) {
 563             throw new UncheckedIOException(e);
 564         }
 565         assertEquals(actual.toString(), decoded);
 566     }
 567 
 568     private static void write(String decoded, String hexdump) {
 569         int n = Huffman.INSTANCE.lengthOf(decoded);
 570         ByteBuffer destination = ByteBuffer.allocate(n); // Extra margin (1) to test having more bytes in the destination than needed is ok
 571         Huffman.Writer writer = new Huffman.Writer();
 572         BuffersTestingKit.forEachSplit(destination, byteBuffers -> {
 573             writer.from(decoded, 0, decoded.length());
 574             boolean written = false;
 575             for (ByteBuffer b : byteBuffers) {
 576                 int pos = b.position();
 577                 written = writer.write(b);
 578                 b.position(pos);
 579             }
 580             assertTrue(written);
 581             ByteBuffer concated = BuffersTestingKit.concat(byteBuffers);
 582             String actual = SpecHelper.toHexdump(concated);
 583             assertEquals(actual, hexdump);
 584             writer.reset();


< prev index next >