2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.datastore.node.utils.stream;
10 import java.io.DataOutput;
11 import java.math.BigDecimal;
12 import java.math.BigInteger;
13 import org.opendaylight.yangtools.yang.common.Empty;
14 import org.opendaylight.yangtools.yang.common.Uint16;
15 import org.opendaylight.yangtools.yang.common.Uint32;
16 import org.opendaylight.yangtools.yang.common.Uint64;
17 import org.opendaylight.yangtools.yang.common.Uint8;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
21 * Magnesium encoding value types. Serialized as a single byte.
24 * Note these constants are organized by their absolute value, which is slightly counter-intuitive when trying to make
25 * sense of what is going on.
27 * TODO: create some sort of facility which would provide symbolic names for debugging and documentation purposes.
29 final class MagnesiumValue {
31 * {@link Boolean#FALSE} value.
33 static final byte BOOLEAN_FALSE = 0x00;
35 * {@link Boolean#TRUE} value.
37 static final byte BOOLEAN_TRUE = 0x01;
39 * An {@link Empty} value.
41 static final byte EMPTY = 0x02;
43 * A Byte, followed by a byte holding the value.
45 static final byte INT8 = 0x03;
47 * A Short, followed by a {@code short} holding the value.
49 static final byte INT16 = 0x04;
51 * An Integer, followed by an {@code int} holding the value.
53 static final byte INT32 = 0x05;
55 * A Long, followed by an {@code long} holding the value.
57 static final byte INT64 = 0x06;
59 * A Uint8, followed by an {@code unsigned byte} holding the value.
61 static final byte UINT8 = 0x07;
63 * A Uint16, followed by a {@code unsigned short} holding the value.
65 static final byte UINT16 = 0x08;
67 * A Uint32, followed by an {@code unsigned int} holding the value.
69 static final byte UINT32 = 0x09;
71 * A Uint64, followed by an {@code unsigned long} holding the value.
73 static final byte UINT64 = 0x0A;
75 * A {@link String}, encoded through {@link DataOutput#writeUTF(String)}. Note this is generally true of any
76 * string with less then 16384 characters.
78 static final byte STRING_UTF = 0x0B;
80 * A {@link String}, encoded as an {@code unsigned short} followed by that many UTF8-encoded bytes.
82 static final byte STRING_2B = 0x0C;
84 * A {@link String}, encoded as an {@code int >= 0} followed by that many UTF8-encoded bytes.
86 static final byte STRING_4B = 0x0D;
88 * A {@link String}, encoded as an {@code int >= 0} followed by that many UTF16 characters, i.e. as produced by
89 * {@link DataOutput#writeChars(String)}.
91 static final byte STRING_CHARS = 0x0E;
93 * Utility 'reference coding' codepoint with {@code unsigned byte} offset. This is not a value type, but is used in
94 * context of various schema-related encodings like constant strings, QNameModule and similar.
96 static final byte STRING_REF_1B = 0x0F;
98 * Utility 'reference coding' codepoint with {@code unsigned short} offset. This is not a value type, but is used in
99 * context of various schema-related encodings like constant strings, QNameModule and similar.
101 static final byte STRING_REF_2B = 0x10;
103 * Utility 'reference coding' codepoint with {@code int} offset. This is not a value type, but is used in context of
104 * various schema-related encodings like constant strings, QNameModule and similar.
106 static final byte STRING_REF_4B = 0x11;
108 * A {@code byte[])}, encoded as a single {@code unsigned byte} followed by 128-383 bytes. Note that smaller
109 * arrays are encoded via {@link #BINARY_0} - {@link #BINARY_127} range.
111 static final byte BINARY_1B = 0x12;
113 * A {@code byte[])}, encoded as a single {@code unsigned short} followed by 384-65919 bytes. See also
114 * {@link #BINARY_1B}.
116 static final byte BINARY_2B = 0x13;
118 * A {@code byte[])}, encoded as a single {@code int} followed by that many bytes bytes. See also
119 * {@link #BINARY_2B}.
121 static final byte BINARY_4B = 0x14;
123 * A {@link YangInstanceIdentifier}, encoded as a single {@code int}, followed by that many components. See
124 * also {@link #YIID_0}, which offers optimized encoding for up to 31 components. Components are encoded using
125 * {@link MagnesiumPathArgument} coding.
127 static final byte YIID = 0x15;
129 * A QName literal. Encoded as QNameModule + String. This literal is expected to be memoized on receiver side, which
130 * assigns the next linear integer identifier. The sender will memoize it too and further references to this QName
131 * will be made via {@link #QNAME_REF_1B}, {@link #QNAME_REF_2B} or {@link #QNAME_REF_4B}.
134 * Note that QNameModule (and String in this context) encoding works similarly -- it can only occur as part of a
135 * QName (coming from here or {@link MagnesiumPathArgument}) and is subject to the same memoization.
138 * For example, given two QNames {@code foo = QName.create("foo", "abc")} and
139 * {@code bar = QName.create("foo", "def")}, if they are written in order {@code foo, bar, foo}, then the following
140 * events are emitted:
142 * QNAME (define QName, assign shorthand Q0)
143 * STRING_UTF "foo" ("foo", assign shorthand S0, implies define QNameModule, assign shorthand M0)
144 * STRING_EMPTY (foo's non-existent revision)
145 * STRING_UTF "abc" ("abc", assign shorthand S1)
146 * QNAME (define QName, assign shorthand Q1)
147 * MODREF_1B (byte)0 (reference M0)
148 * STRING_UTF "def" ("def", assign shorthand S2)
149 * QNAME_REF_1B (byte)0 (reference Q0)
152 // Design note: STRING_EMPTY is required to *NOT* establish a shortcut, as that is less efficient (and hence does
153 // not make sense from the sender, the receiver or the serialization protocol itself.
154 static final byte QNAME = 0x16;
156 * Reference a QName previously defined via {@link #QNAME}. Reference number is encoded as {@code unsigned byte}.
158 static final byte QNAME_REF_1B = 0x17;
160 * Reference a QName previously defined via {@link #QNAME}. Reference number is encoded as {@code unsigned short}.
162 static final byte QNAME_REF_2B = 0x18;
164 * Reference a QName previously defined via {@link #QNAME}. Reference number is encoded as {@code int}.
166 static final byte QNAME_REF_4B = 0x19;
168 * Reference a previously defined QNameModule. Reference number is encoded as {@code unsigned byte}.
170 static final byte MODREF_1B = 0x1A;
172 * Reference a previously defined QNameModule. Reference number is encoded as {@code unsigned short}.
174 static final byte MODREF_2B = 0x1B;
176 * Reference a previously defined QNameModule. Reference number is encoded as {@code int}.
178 static final byte MODREF_4B = 0x1C;
181 * A {@link BigDecimal}, encoded through {@link DataOutput#writeUTF(String)}.
183 // This is legacy compatibility. At some point we will remove support for writing these.
184 static final byte BIGDECIMAL = 0x1D;
186 * A {@link BigInteger}, encoded through {@link DataOutput#writeUTF(String)}.
188 // This is legacy compatibility. At some point we will remove support for writing these.
189 static final byte BIGINTEGER = 0x1E;
194 * Byte value {@code 0}.
196 static final byte INT8_0 = 0x20;
198 * Short value {@code 0}.
200 static final byte INT16_0 = 0x21;
202 * Integer value {@code 0}.
204 static final byte INT32_0 = 0x22;
206 * Long value {@code 0}.
208 static final byte INT64_0 = 0x23;
210 * {@link Uint8#ZERO} value.
212 static final byte UINT8_0 = 0x24;
214 * {@link Uint16#ZERO} value.
216 static final byte UINT16_0 = 0x25;
218 * {@link Uint32#ZERO} value.
220 static final byte UINT32_0 = 0x26;
222 * {@link Uint64#ZERO} value.
224 static final byte UINT64_0 = 0x27;
226 * Empty String value ({@code ""}).
228 static final byte STRING_EMPTY = 0x28;
230 * {@link #INT32} with a 2-byte operand.
232 static final byte INT32_2B = 0x29;
234 * {@link #UINT32} with a 2-byte operand.
236 static final byte UINT32_2B = 0x2A;
238 * {@link #INT64} with a 4-byte operand.
240 static final byte INT64_4B = 0x2B;
242 * {@link #UINT64} with a 4-byte operand.
244 static final byte UINT64_4B = 0x2C;
246 // 0x2D - 0x39 reserved
249 * Empty bits value. This code point starts the range, where the number of bits can be extracted as
250 * {@code code & 0x1F)}. Last three values of this range are used to encode more than 28 entries.
252 static final byte BITS_0 = 0x40;
254 * A bits value of up to 255 entries. Number of values is encoded as the following {@code unsigned byte}.
256 static final byte BITS_1B = 0x5D;
258 * A bits value of up to 65535 entries. Number of values is encoded as the following {@code unsigned short}.
260 static final byte BITS_2B = 0x5E;
262 * A bits value. Number of values is encoded as the following {@code int}.
264 static final byte BITS_4B = 0x5F;
267 * {@link YangInstanceIdentifier} with zero components. This code point starts the range ending with
268 * {@link #YIID_31}, where the number of components can be extracted as {@code code & 0x1F}. Identifiers with
269 * more than 31 components are encoded using {@link #YIID}.
271 static final byte YIID_0 = 0x60;
273 * {@link YangInstanceIdentifier} with 31 components. See {@link #YIID_0}.
275 static final byte YIID_31 = 0x7F;
278 * A {@code byte[]} with 0 bytes. This code point starts the range ending with {@link #BINARY_127}, where
279 * the number of bytes can be extracted as {@code code & 0x7F}. Arrays longer than 127 bytes are encoded using
280 * {@link #BINARY_1B}, {@link #BINARY_2B} and {@link #BINARY_4B} as needed.
282 static final byte BINARY_0 = (byte) 0x80;
284 * A {@code byte[]} with 127 bytes. See {@link #BINARY_0}.
286 static final byte BINARY_127 = (byte) 0xFF;
288 private MagnesiumValue() {