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 static com.google.common.base.Verify.verify;
12 import java.io.DataInput;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 final class SodiumNormalizedNodeInputStreamReader extends LithiumNormalizedNodeInputStreamReader {
21 private final ArrayList<NodeIdentifier> codedNodeIdentifiers = new ArrayList<>();
22 private final List<AugmentationIdentifier> codedAugments = new ArrayList<>();
23 private final List<QName> codedQNames = new ArrayList<>();
25 SodiumNormalizedNodeInputStreamReader(final DataInput input) {
30 public NormalizedNodeStreamVersion getVersion() throws IOException {
31 return NormalizedNodeStreamVersion.SODIUM;
35 QName readQName() throws IOException {
36 final byte valueType = readByte();
38 case TokenTypes.IS_QNAME_CODE:
39 return codedQName(readInt());
40 case TokenTypes.IS_QNAME_VALUE:
43 throw new IOException("Unhandled QName value type " + valueType);
48 AugmentationIdentifier readAugmentationIdentifier() throws IOException {
49 final byte valueType = readByte();
51 case TokenTypes.IS_AUGMENT_CODE:
52 return codecAugmentId(readInt());
53 case TokenTypes.IS_AUGMENT_VALUE:
54 return rawAugmentId();
56 throw new IOException("Unhandled QName value type " + valueType);
61 NodeIdentifier readNodeIdentifier() throws IOException {
62 // NodeIdentifier rides on top of QName, with this method really saying 'interpret next QName as NodeIdentifier'
63 // to do that we inter-mingle with readQName()
64 final byte valueType = readByte();
66 case TokenTypes.IS_QNAME_CODE:
67 return codedNodeIdentifier(readInt());
68 case TokenTypes.IS_QNAME_VALUE:
69 return rawNodeIdentifier();
71 throw new IOException("Unhandled QName value type " + valueType);
75 private NodeIdentifier codedNodeIdentifier(final int code) throws IOException {
76 final NodeIdentifier existing = codedNodeIdentifiers.size() > code ? codedNodeIdentifiers.get(code) : null;
77 return existing != null ? existing : storeNodeIdentifier(code, codedQName(code));
80 private NodeIdentifier rawNodeIdentifier() throws IOException {
81 // Capture size before it incremented
82 final int code = codedQNames.size();
83 return storeNodeIdentifier(code, rawQName());
86 private NodeIdentifier storeNodeIdentifier(final int code, final QName qname) {
87 final NodeIdentifier ret = NodeIdentifier.create(qname);
88 final int size = codedNodeIdentifiers.size();
92 codedNodeIdentifiers.ensureCapacity(code + 1);
93 for (int i = size; i < code; ++i) {
94 codedNodeIdentifiers.add(null);
97 codedNodeIdentifiers.add(ret);
99 final NodeIdentifier check = codedNodeIdentifiers.set(code, ret);
100 verify(check == null);
106 private QName codedQName(final int code) throws IOException {
108 return codedQNames.get(code);
109 } catch (IndexOutOfBoundsException e) {
110 throw new IOException("QName code " + code + " was not found", e);
114 private QName rawQName() throws IOException {
115 final QName qname = super.readQName();
116 codedQNames.add(qname);
120 private AugmentationIdentifier codecAugmentId(final int code) throws IOException {
122 return codedAugments.get(code);
123 } catch (IndexOutOfBoundsException e) {
124 throw new IOException("QName set code " + code + " was not found", e);
128 private AugmentationIdentifier rawAugmentId() throws IOException {
129 final AugmentationIdentifier aid = super.readAugmentationIdentifier();
130 codedAugments.add(aid);