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);
+        }
+    }
+}