The plug-in socket protocol, portable: JSON text <-> data, framing, and the request/response envelopes, in plain Clojure over strings.
hive-gimp.codec is the JVM face of the same protocol and stays on
clojure.data.json, because the socket read loop asks complete-frame? on
every chunk and a compiled parser is what that loop wants. This namespace is
for hosts that have no JSON library: ClojureWasm (cljw) and clojurust
(cljrs). The two are held to each other by hive-gimp.wire-test, a
differential test against clojure.data.json, and the portable build is
held to itself by dev/wire_portability.cljc, run on all three hosts.
Contract parse string -> {:ok value} | {:error message :at index}. Objects -> maps with STRING keys; arrays -> vectors; integers -> longs (doubles past the long range); fractions and exponents -> doubles. Never throws. emit value -> JSON text. Keyword/symbol keys and values emit by name, nil is null, sets emit as arrays, non-finite doubles emit as null. Non-ASCII is written raw, not as \u escapes. complete-frame? true only for exactly one JSON OBJECT (whitespace around it allowed). nil, "" and any proper prefix are not frames. encode-request GimpCommand -> one request frame, newline-terminated. Params are written verbatim, nulls included. decode-response frame -> hive-dsl Result as a plain map: {:ok raw-response} | {:error reason :message .. :detail ..} with reason one of :gimp/unparseable-response or :gimp/malformed-response. Built literally, so this namespace needs no hive-dsl on the host.
Refused input, stated rather than hidden: a lone (unpaired) surrogate \u escape is refused, as is a raw control character inside a string.
Portable: clojure.core, clojure.string and hive-gimp.shape only; no reader conditionals, no host interop. Every scan works on one-char STRINGS, because the hosts disagree on what a char is.
The plug-in socket protocol, portable: JSON text <-> data, framing, and the
request/response envelopes, in plain Clojure over strings.
`hive-gimp.codec` is the JVM face of the same protocol and stays on
clojure.data.json, because the socket read loop asks `complete-frame?` on
every chunk and a compiled parser is what that loop wants. This namespace is
for hosts that have no JSON library: ClojureWasm (cljw) and clojurust
(cljrs). The two are held to each other by hive-gimp.wire-test, a
differential test against clojure.data.json, and the portable build is
held to itself by dev/wire_portability.cljc, run on all three hosts.
Contract
parse string -> {:ok value} | {:error message :at index}.
Objects -> maps with STRING keys; arrays -> vectors;
integers -> longs (doubles past the long range);
fractions and exponents -> doubles. Never throws.
emit value -> JSON text. Keyword/symbol keys and values emit
by name, nil is null, sets emit as arrays, non-finite
doubles emit as null. Non-ASCII is written raw, not as
\u escapes.
complete-frame? true only for exactly one JSON OBJECT (whitespace
around it allowed). nil, "" and any proper prefix are
not frames.
encode-request GimpCommand -> one request frame, newline-terminated.
Params are written verbatim, nulls included.
decode-response frame -> hive-dsl Result as a plain map:
{:ok raw-response} | {:error reason :message .. :detail ..}
with reason one of :gimp/unparseable-response or
:gimp/malformed-response. Built literally, so this
namespace needs no hive-dsl on the host.
Refused input, stated rather than hidden: a lone (unpaired) surrogate
\u escape is refused, as is a raw control character inside a string.
Portable: clojure.core, clojure.string and hive-gimp.shape only; no reader
conditionals, no host interop. Every scan works on one-char STRINGS,
because the hosts disagree on what a char is.(complete-frame? buffer)True when buffer holds exactly one whole JSON object. A response has no
length prefix and no terminator, so parses as an object IS the frame
boundary; an object, not any value, so a truncated answer whose prefix
happens to parse on its own is never mistaken for a whole one.
True when `buffer` holds exactly one whole JSON object. A response has no length prefix and no terminator, so `parses as an object` IS the frame boundary; an object, not any value, so a truncated answer whose prefix happens to parse on its own is never mistaken for a whole one.
(decode-response buffer)One response frame to a hive-dsl Result, spelled as a plain map.
Two failure reasons, kept distinct because they call for different actions: :gimp/unparseable-response (truncated frame, desynced socket, or something other than the plug-in answering) and :gimp/malformed-response (the plug-in answered in a shape this contract does not know).
One response frame to a hive-dsl Result, spelled as a plain map. Two failure reasons, kept distinct because they call for different actions: :gimp/unparseable-response (truncated frame, desynced socket, or something other than the plug-in answering) and :gimp/malformed-response (the plug-in answered in a shape this contract does not know).
(emit v)Value to JSON text. Booleans are tested with =, never true?/false?,
which answer wrongly for booleans on clojurust once the caller is hot.
Value to JSON text. Booleans are tested with `=`, never `true?`/`false?`, which answer wrongly for booleans on clojurust once the caller is hot.
(encode-request command)GimpCommand ({:type string :params {string any}}) to one request frame.
Nil params are sent as null: the reference client sends an omitted
optional that way and the plug-in reads it with .get.
`GimpCommand` ({:type string :params {string any}}) to one request frame.
Nil params are sent as null: the reference client sends an omitted
optional that way and the plug-in reads it with `.get`.(parse s)JSON text to {:ok value} | {:error message :at index}. Never throws.
The text is split once into a vector of one-char strings and every reader
indexes that vector; :at counts those chars. Readers report failure as a
value, never by throwing; the catch is only a backstop for a host error.
JSON text to {:ok value} | {:error message :at index}. Never throws.
The text is split once into a vector of one-char strings and every reader
indexes that vector; `:at` counts those chars. Readers report failure as a
value, never by throwing; the catch is only a backstop for a host error.Appended to every request frame. The plug-in accumulates until its buffer parses, so this is a courtesy rather than a delimiter.
Appended to every request frame. The plug-in accumulates until its buffer parses, so this is a courtesy rather than a delimiter.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |