aboutsummaryrefslogtreecommitdiff
path: root/api/src/main/java/io/opencensus/trace/LowerCaseBase16Encoding.java
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/main/java/io/opencensus/trace/LowerCaseBase16Encoding.java')
-rw-r--r--api/src/main/java/io/opencensus/trace/LowerCaseBase16Encoding.java91
1 files changed, 91 insertions, 0 deletions
diff --git a/api/src/main/java/io/opencensus/trace/LowerCaseBase16Encoding.java b/api/src/main/java/io/opencensus/trace/LowerCaseBase16Encoding.java
new file mode 100644
index 00000000..bca95868
--- /dev/null
+++ b/api/src/main/java/io/opencensus/trace/LowerCaseBase16Encoding.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.trace;
+
+import io.opencensus.internal.Utils;
+import java.util.Arrays;
+
+/** Internal copy of the Guava implementation of the {@code BaseEncoding.base16().lowerCase()}. */
+final class LowerCaseBase16Encoding {
+ private static final String ALPHABET = "0123456789abcdef";
+ private static final int ASCII_CHARACTERS = 128;
+ private static final char[] ENCODING = buildEncodingArray();
+ private static final byte[] DECODING = buildDecodingArray();
+
+ private static char[] buildEncodingArray() {
+ char[] encoding = new char[512];
+ for (int i = 0; i < 256; ++i) {
+ encoding[i] = ALPHABET.charAt(i >>> 4);
+ encoding[i | 0x100] = ALPHABET.charAt(i & 0xF);
+ }
+ return encoding;
+ }
+
+ private static byte[] buildDecodingArray() {
+ byte[] decoding = new byte[ASCII_CHARACTERS];
+ Arrays.fill(decoding, (byte) -1);
+ for (int i = 0; i < ALPHABET.length(); i++) {
+ char c = ALPHABET.charAt(i);
+ decoding[c] = (byte) i;
+ }
+ return decoding;
+ }
+
+ /**
+ * Encodes the specified byte array, and returns the encoded {@code String}.
+ *
+ * @param bytes byte array to be encoded.
+ * @return the encoded {@code String}.
+ */
+ static String encodeToString(byte[] bytes) {
+ StringBuilder stringBuilder = new StringBuilder(bytes.length * 2);
+ for (byte byteVal : bytes) {
+ int b = byteVal & 0xFF;
+ stringBuilder.append(ENCODING[b]);
+ stringBuilder.append(ENCODING[b | 0x100]);
+ }
+ return stringBuilder.toString();
+ }
+
+ /**
+ * Decodes the specified character sequence, and returns the resulting {@code byte[]}.
+ *
+ * @param chars the character sequence to be decoded.
+ * @return the resulting {@code byte[]}
+ * @throws IllegalArgumentException if the input is not a valid encoded string according to this
+ * encoding.
+ */
+ static byte[] decodeToBytes(CharSequence chars) {
+ Utils.checkArgument(chars.length() % 2 == 0, "Invalid input length " + chars.length());
+ int bytesWritten = 0;
+ byte[] bytes = new byte[chars.length() / 2];
+ for (int i = 0; i < chars.length(); i += 2) {
+ bytes[bytesWritten++] = decodeByte(chars.charAt(i), chars.charAt(i + 1));
+ }
+ return bytes;
+ }
+
+ private static byte decodeByte(char hi, char lo) {
+ Utils.checkArgument(lo < ASCII_CHARACTERS && DECODING[lo] != -1, "Invalid character " + lo);
+ Utils.checkArgument(hi < ASCII_CHARACTERS && DECODING[hi] != -1, "Invalid character " + hi);
+ int decoded = DECODING[hi] << 4 | DECODING[lo];
+ return (byte) decoded;
+ }
+
+ // Private constructor to disallow instances.
+ private LowerCaseBase16Encoding() {}
+}