/*
Converts encoded &#92;uxxxx to unicode chars
and changes special saved chars to their original forms
187078
private String loadConvert (char[] in, int off, int len, char[] convtBuf) {
        if (convtBuf.length < len) {
            int newLen = len * 2;
            if (newLen < 0) {
                newLen = Integer.MAX_VALUE;
            }
            convtBuf = new char[newLen];
        }
        char aChar;
        char[] out = convtBuf;
        int outLen = 0;
        int end = off + len;

        while (off < end) {
            aChar = in[off++];
            if (aChar == '\\') {
                aChar = in[off++];
                if(aChar == 'u') {
                    // Read the xxxx
                    int value=0;
                    for (int i=0; i<4; i++) {
                        aChar = in[off++];
                        switch (aChar) {
                          case '0': case '1': case '2': case '3': case '4':
                          case '5': case '6': case '7': case '8': case '9':
                             value = (value << 4) + aChar - '0';
                             break;
                          case 'a': case 'b': case 'c':
                          case 'd': case 'e': case 'f':
                             value = (value << 4) + 10 + aChar - 'a';
                             break;
                          case 'A': case 'B': case 'C':
                          case 'D': case 'E': case 'F':
                             value = (value << 4) + 10 + aChar - 'A';
                             break;
                          default:
                              throw new IllegalArgumentException(
                                           "Malformed \\uxxxx encoding.");
                        }
                     }
                    out[outLen++] = (char)value;
                } else {
                    if (aChar == 't') aChar = '\t';
                    else if (aChar == 'r') aChar = '\r';
                    else if (aChar == 'n') aChar = '\n';
                    else if (aChar == 'f') aChar = '\f';
                    out[outLen++] = aChar;
                }
            } else {
                out[outLen++] = aChar;
            }
        }
        return new String (out, 0, outLen);
    }
835233
public static String toUnicode(String str, boolean isSkipAscii) {
		if (StrUtil.isEmpty(str)) {
			return str;
		}

		final int len = str.length();
		final StrBuilder unicode = StrBuilder.create(str.length() * 6);
		char c;
		for (int i = 0; i < len; i++) {
			c = str.charAt(i);
			if(isSkipAscii && CharUtil.isAsciiPrintable(c) ) {
				unicode.append(c);
			}else {
				unicode.append(HexUtil.toUnicodeHex(c));
			}
		}
		return unicode.toString();
	}
948434
def ucn_to_unicode(ucn):
    
    if isinstance(ucn, string_types):
        ucn = ucn.strip("U+")
        if len(ucn) > int(4):
            char = b'\U' + format(int(ucn, 16), '08x').encode('latin1')
            char = char.decode('unicode_escape')
        else:
            char = unichr(int(ucn, 16))
    else:
        char = unichr(ucn)

    assert isinstance(char, text_type)

    return char
656958
function(string) {
            var output = encodeURIComponent(string);
            output = output.replace(/[^A-Za-z0-9_.~\-%]+/g, escape);
            output = output.replace(/[*]/g, function(ch) {
                return "%" + ch.charCodeAt(0).toString(16).toUpperCase();
            });
            return output;
        }
1360792
function unicode_encode($value, $prefix='\u', $parse_alpha=true, $exclude_str=null)
    {
        if ($prefix) {
            if (strpos($prefix, '\\') !== 0) {
                $prefix = '\\' . $prefix;
            }
            
            if ($prefix !== '\\u' && $prefix !== '\\x') {
                $prefix = '\\u';
            }
        }
        $value = iconv('UTF-8', 'UCS-2', $value);
        $len = strlen($value);
        $newStr = '';
        for ($i = 0; $i < $len - 1; $i = $i + 2)
        {
            $c  = $value[$i];
            $c2 = $value[$i + 1];
            if (ord($c) > 0)
            {    // 两个字节的文字
                $newStr .= '\\u' . strtoupper(base_convert(ord($c), 10, 16).base_convert(ord($c2), 10, 16));
            }
            else
            {
                if ($exclude_str && strpos($exclude_str, $c2) !== false) {
                    $newStr .= $c2;
                } else {
                    if ($prefix == '\\u') {
                        $newStr .= $parse_alpha ? '\\u00' . strtoupper(bin2hex($c2)) : $c2;
                    } else {
                        $newStr .= $parse_alpha ? '\\x' . strtoupper(bin2hex($c2)) : $c2;
                    }
                }
            }
        }
        return $newStr;
    }
224175
function decodeUTF8(bytes) {
  var s = '';
  var i = 0;
  while (i < bytes.length) {
    var c = bytes[i++];
    if (c > 127) {
      if (c > 191 && c < 224) {
        if (i >= bytes.length)
          throw new Error('UTF-8 decode: incomplete 2-byte sequence');
        c = ((c & 31) << 6) | (bytes[i] & 63);
      } else if (c > 223 && c < 240) {
        if (i + 1 >= bytes.length)
          throw new Error('UTF-8 decode: incomplete 3-byte sequence');
        c = ((c & 15) << 12) | ((bytes[i] & 63) << 6) | (bytes[++i] & 63);
      } else if (c > 239 && c < 248) {
        if (i + 2 >= bytes.length)
          throw new Error('UTF-8 decode: incomplete 4-byte sequence');
        c =
          ((c & 7) << 18) |
          ((bytes[i] & 63) << 12) |
          ((bytes[++i] & 63) << 6) |
          (bytes[++i] & 63);
      } else
        throw new Error(
          'UTF-8 decode: unknown multibyte start 0x' +
            c.toString(16) +
            ' at index ' +
            (i - 1)
        );
      ++i;
    }

    if (c <= 0xffff) s += String.fromCharCode(c);
    else if (c <= 0x10ffff) {
      c -= 0x10000;
      s += String.fromCharCode((c >> 10) | 0xd800);
      s += String.fromCharCode((c & 0x3ff) | 0xdc00);
    } else
      throw new Error(
        'UTF-8 decode: code point 0x' + c.toString(16) + ' exceeds UTF-16 reach'
      );
  }
  return s;
}
859742
function fullEncodeURIComponent (str) {
    var rv = encodeURIComponent(str).replace(/[!'()*~]/g, function(c) {
      return '%' + c.charCodeAt(0).toString(16).toUpperCase();
    });
    return rv.replace(/\%20/g,'+');
}
508137
function uriEncodeString( text ){
    return encodeURIComponent(text).replace( /[\!\*\'\(\)]/g, function( chr ){
        chr = chr.charCodeAt(0).toString(16);
        while( chr.length < 2 ){
            chr = '0'+hex;
        }
        return '%'+chr;
    } )
}
829596
function unescapeSpecialChars(text) {

        text = text.replace(/~E(\d+)E/g, function(wholeMatch,m1) {
            var charCodeToReplace = parseInt(m1);
            return String.fromCharCode(charCodeToReplace);
        });

        return text;
    }
920452
function convertCodePoints(regexp) {
		return regexp.replace(/\\x\{([0-9a-fA-F]+)\}/g, function(m, chars) {
			// pad to four hex digits
			while (chars.length < 4) {
				chars = '0' + chars;
			}
			return '\\u' + chars;
		});
	}
496000
function toUtf8String(bytes, ignoreErrors) {
    bytes = bytes_1.arrayify(bytes);
    var result = '';
    var i = 0;
    // Invalid bytes are ignored
    while (i < bytes.length) {
        var c = bytes[i++];
        // 0xxx xxxx
        if (c >> 7 === 0) {
            result += String.fromCharCode(c);
            continue;
        }
        // Multibyte; how many bytes left for this character?
        var extraLength = null;
        var overlongMask = null;
        // 110x xxxx 10xx xxxx
        if ((c & 0xe0) === 0xc0) {
            extraLength = 1;
            overlongMask = 0x7f;
            // 1110 xxxx 10xx xxxx 10xx xxxx
        }
        else if ((c & 0xf0) === 0xe0) {
            extraLength = 2;
            overlongMask = 0x7ff;
            // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
        }
        else if ((c & 0xf8) === 0xf0) {
            extraLength = 3;
            overlongMask = 0xffff;
        }
        else {
            if (!ignoreErrors) {
                if ((c & 0xc0) === 0x80) {
                    throw new Error('invalid utf8 byte sequence; unexpected continuation byte');
                }
                throw new Error('invalid utf8 byte sequence; invalid prefix');
            }
            continue;
        }
        // Do we have enough bytes in our data?
        if (i + extraLength > bytes.length) {
            if (!ignoreErrors) {
                throw new Error('invalid utf8 byte sequence; too short');
            }
            // If there is an invalid unprocessed byte, skip continuation bytes
            for (; i < bytes.length; i++) {
                if (bytes[i] >> 6 !== 0x02) {
                    break;
                }
            }
            continue;
        }
        // Remove the length prefix from the char
        var res = c & ((1 << (8 - extraLength - 1)) - 1);
        for (var j = 0; j < extraLength; j++) {
            var nextChar = bytes[i];
            // Invalid continuation byte
            if ((nextChar & 0xc0) != 0x80) {
                res = null;
                break;
            }
            ;
            res = (res << 6) | (nextChar & 0x3f);
            i++;
        }
        if (res === null) {
            if (!ignoreErrors) {
                throw new Error('invalid utf8 byte sequence; invalid continuation byte');
            }
            continue;
        }
        // Check for overlong seuences (more bytes than needed)
        if (res <= overlongMask) {
            if (!ignoreErrors) {
                throw new Error('invalid utf8 byte sequence; overlong');
            }
            continue;
        }
        // Maximum code point
        if (res > 0x10ffff) {
            if (!ignoreErrors) {
                throw new Error('invalid utf8 byte sequence; out-of-range');
            }
            continue;
        }
        // Reserved for UTF-16 surrogate halves
        if (res >= 0xd800 && res <= 0xdfff) {
            if (!ignoreErrors) {
                throw new Error('invalid utf8 byte sequence; utf-16 surrogate');
            }
            continue;
        }
        if (res <= 0xffff) {
            result += String.fromCharCode(res);
            continue;
        }
        res -= 0x10000;
        result += String.fromCharCode(((res >> 10) & 0x3ff) + 0xd800, (res & 0x3ff) + 0xdc00);
    }
    return result;
}
523456
function b64EncodeUnicode(str) {
  return btoa(
    encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
      function toSolidBytes(match, p1) {
        return String.fromCharCode('0x' + p1);
      }));
}
1241618
function encodeURIComponentPretty (str) {
  return encodeURI(str).replace(/[\/?#]/g, function (c) {
    return '%' + c.charCodeAt(0).toString(16).toUpperCase()
  })
}
155328
function convertData2Hexd (data) {
  if (!isHexString(data)) {
    var hex = ''
    for (var i = 0; i < data.length; i++) {
      hex += data.charCodeAt(i).toString(16)
    }
    return '0x' + hex
  }
  return data
}
290573
public static String unicodeToString(String s) {
        StringBuilder sb = new StringBuilder();
        StringTokenizer st = new StringTokenizer(s, "\\u");
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            if (token.length() > 4) {
                sb.append((char) Integer.parseInt(token.substring(0, 4), 16));
                sb.append(token.substring(4));
            } else {
                sb.append((char) Integer.parseInt(token, 16));
            }
        }
        return sb.toString();
    }
737702
private static int specialChar(char ch) {
        if ((ch > '\u0621' && ch < '\u0626') ||
            (ch == '\u0627') ||
            (ch > '\u062E' && ch < '\u0633') ||
            (ch > '\u0647' && ch < '\u064A') ||
            (ch == '\u0629')) {
            return 1;
        } else if (ch >= '\u064B' && ch<= '\u0652') {
            return 2;
        } else if (ch >= 0x0653 && ch <= 0x0655 ||
                   ch == 0x0670 ||
                   ch >= 0xFE70 && ch <= 0xFE7F) {
            return 3;
        } else {
            return 0;
        }
    }
426356
function escapeString(string) {
  var result = '';
  var char, nextChar;
  var escapeSeq;

  for (var i = 0; i < string.length; i++) {
    char = string.charCodeAt(i);
    // Check for surrogate pairs (reference Unicode 3.0 section "3.7 Surrogates").
    if (char >= 0xD800 && char <= 0xDBFF/* high surrogate */) {
      nextChar = string.charCodeAt(i + 1);
      if (nextChar >= 0xDC00 && nextChar <= 0xDFFF/* low surrogate */) {
        // Combine the surrogate pair and store it escaped.
        result += encodeHex((char - 0xD800) * 0x400 + nextChar - 0xDC00 + 0x10000);
        // Advance index one extra since we already used that char here.
        i++; continue;
      }
    }
    escapeSeq = ESCAPE_SEQUENCES[char];
    result += !escapeSeq && isPrintable(char)
      ? string[i]
      : escapeSeq || encodeHex(char);
  }

  return result;
}