Skip to content

Instantly share code, notes, and snippets.

@IGJoshua
Created October 24, 2018 01:59
Show Gist options
  • Save IGJoshua/2d71822bb9ce5d62ca84f30847b9d1d2 to your computer and use it in GitHub Desktop.
Save IGJoshua/2d71822bb9ce5d62ca84f30847b9d1d2 to your computer and use it in GitHub Desktop.
(s/def :entry/endian #{:endian/little :endian/big})
(s/def :entry/type keyword?)
(s/def :entry/id keyword?)
(s/def ::entry (s/keys :req [:entry/id :entry/type]
:opt [:entry/endian]))
(s/def :entry/size pos-int?)
(s/def :string/encoding #{:utf8 :utf16 :ascii :latin1})
(s/def :string/delimiter string?)
(s/def :entry.type/string (s/merge ::entry
(s/keys :req [:string/encoding
(or :entry/size
:string/delimiter)])))
(s/def :integer/unsigned boolean?)
(s/def :entry.type/int (s/merge ::entry
(s/keys :req [:entry/size]
:opt [:integer/unsigned])))
(s/def ::block (s/coll-of ::entry))
(s/def ::root-block ::block)
(s/def ::spec (s/keys :req [::root-block]))
(defn endian-abbrev
[endian]
(case endian
:endian/little :le
:endian/big :be))
(defmulti parse-entry
(fn [reader parsed-structure entry]
(:entry/type entry)))
(s/fdef parse-entry
:args (s/cat :reader (partial instance? BitReader)
:parsed-structure any?
:entry ::entry))
(defmethod parse-entry :entry.type/string
[^BitReader reader parsed-structure entry]
(read-string reader {:size (:entry/size entry)
:endian (endian-abbrev (:entry/endian entry))
:delimiter (:string/delimiter entry)
:encoding (:string/encoding entry)}))
(defmethod parse-entry :entry.type/int
[^BitReader reader parsed-structure entry]
(let [bytes (read-bytes reader {:size (:entry/size entry)
:endian (endian-abbrev (:entry/endian entry))})])
(if (:integer/unsigned entry)
(tr/bytes->uint bytes)
(tr/bytes->int bytes)))
(defn parse-spec
[spec file]
(let [file (io/open-file file)
reader (:reader file)]
(reduce (fn [structure entry]
(conj structure
(parse-entry reader
structure
entry)))
[]
(::root-block spec))))
(s/fdef parse-spec
:args (s/cat :spec ::spec
:file string?))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment