You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2018/11/08 03:40:27 UTC
[incubator-skywalking] branch master updated: Copies Base64 from
Zipkin (#1891)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 513c1b8 Copies Base64 from Zipkin (#1891)
513c1b8 is described below
commit 513c1b86c6d86b981bf9e5c09c0d041d6c2d624e
Author: Adrian Cole <ad...@users.noreply.github.com>
AuthorDate: Thu Nov 8 11:40:22 2018 +0800
Copies Base64 from Zipkin (#1891)
* Copies Base64 from Zipkin
This copies the last copy of Base64 from Zipkin which can avoid a
dependency on specific JRE. Notes in javadoc show its heritage. We
didn't have unit tests: they can be backported from the source:
https://github.com/square/okio/blob/cc1f5612506f86726c996be6b837b616892e12de/okio/src/test/kotlin/okio/ByteStringTest.kt#L230
Thanks to @swankjesse who created the eldest github ancestor :P
* Adds last version of encoding
---
.../skywalking/apm/agent/core/base64/Base64.java | 165 +++++++++++++++++++++
1 file changed, 165 insertions(+)
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java
new file mode 100644
index 0000000..6467862
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/base64/Base64.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.base64;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Copied from {@code zipkin.internal.Base64}, adapted from {@code okio.Base64}
+ * as JRE 6 doesn't have a base64Url encoder.
+ *
+ * @author okio cited the original author as Alexander Y. Kleymenov
+ */
+public final class Base64 {
+ private Base64() {
+ }
+
+ public static byte[] decode(String in) {
+ // Ignore trailing '=' padding and whitespace from the input.
+ int limit = in.length();
+ for (; limit > 0; limit--) {
+ char c = in.charAt(limit - 1);
+ if (c != '=' && c != '\n' && c != '\r' && c != ' ' && c != '\t') {
+ break;
+ }
+ }
+
+ // If the input includes whitespace, this output array will be longer than necessary.
+ byte[] out = new byte[(int) (limit * 6L / 8L)];
+ int outCount = 0;
+ int inCount = 0;
+
+ int word = 0;
+ for (int pos = 0; pos < limit; pos++) {
+ char c = in.charAt(pos);
+
+ int bits;
+ if (c >= 'A' && c <= 'Z') {
+ // char ASCII value
+ // A 65 0
+ // Z 90 25 (ASCII - 65)
+ bits = c - 65;
+ } else if (c >= 'a' && c <= 'z') {
+ // char ASCII value
+ // a 97 26
+ // z 122 51 (ASCII - 71)
+ bits = c - 71;
+ } else if (c >= '0' && c <= '9') {
+ // char ASCII value
+ // 0 48 52
+ // 9 57 61 (ASCII + 4)
+ bits = c + 4;
+ } else if (c == '+' || c == '-') {
+ bits = 62;
+ } else if (c == '/' || c == '_') {
+ bits = 63;
+ } else if (c == '\n' || c == '\r' || c == ' ' || c == '\t') {
+ continue;
+ } else {
+ return null;
+ }
+
+ // Append this char's 6 bits to the word.
+ word = (word << 6) | (byte) bits;
+
+ // For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes.
+ inCount++;
+ if (inCount % 4 == 0) {
+ out[outCount++] = (byte) (word >> 16);
+ out[outCount++] = (byte) (word >> 8);
+ out[outCount++] = (byte) word;
+ }
+ }
+
+ int lastWordChars = inCount % 4;
+ if (lastWordChars == 1) {
+ // We read 1 char followed by "===". But 6 bits is a truncated byte! Fail.
+ return null;
+ } else if (lastWordChars == 2) {
+ // We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits.
+ word = word << 12;
+ out[outCount++] = (byte) (word >> 16);
+ } else if (lastWordChars == 3) {
+ // We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits.
+ word = word << 6;
+ out[outCount++] = (byte) (word >> 16);
+ out[outCount++] = (byte) (word >> 8);
+ }
+
+ // If we sized our out array perfectly, we're done.
+ if (outCount == out.length) return out;
+
+ // Copy the decoded bytes to a new, right-sized array.
+ byte[] prefix = new byte[outCount];
+ System.arraycopy(out, 0, prefix, 0, outCount);
+ return prefix;
+ }
+
+ private static final byte[] MAP = new byte[] {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
+ '5', '6', '7', '8', '9', '+', '/'
+ };
+
+ private static final byte[] URL_MAP = new byte[] {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
+ '5', '6', '7', '8', '9', '-', '_'
+ };
+
+ public static String encode(byte[] in) {
+ return encode(in, MAP);
+ }
+
+ public static String encodeUrl(byte[] in) {
+ return encode(in, URL_MAP);
+ }
+
+ private static String encode(byte[] in, byte[] map) {
+ int length = (in.length + 2) / 3 * 4;
+ byte[] out = new byte[length];
+ int index = 0, end = in.length - in.length % 3;
+ for (int i = 0; i < end; i += 3) {
+ out[index++] = map[(in[i] & 0xff) >> 2];
+ out[index++] = map[((in[i] & 0x03) << 4) | ((in[i + 1] & 0xff) >> 4)];
+ out[index++] = map[((in[i + 1] & 0x0f) << 2) | ((in[i + 2] & 0xff) >> 6)];
+ out[index++] = map[in[i + 2] & 0x3f];
+ }
+ switch (in.length % 3) {
+ case 1:
+ out[index++] = map[(in[end] & 0xff) >> 2];
+ out[index++] = map[(in[end] & 0x03) << 4];
+ out[index++] = '=';
+ out[index++] = '=';
+ break;
+ case 2:
+ out[index++] = map[(in[end] & 0xff) >> 2];
+ out[index++] = map[((in[end] & 0x03) << 4) | ((in[end + 1] & 0xff) >> 4)];
+ out[index++] = map[(in[end + 1] & 0x0f) << 2];
+ out[index++] = '=';
+ break;
+ }
+ try {
+ return new String(out, "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError(e);
+ }
+ }
+}