Java Nashorn Javascript Library decode(final Object self, final String string, final boolean component)

Here you can find the source of decode(final Object self, final String string, final boolean component)

Description

decode

License

Open Source License

Declaration

private static String decode(final Object self, final String string,
            final boolean component) 

Method Source Code

//package com.java2s;
/*// w  ww  . ja  v a  2 s  .co m
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import static jdk.nashorn.internal.runtime.ECMAErrors.uriError;

public class Main {
    private static final String URI_RESERVED = ";/?:@&=+$,#";

    private static String decode(final Object self, final String string,
            final boolean component) {
        if (string.isEmpty()) {
            return string;
        }

        final int len = string.length();
        final StringBuilder sb = new StringBuilder();

        for (int k = 0; k < len; k++) {
            final char ch = string.charAt(k);
            if (ch != '%') {
                sb.append(ch);
                continue;
            }
            final int start = k;
            if (k + 2 >= len) {
                return error(string, k);
            }

            int B = toHexByte(string.charAt(k + 1), string.charAt(k + 2));
            if (B < 0) {
                return error(string, k + 1);
            }

            k += 2;
            char C;
            // Most significant bit is zero
            if ((B & 0x80) == 0) {
                C = (char) B;
                if (!component && URI_RESERVED.indexOf(C) >= 0) {
                    for (int j = start; j <= k; j++) {
                        sb.append(string.charAt(j));
                    }
                } else {
                    sb.append(C);
                }
            } else {
                // n is utf8 length, V is codepoint and minV is lower bound
                int n, V, minV;

                if ((B & 0xC0) == 0x80) {
                    // 10xxxxxx - illegal first byte
                    return error(string, k);
                } else if ((B & 0x20) == 0) {
                    // 110xxxxx 10xxxxxx
                    n = 2;
                    V = B & 0x1F;
                    minV = 0x80;
                } else if ((B & 0x10) == 0) {
                    // 1110xxxx 10xxxxxx 10xxxxxx
                    n = 3;
                    V = B & 0x0F;
                    minV = 0x800;
                } else if ((B & 0x08) == 0) {
                    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
                    n = 4;
                    V = B & 0x07;
                    minV = 0x10000;
                } else if ((B & 0x04) == 0) {
                    // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
                    n = 5;
                    V = B & 0x03;
                    minV = 0x200000;
                } else if ((B & 0x02) == 0) {
                    // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
                    n = 6;
                    V = B & 0x01;
                    minV = 0x4000000;
                } else {
                    return error(string, k);
                }

                // check bound for sufficient chars
                if (k + (3 * (n - 1)) >= len) {
                    return error(string, k);
                }

                for (int j = 1; j < n; j++) {
                    k++;
                    if (string.charAt(k) != '%') {
                        return error(string, k);
                    }

                    B = toHexByte(string.charAt(k + 1),
                            string.charAt(k + 2));
                    if (B < 0 || (B & 0xC0) != 0x80) {
                        return error(string, k + 1);
                    }

                    V = (V << 6) | (B & 0x3F);
                    k += 2;
                }

                // Check for overlongs and invalid codepoints.
                // The high and low surrogate halves used by UTF-16
                // (U+D800 through U+DFFF) are not legal Unicode values.
                if ((V < minV) || (V >= 0xD800 && V <= 0xDFFF)) {
                    V = Integer.MAX_VALUE;
                }

                if (V < 0x10000) {
                    C = (char) V;
                    if (!component && URI_RESERVED.indexOf(C) >= 0) {
                        for (int j = start; j != k; j++) {
                            sb.append(string.charAt(j));
                        }
                    } else {
                        sb.append(C);
                    }
                } else { // V >= 0x10000
                    if (V > 0x10FFFF) {
                        return error(string, k);
                    }
                    final int L = ((V - 0x10000) & 0x3FF) + 0xDC00;
                    final int H = (((V - 0x10000) >> 10) & 0x3FF) + 0xD800;
                    sb.append((char) H);
                    sb.append((char) L);
                }
            }
        }

        return sb.toString();
    }

    private static String error(final String string, final int index) {
        throw uriError("bad.uri", string, Integer.toString(index));
    }

    private static int toHexByte(final char ch1, final char ch2) {
        final int i1 = hexDigit(ch1);
        final int i2 = hexDigit(ch2);
        if (i1 >= 0 && i2 >= 0) {
            return (i1 << 4) | i2;
        }
        return -1;
    }

    private static int hexDigit(final char ch) {
        final char chu = Character.toUpperCase(ch);
        if (chu >= '0' && chu <= '9') {
            return (chu - '0');
        } else if (chu >= 'A' && chu <= 'F') {
            return (chu - 'A' + 10);
        } else {
            return -1;
        }
    }
}

Related

  1. addToArray(final Object array, final Object value)
  2. addToNativeObject(final Object object, final String key, final Object value)
  3. encode(final Object self, final String string, final boolean component)
  4. error(final String string, final int index)
  5. escape(Object value)
  6. getArrayLength(NativeArray arr)