@ac-kit/format-osc 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/LICENSE +28 -0
- package/README.md +132 -2
- package/dist/errors.d.ts +34 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/framing/_decode-framed-packet.d.ts +9 -0
- package/dist/framing/_decode-framed-packet.d.ts.map +1 -0
- package/dist/framing/_decode-framed-packet.js +23 -0
- package/dist/framing/_decode-framed-packet.js.map +1 -0
- package/dist/framing/osc-datagram-codec.d.ts +17 -0
- package/dist/framing/osc-datagram-codec.d.ts.map +1 -0
- package/dist/framing/osc-datagram-codec.js +21 -0
- package/dist/framing/osc-datagram-codec.js.map +1 -0
- package/dist/framing/osc-datagram-decoder.d.ts +22 -0
- package/dist/framing/osc-datagram-decoder.d.ts.map +1 -0
- package/dist/framing/osc-datagram-decoder.js +26 -0
- package/dist/framing/osc-datagram-decoder.js.map +1 -0
- package/dist/framing/osc-datagram-encoder.d.ts +8 -0
- package/dist/framing/osc-datagram-encoder.d.ts.map +1 -0
- package/dist/framing/osc-datagram-encoder.js +9 -0
- package/dist/framing/osc-datagram-encoder.js.map +1 -0
- package/dist/framing/osc-size-prefixed-codec.d.ts +19 -0
- package/dist/framing/osc-size-prefixed-codec.d.ts.map +1 -0
- package/dist/framing/osc-size-prefixed-codec.js +23 -0
- package/dist/framing/osc-size-prefixed-codec.js.map +1 -0
- package/dist/framing/osc-size-prefixed-decoder.d.ts +40 -0
- package/dist/framing/osc-size-prefixed-decoder.d.ts.map +1 -0
- package/dist/framing/osc-size-prefixed-decoder.js +59 -0
- package/dist/framing/osc-size-prefixed-decoder.js.map +1 -0
- package/dist/framing/osc-size-prefixed-encoder.d.ts +10 -0
- package/dist/framing/osc-size-prefixed-encoder.d.ts.map +1 -0
- package/dist/framing/osc-size-prefixed-encoder.js +20 -0
- package/dist/framing/osc-size-prefixed-encoder.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/packet/_bundle-marker.d.ts +3 -0
- package/dist/packet/_bundle-marker.d.ts.map +1 -0
- package/dist/packet/_bundle-marker.js +3 -0
- package/dist/packet/_bundle-marker.js.map +1 -0
- package/dist/packet/_osc-writer.d.ts +31 -0
- package/dist/packet/_osc-writer.d.ts.map +1 -0
- package/dist/packet/_osc-writer.js +72 -0
- package/dist/packet/_osc-writer.js.map +1 -0
- package/dist/packet/_read-osc-packet.d.ts +19 -0
- package/dist/packet/_read-osc-packet.d.ts.map +1 -0
- package/dist/packet/_read-osc-packet.js +290 -0
- package/dist/packet/_read-osc-packet.js.map +1 -0
- package/dist/packet/_write-osc-packet.d.ts +12 -0
- package/dist/packet/_write-osc-packet.d.ts.map +1 -0
- package/dist/packet/_write-osc-packet.js +155 -0
- package/dist/packet/_write-osc-packet.js.map +1 -0
- package/dist/packet/decode-osc-packet.d.ts +48 -0
- package/dist/packet/decode-osc-packet.d.ts.map +1 -0
- package/dist/packet/decode-osc-packet.js +39 -0
- package/dist/packet/decode-osc-packet.js.map +1 -0
- package/dist/packet/encode-osc-packet.d.ts +32 -0
- package/dist/packet/encode-osc-packet.d.ts.map +1 -0
- package/dist/packet/encode-osc-packet.js +37 -0
- package/dist/packet/encode-osc-packet.js.map +1 -0
- package/dist/packet/osc-packet.d.ts +104 -0
- package/dist/packet/osc-packet.d.ts.map +1 -0
- package/dist/packet/osc-packet.js +2 -0
- package/dist/packet/osc-packet.js.map +1 -0
- package/dist/time-tag/_ntp.d.ts +13 -0
- package/dist/time-tag/_ntp.d.ts.map +1 -0
- package/dist/time-tag/_ntp.js +19 -0
- package/dist/time-tag/_ntp.js.map +1 -0
- package/dist/time-tag/osc-time-tag-from-date.d.ts +29 -0
- package/dist/time-tag/osc-time-tag-from-date.d.ts.map +1 -0
- package/dist/time-tag/osc-time-tag-from-date.js +48 -0
- package/dist/time-tag/osc-time-tag-from-date.js.map +1 -0
- package/dist/time-tag/osc-time-tag-to-date.d.ts +21 -0
- package/dist/time-tag/osc-time-tag-to-date.d.ts.map +1 -0
- package/dist/time-tag/osc-time-tag-to-date.js +26 -0
- package/dist/time-tag/osc-time-tag-to-date.js.map +1 -0
- package/dist/time-tag/osc-time-tag.d.ts +29 -0
- package/dist/time-tag/osc-time-tag.d.ts.map +1 -0
- package/dist/time-tag/osc-time-tag.js +16 -0
- package/dist/time-tag/osc-time-tag.js.map +1 -0
- package/package.json +60 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @ac-kit/format-osc
|
|
2
|
+
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [aca1cb1]
|
|
8
|
+
- @ac-kit/core@0.4.0
|
|
9
|
+
- @ac-kit/format-core@0.1.4
|
|
10
|
+
|
|
11
|
+
## 0.1.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 992cbbb: New package: Open Sound Control 1.0 with the OSC 1.1 additions, from a packet
|
|
16
|
+
model to the bytes on a UDP or TCP transport.
|
|
17
|
+
|
|
18
|
+
- `OscPacket` models messages and bundles, and `OscArgument` every OSC 1.0 and
|
|
19
|
+
1.1 type tag under a descriptive name — `int32`, `float32`, `string`, `blob`,
|
|
20
|
+
`int64`, `timeTag`, `float64`, `symbol`, `char`, `rgba`, `midi`, `true`,
|
|
21
|
+
`false`, `nil`, `impulse` and nested `array`s.
|
|
22
|
+
- `encodeOscPacket` writes one packet with every value range-checked, strings
|
|
23
|
+
as UTF-8 and a type tag string on every message. `decodeOscPacket` reads one
|
|
24
|
+
as untrusted input: bounds-checked reads, strict NUL padding, unknown type
|
|
25
|
+
tags refused, bundle and array nesting bounded by `maxDepth` (32 by
|
|
26
|
+
default), and `OscPacketError` carrying the byte offset on failure. A legacy
|
|
27
|
+
message with no type tag string decodes with no arguments.
|
|
28
|
+
- `oscTimeTagFromDate` and `oscTimeTagToDate` convert NTP time tags under the
|
|
29
|
+
RFC 4330 era rule, covering 1968 to 2104, with `OSC_TIME_TAG_IMMEDIATELY` and
|
|
30
|
+
`isOscTimeTagImmediately` for the reserved value.
|
|
31
|
+
- `createOscDatagramCodec` frames one packet per datagram for message-mode
|
|
32
|
+
transports; `createOscSizePrefixedCodec` frames OSC 1.0 TCP streams with an
|
|
33
|
+
int32 size prefix and a required `maxPacketSize`, an unusable prefix being a
|
|
34
|
+
fatal `OscFrameError`. Each pairs a decoder and an encoder also exported on
|
|
35
|
+
their own.
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [6254a3f]
|
|
40
|
+
- @ac-kit/format-core@0.1.3
|
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Anthony Champagne and contributors
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,133 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ac-kit/format-osc
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Open Sound Control 1.0, with the OSC 1.1 additions, in plain data: messages and
|
|
4
|
+
bundles encoded to and decoded from bytes, NTP time tags converted to and from
|
|
5
|
+
dates, and the codecs that frame packets on a datagram or a byte-stream
|
|
6
|
+
transport.
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { decodeAll } from "@ac-kit/format-core";
|
|
10
|
+
import {
|
|
11
|
+
createOscSizePrefixedDecoder,
|
|
12
|
+
decodeOscPacket,
|
|
13
|
+
encodeOscPacket,
|
|
14
|
+
oscTimeTagFromDate,
|
|
15
|
+
} from "@ac-kit/format-osc";
|
|
16
|
+
|
|
17
|
+
// One UDP datagram.
|
|
18
|
+
const datagram = encodeOscPacket({
|
|
19
|
+
kind: "bundle",
|
|
20
|
+
timeTag: oscTimeTagFromDate(Date.now() + 100),
|
|
21
|
+
elements: [
|
|
22
|
+
{
|
|
23
|
+
kind: "message",
|
|
24
|
+
address: "/oscillator/4/frequency",
|
|
25
|
+
arguments: [{ type: "float32", value: 440 }],
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
decodeOscPacket(datagram);
|
|
30
|
+
|
|
31
|
+
// Packets read from a TCP stream, OSC 1.0 framing.
|
|
32
|
+
const { items } = decodeAll(
|
|
33
|
+
createOscSizePrefixedDecoder({ maxPacketSize: 65_536 }),
|
|
34
|
+
bytes,
|
|
35
|
+
);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
It opens no socket: hand the codecs to whatever drives a transport —
|
|
39
|
+
`@ac-kit/format-core`'s `DecodeStream`, or a `FrameLink` from
|
|
40
|
+
`@ac-kit/net-core`.
|
|
41
|
+
|
|
42
|
+
## Packets
|
|
43
|
+
|
|
44
|
+
`OscPacket` is an `OscMessage` — an address pattern beginning with `/` and its
|
|
45
|
+
`arguments` — or an `OscBundle` — a `timeTag` and its `elements`, which are
|
|
46
|
+
packets in turn.
|
|
47
|
+
|
|
48
|
+
`OscArgument` is discriminated by a descriptive `type`, each naming the tag it
|
|
49
|
+
travels under:
|
|
50
|
+
|
|
51
|
+
| `type` | tag | value |
|
|
52
|
+
| ---------- | ----- | --------------------------------------------------- |
|
|
53
|
+
| `int32` | `i` | `value`: integer, −2^31 to 2^31 − 1 |
|
|
54
|
+
| `float32` | `f` | `value`: `number`, rounded to binary32 |
|
|
55
|
+
| `string` | `s` | `value`: `string` |
|
|
56
|
+
| `blob` | `b` | `value`: `Uint8Array` |
|
|
57
|
+
| `int64` | `h` | `value`: `bigint`, −2^63 to 2^63 − 1 |
|
|
58
|
+
| `timeTag` | `t` | `value`: `OscTimeTag` |
|
|
59
|
+
| `float64` | `d` | `value`: `number` |
|
|
60
|
+
| `symbol` | `S` | `value`: `string` |
|
|
61
|
+
| `char` | `c` | `value`: one character |
|
|
62
|
+
| `rgba` | `r` | `red`, `green`, `blue`, `alpha`: 0–255 |
|
|
63
|
+
| `midi` | `m` | `port`, `status`, `data1`, `data2`: 0–255 |
|
|
64
|
+
| `true` | `T` | — |
|
|
65
|
+
| `false` | `F` | — |
|
|
66
|
+
| `nil` | `N` | — |
|
|
67
|
+
| `impulse` | `I` | — (OSC 1.0's Infinitum) |
|
|
68
|
+
| `array` | `[ ]` | `items`: `OscArgument[]` |
|
|
69
|
+
|
|
70
|
+
`encodeOscPacket` writes one packet. Every message gets a type tag string, `,`
|
|
71
|
+
alone when it has no arguments, and strings are written as UTF-8. A value it
|
|
72
|
+
cannot write as given — an integer out of range, a NUL inside a string, an
|
|
73
|
+
address without its leading `/` — is a `RangeError`, never a silent change.
|
|
74
|
+
|
|
75
|
+
`decodeOscPacket` reads one packet, and treats its input as untrusted:
|
|
76
|
+
|
|
77
|
+
- every read is bounds-checked, so a hostile size can make it fail but never
|
|
78
|
+
read past the input;
|
|
79
|
+
- padding must be NUL bytes, and a packet or bundle element a multiple of 4
|
|
80
|
+
bytes long;
|
|
81
|
+
- an unknown type tag is an error, because the size of its data is unknowable;
|
|
82
|
+
- strings must be valid UTF-8. OSC 1.0 specifies ASCII, which UTF-8 extends,
|
|
83
|
+
and UTF-8 is what OSC 1.1 implementations send;
|
|
84
|
+
- bundles and arrays may nest `maxDepth` levels, 32 by default, counted
|
|
85
|
+
together.
|
|
86
|
+
|
|
87
|
+
A malformed packet throws `OscPacketError`, a `SyntaxError` carrying the byte
|
|
88
|
+
`offset` it gave up at. A message with no type tag string, which OSC 1.0 asks
|
|
89
|
+
receivers to accept from older senders, decodes with no arguments when nothing
|
|
90
|
+
follows its address; with data after it, the types are unknowable and it is an
|
|
91
|
+
error.
|
|
92
|
+
|
|
93
|
+
## Time tags
|
|
94
|
+
|
|
95
|
+
`OscTimeTag` is the 64-bit NTP timestamp of RFC 5905: whole `seconds` since
|
|
96
|
+
1900-01-01T00:00:00Z and a `fraction` of a second in units of 2^-32 s.
|
|
97
|
+
`OSC_TIME_TAG_IMMEDIATELY` is the reserved value asking for dispatch on
|
|
98
|
+
receipt; `isOscTimeTagImmediately` tests for it.
|
|
99
|
+
|
|
100
|
+
`oscTimeTagFromDate` and `oscTimeTagToDate` convert the others. The `seconds`
|
|
101
|
+
field wraps in 2036, so a tag is read with the RFC 4330 era rule: a value with
|
|
102
|
+
its top bit clear falls after 2036-02-07T06:28:16Z. That names every instant
|
|
103
|
+
from 1968-01-20T03:14:08Z to 2104-02-26T09:42:24Z, and converting a date
|
|
104
|
+
outside that range is a `RangeError`. A whole number of milliseconds survives a
|
|
105
|
+
round trip exactly; a tag converted to a `Date` is rounded to the nearest
|
|
106
|
+
millisecond.
|
|
107
|
+
|
|
108
|
+
## Framing
|
|
109
|
+
|
|
110
|
+
A packet carries no length of its own, so each transport frames it:
|
|
111
|
+
|
|
112
|
+
- **Datagrams** (UDP and other message-mode transports): one packet per
|
|
113
|
+
datagram. `createOscDatagramCodec` pairs `createOscDatagramDecoder`, which
|
|
114
|
+
decodes the whole of each datagram, and `createOscDatagramEncoder`. A
|
|
115
|
+
malformed datagram is a recoverable `error` result, and the next one decodes
|
|
116
|
+
as usual.
|
|
117
|
+
- **Streams** (TCP), OSC 1.0's framing: each packet preceded by its size as a
|
|
118
|
+
big-endian int32. `createOscSizePrefixedCodec` pairs
|
|
119
|
+
`createOscSizePrefixedDecoder` and `createOscSizePrefixedEncoder`. The
|
|
120
|
+
decoder requires a `maxPacketSize`. A size that is negative, not a multiple
|
|
121
|
+
of 4 or above that limit is `fatal` with an `OscFrameError`, since nothing
|
|
122
|
+
else delimits a frame; a malformed packet inside a well-sized frame is a
|
|
123
|
+
recoverable `error`.
|
|
124
|
+
|
|
125
|
+
Both are `Decoder`/`Encoder` pairs from `@ac-kit/format-core`, so they run
|
|
126
|
+
under `decodeAll`, `DecodeStream` or a `FrameLink`.
|
|
127
|
+
|
|
128
|
+
OSC 1.1 frames streams with SLIP (RFC 1055) instead; this package does not read
|
|
129
|
+
that form.
|
|
130
|
+
|
|
131
|
+
See the
|
|
132
|
+
[generated API docs](https://anthochamp.github.io/node-essentials/api/format-osc/)
|
|
133
|
+
for the full reference.
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An OSC packet is malformed: a field is truncated, a string or blob is not
|
|
3
|
+
* padded with NUL bytes to a multiple of 4, a type tag is unknown, a bundle
|
|
4
|
+
* element's size does not fit its bundle, nesting exceeds `maxDepth`, or a
|
|
5
|
+
* string is not valid UTF-8.
|
|
6
|
+
*
|
|
7
|
+
* Thrown by {@link decodeOscPacket}, and reported as a recoverable `error`
|
|
8
|
+
* decode result by the datagram and size-prefixed decoders. A packet built by
|
|
9
|
+
* the caller that {@link encodeOscPacket} cannot write — an integer out of
|
|
10
|
+
* range, a NUL inside a string — is a `RangeError` instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare class OscPacketError extends SyntaxError {
|
|
13
|
+
/** Byte offset in the packet of the field the decoder gave up at. */
|
|
14
|
+
readonly offset: number;
|
|
15
|
+
constructor(message: string,
|
|
16
|
+
/** Byte offset in the packet of the field the decoder gave up at. */
|
|
17
|
+
offset: number, options?: ErrorOptions);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The size prefix of an OSC 1.0 stream frame is unusable: negative, not a
|
|
21
|
+
* multiple of 4, or above the decoder's `maxPacketSize`.
|
|
22
|
+
*
|
|
23
|
+
* Reported as a `fatal` decode result by {@link createOscSizePrefixedDecoder}:
|
|
24
|
+
* the prefix is the only thing delimiting a frame, so once it cannot be trusted
|
|
25
|
+
* there is no position to resynchronise from.
|
|
26
|
+
*/
|
|
27
|
+
export declare class OscFrameError extends SyntaxError {
|
|
28
|
+
/** The declared packet size, as a signed 32-bit integer. */
|
|
29
|
+
readonly size: number;
|
|
30
|
+
constructor(message: string,
|
|
31
|
+
/** The declared packet size, as a signed 32-bit integer. */
|
|
32
|
+
size: number);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAG7C,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM;IAHxB,YACC,OAAO,EAAE,MAAM;IACf,qEAAqE;IAC5D,MAAM,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,YAAY,EAItB;CACD;AAED;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAG5C,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM;IAHtB,YACC,OAAO,EAAE,MAAM;IACf,4DAA4D;IACnD,IAAI,EAAE,MAAM,EAIrB;CACD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An OSC packet is malformed: a field is truncated, a string or blob is not
|
|
3
|
+
* padded with NUL bytes to a multiple of 4, a type tag is unknown, a bundle
|
|
4
|
+
* element's size does not fit its bundle, nesting exceeds `maxDepth`, or a
|
|
5
|
+
* string is not valid UTF-8.
|
|
6
|
+
*
|
|
7
|
+
* Thrown by {@link decodeOscPacket}, and reported as a recoverable `error`
|
|
8
|
+
* decode result by the datagram and size-prefixed decoders. A packet built by
|
|
9
|
+
* the caller that {@link encodeOscPacket} cannot write — an integer out of
|
|
10
|
+
* range, a NUL inside a string — is a `RangeError` instead.
|
|
11
|
+
*/
|
|
12
|
+
export class OscPacketError extends SyntaxError {
|
|
13
|
+
offset;
|
|
14
|
+
constructor(message,
|
|
15
|
+
/** Byte offset in the packet of the field the decoder gave up at. */
|
|
16
|
+
offset, options) {
|
|
17
|
+
super(`${message} (at byte ${offset})`, options);
|
|
18
|
+
this.offset = offset;
|
|
19
|
+
this.name = "OscPacketError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The size prefix of an OSC 1.0 stream frame is unusable: negative, not a
|
|
24
|
+
* multiple of 4, or above the decoder's `maxPacketSize`.
|
|
25
|
+
*
|
|
26
|
+
* Reported as a `fatal` decode result by {@link createOscSizePrefixedDecoder}:
|
|
27
|
+
* the prefix is the only thing delimiting a frame, so once it cannot be trusted
|
|
28
|
+
* there is no position to resynchronise from.
|
|
29
|
+
*/
|
|
30
|
+
export class OscFrameError extends SyntaxError {
|
|
31
|
+
size;
|
|
32
|
+
constructor(message,
|
|
33
|
+
/** The declared packet size, as a signed 32-bit integer. */
|
|
34
|
+
size) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.size = size;
|
|
37
|
+
this.name = "OscFrameError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,cAAe,SAAQ,WAAW;IAIpC,MAAM;IAHhB,YACC,OAAe;IACf,qEAAqE;IAC5D,MAAc,EACvB,OAAsB;QAEtB,KAAK,CAAC,GAAG,OAAO,aAAa,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;sBAHxC,MAAM;QAIf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC9B,CAAC;CACD;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,aAAc,SAAQ,WAAW;IAInC,IAAI;IAHd,YACC,OAAe;IACf,4DAA4D;IACnD,IAAY;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;oBAFN,IAAI;QAGb,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC7B,CAAC;CACD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DecodeResult } from "@ac-kit/format-core";
|
|
2
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
3
|
+
/**
|
|
4
|
+
* Decodes `packet` as the whole content of a frame `consumed` units long. A
|
|
5
|
+
* malformed packet inside an intact frame is a recoverable `error`: the frame
|
|
6
|
+
* boundary is known, so the next frame is unaffected.
|
|
7
|
+
*/
|
|
8
|
+
export declare function decodeFramedPacket_(packet: Uint8Array, maxDepth: number, consumed: number): DecodeResult<OscPacket>;
|
|
9
|
+
//# sourceMappingURL=_decode-framed-packet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_decode-framed-packet.d.ts","sourceRoot":"","sources":["../../src/framing/_decode-framed-packet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACd,YAAY,CAAC,SAAS,CAAC,CAazB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { OscPacketError } from "../errors.js";
|
|
2
|
+
import { readOscPacket_ } from "../packet/_read-osc-packet.js";
|
|
3
|
+
/**
|
|
4
|
+
* Decodes `packet` as the whole content of a frame `consumed` units long. A
|
|
5
|
+
* malformed packet inside an intact frame is a recoverable `error`: the frame
|
|
6
|
+
* boundary is known, so the next frame is unaffected.
|
|
7
|
+
*/
|
|
8
|
+
export function decodeFramedPacket_(packet, maxDepth, consumed) {
|
|
9
|
+
try {
|
|
10
|
+
return {
|
|
11
|
+
status: "decoded",
|
|
12
|
+
value: readOscPacket_(packet, maxDepth),
|
|
13
|
+
consumed,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
if (error instanceof OscPacketError) {
|
|
18
|
+
return { status: "error", error, consumed };
|
|
19
|
+
}
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=_decode-framed-packet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_decode-framed-packet.js","sourceRoot":"","sources":["../../src/framing/_decode-framed-packet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAClC,MAAkB,EAClB,QAAgB,EAChB,QAAgB;IAEhB,IAAI,CAAC;QACJ,OAAO;YACN,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC;YACvC,QAAQ;SACR,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;YACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC7C,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Codec } from "@ac-kit/format-core";
|
|
2
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
3
|
+
import { type OscDatagramDecoderOptions } from "./osc-datagram-decoder.js";
|
|
4
|
+
/** Options for {@link createOscDatagramCodec}. */
|
|
5
|
+
export type OscDatagramCodecOptions = OscDatagramDecoderOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Creates the OSC codec for a message-mode transport such as UDP: one packet
|
|
8
|
+
* per datagram, in both directions.
|
|
9
|
+
*
|
|
10
|
+
* Use {@link createOscDatagramDecoder} or {@link createOscDatagramEncoder}
|
|
11
|
+
* directly where only one direction is needed; a `FrameLink` needs both. On a
|
|
12
|
+
* byte-stream transport use {@link createOscSizePrefixedCodec} instead.
|
|
13
|
+
*
|
|
14
|
+
* @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createOscDatagramCodec(options?: OscDatagramCodecOptions): Codec<OscPacket>;
|
|
17
|
+
//# sourceMappingURL=osc-datagram-codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-datagram-codec.d.ts","sourceRoot":"","sources":["../../src/framing/osc-datagram-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAEN,KAAK,yBAAyB,EAC9B,MAAM,2BAA2B,CAAC;AAGnC,kDAAkD;AAClD,MAAM,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEhE;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACrC,OAAO,CAAC,EAAE,uBAAuB,GAC/B,KAAK,CAAC,SAAS,CAAC,CAQlB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createOscDatagramDecoder, } from "./osc-datagram-decoder.js";
|
|
2
|
+
import { createOscDatagramEncoder } from "./osc-datagram-encoder.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the OSC codec for a message-mode transport such as UDP: one packet
|
|
5
|
+
* per datagram, in both directions.
|
|
6
|
+
*
|
|
7
|
+
* Use {@link createOscDatagramDecoder} or {@link createOscDatagramEncoder}
|
|
8
|
+
* directly where only one direction is needed; a `FrameLink` needs both. On a
|
|
9
|
+
* byte-stream transport use {@link createOscSizePrefixedCodec} instead.
|
|
10
|
+
*
|
|
11
|
+
* @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
|
|
12
|
+
*/
|
|
13
|
+
export function createOscDatagramCodec(options) {
|
|
14
|
+
const decoder = createOscDatagramDecoder(options);
|
|
15
|
+
const encoder = createOscDatagramEncoder();
|
|
16
|
+
return {
|
|
17
|
+
decode: (view, context) => decoder.decode(view, context),
|
|
18
|
+
encode: (value) => encoder.encode(value),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=osc-datagram-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-datagram-codec.js","sourceRoot":"","sources":["../../src/framing/osc-datagram-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,wBAAwB,GAExB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAKrE;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CACrC,OAAiC;IAEjC,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,wBAAwB,EAAE,CAAC;IAE3C,OAAO;QACN,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;QACxD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;KACxC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Decoder } from "@ac-kit/format-core";
|
|
2
|
+
import type { DecodeOscPacketOptions } from "../packet/decode-osc-packet.js";
|
|
3
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
4
|
+
/** Options for {@link createOscDatagramDecoder}. */
|
|
5
|
+
export type OscDatagramDecoderOptions = DecodeOscPacketOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Creates the read half for a message-mode transport such as UDP, where every
|
|
8
|
+
* delivery is exactly one OSC packet.
|
|
9
|
+
*
|
|
10
|
+
* Each call decodes the whole view as one packet and consumes all of it. A
|
|
11
|
+
* malformed datagram is a recoverable `error` carrying an
|
|
12
|
+
* {@link OscPacketError}: it is dropped and the next datagram decodes as usual.
|
|
13
|
+
* The decoder never answers `incomplete` — a datagram cannot grow — so it is
|
|
14
|
+
* only meaningful where the driver hands it one datagram per call; on a byte
|
|
15
|
+
* stream use {@link createOscSizePrefixedDecoder}.
|
|
16
|
+
*
|
|
17
|
+
* Time is O(n) in the datagram's length.
|
|
18
|
+
*
|
|
19
|
+
* @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createOscDatagramDecoder(options?: OscDatagramDecoderOptions): Decoder<OscPacket>;
|
|
22
|
+
//# sourceMappingURL=osc-datagram-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-datagram-decoder.d.ts","sourceRoot":"","sources":["../../src/framing/osc-datagram-decoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,qBAAqB,CAAC;AAGjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,oDAAoD;AACpD,MAAM,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAE/D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACvC,OAAO,CAAC,EAAE,yBAAyB,GACjC,OAAO,CAAC,SAAS,CAAC,CAQpB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { resolveMaxDepth_ } from "../packet/_read-osc-packet.js";
|
|
2
|
+
import { decodeFramedPacket_ } from "./_decode-framed-packet.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the read half for a message-mode transport such as UDP, where every
|
|
5
|
+
* delivery is exactly one OSC packet.
|
|
6
|
+
*
|
|
7
|
+
* Each call decodes the whole view as one packet and consumes all of it. A
|
|
8
|
+
* malformed datagram is a recoverable `error` carrying an
|
|
9
|
+
* {@link OscPacketError}: it is dropped and the next datagram decodes as usual.
|
|
10
|
+
* The decoder never answers `incomplete` — a datagram cannot grow — so it is
|
|
11
|
+
* only meaningful where the driver hands it one datagram per call; on a byte
|
|
12
|
+
* stream use {@link createOscSizePrefixedDecoder}.
|
|
13
|
+
*
|
|
14
|
+
* Time is O(n) in the datagram's length.
|
|
15
|
+
*
|
|
16
|
+
* @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
|
|
17
|
+
*/
|
|
18
|
+
export function createOscDatagramDecoder(options) {
|
|
19
|
+
const maxDepth = resolveMaxDepth_(options?.maxDepth);
|
|
20
|
+
return {
|
|
21
|
+
decode(view) {
|
|
22
|
+
return decodeFramedPacket_(view, maxDepth, view.length);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=osc-datagram-decoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-datagram-decoder.js","sourceRoot":"","sources":["../../src/framing/osc-datagram-decoder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKjE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CACvC,OAAmC;IAEnC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAErD,OAAO;QACN,MAAM,CAAC,IAAgB;YACtB,OAAO,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Encoder } from "@ac-kit/format-core";
|
|
2
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the write half for a message-mode transport such as UDP: each packet
|
|
5
|
+
* becomes one datagram, exactly as {@link encodeOscPacket} writes it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createOscDatagramEncoder(): Encoder<OscPacket>;
|
|
8
|
+
//# sourceMappingURL=osc-datagram-encoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-datagram-encoder.d.ts","sourceRoot":"","sources":["../../src/framing/osc-datagram-encoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAAC,SAAS,CAAC,CAE7D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { encodeOscPacket } from "../packet/encode-osc-packet.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates the write half for a message-mode transport such as UDP: each packet
|
|
4
|
+
* becomes one datagram, exactly as {@link encodeOscPacket} writes it.
|
|
5
|
+
*/
|
|
6
|
+
export function createOscDatagramEncoder() {
|
|
7
|
+
return { encode: encodeOscPacket };
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=osc-datagram-encoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-datagram-encoder.js","sourceRoot":"","sources":["../../src/framing/osc-datagram-encoder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGjE;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACvC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Codec } from "@ac-kit/format-core";
|
|
2
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
3
|
+
import { type OscSizePrefixedDecoderOptions } from "./osc-size-prefixed-decoder.js";
|
|
4
|
+
/** Options for {@link createOscSizePrefixedCodec}. */
|
|
5
|
+
export type OscSizePrefixedCodecOptions = OscSizePrefixedDecoderOptions;
|
|
6
|
+
/**
|
|
7
|
+
* Creates the OSC codec for a byte-stream transport such as TCP, using OSC
|
|
8
|
+
* 1.0's stream framing: each packet preceded by its size as a big-endian
|
|
9
|
+
* int32.
|
|
10
|
+
*
|
|
11
|
+
* Use {@link createOscSizePrefixedDecoder} or
|
|
12
|
+
* {@link createOscSizePrefixedEncoder} directly where only one direction is
|
|
13
|
+
* needed; a `FrameLink` needs both. On a message-mode transport use
|
|
14
|
+
* {@link createOscDatagramCodec} instead.
|
|
15
|
+
*
|
|
16
|
+
* @throws {RangeError} As {@link createOscSizePrefixedDecoder}.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createOscSizePrefixedCodec(options: OscSizePrefixedCodecOptions): Codec<OscPacket>;
|
|
19
|
+
//# sourceMappingURL=osc-size-prefixed-codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-size-prefixed-codec.d.ts","sourceRoot":"","sources":["../../src/framing/osc-size-prefixed-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAEN,KAAK,6BAA6B,EAClC,MAAM,gCAAgC,CAAC;AAGxC,sDAAsD;AACtD,MAAM,MAAM,2BAA2B,GAAG,6BAA6B,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,2BAA2B,GAClC,KAAK,CAAC,SAAS,CAAC,CAQlB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createOscSizePrefixedDecoder, } from "./osc-size-prefixed-decoder.js";
|
|
2
|
+
import { createOscSizePrefixedEncoder } from "./osc-size-prefixed-encoder.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the OSC codec for a byte-stream transport such as TCP, using OSC
|
|
5
|
+
* 1.0's stream framing: each packet preceded by its size as a big-endian
|
|
6
|
+
* int32.
|
|
7
|
+
*
|
|
8
|
+
* Use {@link createOscSizePrefixedDecoder} or
|
|
9
|
+
* {@link createOscSizePrefixedEncoder} directly where only one direction is
|
|
10
|
+
* needed; a `FrameLink` needs both. On a message-mode transport use
|
|
11
|
+
* {@link createOscDatagramCodec} instead.
|
|
12
|
+
*
|
|
13
|
+
* @throws {RangeError} As {@link createOscSizePrefixedDecoder}.
|
|
14
|
+
*/
|
|
15
|
+
export function createOscSizePrefixedCodec(options) {
|
|
16
|
+
const decoder = createOscSizePrefixedDecoder(options);
|
|
17
|
+
const encoder = createOscSizePrefixedEncoder();
|
|
18
|
+
return {
|
|
19
|
+
decode: (view, context) => decoder.decode(view, context),
|
|
20
|
+
encode: (value) => encoder.encode(value),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=osc-size-prefixed-codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-size-prefixed-codec.js","sourceRoot":"","sources":["../../src/framing/osc-size-prefixed-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,4BAA4B,GAE5B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAK9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,0BAA0B,CACzC,OAAoC;IAEpC,MAAM,OAAO,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,4BAA4B,EAAE,CAAC;IAE/C,OAAO;QACN,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;QACxD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;KACxC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type Decoder } from "@ac-kit/format-core";
|
|
2
|
+
import type { DecodeOscPacketOptions } from "../packet/decode-osc-packet.js";
|
|
3
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
4
|
+
/** Options for {@link createOscSizePrefixedDecoder}. */
|
|
5
|
+
export type OscSizePrefixedDecoderOptions = DecodeOscPacketOptions & {
|
|
6
|
+
/**
|
|
7
|
+
* Largest packet size, in bytes, a frame may declare. Required: the prefix
|
|
8
|
+
* can announce up to 2 GiB, and only the caller knows what its peers send. A
|
|
9
|
+
* frame is held in the driver's buffer until it is complete, so this also
|
|
10
|
+
* bounds what one frame can make that buffer retain.
|
|
11
|
+
*/
|
|
12
|
+
maxPacketSize: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Creates the read half of OSC 1.0's stream framing, for a byte-stream
|
|
16
|
+
* transport such as TCP: each packet preceded by its size as a big-endian
|
|
17
|
+
* int32.
|
|
18
|
+
*
|
|
19
|
+
* - Until the 4-byte prefix and then the whole packet have arrived, the result is
|
|
20
|
+
* `incomplete` with `needAtLeast` set to the bytes required.
|
|
21
|
+
* - A declared size that is negative, not a multiple of 4, or above
|
|
22
|
+
* `maxPacketSize` is `fatal` with an {@link OscFrameError}: the prefix is the
|
|
23
|
+
* only frame delimiter, so once it is wrong there is nothing to resynchronise
|
|
24
|
+
* on. It is rejected as soon as the prefix arrives, before any of the packet
|
|
25
|
+
* is buffered.
|
|
26
|
+
* - A malformed packet inside a well-sized frame is a recoverable `error`
|
|
27
|
+
* carrying an {@link OscPacketError}, whose `offset` counts from the start of
|
|
28
|
+
* the packet, after the prefix. The frame is consumed and the next one
|
|
29
|
+
* decodes as usual.
|
|
30
|
+
*
|
|
31
|
+
* OSC 1.1 frames streams with SLIP instead; this decoder reads the OSC 1.0
|
|
32
|
+
* form, which most TCP implementations still send.
|
|
33
|
+
*
|
|
34
|
+
* Time is O(n) in the frame's size per decoded frame.
|
|
35
|
+
*
|
|
36
|
+
* @throws {RangeError} When `maxPacketSize` is not a non-negative integer, or
|
|
37
|
+
* `maxDepth` as {@link decodeOscPacket}.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createOscSizePrefixedDecoder(options: OscSizePrefixedDecoderOptions): Decoder<OscPacket>;
|
|
40
|
+
//# sourceMappingURL=osc-size-prefixed-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-size-prefixed-decoder.d.ts","sourceRoot":"","sources":["../../src/framing/osc-size-prefixed-decoder.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,OAAO,EAEZ,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,wDAAwD;AACxD,MAAM,MAAM,6BAA6B,GAAG,sBAAsB,GAAG;IACpE;;;;;OAKG;IACH,aAAa,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,6BAA6B,GACpC,OAAO,CAAC,SAAS,CAAC,CAoCpB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getUint32Be } from "@ac-kit/core";
|
|
2
|
+
import { decodeIncomplete, } from "@ac-kit/format-core";
|
|
3
|
+
import { OscFrameError } from "../errors.js";
|
|
4
|
+
import { resolveMaxDepth_ } from "../packet/_read-osc-packet.js";
|
|
5
|
+
import { decodeFramedPacket_ } from "./_decode-framed-packet.js";
|
|
6
|
+
/**
|
|
7
|
+
* Creates the read half of OSC 1.0's stream framing, for a byte-stream
|
|
8
|
+
* transport such as TCP: each packet preceded by its size as a big-endian
|
|
9
|
+
* int32.
|
|
10
|
+
*
|
|
11
|
+
* - Until the 4-byte prefix and then the whole packet have arrived, the result is
|
|
12
|
+
* `incomplete` with `needAtLeast` set to the bytes required.
|
|
13
|
+
* - A declared size that is negative, not a multiple of 4, or above
|
|
14
|
+
* `maxPacketSize` is `fatal` with an {@link OscFrameError}: the prefix is the
|
|
15
|
+
* only frame delimiter, so once it is wrong there is nothing to resynchronise
|
|
16
|
+
* on. It is rejected as soon as the prefix arrives, before any of the packet
|
|
17
|
+
* is buffered.
|
|
18
|
+
* - A malformed packet inside a well-sized frame is a recoverable `error`
|
|
19
|
+
* carrying an {@link OscPacketError}, whose `offset` counts from the start of
|
|
20
|
+
* the packet, after the prefix. The frame is consumed and the next one
|
|
21
|
+
* decodes as usual.
|
|
22
|
+
*
|
|
23
|
+
* OSC 1.1 frames streams with SLIP instead; this decoder reads the OSC 1.0
|
|
24
|
+
* form, which most TCP implementations still send.
|
|
25
|
+
*
|
|
26
|
+
* Time is O(n) in the frame's size per decoded frame.
|
|
27
|
+
*
|
|
28
|
+
* @throws {RangeError} When `maxPacketSize` is not a non-negative integer, or
|
|
29
|
+
* `maxDepth` as {@link decodeOscPacket}.
|
|
30
|
+
*/
|
|
31
|
+
export function createOscSizePrefixedDecoder(options) {
|
|
32
|
+
const { maxPacketSize } = options;
|
|
33
|
+
if (!Number.isInteger(maxPacketSize) || maxPacketSize < 0) {
|
|
34
|
+
throw new RangeError(`maxPacketSize must be a non-negative integer, got ${maxPacketSize}`);
|
|
35
|
+
}
|
|
36
|
+
const maxDepth = resolveMaxDepth_(options.maxDepth);
|
|
37
|
+
return {
|
|
38
|
+
decode(view) {
|
|
39
|
+
if (view.length < 4) {
|
|
40
|
+
return decodeIncomplete(4);
|
|
41
|
+
}
|
|
42
|
+
const size = getUint32Be(view, 0) | 0;
|
|
43
|
+
if (size < 0 || size % 4 !== 0 || size > maxPacketSize) {
|
|
44
|
+
return {
|
|
45
|
+
status: "fatal",
|
|
46
|
+
error: new OscFrameError(size > maxPacketSize
|
|
47
|
+
? `OSC frame size ${size} exceeds the ${maxPacketSize} byte limit`
|
|
48
|
+
: `OSC frame size ${size} is not a non-negative multiple of 4`, size),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const total = 4 + size;
|
|
52
|
+
if (view.length < total) {
|
|
53
|
+
return decodeIncomplete(total);
|
|
54
|
+
}
|
|
55
|
+
return decodeFramedPacket_(view.subarray(4, total), maxDepth, total);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=osc-size-prefixed-decoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-size-prefixed-decoder.js","sourceRoot":"","sources":["../../src/framing/osc-size-prefixed-decoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACN,gBAAgB,GAGhB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAajE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,4BAA4B,CAC3C,OAAsC;IAEtC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,UAAU,CACnB,qDAAqD,aAAa,EAAE,CACpE,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEpD,OAAO;QACN,MAAM,CAAC,IAAgB;YACtB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC;YAC5B,CAAC;YAED,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC;gBACxD,OAAO;oBACN,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,IAAI,aAAa,CACvB,IAAI,GAAG,aAAa;wBACnB,CAAC,CAAC,kBAAkB,IAAI,gBAAgB,aAAa,aAAa;wBAClE,CAAC,CAAC,kBAAkB,IAAI,sCAAsC,EAC/D,IAAI,CACJ;iBACD,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC;YACvB,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;gBACzB,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;YAED,OAAO,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACtE,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Encoder } from "@ac-kit/format-core";
|
|
2
|
+
import type { OscPacket } from "../packet/osc-packet.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates the write half of OSC 1.0's stream framing: each packet preceded by
|
|
5
|
+
* its size as a big-endian int32, in one buffer.
|
|
6
|
+
*
|
|
7
|
+
* @throws {RangeError} From `encode`, as {@link encodeOscPacket}.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createOscSizePrefixedEncoder(): Encoder<OscPacket>;
|
|
10
|
+
//# sourceMappingURL=osc-size-prefixed-encoder.d.ts.map
|