2 * Copyright (c) 2016 Cisco Systems, Inc. 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.access.concepts;
10 import java.io.DataInput;
11 import java.io.DataOutput;
12 import java.io.IOException;
14 //FIXME: this really should go into yangtools/common/concepts.
15 public final class WritableObjects {
16 private WritableObjects() {
17 throw new UnsupportedOperationException();
21 * Write a long value into a {@link DataOutput}, compressing potential zero bytes. This method is useful for
22 * serializing counters and similar, which have a wide range, but typically do not use it. The value provided is
23 * treated as unsigned.
25 * This methods writes the number of trailing non-zero in the value. It then writes the minimum required bytes
26 * to reconstruct the value by left-padding zeroes. Inverse operation is performed by {@link #readLong(DataInput)}.
29 * @param value long value to write
31 public static void writeLong(final DataOutput out, final long value) throws IOException {
32 final int bytes = valueBytes(value);
34 writeValue(out, value, bytes);
37 public static long readLong(final DataInput in) throws IOException {
38 return readValue(in, in.readByte());
41 private static long readValue(final DataInput in, final int flags) throws IOException {
42 int bytes = flags & 0xf;
48 value = (in.readInt() & 0xFFFFFFFFL) << (bytes * Byte.SIZE);
52 value |= in.readUnsignedShort() << (bytes * Byte.SIZE);
55 value |= in.readUnsignedByte();
66 private static void writeValue(final DataOutput out, final long value, final int bytes) throws IOException {
71 out.writeInt((int)(value >>> (left * Byte.SIZE)));
75 out.writeShort((int)(value >>> (left * Byte.SIZE)));
78 out.writeByte((int)(value & 0xFF));
85 private static int valueBytes(final long value) {
86 // This is a binary search for the first match. Note that we need to mask bits from the most significant one
87 if ((value & 0xFFFFFFFF00000000L) != 0) {
88 if ((value & 0xFFFF000000000000L) != 0) {
89 return (value & 0xFF00000000000000L) != 0 ? 8 : 7;
91 return (value & 0xFF0000000000L) != 0 ? 6 : 5;
93 } else if ((value & 0xFFFFFFFFL) != 0) {
94 if ((value & 0xFFFF0000L) != 0) {
95 return (value & 0xFF000000L) != 0 ? 4 : 3;
97 return (value & 0xFF00L) != 0 ? 2 : 1;