Un-escape a byte sequence as escaped using
{@link #escapeBytes(ByteString)}.  Two-digit hex escapes (starting with
"\x") are also recognized.
545499
static ByteString unescapeBytes(final CharSequence charString)
      throws InvalidEscapeSequenceException {
    // First convert the Java character sequence to UTF-8 bytes.
    ByteString input = ByteString.copyFromUtf8(charString.toString());
    // Then unescape certain byte sequences introduced by ASCII '\\'.  The valid
    // escapes can all be expressed with ASCII characters, so it is safe to
    // operate on bytes here.
    //
    // Unescaping the input byte array will result in a byte sequence that's no
    // longer than the input.  That's because each escape sequence is between
    // two and four bytes long and stands for a single byte.
    final byte[] result = new byte[input.size()];
    int pos = 0;
    for (int i = 0; i < input.size(); i++) {
      byte c = input.byteAt(i);
      if (c == '\\') {
        if (i + 1 < input.size()) {
          ++i;
          c = input.byteAt(i);
          if (isOctal(c)) {
            // Octal escape.
            int code = digitValue(c);
            if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
              ++i;
              code = code * 8 + digitValue(input.byteAt(i));
            }
            if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
              ++i;
              code = code * 8 + digitValue(input.byteAt(i));
            }
            // TODO: Check that 0 <= code && code <= 0xFF.
            result[pos++] = (byte)code;
          } else {
            switch (c) {
              case 'a' : result[pos++] = 0x07; break;
              case 'b' : result[pos++] = '\b'; break;
              case 'f' : result[pos++] = '\f'; break;
              case 'n' : result[pos++] = '\n'; break;
              case 'r' : result[pos++] = '\r'; break;
              case 't' : result[pos++] = '\t'; break;
              case 'v' : result[pos++] = 0x0b; break;
              case '\\': result[pos++] = '\\'; break;
              case '\'': result[pos++] = '\''; break;
              case '"' : result[pos++] = '\"'; break;

              case 'x':
                // hex escape
                int code = 0;
                if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
                  ++i;
                  code = digitValue(input.byteAt(i));
                } else {
                  throw new InvalidEscapeSequenceException(
                      "Invalid escape sequence: '\\x' with no digits");
                }
                if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
                  ++i;
                  code = code * 16 + digitValue(input.byteAt(i));
                }
                result[pos++] = (byte)code;
                break;

              default:
                throw new InvalidEscapeSequenceException(
                    "Invalid escape sequence: '\\" + (char)c + '\'');
            }
          }
        } else {
          throw new InvalidEscapeSequenceException(
              "Invalid escape sequence: '\\' at end of string.");
        }
      } else {
        result[pos++] = c;
      }
    }

    return ByteString.copyFrom(result, 0, pos);
  }
102845
private final static String escape(String src) {
        if (src == null) {
            return "";
        }
        StringBuffer result = null;
        for (int i = 0, max = src.length(), delta = 0; i < max; i++) {
            char c = src.charAt(i);
            if (!Character.isWhitespace(c) && Character.isISOControl(c) || Character.getType(c) == Character.UNASSIGNED) {
                String hexVal = Integer.toHexString(c);
                String replacement = "\\u" + ("0000" + hexVal).substring(hexVal.length());
                if (result == null) {
                    result = new StringBuffer(src);
                }
                result.replace(i + delta, i + delta + 1, replacement);
                delta += replacement.length() - 1;
            }
        }
        if (result == null) {
            return src;
        } else {
            return result.toString();
        }
    }
1095837
private static String escape(String string) {
        StringBuilder sb = new StringBuilder((int) (string.length() * 1.1));
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);
            switch (c) {
            case ',':
                sb.append("=2C");
                break;
            case '=':
                sb.append("=3D");
                break;
            default:
                sb.append(c);
                break;
            }
        }
        return sb.toString();
    }
993988
public static String encodeHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_CHARS[v >>> 4];
            hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
        }
        return new String(hexChars);
    }
771502
public static String toHex(byte[] bytes) {
    StringBuffer buffer = new StringBuffer();

    for (byte b : bytes) {
      buffer.append(String.format("%02X", b));
    }

    return buffer.toString();
  }
40431
private String escape(String value)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < value.length(); ++i)
        {
            char c = value.charAt(i);
            if (c < reservedChars.length && reservedChars[c] == c)
            {
                result.append(ESCAPE_PREFIX);
                int code = c & 0xFF;
                if (code < 16) result.append("0");
                result.append(Integer.toHexString(code));
            }
            else
            {
                result.append(c);
            }
        }
        return result.toString();
    }
479662
private static String unescapeLiteral(final String text) {

        if (text == null) {
            return null;
        }

        StringBuilder strBuilder = null;

        final int max = text.length();

        int readOffset = 0;
        int referenceOffset = 0;

        char c;

        for (int i = 0; i < max; i++) {

            c = text.charAt(i);

            /*
             * Check the need for an unescape operation at this point
             */

            if (c != ESCAPE_PREFIX || (i + 1) >= max) {
                continue;
            }

            if (c == ESCAPE_PREFIX) {

                switch (text.charAt(i + 1)) {
                    case '\'': c = '\''; referenceOffset = i + 1; break;
                    case '\\': c = '\\'; referenceOffset = i + 1; break;
                    // We weren't able to consume any valid escape chars, just not consider it an escape operation
                    default: referenceOffset = i; break;
                }

            }


            /*
             * At this point we know for sure we will need some kind of unescape, so we
             * can increase the offset and initialize the string builder if needed, along with
             * copying to it all the contents pending up to this point.
             */

            if (strBuilder == null) {
                strBuilder = new StringBuilder(max + 5);
            }

            if (i - readOffset > 0) {
                strBuilder.append(text, readOffset, i);
            }

            i = referenceOffset;
            readOffset = i + 1;

            /*
             * Write the unescaped char
             */
            strBuilder.append(c);

        }


        /*
         * -----------------------------------------------------------------------------------------------
         * Final cleaning: return the original String object if no unescape was actually needed. Otherwise
         *                 append the remaining escaped text to the string builder and return.
         * -----------------------------------------------------------------------------------------------
         */

        if (strBuilder == null) {
            return text;
        }

        if (max - readOffset > 0) {
            strBuilder.append(text, readOffset, max);
        }

        return strBuilder.toString();

    }
793647
public static byte[] decodeHex(char[] hexData) {

		int len = hexData.length;

		if ((len & 0x01) != 0) {
			throw new RuntimeException("Odd number of characters.");
		}

		byte[] out = new byte[len >> 1];

		// two characters form the hex value.
		for (int i = 0, j = 0; j < len; i++) {
			int f = toDigit(hexData[j], j) << 4;
			j++;
			f = f | toDigit(hexData[j], j);
			j++;
			out[i] = (byte) (f & 0xFF);
		}

		return out;
	}
557604
private static String encode(String value, BitSet unescapedChars) {
        // Code from org.apache.commons.codec.net.URLCodec.encodeUrl(BitSet, byte[])
        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        for (final byte c : value.getBytes(CHARSET)) {
            int b = c;
            if (b < 0) {
                b = 256 + b;
            }
            if (unescapedChars.get(b)) {
                buffer.write(b);
            } else {
                buffer.write(ESCAPE_CHAR);
                final char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, HEXADECIMAL_RADIX));
                final char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, HEXADECIMAL_RADIX));
                buffer.write(hex1);
                buffer.write(hex2);
            }
        }
        return new String(buffer.toByteArray(), CHARSET);
    }
1092494
private static void byte2hex(byte b, StringBuffer buf) {
        char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        int high = ((b & 0xf0) >> 4);
        int low = (b & 0x0f);
        buf.append(hexChars[high]);
        buf.append(hexChars[low]);
    }
341678
public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
		if (rawContent == null)
			return "";
		else {
			StringBuffer sb = new StringBuffer();

			for (int i = 0; i < rawContent.length(); i++) {
				char ch = rawContent.charAt(i);
				if (ch == '\'')
					sb.append("&#39;");
				else if (ch == '&')
					sb.append("&amp;");
				else if (ch == '"')
					sb.append("&quot;");
				else if (ch == '<')
					sb.append("&lt;");
				else if (ch == '>')
					sb.append("&gt;");
				else if (ch > '~' && charset != null && charSetImpliesAscii(charset)) 
					// TODO - why is hashcode the only way to get the unicode number for the character
					// in jre 5.0?
					sb.append("&#x"+Integer.toHexString(ch).toUpperCase()+";");
				else if (isNoLines) {
					if (ch == '\r')
						sb.append("&#xA;");
					else if (ch != '\n')
						sb.append(ch);
				}
				else
					sb.append(ch);
			}
			return sb.toString();
		}
	}
1024905
private void escape(String value) {
        int n = value.length();
        int i = 0;
        for (int j = 0; j < n; ++j) {
            char c = value.charAt(j);
            int k = ESCAPED_CHARS.indexOf(c);
            if (k >= 0 || c < ' ') {
                if (i < j) {
                    append(value, i, j);
                }
                if (k >= 0) {
                    append(ESCAPE_SEQ[k]);
                } else {
                    append("\\u");
                    append(String.format("%04x", Integer.valueOf(c)));
                }
                i = j + 1;
            }
        }
        if (i < n) {
            append(value, i, n);
        }
    }
877211
public static String toHexString(byte b) {
		final char[] out = new char[2];
		out[0] = hexDigits[(0xF0 & b) >>> 4];
		out[1] = hexDigits[0x0F & b];
		return new String(out);
	}
534835
public static byte[] decodeHex(String hexString) {
    int length = hexString.length();

    if ((length & 0x01) != 0) {
      throw new IllegalArgumentException("Odd number of characters.");
    }

    boolean badHex = false;
    byte[] out = new byte[length >> 1];
    for (int i = 0, j = 0; j < length; i++) {
      int c1 = hexString.charAt(j++);
      if (c1 > 'f') {
        badHex = true;
        break;
      }

      final byte d1 = DIGITS[c1];
      if (d1 == -1) {
        badHex = true;
        break;
      }

      int c2 = hexString.charAt(j++);
      if (c2 > 'f') {
        badHex = true;
        break;
      }

      final byte d2 = DIGITS[c2];
      if (d2 == -1) {
        badHex = true;
        break;
      }

      out[i] = (byte) (d1 << 4 | d2);
    }

    if (badHex) {
      throw new IllegalArgumentException("Invalid hexadecimal digit: " + hexString);
    }

    return out;
  }
84516
public static final String bytesToHex(byte[] bs, int off, int length) {
		StringBuffer sb = new StringBuffer(length * 2);
		bytesToHexAppend(bs, off, length, sb);
		return sb.toString();
	}
1009853
private static String bytes2Hex(byte[] bts) {
		String des = "";
		String tmp = null;

		for (byte bt : bts) {
			tmp = (Integer.toHexString(bt & 0xFF));
			if (tmp.length() == 1) {
				des += "0";
			}
			des += tmp;
		}
		return des;
	}
2979
private char readEscapeCharacter() throws JSONException {
        char escaped = in.charAt(pos++);
        switch (escaped) {
            case 'u':
                if (pos + 4 > in.length()) {
                    throw syntaxError("Unterminated escape sequence");
                }
                String hex = in.substring(pos, pos + 4);
                pos += 4;
                try {
                    return (char) Integer.parseInt(hex, 16);
                } catch (NumberFormatException nfe) {
                    throw syntaxError("Invalid escape sequence: " + hex);
                }

            case 't':
                return '\t';

            case 'b':
                return '\b';

            case 'n':
                return '\n';

            case 'r':
                return '\r';

            case 'f':
                return '\f';

            case '\'':
            case '"':
            case '\\':
            default:
                return escaped;
        }
    }