403578d47f38698b7515f25f6d3ab70a2193ba46
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / MagnesiumValue.java
1 /*
2  * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.datastore.node.utils.stream;
9
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;
19
20 /**
21  * Magnesium encoding value types. Serialized as a single byte.
22  */
23 /*
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.
26  *
27  * TODO: create some sort of facility which would provide symbolic names for debugging and documentation purposes.
28  */
29 final class MagnesiumValue {
30     /**
31      * {@link Boolean#FALSE} value.
32      */
33     static final byte BOOLEAN_FALSE  = 0x00;
34     /**
35      * {@link Boolean#TRUE} value.
36      */
37     static final byte BOOLEAN_TRUE   = 0x01;
38     /**
39      * An {@link Empty} value.
40      */
41     static final byte EMPTY          = 0x02;
42     /**
43      * A Byte, followed by a byte holding the value.
44      */
45     static final byte INT8           = 0x03;
46     /**
47      * A Short, followed by a {@code short} holding the value.
48      */
49     static final byte INT16          = 0x04;
50     /**
51      * An Integer, followed by an {@code int} holding the value.
52      */
53     static final byte INT32          = 0x05;
54     /**
55      * A Long, followed by an {@code long} holding the value.
56      */
57     static final byte INT64          = 0x06;
58     /**
59      * A Uint8, followed by an {@code unsigned byte} holding the value.
60      */
61     static final byte UINT8          = 0x07;
62     /**
63      * A Uint16, followed by a {@code unsigned short} holding the value.
64      */
65     static final byte UINT16         = 0x08;
66     /**
67      * A Uint32, followed by an {@code unsigned int} holding the value.
68      */
69     static final byte UINT32         = 0x09;
70     /**
71      * A Uint64, followed by an {@code unsigned long} holding the value.
72      */
73     static final byte UINT64         = 0x0A;
74     /**
75      * A {@link String}, encoded through {@link DataOutput#writeUTF(String)}. Note this is generally true of any
76      * string with less then 16384 characters.
77      */
78     static final byte STRING_UTF     = 0x0B;
79     /**
80      * A {@link String}, encoded as an {@code unsigned short} followed by that many UTF8-encoded bytes.
81      */
82     static final byte STRING_2B      = 0x0C;
83     /**
84      * A {@link String}, encoded as an {@code int >= 0} followed by that many UTF8-encoded bytes.
85      */
86     static final byte STRING_4B      = 0x0D;
87     /**
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)}.
90      */
91     static final byte STRING_CHARS   = 0x0E;
92     /**
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.
95      */
96     static final byte STRING_REF_1B  = 0x0F;
97     /**
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.
100      */
101     static final byte STRING_REF_2B  = 0x10;
102     /**
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.
105      */
106     static final byte STRING_REF_4B  = 0x11;
107     /**
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.
110      */
111     static final byte BINARY_1B      = 0x12;
112     /**
113      * A {@code byte[])}, encoded as a single {@code unsigned short} followed by 384-65919 bytes. See also
114      * {@link #BINARY_1B}.
115      */
116     static final byte BINARY_2B      = 0x13;
117     /**
118      * A {@code byte[])}, encoded as a single {@code int} followed by that many bytes bytes. See also
119      * {@link #BINARY_2B}.
120      */
121     static final byte BINARY_4B      = 0x14;
122     /**
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.
126      */
127     static final byte YIID           = 0x15;
128     /**
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}.
132      *
133      * <p>
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.
136      *
137      * <p>
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:
141      * <pre>
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)
150      * </pre>
151      */
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;
155     /**
156      * Reference a QName previously defined via {@link #QNAME}. Reference number is encoded as {@code unsigned byte}.
157      */
158     static final byte QNAME_REF_1B   = 0x17;
159     /**
160      * Reference a QName previously defined via {@link #QNAME}. Reference number is encoded as {@code unsigned short}.
161      */
162     static final byte QNAME_REF_2B   = 0x18;
163     /**
164      * Reference a QName previously defined via {@link #QNAME}. Reference number is encoded as {@code int}.
165      */
166     static final byte QNAME_REF_4B   = 0x19;
167     /**
168      * Reference a previously defined QNameModule. Reference number is encoded as {@code unsigned byte}.
169      */
170     static final byte MODREF_1B      = 0x1A;
171     /**
172      * Reference a previously defined QNameModule. Reference number is encoded as {@code unsigned short}.
173      */
174     static final byte MODREF_2B      = 0x1B;
175     /**
176      * Reference a previously defined QNameModule. Reference number is encoded as {@code int}.
177      */
178     static final byte MODREF_4B      = 0x1C;
179
180     /**
181      * A {@link BigDecimal}, encoded through {@link DataOutput#writeUTF(String)}.
182      */
183     // This is legacy compatibility. At some point we will remove support for writing these.
184     static final byte BIGDECIMAL     = 0x1D;
185     /**
186      * A {@link BigInteger}, encoded through {@link DataOutput#writeUTF(String)}.
187      */
188     // This is legacy compatibility. At some point we will remove support for writing these.
189     static final byte BIGINTEGER     = 0x1E;
190
191     // 0x1F reserved
192
193     /**
194      * Byte value {@code 0}.
195      */
196     static final byte INT8_0         = 0x20;
197     /**
198      * Short value {@code 0}.
199      */
200     static final byte INT16_0        = 0x21;
201     /**
202      * Integer value {@code 0}.
203      */
204     static final byte INT32_0        = 0x22;
205     /**
206      * Long value {@code 0}.
207      */
208     static final byte INT64_0        = 0x23;
209     /**
210      * {@link Uint8#ZERO} value.
211      */
212     static final byte UINT8_0        = 0x24;
213     /**
214      * {@link Uint16#ZERO} value.
215      */
216     static final byte UINT16_0       = 0x25;
217     /**
218      * {@link Uint32#ZERO} value.
219      */
220     static final byte UINT32_0       = 0x26;
221     /**
222      * {@link Uint64#ZERO} value.
223      */
224     static final byte UINT64_0       = 0x27;
225     /**
226      * Empty String value ({@code ""}).
227      */
228     static final byte STRING_EMPTY   = 0x28;
229     /**
230      * {@link #INT32} with a 2-byte operand.
231      */
232     static final byte INT32_2B       = 0x29;
233     /**
234      * {@link #UINT32} with a 2-byte operand.
235      */
236     static final byte UINT32_2B      = 0x2A;
237     /**
238      * {@link #INT64} with a 4-byte operand.
239      */
240     static final byte INT64_4B       = 0x2B;
241     /**
242      * {@link #UINT64} with a 4-byte operand.
243      */
244     static final byte UINT64_4B      = 0x2C;
245
246     // 0x2D - 0x39 reserved
247
248     /**
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.
251      */
252     static final byte BITS_0         = 0x40;
253     /**
254      * A bits value of up to 255 entries. Number of values is encoded as the following {@code unsigned byte}.
255      */
256     static final byte BITS_1B        = 0x5D;
257     /**
258      * A bits value of up to 65535 entries. Number of values is encoded as the following {@code unsigned short}.
259      */
260     static final byte BITS_2B        = 0x5E;
261     /**
262      * A bits value. Number of values is encoded as the following {@code int}.
263      */
264     static final byte BITS_4B        = 0x5F;
265
266     /**
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}.
270      */
271     static final byte YIID_0         = 0x60;
272     /**
273      * {@link YangInstanceIdentifier} with 31 components. See {@link #YIID_0}.
274      */
275     static final byte YIID_31        = 0x7F;
276
277     /**
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.
281      */
282     static final byte BINARY_0       = (byte) 0x80;
283     /**
284      * A {@code byte[]} with 127 bytes. See {@link #BINARY_0}.
285      */
286     static final byte BINARY_127     = (byte) 0xFF;
287
288     private MagnesiumValue() {
289
290     }
291 }