private short readPlainShort() throws IOException {
   input.ensureReadAhead(2);
   int count = input.pos;
   final byte buf[] = input.buf;
   int ch1 = (buf[count++] + 256) & 0xff;
   int ch2 = (buf[count++] + 256) & 0xff;
   input.pos = count;
   return (short) ((ch2 << 8) + (ch1 << 0));
 }
 /**
  * len < 127 !!!!!
  *
  * @return
  * @throws java.io.IOException
  */
 @Override
 public String readStringAsc() throws IOException {
   int len = readFByte();
   if (ascStringCache == null || ascStringCache.length < len) ascStringCache = new byte[len];
   input.ensureReadAhead(len);
   System.arraycopy(input.buf, input.pos, ascStringCache, 0, len);
   input.pos += len;
   return new String(ascStringCache, 0, 0, len);
 }
 @Override
 public short readFShort() throws IOException {
   input.ensureReadAhead(3);
   int head = readFByte() & 0xff;
   if (head >= 0 && head < 255) {
     return (short) head;
   }
   int ch1 = readFByte() & 0xff;
   int ch2 = readFByte() & 0xff;
   return (short) ((ch1 << 0) + (ch2 << 8));
 }
 @Override
 public char readFChar() throws IOException {
   input.ensureReadAhead(3);
   char head = (char) ((readFByte() + 256) & 0xff);
   // -128 = short byte, -127 == 4 byte
   if (head >= 0 && head < 255) {
     return head;
   }
   int ch1 = readFByte() & 0xff;
   int ch2 = readFByte() & 0xff;
   return (char) ((ch1 << 0) + (ch2 << 8));
 }
 @Override
 public int readPlainInt() throws IOException {
   input.ensureReadAhead(4);
   int count = input.pos;
   final byte buf[] = input.buf;
   int ch1 = (buf[count++] + 256) & 0xff;
   int ch2 = (buf[count++] + 256) & 0xff;
   int ch3 = (buf[count++] + 256) & 0xff;
   int ch4 = (buf[count++] + 256) & 0xff;
   input.pos = count;
   int res = (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
   return res;
 }
 @Override
 public long readFLong() throws IOException {
   input.ensureReadAhead(9);
   byte head = readFByte();
   // -128 = short byte, -127 == 4 byte
   if (head > -126 && head <= 127) {
     return head;
   }
   if (head == -128) {
     int count = input.pos;
     final byte buf[] = input.buf;
     int ch1 = (buf[count++] + 256) & 0xff;
     int ch2 = (buf[count++] + 256) & 0xff;
     input.pos = count;
     return (short) ((ch2 << 8) + (ch1 << 0));
   } else if (head == -127) {
     int count = input.pos;
     final byte buf[] = input.buf;
     int ch1 = (buf[count++] + 256) & 0xff;
     int ch2 = (buf[count++] + 256) & 0xff;
     int ch3 = (buf[count++] + 256) & 0xff;
     int ch4 = (buf[count++] + 256) & 0xff;
     input.pos = count;
     int res = (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
     return res;
   } else {
     ensureReadAhead(8);
     int count = input.pos;
     final byte buf[] = input.buf;
     long ch8 = (buf[count++] + 256) & 0xff;
     long ch7 = (buf[count++] + 256) & 0xff;
     long ch6 = (buf[count++] + 256) & 0xff;
     long ch5 = (buf[count++] + 256) & 0xff;
     long ch4 = (buf[count++] + 256) & 0xff;
     long ch3 = (buf[count++] + 256) & 0xff;
     long ch2 = (buf[count++] + 256) & 0xff;
     long ch1 = (buf[count++] + 256) & 0xff;
     input.pos = count;
     return ((ch1 << 56)
         + (ch2 << 48)
         + (ch3 << 40)
         + (ch4 << 32)
         + (ch5 << 24)
         + (ch6 << 16)
         + (ch7 << 8)
         + (ch8 << 0));
   }
 }
 public String readStringUTF() throws IOException {
   int len = readFInt();
   char[] charBuf = getCharBuf(len * 3);
   input.ensureReadAhead(len * 3);
   byte buf[] = input.buf;
   int count = input.pos;
   int chcount = 0;
   for (int i = 0; i < len; i++) {
     char head = (char) ((buf[count++] + 256) & 0xff);
     if (head < 255) {
       charBuf[chcount++] = head;
     } else {
       int ch1 = ((buf[count++] + 256) & 0xff);
       int ch2 = ((buf[count++] + 256) & 0xff);
       charBuf[chcount++] = (char) ((ch1 << 0) + (ch2 << 8));
     }
   }
   input.pos = count;
   return new String(charBuf, 0, chcount);
 }
 private long readPlainLong() throws IOException {
   input.ensureReadAhead(8);
   int count = input.pos;
   final byte buf[] = input.buf;
   long ch8 = (buf[count++] + 256) & 0xff;
   long ch7 = (buf[count++] + 256) & 0xff;
   long ch6 = (buf[count++] + 256) & 0xff;
   long ch5 = (buf[count++] + 256) & 0xff;
   long ch4 = (buf[count++] + 256) & 0xff;
   long ch3 = (buf[count++] + 256) & 0xff;
   long ch2 = (buf[count++] + 256) & 0xff;
   long ch1 = (buf[count++] + 256) & 0xff;
   input.pos = count;
   return ((ch1 << 56)
       + (ch2 << 48)
       + (ch3 << 40)
       + (ch4 << 32)
       + (ch5 << 24)
       + (ch6 << 16)
       + (ch7 << 8)
       + (ch8 << 0));
 }
 @Override
 public void readPlainBytes(byte[] b, int off, int len) {
   input.ensureReadAhead(len);
   System.arraycopy(input.buf, input.pos, b, off, len);
 }
 public void ensureReadAhead(int bytes) {
   input.ensureReadAhead(bytes);
 }
 @Override
 public final byte readFByte() throws IOException {
   input.ensureReadAhead(1);
   return input.buf[input.pos++];
 }