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.controller.cluster.datastore.node.utils.QNameFactory;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.QNameModule;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
22 final class NeonSR2NormalizedNodeInputStreamReader extends LithiumNormalizedNodeInputStreamReader {
23 private final ArrayList<NodeIdentifier> codedNodeIdentifiers = new ArrayList<>();
24 private final List<AugmentationIdentifier> codedAugments = new ArrayList<>();
25 private final List<QNameModule> codedModules = new ArrayList<>();
26 private final List<QName> codedQNames = new ArrayList<>();
28 NeonSR2NormalizedNodeInputStreamReader(final DataInput input) {
33 public NormalizedNodeStreamVersion getVersion() throws IOException {
34 return NormalizedNodeStreamVersion.NEON_SR2;
38 public QName readQName() throws IOException {
39 final byte valueType = readByte();
41 case TokenTypes.IS_QNAME_CODE:
42 return codedQName(readInt());
43 case TokenTypes.IS_QNAME_VALUE:
46 throw new IOException("Unhandled QName value type " + valueType);
51 AugmentationIdentifier readAugmentationIdentifier() throws IOException {
52 final byte valueType = readByte();
54 case TokenTypes.IS_AUGMENT_CODE:
55 return codedAugmentId(readInt());
56 case TokenTypes.IS_AUGMENT_VALUE:
57 return rawAugmentId();
59 throw new IOException("Unhandled QName value type " + valueType);
64 NodeIdentifier readNodeIdentifier() throws IOException {
65 // NodeIdentifier rides on top of QName, with this method really saying 'interpret next QName as NodeIdentifier'
66 // to do that we inter-mingle with readQName()
67 final byte valueType = readByte();
69 case TokenTypes.IS_QNAME_CODE:
70 return codedNodeIdentifier(readInt());
71 case TokenTypes.IS_QNAME_VALUE:
72 return rawNodeIdentifier();
74 throw new IOException("Unhandled QName value type " + valueType);
78 private QNameModule readModule() throws IOException {
79 final byte valueType = readByte();
81 case TokenTypes.IS_MODULE_CODE:
82 return codedModule(readInt());
83 case TokenTypes.IS_MODULE_VALUE:
86 throw new IOException("Unhandled QName value type " + valueType);
90 private NodeIdentifier codedNodeIdentifier(final int code) throws IOException {
91 final NodeIdentifier existing = codedNodeIdentifiers.size() > code ? codedNodeIdentifiers.get(code) : null;
92 return existing != null ? existing : storeNodeIdentifier(code, codedQName(code));
95 private NodeIdentifier rawNodeIdentifier() throws IOException {
96 // Capture size before it incremented
97 final int code = codedQNames.size();
98 return storeNodeIdentifier(code, rawQName());
101 private NodeIdentifier storeNodeIdentifier(final int code, final QName qname) {
102 final NodeIdentifier ret = NodeIdentifier.create(qname);
103 final int size = codedNodeIdentifiers.size();
107 codedNodeIdentifiers.ensureCapacity(code + 1);
108 for (int i = size; i < code; ++i) {
109 codedNodeIdentifiers.add(null);
112 codedNodeIdentifiers.add(ret);
114 final NodeIdentifier check = codedNodeIdentifiers.set(code, ret);
115 verify(check == null);
121 private QName codedQName(final int code) throws IOException {
123 return codedQNames.get(code);
124 } catch (IndexOutOfBoundsException e) {
125 throw new IOException("QName code " + code + " was not found", e);
129 private QName rawQName() throws IOException {
130 final String localName = readCodedString();
131 final QNameModule module = readModule();
132 final QName qname = QNameFactory.create(module, localName);
133 codedQNames.add(qname);
137 private AugmentationIdentifier codedAugmentId(final int code) throws IOException {
139 return codedAugments.get(code);
140 } catch (IndexOutOfBoundsException e) {
141 throw new IOException("QName set code " + code + " was not found", e);
145 private AugmentationIdentifier rawAugmentId() throws IOException {
146 final AugmentationIdentifier aid = super.readAugmentationIdentifier();
147 codedAugments.add(aid);
151 private QNameModule codedModule(final int code) throws IOException {
153 return codedModules.get(code);
154 } catch (IndexOutOfBoundsException e) {
155 throw new IOException("Module code " + code + " was not found", e);
159 private QNameModule rawModule() throws IOException {
160 final String namespace = readCodedString();
161 final String revision = readCodedString();
162 final QNameModule mod = QNameFactory.createModule(namespace, revision);
163 codedModules.add(mod);