private static int checkKeyValueTagBytes(byte[] buf, int offset, int length, int pos,
    int endOffset) {
    if (pos + Bytes.SIZEOF_SHORT > endOffset) {
      String msg =
        "Overflow when reading tags length at position=" + pos + bytesToHex(buf, offset, length);
      LOG.warn(msg);
      throw new IllegalArgumentException(msg);
    }
    short tagsLen = Bytes.toShort(buf, pos);
    pos += Bytes.SIZEOF_SHORT;
    if (tagsLen < 0 || pos + tagsLen > endOffset) {
      String msg = "Invalid tags length in KeyValue at position=" + (pos - Bytes.SIZEOF_SHORT)
        + bytesToHex(buf, offset, length);
      LOG.warn(msg);
      throw new IllegalArgumentException(msg);
    }
    int tagsEndOffset = pos + tagsLen;
    for (; pos < tagsEndOffset;) {
      if (pos + Tag.TAG_LENGTH_SIZE > endOffset) {
        String msg =
          "Overflow when reading tag length at position=" + pos + bytesToHex(buf, offset, length);
        LOG.warn(msg);
        throw new IllegalArgumentException(msg);
      }
      short tagLen = Bytes.toShort(buf, pos);
      pos += Tag.TAG_LENGTH_SIZE;
      // tagLen contains one byte tag type, so must be not less than 1.
      if (tagLen < 1 || pos + tagLen > endOffset) {
        String msg = "Invalid tag length at position=" + (pos - Tag.TAG_LENGTH_SIZE)
          + ", tagLength=" + tagLen + bytesToHex(buf, offset, length);
        LOG.warn(msg);
        throw new IllegalArgumentException(msg);
      }
      pos += tagLen;
    }
    return pos;
  }
Write out a KeyValue in the manner in which we used to when KeyValue was a Writable.
@return Length written on stream
@see #create(DataInput) for the inverse function
hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValueUtil.java