public static byte[] decodeBlobVar(PositionedByteRange src) {
    final byte header = src.get();
    if (header == NULL || header == DESCENDING.apply(NULL)) {
      return null;
    }
    assert header == BLOB_VAR || header == DESCENDING.apply(BLOB_VAR);
    Order ord = BLOB_VAR == header ? ASCENDING : DESCENDING;
    if (src.peek() == ord.apply(TERM)) {
      // skip empty input buffer.
      src.get();
      return new byte[0];
    }
    final int offset = src.getOffset(), start = src.getPosition();
    int end;
    byte[] a = src.getBytes();
    for (end = start; (byte) (ord.apply(a[offset + end]) & 0x80) != TERM; end++)
      ;
    end++; // increment end to 1-past last byte
    // create ret buffer using length of encoded data + 1 (header byte)
    PositionedByteRange ret =
      new SimplePositionedMutableByteRange(blobVarDecodedLength(end - start + 1));
    int s = 6;
    byte t = (byte) ((ord.apply(a[offset + start]) << 1) & 0xff);
    for (int i = start + 1; i < end; i++) {
      if (s == 7) {
        ret.put((byte) (t | (ord.apply(a[offset + i]) & 0x7f)));
        i++;
        // explicitly reset t -- clean up overflow buffer after decoding
        // a full cycle and retain assertion condition below. This happens
        t = 0; // when the LSB in the last encoded byte is 1. (HBASE-9893)
      } else {
        ret.put((byte) (t | ((ord.apply(a[offset + i]) & 0x7f) >>> s)));
      }
      if (i == end) break;
      t = (byte) ((ord.apply(a[offset + i]) << (8 - s)) & 0xff);
      s = s == 1 ? 7 : s - 1;
    }
    src.setPosition(end);
    assert t == 0 : "Unexpected bits remaining after decoding blob.";
    assert ret.getPosition() == ret.getLength() : "Allocated unnecessarily large return buffer.";
    return ret.getBytes();
  }
Decode a blob value that was encoded using BlobVar encoding.
hbase-common/src/main/java/org/apache/hadoop/hbase/util/OrderedBytes.java