Reading/writing functions of stream and buffer for little-endian data. | (ns cljam.io.util.lsb {:deprecated "0.8.5"} (:refer-clojure :exclude [read-string]) (:require [cljam.util :refer [string->bytes]]) (:import [java.io DataInput InputStream DataOutputStream EOFException ByteArrayOutputStream] [java.nio Buffer ByteBuffer ByteOrder])) |
Generates a new | (defn gen-byte-buffer (^ByteBuffer [] (.order (ByteBuffer/allocate 8) ByteOrder/LITTLE_ENDIAN)) (^ByteBuffer [size] (.order (ByteBuffer/allocate size) ByteOrder/LITTLE_ENDIAN))) |
Reading | |
Provides feature of reading little-endian values. | (defprotocol LSBReadable (skip [this length] "Skips over 'length' bytes of data, discarding the skipped bytes.") (read-byte [this] "Reads 1 byte. Returns a byte value.") (read-ubyte [this] "Reads 1 byte. Returns an unsigned byte value as long.") (read-short [this] "Reads 2 bytes. Returns a short value.") (read-ushort [this] "Reads 2 bytes. Returns an unsigned short value as long.") (read-int [this] "Reads 4 bytes. Returns an int value.") (read-uint [this] "Reads 4 bytes. Returns an unsigned int value as long.") (read-long [this] "Reads 8 bytes. Returns a long value. ") (read-float [this] "Reads 4 bytes. Returns a float value.") (read-double [this] "Reads 8 bytes. Returns a double value.") (read-bytes [this length] [this buffer offset length] "Reads 'length' bytes to buffer starting from offset bytes. Returns a new byte-array if called without buffer.") (read-string [this length] "Reads 'length' bytes. Returns a String.") (read-null-terminated-string [this] "Reads until next null character. Returns a String without the null.")) |
(extend-type ByteBuffer LSBReadable (skip [this ^long length] (.position ^Buffer this (+ (.position this) length))) (read-byte [this] (.get this)) (read-ubyte [this] (bit-and (.get this) 0xFF)) (read-short [this] (.order this ByteOrder/LITTLE_ENDIAN) (.getShort this)) (read-ushort [this] (.order this ByteOrder/LITTLE_ENDIAN) (bit-and (.getShort this) 0xFFFF)) (read-int [this] (.order this ByteOrder/LITTLE_ENDIAN) (.getInt this)) (read-uint [this] (.order this ByteOrder/LITTLE_ENDIAN) (bit-and (.getInt this) 0xFFFFFFFF)) (read-long [this] (.order this ByteOrder/LITTLE_ENDIAN) (.getLong this)) (read-float [this] (.order this ByteOrder/LITTLE_ENDIAN) (.getFloat this)) (read-double [this] (.order this ByteOrder/LITTLE_ENDIAN) (.getDouble this)) (read-bytes ([this ^long length] (let [ba (byte-array length)] (.get this ba) ba)) ([this ^bytes buffer ^long offset ^long length] (.get this buffer (int offset) (int length)) buffer)) (read-string [this ^long length] (let [ba (byte-array length)] (.get this ba) (String. ba))) (read-null-terminated-string [this] (let [start (.position this) end (do (while (not (zero? (.get this)))) (.position this)) offset (.arrayOffset this)] (String. (.array this) (+ offset start) (dec (- end start)))))) | |
(extend-type DataInput LSBReadable (skip [this ^long length] (.skipBytes this length)) (read-byte [this] (.readByte this)) (read-ubyte [this] (.readUnsignedByte this)) (read-short [this] (let [bb (gen-byte-buffer 2)] (.readFully this (.array bb)) (.getShort bb))) (read-ushort [this] (bit-and (short (read-short this)) 0xFFFF)) (read-int [this] (let [bb (gen-byte-buffer 4)] (.readFully this (.array bb)) (.getInt bb))) (read-uint [this] (bit-and (int (read-int this)) 0xFFFFFFFF)) (read-long [this] (let [bb (gen-byte-buffer 8)] (.readFully this (.array bb)) (.getLong bb))) (read-float [this] (Float/intBitsToFloat (read-int this))) (read-double [this] (Double/longBitsToDouble (read-long this))) (read-bytes ([this ^long length] (let [ba (byte-array length)] (.readFully this ba) ba)) ([this buffer ^long offset ^long length] (.readFully this buffer offset length) buffer)) (read-string [this ^long length] (let [ba (byte-array length)] (.readFully this ba) (String. ba))) (read-null-terminated-string [this] (with-open [baos (ByteArrayOutputStream. 32)] (loop [] (let [b (.readByte this)] (when-not (zero? b) (.write baos b) (recur)))) (.toString baos)))) | |
(extend-type InputStream LSBReadable (skip [this ^long length] (.skip this length)) (read-byte [this] (unchecked-byte (.read this))) (read-ubyte [this] (bit-and (.read this) 0xFF)) (read-short [this] (let [bb (gen-byte-buffer 2)] (read-bytes this (.array bb) 0 2) (.getShort bb))) (read-ushort [this] (bit-and (short (read-short this)) 0xFFFF)) (read-int [this] (let [bb (gen-byte-buffer 4)] (read-bytes this (.array bb) 0 4) (.getInt bb))) (read-uint [this] (bit-and (int (read-int this)) 0xFFFFFFFF)) (read-long [this] (let [bb (gen-byte-buffer 8)] (read-bytes this (.array bb) 0 8) (.getLong bb))) (read-float [this] (Float/intBitsToFloat (read-int this))) (read-double [this] (Double/longBitsToDouble (read-long this))) (read-bytes ([this ^long length] (let [ba (byte-array length)] (read-bytes this ba 0 length))) ([this buffer ^long offset ^long length] (loop [total-read 0] (when (< total-read length) (let [n (.read this buffer (+ offset total-read) (- length total-read))] (if (neg? n) (throw (EOFException. "Premature EOF")) (recur (+ total-read n)))))) buffer)) (read-string [this ^long length] (String. ^bytes (read-bytes this length))) (read-null-terminated-string [this] (with-open [baos (ByteArrayOutputStream. 32)] (loop [] (let [b (.read this)] (when-not (zero? b) (.write baos b) (recur)))) (.toString baos)))) | |
Writing | |
Provides feature of writing little-endian values. | (defprotocol LSBWritable (write-ubyte [this n] "Writes 1 byte.") (write-char [this n] "Writes a 1-byte ascii character.") (write-short [this n] "Writes a 2-byte short value.") (write-ushort [this n] "Writes a 2-byte unsigned short value.") (write-int [this n] "Writes a 4-byte integer value.") (write-uint [this n] "Writes a 4-byte unsigned integer value.") (write-long [this n] "Writes an 8-byte long value.") (write-float [this n] "Writes a 4-byte float value.") (write-bytes [this b] "Writes a byte-array.") (write-string [this s] "Writes a string as a sequence of ascii characters.")) |
(extend-type ByteBuffer LSBWritable (write-ubyte [w b] (.put w (unchecked-byte b))) (write-char [w b] (.put w (unchecked-byte (long b)))) (write-short [w n] (.order w ByteOrder/LITTLE_ENDIAN) (.putShort w n)) (write-ushort [w n] (.order w ByteOrder/LITTLE_ENDIAN) (.putShort w (unchecked-short n))) (write-int [w n] (.order w ByteOrder/LITTLE_ENDIAN) (.putInt w n)) (write-uint [w n] (.order w ByteOrder/LITTLE_ENDIAN) (.putInt w (unchecked-int n))) (write-long [w n] (.order w ByteOrder/LITTLE_ENDIAN) (.putLong w n)) (write-float [w n] (.order w ByteOrder/LITTLE_ENDIAN) (.putFloat w n)) (write-bytes [w ^bytes b] (.put w b)) (write-string [w s] (.put w (string->bytes s)))) | |
(extend-type DataOutputStream LSBWritable (write-ubyte [w b] (let [bb (gen-byte-buffer)] (.putShort bb b) (.write w (.array bb) 0 1))) (write-char [w b] (let [bb (gen-byte-buffer)] (.putChar bb b) (.write w (.array bb) 0 1))) (write-short [w n] (let [bb (gen-byte-buffer)] (.putShort bb n) (.write w (.array bb) 0 2))) (write-ushort [w n] (let [bb (gen-byte-buffer)] (.putInt bb n) (.write w (.array bb) 0 2))) (write-int [w n] (let [bb (gen-byte-buffer)] (.putInt bb n) (.write w (.array bb) 0 4))) (write-uint [w n] (let [bb (gen-byte-buffer)] (.putInt bb (unchecked-int n)) (.write w (.array bb) 0 4))) (write-long [w n] (let [bb (gen-byte-buffer)] (.putLong bb n) (.write w (.array bb) 0 8))) (write-float [w n] (let [bb (gen-byte-buffer)] (.putFloat bb n) (.write w (.array bb) 0 4))) (write-bytes [w ^bytes b] (.write w b 0 (alength b))) (write-string [w s] (let [data-bytes (string->bytes s)] (.write w data-bytes 0 (alength data-bytes))))) | |
(extend-type java.nio.channels.FileChannel LSBWritable (write-ubyte [w b] (let [bb (-> (gen-byte-buffer 1) (.put (unchecked-byte b)))] (.clear ^Buffer bb) (.write w bb))) (write-char [w b] (let [bb (-> (gen-byte-buffer 1) (.putChar b))] (.clear ^Buffer bb) (.write w bb))) (write-short [w n] (let [bb (-> (gen-byte-buffer 2) (.putShort n))] (.clear ^Buffer bb) (.write w bb))) (write-ushort [w n] (let [bb (-> (gen-byte-buffer 2) (.putShort (unchecked-short n)))] (.clear ^Buffer bb) (.write w bb))) (write-int [w n] (let [bb (-> (gen-byte-buffer 4) (.putInt n))] (.clear ^Buffer bb) (.write w bb))) (write-uint [w n] (let [bb (-> (gen-byte-buffer 4) (.putInt (unchecked-int n)))] (.clear ^Buffer bb) (.write w bb))) (write-long [w n] (let [bb (-> (gen-byte-buffer 8) (.putLong n))] (.clear ^Buffer bb) (.write w bb))) (write-float [w n] (let [bb (-> (gen-byte-buffer 4) (.putFloat n))] (.clear ^Buffer bb) (.write w bb))) (write-bytes [w ^bytes b] (.write w (ByteBuffer/wrap b))) (write-string [w s] (.write w (ByteBuffer/wrap (string->bytes s))))) | |