Skip to content

Commit add223c

Browse files
committed
Adapt references specs to work with cljs.
Among with some codestyle fixes and function naming consistency improvements.
1 parent b229538 commit add223c

File tree

6 files changed

+239
-194
lines changed

6 files changed

+239
-194
lines changed

src/octet/core.cljc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
(util/defalias string string-spec/string)
4343
(util/defalias string* string-spec/string*)
4444
(util/defalias vector* coll-spec/vector*)
45-
(util/defalias ref-string* ref-spec/ref-string*)
46-
(util/defalias ref-bytes* ref-spec/ref-bytes*)
45+
(util/defalias ref-string ref-spec/ref-string)
46+
(util/defalias ref-bytes ref-spec/ref-bytes)
4747
(util/defalias int16 basic-spec/int16)
4848
(util/defalias uint16 basic-spec/uint16)
4949
(util/defalias int32 basic-spec/int32)

src/octet/spec.cljc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
(read [_ buff start] "Read all data from buffer.")
4242
(write [_ buff start data] "Read all data from buffer."))
4343

44+
(defprotocol ISpecWithRef
45+
"Abstraction to support specs having references to other
46+
specs within an AssociativeSpec or an IndexedSpec"
47+
(read* [_ buff start data] "Read data from buffer, use data to calculate length etc")
48+
(write* [_ buff start value types data] "Write data from buffer, use data to store length etc"))
49+
4450
(defprotocol ISpecSize
4551
"Abstraction for calculate size of static specs."
4652
(size [_] "Calculate the size in bytes of the object."))
@@ -49,12 +55,6 @@
4955
"Abstraction for calculate size for dynamic specs."
5056
(size* [_ data] "Calculate the size in bytes of the object having a data."))
5157

52-
(defprotocol ISpecWithRef
53-
"Abstraction to support specs having references to other
54-
specs within an AssociativeSpec or an IndexedSpec"
55-
(read* [_ buff start data] "Read data from buffer, use data to calculate length etc")
56-
(write* [_ buff start value types data] "Write data from buffer, use data to store length etc"))
57-
5858
;; --- Composed Spec Types
5959

6060
(deftype AssociativeSpec [data dict types]

src/octet/spec/basic.cljc

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727
(:require [octet.buffer :as buffer]
2828
[octet.spec :as spec]))
2929

30-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31-
;; Types implementation
32-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30+
;; --- Types implementation
3331

3432
(defn primitive-spec
3533
[size readfn writefn]
@@ -115,9 +113,7 @@
115113
(buffer/write-bytes buff pos size value)
116114
size)))
117115

118-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
119-
;; Unsigned Primitives
120-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
116+
;; --- Unsigned Primitives
121117

122118
(def ^{:doc "Unsinged int16 type spec."}
123119
uint16 (primitive-spec 2 buffer/read-ushort buffer/write-ushort))

src/octet/spec/reference.cljc

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
;; Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>
1+
;; Copyright (c) 2015-2018 Andrey Antukh <niwi@niwi.nz>
22
;; All rights reserved.
33
;;
44
;; Redistribution and use in source and binary forms, with or without
@@ -23,72 +23,121 @@
2323
;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2424

2525
(ns octet.spec.reference
26+
"Spec types for arbitrary length byte arrays/strings with a length reference."
2627
(:require [octet.buffer :as buffer]
2728
[octet.spec :as spec]
29+
[octet.spec.basic :as basic-spec]
2830
[octet.spec.string :as string-spec]))
2931

30-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31-
;; Spec types for arbitrary length byte arrays/strings with a length reference
32-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3332

34-
(defn- ref-size [type data]
35-
(if (satisfies? spec/ISpecSize type)
36-
(.size type)
37-
(.size* type data)))
33+
(defn- ref-size
34+
[type data]
35+
(cond
36+
(satisfies? spec/ISpecDynamicSize type)
37+
(spec/size* type data)
3838

39-
(defn- coerce-types [types]
39+
(satisfies? spec/ISpecSize type)
40+
(spec/size type)
41+
42+
:else
43+
(throw (ex-info "Unexpected type" {:type type}))))
44+
45+
(defn- coerce-types
4046
"to make it terser to handle both maps (assoc spec) and seq/vector
4147
(indexed spec), we coerce the seq/vector types to maps where the
4248
keys are indexes"
43-
(cond (map? types) types
44-
(or (seq? types)
45-
(vector? types)) (apply array-map (interleave (range) types))
46-
:else (throw (ex-info "invalid type structure, not map, seq or vector"
47-
{:type-structure types}))))
48-
49-
(defn- ref-len-offset [ref-kw-or-index types data]
50-
"for ref-xxxx* specs, calculate the byte offset of the
49+
[types]
50+
(cond
51+
(map? types)
52+
types
53+
54+
(or (seq? types)
55+
(vector? types))
56+
(apply array-map (interleave (range) types))
57+
58+
:else (throw (ex-info "invalid type structure, not map, seq or vector"
59+
{:type-structure types}))))
60+
61+
(defn- ref-len-offset
62+
"for ref-xxxx specs, calculate the byte offset of the
5163
spec containing the length, i.e. (spec :a (int16) :b (int16) c: (ref-string* :b))
5264
would cause this method to be called with :b (since the ref-string has a :b
5365
reference as its length) and should then return 2 as the second int16 is at byte offset 2"
66+
[ref-kw-or-index types data]
5467
(reduce-kv
55-
(fn [acc kw-or-index type]
56-
(if (= ref-kw-or-index kw-or-index)
57-
(reduced acc)
58-
(+ acc (ref-size type (get data kw-or-index)))))
59-
0
60-
types))
61-
62-
(defn- ref-write* [ref-kw-or-index buff pos value types data]
68+
(fn [acc kw-or-index type]
69+
(if (= ref-kw-or-index kw-or-index)
70+
(reduced acc)
71+
(+ acc (ref-size type (get data kw-or-index)))))
72+
0
73+
types))
74+
75+
(defn- ref-write-length
76+
[type buff offset length]
77+
(cond
78+
(identical? basic-spec/int16 type)
79+
(buffer/write-short buff offset length)
80+
81+
(identical? basic-spec/int32 type)
82+
(buffer/write-int buff offset length)
83+
84+
(identical? basic-spec/int64 type)
85+
(buffer/write-long buff offset length)
86+
87+
(identical? basic-spec/int64 type)
88+
(buffer/write-long buff offset length)
89+
90+
(identical? basic-spec/uint16 type)
91+
(buffer/write-ushort buff offset length)
92+
93+
(identical? basic-spec/uint32 type)
94+
(buffer/write-uint buff offset length)
95+
96+
(identical? basic-spec/uint64 type)
97+
(buffer/write-ulong buff offset length)
98+
99+
:else
100+
(throw (ex-info "Invalid reference type: should be int16, int32, int64 and unsigned variants" {}))))
101+
102+
(defn- ref-write
63103
"write a ref spec, will also write the length to the length spec"
104+
[ref-kw-or-index buff pos value types data]
64105
(let [input (if (string? value) (string-spec/string->bytes value) value)
65106
length (count input)
66107
types (coerce-types types)
67108
len-offset (ref-len-offset ref-kw-or-index types data)
68109
len-type (get types ref-kw-or-index)]
69-
(.write len-type buff len-offset length)
110+
(ref-write-length len-type buff len-offset length)
70111
(buffer/write-bytes buff pos length input)
71112
(+ length)))
72113

73-
(defn- ref-read* [ref-kw-or-index buff pos parent]
114+
(defn- ref-read
74115
"read ref spec, will read the length from the length spec"
75-
(let [datasize (cond (map? parent) (ref-kw-or-index parent)
76-
(or (seq? parent) (vector? parent)) (get parent ref-kw-or-index)
77-
:else (throw (ex-info
78-
(str "bad ref-string*/ref-bytes* length reference - " ref-kw-or-index)
79-
{:length-kw ref-kw-or-index
80-
:data-read parent})))
116+
[ref-kw-or-index buff pos parent]
117+
(let [datasize (cond
118+
(map? parent)
119+
(ref-kw-or-index parent)
120+
121+
(or (seq? parent) (vector? parent))
122+
(get parent ref-kw-or-index)
123+
124+
:else
125+
(throw (ex-info
126+
(str "bad ref-string/ref-bytes length reference - " ref-kw-or-index)
127+
{:length-kw ref-kw-or-index
128+
:data-read parent})))
129+
;; _ (println "FOFOFO:" parent ref-kw-or-index)
81130
data (buffer/read-bytes buff pos datasize)]
82131
[datasize data]))
83132

84-
(defn ref-bytes*
85-
[ref-kw-or-index]
133+
(defn ref-bytes
86134
"create a dynamic length byte array where the length of the byte array is stored in another
87135
spec within the containing indexed spec or associative spec. Example usages:
88136
(spec (int16) (int16) (ref-bytes* 1))
89137
(spec :a (int16) :b (int32) (ref-bytes* :b))
90138
where the first example would store the length of the byte array in the second int16 and
91139
the second example would store the length of the byte array in the int32 at key :b."
140+
[ref-kw-or-index]
92141
(reify
93142
#?@(:clj
94143
[clojure.lang.IFn
@@ -103,12 +152,12 @@
103152

104153
spec/ISpecWithRef
105154
(read* [_ buff pos parent]
106-
(ref-read* ref-kw-or-index buff pos parent))
155+
(ref-read ref-kw-or-index buff pos parent))
107156

108157
(write* [_ buff pos value types data]
109-
(ref-write* ref-kw-or-index buff pos value types data))))
158+
(ref-write ref-kw-or-index buff pos value types data))))
110159

111-
(defn ref-string*
160+
(defn ref-string
112161
"create a dynamic length string where the length of the string is stored in another
113162
spec within the containing indexed spec or associative spec. Example usages:
114163
(spec (int16) (int16) (ref-string* 1))
@@ -131,13 +180,8 @@
131180

132181
spec/ISpecWithRef
133182
(read* [_ buff pos parent]
134-
(let [[datasize bytes] (ref-read* ref-kw-or-index buff pos parent)]
183+
(let [[datasize bytes] (ref-read ref-kw-or-index buff pos parent)]
135184
[datasize (string-spec/bytes->string bytes datasize)]))
136185

137186
(write* [_ buff pos value types data]
138-
(ref-write* ref-kw-or-index buff pos value types data))))
139-
140-
(defn ref-vector*
141-
[ref-kw-or-index]
142-
;; TODO: implement this
143-
)
187+
(ref-write ref-kw-or-index buff pos value types data))))

0 commit comments

Comments
 (0)