Functions for reading little-endian data using DataInput.

NOTE: This namespace is intended to be used only from within cljam, and should not be used outside cljam.

(ns cljam.io.util.lsb.data-io
  (:refer-clojure :exclude [read-string])
  (:require [cljam.io.util.byte-buffer :as bb])
  (:import [java.io ByteArrayOutputStream DataInput]))

Skips over 'length' bytes of data, discarding the skipped bytes.

(defn skip
  [^DataInput input ^long length]
  (.skipBytes input length))

Reads 1 byte. Returns a byte value.

(defn read-byte
  [^DataInput input]
  (.readByte input))

Reads 1 byte. Returns an unsigned byte value as long.

(defn read-ubyte
  [^DataInput input]
  (.readUnsignedByte input))

Reads 2 bytes. Returns a short value.

(defn read-short
  [^DataInput input]
  (let [bb (bb/allocate-lsb-byte-buffer 2)]
    (.readFully input (.array bb))
    (.getShort bb)))

Reads 2 bytes. Returns an unsigned short value as long.

(defn read-ushort
  [^DataInput input]
  (bit-and (short (read-short input)) 0xFFFF))

Reads 4 bytes. Returns an int value.

(defn read-int
  [^DataInput input]
  (let [bb (bb/allocate-lsb-byte-buffer 4)]
    (.readFully input (.array bb))
    (.getInt bb)))

Reads 4 bytes. Returns an unsigned int value as long.

(defn read-uint
  [^DataInput input]
  (bit-and (int (read-int input)) 0xFFFFFFFF))

Reads 8 bytes. Returns a long value.

(defn read-long
  [^DataInput input]
  (let [bb (bb/allocate-lsb-byte-buffer 8)]
    (.readFully input (.array bb))
    (.getLong bb)))

Reads 4 bytes. Returns a float value.

(defn read-float
  [^DataInput input]
  (Float/intBitsToFloat (read-int input)))

Reads 8 bytes. Returns a double value.

(defn read-double
  [^DataInput input]
  (Double/longBitsToDouble (read-long input)))

Reads 'length' bytes to buffer starting from offset bytes. Returns a new byte-array if called without buffer.

(defn read-bytes
  ([^DataInput input ^long length]
   (let [ba (byte-array length)]
     (.readFully input ba)
     ba))
  ([^DataInput input buffer ^long offset ^long length]
   (.readFully input buffer offset length)
   buffer))

Reads 'length' bytes. Returns a String.

(defn read-string
  [^DataInput input ^long length]
  (let [ba (byte-array length)]
    (.readFully input ba)
    (String. ba)))

Reads until next null character. Returns a String without the null.

(defn read-null-terminated-string
  [^DataInput input]
  (with-open [baos (ByteArrayOutputStream. 32)]
    (loop []
      (let [b (.readByte input)]
        (when-not (zero? b)
          (.write baos b)
          (recur))))
    (.toString baos)))