private static final @NonNull Integer INT32_0 = 0;
private static final @NonNull Long INT64_0 = 0L;
private static final byte @NonNull[] BINARY_0 = new byte[0];
- private static final @NonNull LegacyAugmentationIdentifier EMPTY_AID =
- new LegacyAugmentationIdentifier(ImmutableSet.of());
- private final List<LegacyAugmentationIdentifier> codedAugments = new ArrayList<>();
private final List<NodeIdentifier> codedNodeIdentifiers = new ArrayList<>();
private final List<QNameModule> codedModules = new ArrayList<>();
private final List<String> codedStrings = new ArrayList<>();
case PotassiumNode.NODE_CHOICE:
streamChoice(writer, nodeHeader);
break;
- case PotassiumNode.NODE_AUGMENTATION:
- streamAugmentation(writer, nodeHeader);
- break;
case PotassiumNode.NODE_ANYXML:
streamAnyxml(writer, nodeHeader);
break;
}
}
- private void streamAugmentation(final NormalizedNodeStreamWriter writer, final byte nodeHeader) throws IOException {
- final var augIdentifier = decodeAugmentationIdentifier(nodeHeader);
- LOG.trace("Streaming augmentation node {}", augIdentifier);
- for (byte nodeType = input.readByte(); nodeType != PotassiumNode.NODE_END; nodeType = input.readByte()) {
- // FIXME: not just null, but augmentation identifier for debug
- streamNormalizedNode(writer, null, nodeType);
- }
- }
-
private void streamChoice(final NormalizedNodeStreamWriter writer, final byte nodeHeader) throws IOException {
final NodeIdentifier identifier = decodeNodeIdentifier(nodeHeader);
LOG.trace("Streaming choice node {}", identifier);
}
}
- private LegacyAugmentationIdentifier decodeAugmentationIdentifier(final byte nodeHeader) throws IOException {
- final int index;
- switch (nodeHeader & PotassiumNode.ADDR_MASK) {
- case PotassiumNode.ADDR_DEFINE:
- return readAugmentationIdentifier();
- case PotassiumNode.ADDR_LOOKUP_1B:
- index = input.readUnsignedByte();
- break;
- case PotassiumNode.ADDR_LOOKUP_4B:
- index = input.readInt();
- break;
- default:
- throw new InvalidNormalizedNodeStreamException(
- "Unexpected augmentation identifier addressing in header " + nodeHeader);
- }
-
- try {
- return codedAugments.get(index);
- } catch (IndexOutOfBoundsException e) {
- throw new InvalidNormalizedNodeStreamException("Invalid augmentation identifier reference " + index, e);
- }
- }
-
@Override
public YangInstanceIdentifier readYangInstanceIdentifier() throws IOException {
final byte type = input.readByte();
}
@Override
- @Deprecated(since = "11.0.0", forRemoval = true)
- public Either<PathArgument, LegacyPathArgument> readLegacyPathArgument() throws IOException {
+ public PathArgument readPathArgument() throws IOException {
final byte header = input.readByte();
return switch (header & PotassiumPathArgument.TYPE_MASK) {
- case PotassiumPathArgument.AUGMENTATION_IDENTIFIER -> Either.ofSecond(readAugmentationIdentifier(header));
case PotassiumPathArgument.NODE_IDENTIFIER -> {
verifyPathIdentifierOnly(header);
- yield Either.ofFirst(readNodeIdentifier(header));
+ yield readNodeIdentifier(header);
}
- case PotassiumPathArgument.NODE_IDENTIFIER_WITH_PREDICATES ->
- Either.ofFirst(readNodeIdentifierWithPredicates(header));
+ case PotassiumPathArgument.NODE_IDENTIFIER_WITH_PREDICATES -> readNodeIdentifierWithPredicates(header);
case PotassiumPathArgument.NODE_WITH_VALUE -> {
verifyPathIdentifierOnly(header);
- yield Either.ofFirst(readNodeWithValue(header));
- }
- case PotassiumPathArgument.MOUNTPOINT_IDENTIFIER -> {
- verifyPathIdentifierOnly(header);
- yield Either.ofSecond(new LegacyMountPointIdentifier(readNodeIdentifier(header).getNodeType()));
+ yield readNodeWithValue(header);
}
default -> throw new InvalidNormalizedNodeStreamException("Unexpected PathArgument header " + header);
};
}
- private @NonNull LegacyAugmentationIdentifier readAugmentationIdentifier() throws IOException {
- final var result = readAugmentationIdentifier(input.readInt());
- codedAugments.add(result);
- return result;
- }
-
- private @NonNull LegacyAugmentationIdentifier readAugmentationIdentifier(final byte header) throws IOException {
- final byte count = mask(header, PotassiumPathArgument.AID_COUNT_MASK);
- return switch (count) {
- case PotassiumPathArgument.AID_COUNT_1B -> readAugmentationIdentifier(input.readUnsignedByte());
- case PotassiumPathArgument.AID_COUNT_2B -> readAugmentationIdentifier(input.readUnsignedShort());
- case PotassiumPathArgument.AID_COUNT_4B -> readAugmentationIdentifier(input.readInt());
- default -> readAugmentationIdentifier(rshift(count, PotassiumPathArgument.AID_COUNT_SHIFT));
- };
- }
-
- private @NonNull LegacyAugmentationIdentifier readAugmentationIdentifier(final int size) throws IOException {
- if (size > 0) {
- final var qnames = ImmutableSet.<QName>builderWithExpectedSize(size);
- for (int i = 0; i < size; ++i) {
- qnames.add(readQName());
- }
- return new LegacyAugmentationIdentifier(qnames.build());
- } else if (size == 0) {
- return EMPTY_AID;
- } else {
- throw new InvalidNormalizedNodeStreamException("Invalid augmentation identifier size " + size);
- }
+ @Override
+ @Deprecated(since = "11.0.0", forRemoval = true)
+ public Either<PathArgument, LegacyPathArgument> readLegacyPathArgument() throws IOException {
+ return Either.ofFirst(readPathArgument());
}
private @NonNull NodeIdentifier readNodeIdentifier() throws IOException {
* | | Type|
* +-+-+-+-+-+-+-+-+
* </pre>
- * There are five type defined:
+ * There are three type defined:
* <ul>
- * <li>{@link #AUGMENTATION_IDENTIFIER}, which additionally holds the number of QName elements encoded:
- * <pre>
- * 7 6 5 4 3 2 1 0
- * +-+-+-+-+-+-+-+-+
- * | Count |0 0 0|
- * +-+-+-+-+-+-+-+-+
- * </pre>
- * Where count is coded as an unsigned integer, with {@link #AID_COUNT_1B} and {@link #AID_COUNT_2B} and
- * {@link #AID_COUNT_4B} indicating extended coding with up to 4 additional bytes. This byte is followed by
- * {@code count} {@link PotassiumValue} QNames.
+ * <li>{@link #NODE_IDENTIFIER}, which encodes a QName:
* <pre>
* 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+
* |0 0 0| Q |0 0 1|
* +-+-+-+-+-+-+-+-+
* </pre>
- * Where QName coding is achieved via {@link #QNAME_DEF}, {@link #QNAME_REF_1B}, {@link #QNAME_REF_2B} and
- * {@link #QNAME_REF_4B}.
- * </li>
* <li>{@link #NODE_IDENTIFIER_WITH_PREDICATES}, which encodes a QName same way NodeIdentifier does:
* <pre>
* 7 6 5 4 3 2 1 0
* </pre>
* but is additionally followed by a single encoded value, as per {@link PotassiumValue}.
* </li>
- * <li>{@link #MOUNTPOINT_IDENTIFIER}, which encodes a QName same way NodeIdentifier does:
- * <pre>
- * 7 6 5 4 3 2 1 0
- * +-+-+-+-+-+-+-+-+
- * |0 0 0| Q |1 0 0|
- * +-+-+-+-+-+-+-+-+
- * </pre>
* </li>
* </ul>
*/
final class PotassiumPathArgument {
// 3 bits reserved for type...
- static final byte AUGMENTATION_IDENTIFIER = 0x00;
static final byte NODE_IDENTIFIER = 0x01;
static final byte NODE_IDENTIFIER_WITH_PREDICATES = 0x02;
static final byte NODE_WITH_VALUE = 0x03;
- static final byte MOUNTPOINT_IDENTIFIER = 0x04;
- // ... leaving three values currently unused
+ // ... leaving five values currently unused
+ // FIXME: this means we can use just two bits for type encoding
+ // 0x00 reserved
+ // 0x04 reserved
// 0x05 reserved
// 0x06 reserved
// 0x07 reserved
static final byte TYPE_MASK = 0x07;
- // In case of AUGMENTATION_IDENTIFIER, top 5 bits are used to encode the number of path arguments, except last three
- // values. This means that up to AugmentationIdentifiers with up to 28 components have this length encoded inline,
- // otherwise we encode them in following 1 (unsigned), 2 (unsigned) or 4 (signed) bytes
- static final byte AID_COUNT_1B = (byte) 0xE8;
- static final byte AID_COUNT_2B = (byte) 0xF0;
- static final byte AID_COUNT_4B = (byte) 0xF8;
- static final byte AID_COUNT_MASK = AID_COUNT_4B;
- static final byte AID_COUNT_SHIFT = 3;
-
// For normal path path arguments we can either define a QName reference or follow a 1-4 byte reference.
static final byte QNAME_DEF = 0x00;
static final byte QNAME_REF_1B = 0x08; // Unsigned