Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 67 additions & 29 deletions src/byte_spec.clj
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,70 @@
(.writeByte *spec-out* (count s))
(.write *spec-out* (.getBytes s)))

(defn read-fstring [len]
(let [bytes (byte-array len)]
(.readFully *spec-in* bytes)
(String. bytes)))

(defn- write-fstring [s len]
(let [actual (if (<= (count s) len)
(.substring s 0 len)
(apply str s (take (- len (count s)) (repeat " "))))]
(.write *spec-out* (.getBytes actual))))

(defn- read-int16-little []
(let [b1 (.readUnsignedByte *spec-in*)
b2 (bit-shift-left (.readUnsignedByte *spec-in*) 8)]
(reduce bit-or [b1 b2])))

(defn- read-int32-little []
(let [b1 (.readUnsignedByte *spec-in*)
b2 (bit-shift-left (.readUnsignedByte *spec-in*) 8)
b3 (bit-shift-left (.readUnsignedByte *spec-in*) 16)
b4 (bit-shift-left (.readUnsignedByte *spec-in*) 24)]
(reduce bit-or [b1 b2 b3 b4])))

(defn seek-by [offset]
(.seek *spec-in* (+ (.getFilePointer *spec-in*) offset)))

;; Standard numeric types + Pascal style strings.
;; pstring => a byte giving the string length followed by the ascii bytes
(def READERS {
:int8 #(.readByte *spec-in*)
:int16 #(.readShort *spec-in*)
:int32 #(.readInt *spec-in*)
:int64 #(.readLong *spec-in*)
:float32 #(.readFloat *spec-in*)
:int8 #(.readByte *spec-in*)
:int16 #(.readShort *spec-in*)
:int16-l read-int16-little
:int32 #(.readInt *spec-in*)
:int32-l read-int32-little
:int64 #(.readLong *spec-in*)
:float32 #(.readFloat *spec-in*)
:float64 #(.readDouble *spec-in*)

:byte #(.readByte *spec-in*)
:short #(.readShort *spec-in*)
:int #(.readInt *spec-in*)
:long #(.readLong *spec-in*)
:float #(.readFloat *spec-in*)
:byte #(.readByte *spec-in*)
:short #(.readShort *spec-in*)
:int #(.readInt *spec-in*)
:long #(.readLong *spec-in*)
:float #(.readFloat *spec-in*)
:double #(.readDouble *spec-in*)

:string read-pstring
:string read-pstring
})

(def WRITERS {
:int8 #(.writeByte *spec-out* %1)
:int16 #(.writeShort *spec-out* %1)
:int32 #(.writeInt *spec-out* %1)
:int64 #(.writeLong *spec-out* %1)
:int8 #(.writeByte *spec-out* %1)
:int16 #(.writeShort *spec-out* %1)
:int32 #(.writeInt *spec-out* %1)
:int64 #(.writeLong *spec-out* %1)
:float32 #(.writeFloat *spec-out* %1)
:float64 #(.writeDouble *spec-out* %1)

:byte #(.writeByte *spec-out* %1)
:short #(.writeShort *spec-out* %1)
:int #(.writeInt *spec-out* %1)
:long #(.writeLong *spec-out* %1)
:byte #(.writeByte *spec-out* %1)
:short #(.writeShort *spec-out* %1)
:int #(.writeInt *spec-out* %1)
:long #(.writeLong *spec-out* %1)
:float #(.writeFloat *spec-out* %1)
:double #(.writeDouble *spec-out* %1)

:string write-pstring
:string write-pstring
})

; TODO: Make this complete
Expand Down Expand Up @@ -104,7 +132,7 @@
(declare spec-read)

(defn- spec-read-array [spec size]
;(println (str "[" (if (map? spec) (:name spec) spec) "] size = " size))
;;(println (str "[" (if (map? spec) (:name spec) spec) "] size = " size))
(loop [i size
ary []]
(if (pos? i)
Expand All @@ -120,21 +148,31 @@
[spec]
(loop [specs (:specs spec)
data {}]
;(println (str "spec-read - " (:name spec)))
;;(println (str "spec-read - " (:name spec)))
(if specs
(let [{:keys [fname ftype fdefault]} (first specs)
;_ (println (str ftype ": " fname " default: -" fdefault "-" ))
;;_ (println (str ftype ": " fname " default: -" fdefault "-" ))
fval (cond
; basic type
;; basic type
(contains? READERS ftype) ((ftype READERS))

; sub-spec
;; sub-spec
(map? ftype) (spec-read ftype)

; array
(vector? ftype) (spec-read-array (first ftype)
((keyword (str "n-" (name fname))) data)))]
;(println (str ftype ": " fname " <- " (if (vector? fval) (str "[" (:name (first ftype)) "]") fval)))
;; array or fstring
(vector? ftype)
(if (= :fstring (first ftype))
(read-fstring (second ftype))
(spec-read-array (first ftype)
(if (= 2 (count ftype))
(second ftype)
((keyword (str "n-" (name fname))) data))))

;; function
(fn? ftype) (ftype)
)]
#_(println (str ftype ": " fname " <- "
(if (vector? fval) (str fval) fval)))
(recur (next specs) (assoc data fname fval)))
data)))

Expand Down