< prev index next >
   1 /*
   2  * To change this license header, choose License Headers in Project Properties.
   3  * To change this template file, choose Tools | Templates
   4  * and open the template in the editor.
   5  */
   6 package java.net.http;
   7 
   8 import java.nio.ByteBuffer;
   9 import java.util.LinkedList;
  10 import java.util.List;
  11 
  12 /**
  13  * Represents one frame. May be initialized with a leftover buffer from previous
  14  * frame. Call {@code haveFrame()} to determine if buffers contains at least one
  15  * frame. If false, the obtain another buffer and call {@code}input(ByteBuffer)}.
  16  * There may be additional bytes at end of the frame list.
  17  */
  18 class FrameReader {
  19 
  20     final List<ByteBuffer> buffers;
  21 
  22     FrameReader() {
  23         buffers = new LinkedList<>();
  24     }
  25 
  26     FrameReader(FrameReader that) {
  27         this.buffers = that.buffers;
  28     }
  29 
  30     FrameReader(ByteBuffer remainder) {
  31         buffers = new LinkedList<>();
  32         if (remainder != null) {
  33             buffers.add(remainder);
  34         }
  35     }
  36 
  37     public synchronized void input(ByteBuffer buffer) {
  38         buffers.add(buffer);
  39     }
  40 
  41     public synchronized boolean haveFrame() {
  42         //buffers = Utils.superCompact(buffers, () -> ByteBuffer.allocate(Utils.BUFSIZE));
  43         int size = 0;
  44         for (ByteBuffer buffer : buffers) {
  45             size += buffer.remaining();
  46         }
  47         if (size < 3) {
  48             return false; // don't have length yet
  49         }
  50         // we at least have length field
  51         int length = 0;
  52         int j = 0;
  53         ByteBuffer b = buffers.get(j);
  54         b.mark();
  55         for (int i=0; i<3; i++) {
  56             while (!b.hasRemaining()) {
  57                 b.reset();
  58                 b = buffers.get(++j);
  59                 b.mark();
  60             }
  61             length = (length << 8) + (b.get() & 0xff);
  62         }
  63         b.reset();
  64         return (size >= length + 9); // frame length
  65     }
  66 
  67     synchronized List<ByteBuffer> frame() {
  68         return buffers;
  69     }
  70 }
< prev index next >