Remove dd_plist from third_party
diff --git a/third_party/BUILD b/third_party/BUILD
index 5bc45b7..0cdea9f 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -19,7 +19,6 @@
"//third_party/java/android_databinding:srcs",
"//third_party/java/aosp_gradle_core:srcs",
"//third_party/java/apkbuilder:srcs",
- "//third_party/java/dd_plist:srcs",
"//third_party/java/j2objc:srcs",
"//third_party/java/jacoco:srcs",
"//third_party/java/javapoet:srcs",
diff --git a/third_party/java/dd_plist/BUILD b/third_party/java/dd_plist/BUILD
deleted file mode 100644
index 2a5c40e..0000000
--- a/third_party/java/dd_plist/BUILD
+++ /dev/null
@@ -1,16 +0,0 @@
-load("@rules_java//java:defs.bzl", "java_library")
-
-package(default_visibility = ["//visibility:public"])
-
-licenses(["notice"]) # MIT
-
-filegroup(
- name = "srcs",
- srcs = glob(["**"]),
- visibility = ["//third_party:__pkg__"],
-)
-
-java_library(
- name = "dd_plist",
- srcs = glob(["java/**/*.java"]),
-)
diff --git a/third_party/java/dd_plist/LICENSE b/third_party/java/dd_plist/LICENSE
deleted file mode 100644
index d187b74..0000000
--- a/third_party/java/dd_plist/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2012 Daniel Dreibrodt
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/third_party/java/dd_plist/java/com/dd/plist/ASCIIPropertyListParser.java b/third_party/java/dd_plist/java/com/dd/plist/ASCIIPropertyListParser.java
deleted file mode 100644
index 533fb39..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/ASCIIPropertyListParser.java
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.text.ParseException;
-import java.text.StringCharacterIterator;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Parser for ASCII property lists. Supports Apple OS X/iOS and GnuStep/NeXTSTEP format.
- * This parser is based on the recursive descent paradigm, but the underlying grammar
- * is not explicitely defined.
- * <p/>
- * Resources on ASCII property list format:
- * <ul>
- * <li><a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/PropertyLists/OldStylePlists/OldStylePLists.html>
- * Property List Programming Guide - Old-Style ASCII Property Lists
- * </a></li>
- * <li><a href="http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSPropertyList.html">
- * GnuStep - NSPropertyListSerialization class documentation
- * </a></li>
- * </ul>
- *
- * @author Daniel Dreibrodt
- */
-public class ASCIIPropertyListParser {
-
- /**
- * Parses an ASCII property list file.
- *
- * @param f The ASCII property list file.
- * @return The root object of the property list. This is usally a NSDictionary but can also be a NSArray.
- * @throws Exception When an error occurs during parsing.
- */
- public static NSObject parse(File f) throws IOException, ParseException {
- return parse(new FileInputStream(f));
- }
-
- /**
- * Parses an ASCII property list from an input stream.
- *
- * @param in The input stream that points to the property list's data.
- * @return The root object of the property list. This is usally a NSDictionary but can also be a NSArray.
- * @throws Exception When an error occurs during parsing.
- */
- public static NSObject parse(InputStream in) throws ParseException, IOException {
- byte[] buf = PropertyListParser.readAll(in);
- in.close();
- return parse(buf);
- }
-
- /**
- * Parses an ASCII property list from a byte array.
- *
- * @param bytes The ASCII property list data.
- * @return The root object of the property list. This is usally a NSDictionary but can also be a NSArray.
- * @throws Exception When an error occurs during parsing.
- */
- public static NSObject parse(byte[] bytes) throws ParseException {
- ASCIIPropertyListParser parser = new ASCIIPropertyListParser(bytes);
- return parser.parse();
- }
-
- public static final char WHITESPACE_SPACE = ' ';
- public static final char WHITESPACE_TAB = '\t';
- public static final char WHITESPACE_NEWLINE = '\n';
- public static final char WHITESPACE_CARRIAGE_RETURN = '\r';
-
- public static final char ARRAY_BEGIN_TOKEN = '(';
- public static final char ARRAY_END_TOKEN = ')';
- public static final char ARRAY_ITEM_DELIMITER_TOKEN = ',';
-
- public static final char DICTIONARY_BEGIN_TOKEN = '{';
- public static final char DICTIONARY_END_TOKEN = '}';
- public static final char DICTIONARY_ASSIGN_TOKEN = '=';
- public static final char DICTIONARY_ITEM_DELIMITER_TOKEN = ';';
-
- public static final char QUOTEDSTRING_BEGIN_TOKEN = '"';
- public static final char QUOTEDSTRING_END_TOKEN = '"';
- public static final char QUOTEDSTRING_ESCAPE_TOKEN = '\\';
-
- public static final char DATA_BEGIN_TOKEN = '<';
- public static final char DATA_END_TOKEN = '>';
-
- public static final char DATA_GSOBJECT_BEGIN_TOKEN = '*';
- public static final char DATA_GSDATE_BEGIN_TOKEN = 'D';
- public static final char DATA_GSBOOL_BEGIN_TOKEN = 'B';
- public static final char DATA_GSBOOL_TRUE_TOKEN = 'Y';
- public static final char DATA_GSBOOL_FALSE_TOKEN = 'N';
- public static final char DATA_GSINT_BEGIN_TOKEN = 'I';
- public static final char DATA_GSREAL_BEGIN_TOKEN = 'R';
-
- public static final char DATE_DATE_FIELD_DELIMITER = '-';
- public static final char DATE_TIME_FIELD_DELIMITER = ':';
- public static final char DATE_GS_DATE_TIME_DELIMITER = ' ';
- public static final char DATE_APPLE_DATE_TIME_DELIMITER = 'T';
- public static final char DATE_APPLE_END_TOKEN = 'Z';
-
- public static final char COMMENT_BEGIN_TOKEN = '/';
- public static final char MULTILINE_COMMENT_SECOND_TOKEN = '*';
- public static final char SINGLELINE_COMMENT_SECOND_TOKEN = '/';
- public static final char MULTILINE_COMMENT_END_TOKEN = '/';
-
- /**
- * Property list source data
- */
- private byte[] data;
- /**
- * Current parsing index
- */
- private int index;
-
- /**
- * Only allow subclasses to change instantiation.
- */
- protected ASCIIPropertyListParser() {
-
- }
-
- /**
- * Creates a new parser for the given property list content.
- *
- * @param propertyListContent The content of the property list that is to be parsed.
- */
- private ASCIIPropertyListParser(byte[] propertyListContent) {
- data = propertyListContent;
- }
-
- /**
- * Checks whether the given sequence of symbols can be accepted.
- *
- * @param sequence The sequence of tokens to look for.
- * @return Whether the given tokens occur at the current parsing position.
- */
- private boolean acceptSequence(char... sequence) {
- for (int i = 0; i < sequence.length; i++) {
- if (data[index + i] != sequence[i])
- return false;
- }
- return true;
- }
-
- /**
- * Checks whether the given symbols can be accepted, that is, if one
- * of the given symbols is found at the current parsing position.
- *
- * @param acceptableSymbols The symbols to check.
- * @return Whether one of the symbols can be accepted or not.
- */
- private boolean accept(char... acceptableSymbols) {
- boolean symbolPresent = false;
- for (char c : acceptableSymbols) {
- if (data[index] == c)
- symbolPresent = true;
- }
- return symbolPresent;
- }
-
- /**
- * Checks whether the given symbol can be accepted, that is, if
- * the given symbols is found at the current parsing position.
- *
- * @param acceptableSymbol The symbol to check.
- * @return Whether the symbol can be accepted or not.
- */
- private boolean accept(char acceptableSymbol) {
- return data[index] == acceptableSymbol;
- }
-
- /**
- * Expects the input to have one of the given symbols at the current parsing position.
- *
- * @param expectedSymbols The expected symbols.
- * @throws ParseException If none of the expected symbols could be found.
- */
- private void expect(char... expectedSymbols) throws ParseException {
- if (!accept(expectedSymbols)) {
- String excString = "Expected '" + expectedSymbols[0] + "'";
- for (int i = 1; i < expectedSymbols.length; i++) {
- excString += " or '" + expectedSymbols[i] + "'";
- }
- excString += " but found '" + (char) data[index] + "'";
- throw new ParseException(excString, index);
- }
- }
-
- /**
- * Expects the input to have the given symbol at the current parsing position.
- *
- * @param expectedSymbol The expected symbol.
- * @throws ParseException If the expected symbol could be found.
- */
- private void expect(char expectedSymbol) throws ParseException {
- if (!accept(expectedSymbol))
- throw new ParseException("Expected '" + expectedSymbol + "' but found '" + (char) data[index] + "'", index);
- }
-
- /**
- * Reads an expected symbol.
- *
- * @param symbol The symbol to read.
- * @throws ParseException If the expected symbol could not be read.
- */
- private void read(char symbol) throws ParseException {
- expect(symbol);
- index++;
- }
-
- /**
- * Skips the current symbol.
- */
- private void skip() {
- index++;
- }
-
- /**
- * Skips several symbols
- *
- * @param numSymbols The amount of symbols to skip.
- */
- private void skip(int numSymbols) {
- index += numSymbols;
- }
-
- /**
- * Skips all whitespaces and comments from the current parsing position onward.
- */
- private void skipWhitespacesAndComments() {
- boolean commentSkipped;
- do {
- commentSkipped = false;
-
- //Skip whitespaces
- while (accept(WHITESPACE_CARRIAGE_RETURN, WHITESPACE_NEWLINE, WHITESPACE_SPACE, WHITESPACE_TAB)) {
- skip();
- }
-
- //Skip single line comments "//..."
- if (acceptSequence(COMMENT_BEGIN_TOKEN, SINGLELINE_COMMENT_SECOND_TOKEN)) {
- skip(2);
- readInputUntil(WHITESPACE_CARRIAGE_RETURN, WHITESPACE_NEWLINE);
- commentSkipped = true;
- }
- //Skip multi line comments "/* ... */"
- else if (acceptSequence(COMMENT_BEGIN_TOKEN, MULTILINE_COMMENT_SECOND_TOKEN)) {
- skip(2);
- while (true) {
- if (acceptSequence(MULTILINE_COMMENT_SECOND_TOKEN, MULTILINE_COMMENT_END_TOKEN)) {
- skip(2);
- break;
- }
- skip();
- }
- commentSkipped = true;
- }
- }
- while (commentSkipped); //if a comment was skipped more whitespace or another comment can follow, so skip again
- }
-
- private String toUtf8String(ByteArrayOutputStream stream) {
- try {
- return stream.toString("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Reads input until one of the given symbols is found.
- *
- * @param symbols The symbols that can occur after the string to read.
- * @return The input until one the given symbols.
- */
- private String readInputUntil(char... symbols) {
- ByteArrayOutputStream stringBytes = new ByteArrayOutputStream();
- while (!accept(symbols)) {
- stringBytes.write(data[index]);
- skip();
- }
- return toUtf8String(stringBytes);
- }
-
- /**
- * Reads input until the given symbol is found.
- *
- * @param symbol The symbol that can occur after the string to read.
- * @return The input until the given symbol.
- */
- private String readInputUntil(char symbol) {
- ByteArrayOutputStream stringBytes = new ByteArrayOutputStream();
- while (!accept(symbol)) {
- stringBytes.write(data[index]);
- skip();
- }
- return toUtf8String(stringBytes);
- }
-
- /**
- * Parses the property list from the beginning and returns the root object
- * of the property list.
- *
- * @return The root object of the property list. This can either be a NSDictionary or a NSArray.
- * @throws ParseException When an error occured during parsing
- */
- public NSObject parse() throws ParseException {
- index = 0;
- skipWhitespacesAndComments();
- expect(DICTIONARY_BEGIN_TOKEN, ARRAY_BEGIN_TOKEN, COMMENT_BEGIN_TOKEN);
- try {
- return parseObject();
- } catch (ArrayIndexOutOfBoundsException ex) {
- throw new ParseException("Reached end of input unexpectedly.", index);
- }
- }
-
- /**
- * Parses the NSObject found at the current position in the property list
- * data stream.
- *
- * @return The parsed NSObject.
- * @see ASCIIPropertyListParser#index
- */
- private NSObject parseObject() throws ParseException {
- switch (data[index]) {
- case ARRAY_BEGIN_TOKEN: {
- return parseArray();
- }
- case DICTIONARY_BEGIN_TOKEN: {
- return parseDictionary();
- }
- case DATA_BEGIN_TOKEN: {
- return parseData();
- }
- case QUOTEDSTRING_BEGIN_TOKEN: {
- String quotedString = parseQuotedString();
- //apple dates are quoted strings of length 20 and after the 4 year digits a dash is found
- if (quotedString.length() == 20 && quotedString.charAt(4) == DATE_DATE_FIELD_DELIMITER) {
- try {
- return new NSDate(quotedString);
- } catch (Exception ex) {
- //not a date? --> return string
- return new NSString(quotedString);
- }
- } else {
- return new NSString(quotedString);
- }
- }
- default: {
- //0-9
- if (data[index] > 0x2F && data[index] < 0x3A) {
- //could be a date or just a string
- return parseDateString();
- } else {
- //non-numerical -> string or boolean
- String parsedString = parseString();
- return new NSString(parsedString);
- }
- }
- }
- }
-
- /**
- * Parses an array from the current parsing position.
- * The prerequisite for calling this method is, that an array begin token has been read.
- *
- * @return The array found at the parsing position.
- */
- private NSArray parseArray() throws ParseException {
- //Skip begin token
- skip();
- skipWhitespacesAndComments();
- List<NSObject> objects = new LinkedList<NSObject>();
- while (!accept(ARRAY_END_TOKEN)) {
- objects.add(parseObject());
- skipWhitespacesAndComments();
- if (accept(ARRAY_ITEM_DELIMITER_TOKEN)) {
- skip();
- } else {
- break; //must have reached end of array
- }
- skipWhitespacesAndComments();
- }
- //parse end token
- read(ARRAY_END_TOKEN);
- return new NSArray(objects.toArray(new NSObject[objects.size()]));
- }
-
- /**
- * Parses a dictionary from the current parsing position.
- * The prerequisite for calling this method is, that a dictionary begin token has been read.
- *
- * @return The dictionary found at the parsing position.
- */
- private NSDictionary parseDictionary() throws ParseException {
- //Skip begin token
- skip();
- skipWhitespacesAndComments();
- NSDictionary dict = new NSDictionary();
- while (!accept(DICTIONARY_END_TOKEN)) {
- //Parse key
- String keyString;
- if (accept(QUOTEDSTRING_BEGIN_TOKEN)) {
- keyString = parseQuotedString();
- } else {
- keyString = parseString();
- }
- skipWhitespacesAndComments();
-
- //Parse assign token
- read(DICTIONARY_ASSIGN_TOKEN);
- skipWhitespacesAndComments();
-
- NSObject object = parseObject();
- dict.put(keyString, object);
- skipWhitespacesAndComments();
- read(DICTIONARY_ITEM_DELIMITER_TOKEN);
- skipWhitespacesAndComments();
- }
- //skip end token
- skip();
- return dict;
- }
-
- /**
- * Parses a data object from the current parsing position.
- * This can either be a NSData object or a GnuStep NSNumber or NSDate.
- * The prerequisite for calling this method is, that a data begin token has been read.
- *
- * @return The data object found at the parsing position.
- */
- private NSObject parseData() throws ParseException {
- NSObject obj = null;
- //Skip begin token
- skip();
- if (accept(DATA_GSOBJECT_BEGIN_TOKEN)) {
- skip();
- expect(DATA_GSBOOL_BEGIN_TOKEN, DATA_GSDATE_BEGIN_TOKEN, DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN);
- if (accept(DATA_GSBOOL_BEGIN_TOKEN)) {
- //Boolean
- skip();
- expect(DATA_GSBOOL_TRUE_TOKEN, DATA_GSBOOL_FALSE_TOKEN);
- if (accept(DATA_GSBOOL_TRUE_TOKEN)) {
- obj = new NSNumber(true);
- } else {
- obj = new NSNumber(false);
- }
- //Skip the parsed boolean token
- skip();
- } else if (accept(DATA_GSDATE_BEGIN_TOKEN)) {
- //Date
- skip();
- String dateString = readInputUntil(DATA_END_TOKEN);
- obj = new NSDate(dateString);
- } else if (accept(DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN)) {
- //Number
- skip();
- String numberString = readInputUntil(DATA_END_TOKEN);
- obj = new NSNumber(numberString);
- }
- //parse data end token
- read(DATA_END_TOKEN);
- } else {
- String dataString = readInputUntil(DATA_END_TOKEN);
- dataString = dataString.replaceAll("\\s+", "");
-
- int numBytes = dataString.length() / 2;
- byte[] bytes = new byte[numBytes];
- for (int i = 0; i < bytes.length; i++) {
- String byteString = dataString.substring(i * 2, i * 2 + 2);
- int byteValue = Integer.parseInt(byteString, 16);
- bytes[i] = (byte) byteValue;
- }
- obj = new NSData(bytes);
-
- //skip end token
- skip();
- }
-
- return obj;
- }
-
- /**
- * Attempts to parse a plain string as a date if possible.
- *
- * @return A NSDate if the string represents such an object. Otherwise a NSString is returned.
- */
- private NSObject parseDateString() {
- String numericalString = parseString();
- if (numericalString.length() > 4 && numericalString.charAt(4) == DATE_DATE_FIELD_DELIMITER) {
- try {
- return new NSDate(numericalString);
- } catch(Exception ex) {
- //An exception occurs if the string is not a date but just a string
- }
- }
- return new NSString(numericalString);
- }
-
- /**
- * Parses a plain string from the current parsing position.
- * The string is made up of all characters to the next whitespace, delimiter token or assignment token.
- *
- * @return The string found at the current parsing position.
- */
- private String parseString() {
- return readInputUntil(WHITESPACE_SPACE, WHITESPACE_TAB, WHITESPACE_NEWLINE, WHITESPACE_CARRIAGE_RETURN,
- ARRAY_ITEM_DELIMITER_TOKEN, DICTIONARY_ITEM_DELIMITER_TOKEN, DICTIONARY_ASSIGN_TOKEN, ARRAY_END_TOKEN);
- }
-
- /**
- * Parses a quoted string from the current parsing position.
- * The prerequisite for calling this method is, that a quoted string begin token has been read.
- *
- * @return The quoted string found at the parsing method with all special characters unescaped.
- * @throws ParseException If an error occured during parsing.
- */
- private String parseQuotedString() throws ParseException {
- //Skip begin token
- skip();
- ByteArrayOutputStream quotedString = new ByteArrayOutputStream();
- boolean unescapedBackslash = true;
- //Read from opening quotation marks to closing quotation marks and skip escaped quotation marks
- while (data[index] != QUOTEDSTRING_END_TOKEN || (data[index - 1] == QUOTEDSTRING_ESCAPE_TOKEN && unescapedBackslash)) {
- quotedString.write(data[index]);
- if (accept(QUOTEDSTRING_ESCAPE_TOKEN)) {
- unescapedBackslash = !(data[index - 1] == QUOTEDSTRING_ESCAPE_TOKEN && unescapedBackslash);
- }
- skip();
- }
- String unescapedString;
- try {
- unescapedString = parseQuotedString(toUtf8String(quotedString));
- } catch (Exception ex) {
- throw new ParseException("The quoted string could not be parsed.", index);
- }
- //skip end token
- skip();
- return unescapedString;
- }
-
- /**
- * Used to encode the parsed strings
- */
- private static CharsetEncoder asciiEncoder;
-
- /**
- * Parses a string according to the format specified for ASCII property lists.
- * Such strings can contain escape sequences which are unescaped in this method.
- *
- * @param s The escaped string according to the ASCII property list format, without leading and trailing quotation marks.
- * @return The unescaped string in UTF-8 or ASCII format, depending on the contained characters.
- * @throws Exception If the string could not be properly parsed.
- */
- public static synchronized String parseQuotedString(String s) throws UnsupportedEncodingException, CharacterCodingException {
- StringBuilder parsed = new StringBuilder();
- StringCharacterIterator iterator = new StringCharacterIterator(s);
- char c = iterator.current();
-
- while (iterator.getIndex() < iterator.getEndIndex()) {
- switch (c) {
- case '\\': { //An escaped sequence is following
- parsed.append(parseEscapedSequence(iterator));
- break;
- }
- default: {
- parsed.append(c);
- break;
- }
- }
- c = iterator.next();
- }
- return parsed.toString();
- }
-
- /**
- * Unescapes an escaped character sequence, e.g. \\u00FC.
- *
- * @param iterator The string character iterator pointing to the first character after the backslash
- * @return The unescaped character
- */
- private static char parseEscapedSequence(StringCharacterIterator iterator) {
- char c = iterator.next();
- if (c == 'b') {
- return '\b';
- } else if (c == 'n') {
- return '\n';
- } else if (c == 'r') {
- return '\r';
- } else if (c == 't') {
- return '\t';
- } else if (c == 'U' || c == 'u') {
- //4 digit hex Unicode value
- String byte1 = "";
- byte1 += iterator.next();
- byte1 += iterator.next();
- String byte2 = "";
- byte2 += iterator.next();
- byte2 += iterator.next();
- return (char) ((Integer.parseInt(byte1, 16) << 8) + Integer.parseInt(byte2, 16));
- } else if ((c >= '0') && (c <= '7')) {
- //3 digit octal ASCII value
- String num = "";
- num += c;
- num += iterator.next();
- num += iterator.next();
- return (char) Integer.parseInt(num, 8);
- } else {
- // Possibly something that needn't be escaped, but we should accept it
- // it anyway for consistency with Apple tools.
- return c;
- }
- }
-
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/Base64.java b/third_party/java/dd_plist/java/com/dd/plist/Base64.java
deleted file mode 100644
index e6a7ae3..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/Base64.java
+++ /dev/null
@@ -1,2126 +0,0 @@
-/**
- * plist - An open source library to parse and generate property lists
- *
- * Copyright (C) 2012 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-/**
- * <p>Encodes and decodes to and from Base64 notation.</p>
- * <p>Homepage: <a href="http://iharder.net/base64">http://iharder.net/base64</a>.</p>
- *
- * <p>Example:</p>
- *
- * <code>String encoded = Base64.encode( myByteArray );</code>
- *
- * <code>byte[] myByteArray = Base64.decode( encoded );</code>
- *
- * <p>The <tt>options</tt> parameter, which appears in a few places, is used to pass
- * several pieces of information to the encoder. In the "higher level" methods such as
- * encodeBytes( bytes, options ) the options parameter can be used to indicate such
- * things as first gzipping the bytes before encoding them, not inserting linefeeds,
- * and encoding using the URL-safe and Ordered dialects.</p>
- *
- * <p>Note, according to <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>,
- * Section 2.1, implementations should not add line feeds unless explicitly told
- * to do so. I've got Base64 set to this behavior now, although earlier versions
- * broke lines by default.</p>
- *
- * <p>The constants defined in Base64 can be OR-ed together to combine options, so you
- * might make a call like this:</p>
- *
- * <code>String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES );</code>
- * <p>to compress the data before encoding it and then making the output have newline characters.</p>
- * <p>Also...</p>
- * <code>String encoded = Base64.encodeBytes( crazyString.getBytes() );</code>
- *
- *
- *
- * <p>
- * Change Log:
- * </p>
- *
- * <ul>
- * <li>v2.3.7 - Fixed subtle bug when base 64 input stream contained the
- * value 01111111, which is an invalid base 64 character but should not
- * throw an ArrayIndexOutOfBoundsException either. Led to discovery of
- * mishandling (or potential for better handling) of other bad input
- * characters. You should now get an IOException if you try decoding
- * something that has bad characters in it.</li>
- * <li>v2.3.6 - Fixed bug when breaking lines and the final byte of the encoded
- * string ended in the last column; the buffer was not properly shrunk and
- * contained an extra (null) byte that made it into the string.</li>
- * <li>v2.3.5 - Fixed bug in {@link #encodeFromFile} where estimated buffer size
- * was wrong for files of size 31, 34, and 37 bytes.</li>
- * <li>v2.3.4 - Fixed bug when working with gzipped streams whereby flushing
- * the Base64.B64OutputStream closed the Base64 encoding (by padding with equals
- * signs) too soon. Also added an option to suppress the automatic decoding
- * of gzipped streams. Also added experimental support for specifying a
- * class loader when using the
- * {@link #decodeToObject(java.lang.String, int, java.lang.ClassLoader)}
- * method.</li>
- * <li>v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java
- * footprint with its CharEncoders and so forth. Fixed some javadocs that were
- * inconsistent. Removed imports and specified things like java.io.IOException
- * explicitly inline.</li>
- * <li>v2.3.2 - Reduced memory footprint! Finally refined the "guessing" of how big the
- * final encoded data will be so that the code doesn't have to create two output
- * arrays: an oversized initial one and then a final, exact-sized one. Big win
- * when using the {@link #encodeBytesToBytes(byte[])} family of methods (and not
- * using the gzip options which uses a different mechanism with streams and stuff).</li>
- * <li>v2.3.1 - Added {@link #encodeBytesToBytes(byte[], int, int, int)} and some
- * similar helper methods to be more efficient with memory by not returning a
- * String but just a byte array.</li>
- * <li>v2.3 - <strong>This is not a drop-in replacement!</strong> This is two years of comments
- * and bug fixes queued up and finally executed. Thanks to everyone who sent
- * me stuff, and I'm sorry I wasn't able to distribute your fixes to everyone else.
- * Much bad coding was cleaned up including throwing exceptions where necessary
- * instead of returning null values or something similar. Here are some changes
- * that may affect you:
- * <ul>
- * <li><em>Does not break lines, by default.</em> This is to keep in compliance with
- * <a href="http://www.faqs.org/rfcs/rfc3548.html">RFC3548</a>.</li>
- * <li><em>Throws exceptions instead of returning null values.</em> Because some operations
- * (especially those that may permit the GZIP option) use IO streams, there
- * is a possiblity of an java.io.IOException being thrown. After some discussion and
- * thought, I've changed the behavior of the methods to throw java.io.IOExceptions
- * rather than return null if ever there's an error. I think this is more
- * appropriate, though it will require some changes to your code. Sorry,
- * it should have been done this way to begin with.</li>
- * <li><em>Removed all references to System.out, System.err, and the like.</em>
- * Shame on me. All I can say is sorry they were ever there.</li>
- * <li><em>Throws NullPointerExceptions and IllegalArgumentExceptions</em> as needed
- * such as when passed arrays are null or offsets are invalid.</li>
- * <li>Cleaned up as much javadoc as I could to avoid any javadoc warnings.
- * This was especially annoying before for people who were thorough in their
- * own projects and then had gobs of javadoc warnings on this file.</li>
- * </ul>
- * <li>v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug
- * when using very small files (~< 40 bytes).</li>
- * <li>v2.2 - Added some helper methods for encoding/decoding directly from
- * one file to the next. Also added a main() method to support command line
- * encoding/decoding from one file to the next. Also added these Base64 dialects:
- * <ol>
- * <li>The default is RFC3548 format.</li>
- * <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates
- * URL and file name friendly format as described in Section 4 of RFC3548.
- * http://www.faqs.org/rfcs/rfc3548.html</li>
- * <li>Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates
- * URL and file name friendly format that preserves lexical ordering as described
- * in http://www.faqs.org/qa/rfcc-1940.html</li>
- * </ol>
- * Special thanks to Jim Kellerman at <a href="http://www.powerset.com/">http://www.powerset.com/</a>
- * for contributing the new Base64 dialects.
- * </li>
- *
- * <li>v2.1 - Cleaned up javadoc comments and unused variables and methods. Added
- * some convenience methods for reading and writing to and from files.</li>
- * <li>v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems
- * with other encodings (like EBCDIC).</li>
- * <li>v2.0.1 - Fixed an error when decoding a single byte, that is, when the
- * encoded data was a single byte.</li>
- * <li>v2.0 - I got rid of methods that used booleans to set options.
- * Now everything is more consolidated and cleaner. The code now detects
- * when data that's being decoded is gzip-compressed and will decompress it
- * automatically. Generally things are cleaner. You'll probably have to
- * change some method calls that you were making to support the new
- * options format (<tt>int</tt>s that you "OR" together).</li>
- * <li>v1.5.1 - Fixed bug when decompressing and decoding to a
- * byte[] using <tt>decode( String s, boolean gzipCompressed )</tt>.
- * Added the ability to "suspend" encoding in the Output Stream so
- * you can turn on and off the encoding if you need to embed base64
- * data in an otherwise "normal" stream (like an XML file).</li>
- * <li>v1.5 - Output stream pases on flush() command but doesn't do anything itself.
- * This helps when using GZIP streams.
- * Added the ability to GZip-compress objects before encoding them.</li>
- * <li>v1.4 - Added helper methods to read/write files.</li>
- * <li>v1.3.6 - Fixed B64OutputStream.flush() so that 'position' is reset.</li>
- * <li>v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream
- * where last buffer being read, if not completely full, was not returned.</li>
- * <li>v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.</li>
- * <li>v1.3.3 - Fixed I/O streams which were totally messed up.</li>
- * </ul>
- *
- * <p>
- * I am placing this code in the Public Domain. Do with it as you will.
- * This software comes with no guarantees or warranties but with
- * plenty of well-wishing instead!
- * Please visit <a href="http://iharder.net/base64">http://iharder.net/base64</a>
- * periodically to check for updates or to contribute improvements.
- * </p>
- *
- * @author Robert Harder
- * @author rob@iharder.net
- * @version 2.3.7
- */
-public class Base64 {
-
-/* ******** P U B L I C F I E L D S ******** */
-
-
- /**
- * No options specified. Value is zero.
- */
- public final static int NO_OPTIONS = 0;
-
- /**
- * Specify encoding in first bit. Value is one.
- */
- public final static int ENCODE = 1;
-
-
- /**
- * Specify decoding in first bit. Value is zero.
- */
- public final static int DECODE = 0;
-
-
- /**
- * Specify that data should be gzip-compressed in second bit. Value is two.
- */
- public final static int GZIP = 2;
-
- /**
- * Specify that gzipped data should <em>not</em> be automatically gunzipped.
- */
- public final static int DONT_GUNZIP = 4;
-
-
- /**
- * Do break lines when encoding. Value is 8.
- */
- public final static int DO_BREAK_LINES = 8;
-
- /**
- * Encode using Base64-like encoding that is URL- and Filename-safe as described
- * in Section 4 of RFC3548:
- * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
- * It is important to note that data encoded this way is <em>not</em> officially valid Base64,
- * or at the very least should not be called Base64 without also specifying that is
- * was encoded using the URL- and Filename-safe dialect.
- */
- public final static int URL_SAFE = 16;
-
-
- /**
- * Encode using the special "ordered" dialect of Base64 described here:
- * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
- */
- public final static int ORDERED = 32;
-
-
-/* ******** P R I V A T E F I E L D S ******** */
-
-
- /**
- * Maximum line length (76) of Base64 output.
- */
- private final static int MAX_LINE_LENGTH = 76;
-
-
- /**
- * The equals sign (=) as a byte.
- */
- private final static byte EQUALS_SIGN = (byte) '=';
-
-
- /**
- * The new line character (\n) as a byte.
- */
- private final static byte NEW_LINE = (byte) '\n';
-
-
- /**
- * Preferred encoding.
- */
- private final static String PREFERRED_ENCODING = "US-ASCII";
-
-
- private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
- private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding
-
-
-/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */
-
- /**
- * The 64 valid Base64 values.
- */
- /* Host platform me be something funny like EBCDIC, so we hardcode these values. */
- private final static byte[] _STANDARD_ALPHABET = {
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
- (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
- (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
- (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
- (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/'
- };
-
-
- /**
- * Translates a Base64 value to either its 6-bit reconstruction value
- * or a negative number indicating some other meaning.
- */
- private final static byte[] _STANDARD_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- 62, // Plus sign at decimal 43
- -9, -9, -9, // Decimal 44 - 46
- 63, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255
- };
-
-
-/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */
-
- /**
- * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548:
- * <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
- * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash."
- */
- private final static byte[] _URL_SAFE_ALPHABET = {
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
- (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
- (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
- (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5',
- (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '-', (byte) '_'
- };
-
- /**
- * Used in decoding URL- and Filename-safe dialects of Base64.
- */
- private final static byte[] _URL_SAFE_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- -9, // Plus sign at decimal 43
- -9, // Decimal 44
- 62, // Minus sign at decimal 45
- -9, // Decimal 46
- -9, // Slash at decimal 47
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
- -9, -9, -9, -9, // Decimal 91 - 94
- 63, // Underscore at decimal 95
- -9, // Decimal 96
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255
- };
-
-
-
-/* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */
-
- /**
- * I don't get the point of this technique, but someone requested it,
- * and it is described here:
- * <a href="http://www.faqs.org/qa/rfcc-1940.html">http://www.faqs.org/qa/rfcc-1940.html</a>.
- */
- private final static byte[] _ORDERED_ALPHABET = {
- (byte) '-',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
- (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
- (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
- (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
- (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
- (byte) '_',
- (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
- (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
- (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z'
- };
-
- /**
- * Used in decoding the "ordered" dialect of Base64.
- */
- private final static byte[] _ORDERED_DECODABET = {
- -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
- -5, -5, // Whitespace: Tab and Linefeed
- -9, -9, // Decimal 11 - 12
- -5, // Whitespace: Carriage Return
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
- -9, -9, -9, -9, -9, // Decimal 27 - 31
- -5, // Whitespace: Space
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
- -9, // Plus sign at decimal 43
- -9, // Decimal 44
- 0, // Minus sign at decimal 45
- -9, // Decimal 46
- -9, // Slash at decimal 47
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // Numbers zero through nine
- -9, -9, -9, // Decimal 58 - 60
- -1, // Equals sign at decimal 61
- -9, -9, -9, // Decimal 62 - 64
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // Letters 'A' through 'M'
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // Letters 'N' through 'Z'
- -9, -9, -9, -9, // Decimal 91 - 94
- 37, // Underscore at decimal 95
- -9, // Decimal 96
- 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, // Letters 'a' through 'm'
- 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // Letters 'n' through 'z'
- -9, -9, -9, -9, -9 // Decimal 123 - 127
- , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243
- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255
- };
-
-
-/* ******** D E T E R M I N E W H I C H A L H A B E T ******** */
-
-
- /**
- * Returns one of the _SOMETHING_ALPHABET byte arrays depending on
- * the options specified.
- * It's possible, though silly, to specify ORDERED <b>and</b> URLSAFE
- * in which case one of them will be picked, though there is
- * no guarantee as to which one will be picked.
- */
- private static byte[] getAlphabet(int options) {
- if ((options & URL_SAFE) == URL_SAFE) {
- return _URL_SAFE_ALPHABET;
- } else if ((options & ORDERED) == ORDERED) {
- return _ORDERED_ALPHABET;
- } else {
- return _STANDARD_ALPHABET;
- }
- } // end getAlphabet
-
-
- /**
- * Returns one of the _SOMETHING_DECODABET byte arrays depending on
- * the options specified.
- * It's possible, though silly, to specify ORDERED and URL_SAFE
- * in which case one of them will be picked, though there is
- * no guarantee as to which one will be picked.
- */
- private static byte[] getDecodabet(int options) {
- if ((options & URL_SAFE) == URL_SAFE) {
- return _URL_SAFE_DECODABET;
- } else if ((options & ORDERED) == ORDERED) {
- return _ORDERED_DECODABET;
- } else {
- return _STANDARD_DECODABET;
- }
- } // end getAlphabet
-
-
- /**
- * Defeats instantiation.
- */
- private Base64() {
- }
-
-
-
-
-/* ******** E N C O D I N G M E T H O D S ******** */
-
-
- /**
- * Encodes up to the first three bytes of array <var>threeBytes</var>
- * and returns a four-byte array in Base64 notation.
- * The actual number of significant bytes in your array is
- * given by <var>numSigBytes</var>.
- * The array <var>threeBytes</var> needs only be as big as
- * <var>numSigBytes</var>.
- * Code can reuse a byte array by passing a four-byte array as <var>b4</var>.
- *
- * @param b4 A reusable byte array to reduce array instantiation
- * @param threeBytes the array to convert
- * @param numSigBytes the number of significant bytes in your array
- * @return four byte array in Base64 notation.
- * @since 1.5.1
- */
- private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes, int options) {
- encode3to4(threeBytes, 0, numSigBytes, b4, 0, options);
- return b4;
- } // end encode3to4
-
-
- /**
- * <p>Encodes up to three bytes of the array <var>source</var>
- * and writes the resulting four Base64 bytes to <var>destination</var>.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * <var>srcOffset</var> and <var>destOffset</var>.
- * This method does not check to make sure your arrays
- * are large enough to accomodate <var>srcOffset</var> + 3 for
- * the <var>source</var> array or <var>destOffset</var> + 4 for
- * the <var>destination</var> array.
- * The actual number of significant bytes in your array is
- * given by <var>numSigBytes</var>.</p>
- * <p>This is the lowest level of the encoding methods with
- * all possible parameters.</p>
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param numSigBytes the number of significant bytes in your array
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @return the <var>destination</var> array
- * @since 1.3
- */
- private static byte[] encode3to4(
- byte[] source, int srcOffset, int numSigBytes,
- byte[] destination, int destOffset, int options) {
-
- byte[] ALPHABET = getAlphabet(options);
-
- // 1 2 3
- // 01234567890123456789012345678901 Bit position
- // --------000000001111111122222222 Array position from threeBytes
- // --------| || || || | Six bit groups to index ALPHABET
- // >>18 >>12 >> 6 >> 0 Right shift necessary
- // 0x3f 0x3f 0x3f Additional AND
-
- // Create buffer with zero-padding if there are only one or two
- // significant bytes passed in the array.
- // We have to shift left 24 in order to flush out the 1's that appear
- // when Java treats a value as negative that is cast from a byte to an int.
- int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
- | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
- | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
-
- switch (numSigBytes) {
- case 3:
- destination[destOffset] = ALPHABET[(inBuff >>> 18)];
- destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
- return destination;
-
- case 2:
- destination[destOffset] = ALPHABET[(inBuff >>> 18)];
- destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
-
- case 1:
- destination[destOffset] = ALPHABET[(inBuff >>> 18)];
- destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
- destination[destOffset + 2] = EQUALS_SIGN;
- destination[destOffset + 3] = EQUALS_SIGN;
- return destination;
-
- default:
- return destination;
- } // end switch
- } // end encode3to4
-
-
- /**
- * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
- * writing it to the <code>encoded</code> ByteBuffer.
- * This is an experimental feature. Currently it does not
- * pass along any options (such as {@link #DO_BREAK_LINES}
- * or {@link #GZIP}.
- *
- * @param raw input buffer
- * @param encoded output buffer
- * @since 2.3
- */
- public static void encode(java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded) {
- byte[] raw3 = new byte[3];
- byte[] enc4 = new byte[4];
-
- while (raw.hasRemaining()) {
- int rem = Math.min(3, raw.remaining());
- raw.get(raw3, 0, rem);
- Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
- encoded.put(enc4);
- } // end input remaining
- }
-
-
- /**
- * Performs Base64 encoding on the <code>raw</code> ByteBuffer,
- * writing it to the <code>encoded</code> CharBuffer.
- * This is an experimental feature. Currently it does not
- * pass along any options (such as {@link #DO_BREAK_LINES}
- * or {@link #GZIP}.
- *
- * @param raw input buffer
- * @param encoded output buffer
- * @since 2.3
- */
- public static void encode(java.nio.ByteBuffer raw, java.nio.CharBuffer encoded) {
- byte[] raw3 = new byte[3];
- byte[] enc4 = new byte[4];
-
- while (raw.hasRemaining()) {
- int rem = Math.min(3, raw.remaining());
- raw.get(raw3, 0, rem);
- Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS);
- for (int i = 0; i < 4; i++) {
- encoded.put((char) (enc4[i] & 0xFF));
- }
- } // end input remaining
- }
-
-
- /**
- * Serializes an object and returns the Base64-encoded
- * version of that serialized object.
- *
- * <p>As of v 2.3, if the object
- * cannot be serialized or there is another error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * The object is not GZip-compressed before being encoded.
- *
- * @param serializableObject The object to encode
- * @return The Base64-encoded object
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if serializedObject is null
- * @since 1.4
- */
- public static String encodeObject(java.io.Serializable serializableObject)
- throws java.io.IOException {
- return encodeObject(serializableObject, NO_OPTIONS);
- } // end encodeObject
-
-
- /**
- * Serializes an object and returns the Base64-encoded
- * version of that serialized object.
- *
- * <p>As of v 2.3, if the object
- * cannot be serialized or there is another error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * The object is not GZip-compressed before being encoded.
- *
- * Example options:<pre>
- * GZIP: gzip-compresses object before encoding it.
- * DO_BREAK_LINES: break lines at 76 characters
- * </pre>
- *
- * Example: <code>encodeObject( myObj, Base64.GZIP )</code> or
- *
- * Example: <code>encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
- *
- * @param serializableObject The object to encode
- * @param options Specified options
- * @return The Base64-encoded object
- * @throws java.io.IOException if there is an error
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public static String encodeObject(java.io.Serializable serializableObject, int options)
- throws java.io.IOException {
-
- if (serializableObject == null) {
- throw new NullPointerException("Cannot serialize a null object.");
- } // end if: null
-
- // Streams
- java.io.ByteArrayOutputStream baos = null;
- java.io.OutputStream b64os = null;
- java.util.zip.GZIPOutputStream gzos = null;
- java.io.ObjectOutputStream oos = null;
-
-
- try {
- // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
- baos = new java.io.ByteArrayOutputStream();
- b64os = new B64OutputStream(baos, ENCODE | options);
- if ((options & GZIP) != 0) {
- // Gzip
- gzos = new java.util.zip.GZIPOutputStream(b64os);
- oos = new java.io.ObjectOutputStream(gzos);
- } else {
- // Not gzipped
- oos = new java.io.ObjectOutputStream(b64os);
- }
- oos.writeObject(serializableObject);
- } // end try
- catch (java.io.IOException e) {
- // Catch it and then throw it immediately so that
- // the finally{} block is called for cleanup.
- throw e;
- } // end catch
- finally {
- try {
- oos.close();
- } catch (Exception e) {
- }
- try {
- gzos.close();
- } catch (Exception e) {
- }
- try {
- b64os.close();
- } catch (Exception e) {
- }
- try {
- baos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- // Return value according to relevant encoding.
- try {
- return new String(baos.toByteArray(), PREFERRED_ENCODING);
- } // end try
- catch (java.io.UnsupportedEncodingException uue) {
- // Fall back to some Java default
- return new String(baos.toByteArray());
- } // end catch
-
- } // end encode
-
-
- /**
- * Encodes a byte array into Base64 notation.
- * Does not GZip-compress data.
- *
- * @param source The data to convert
- * @return The data in Base64-encoded form
- * @throws NullPointerException if source array is null
- * @since 1.4
- */
- public static String encodeBytes(byte[] source) {
- // Since we're not going to have the GZIP encoding turned on,
- // we're not going to have an java.io.IOException thrown, so
- // we should not force the user to have to catch it.
- String encoded = null;
- try {
- encoded = encodeBytes(source, 0, source.length, NO_OPTIONS);
- } catch (java.io.IOException ex) {
- assert false : ex.getMessage();
- } // end catch
- assert encoded != null;
- return encoded;
- } // end encodeBytes
-
-
- /**
- * Encodes a byte array into Base64 notation.
- * <p>
- * Example options:<pre>
- * GZIP: gzip-compresses object before encoding it.
- * DO_BREAK_LINES: break lines at 76 characters
- * <i>Note: Technically, this makes your encoding non-compliant.</i>
- * </pre>
- * <p>
- * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
- * <p>
- * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
- *
- *
- * <p>As of v 2.3, if there is an error with the GZIP stream,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param source The data to convert
- * @param options Specified options
- * @return The Base64-encoded data as a String
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if source array is null
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public static String encodeBytes(byte[] source, int options) throws java.io.IOException {
- return encodeBytes(source, 0, source.length, options);
- } // end encodeBytes
-
-
- /**
- * Encodes a byte array into Base64 notation.
- * Does not GZip-compress data.
- *
- * <p>As of v 2.3, if there is an error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @return The Base64-encoded data as a String
- * @throws NullPointerException if source array is null
- * @throws IllegalArgumentException if source array, offset, or length are invalid
- * @since 1.4
- */
- public static String encodeBytes(byte[] source, int off, int len) {
- // Since we're not going to have the GZIP encoding turned on,
- // we're not going to have an java.io.IOException thrown, so
- // we should not force the user to have to catch it.
- String encoded = null;
- try {
- encoded = encodeBytes(source, off, len, NO_OPTIONS);
- } catch (java.io.IOException ex) {
- assert false : ex.getMessage();
- } // end catch
- assert encoded != null;
- return encoded;
- } // end encodeBytes
-
-
- /**
- * Encodes a byte array into Base64 notation.
- * <p>
- * Example options:<pre>
- * GZIP: gzip-compresses object before encoding it.
- * DO_BREAK_LINES: break lines at 76 characters
- * <i>Note: Technically, this makes your encoding non-compliant.</i>
- * </pre>
- * <p>
- * Example: <code>encodeBytes( myData, Base64.GZIP )</code> or
- * <p>
- * Example: <code>encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES )</code>
- *
- *
- * <p>As of v 2.3, if there is an error with the GZIP stream,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned a null value, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @param options Specified options
- * @return The Base64-encoded data as a String
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if source array is null
- * @throws IllegalArgumentException if source array, offset, or length are invalid
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public static String encodeBytes(byte[] source, int off, int len, int options) throws java.io.IOException {
- byte[] encoded = encodeBytesToBytes(source, off, len, options);
-
- // Return value according to relevant encoding.
- try {
- return new String(encoded, PREFERRED_ENCODING);
- } // end try
- catch (java.io.UnsupportedEncodingException uue) {
- return new String(encoded);
- } // end catch
-
- } // end encodeBytes
-
-
- /**
- * Similar to {@link #encodeBytes(byte[])} but returns
- * a byte array instead of instantiating a String. This is more efficient
- * if you're working with I/O streams and have large data sets to encode.
- *
- * @param source The data to convert
- * @return The Base64-encoded data as a byte[] (of ASCII characters)
- * @throws NullPointerException if source array is null
- * @since 2.3.1
- */
- public static byte[] encodeBytesToBytes(byte[] source) {
- byte[] encoded = null;
- try {
- encoded = encodeBytesToBytes(source, 0, source.length, Base64.NO_OPTIONS);
- } catch (java.io.IOException ex) {
- assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
- }
- return encoded;
- }
-
-
- /**
- * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns
- * a byte array instead of instantiating a String. This is more efficient
- * if you're working with I/O streams and have large data sets to encode.
- *
- * @param source The data to convert
- * @param off Offset in array where conversion should begin
- * @param len Length of data to convert
- * @param options Specified options
- * @return The Base64-encoded data as a String
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if source array is null
- * @throws IllegalArgumentException if source array, offset, or length are invalid
- * @see Base64#GZIP
- * @see Base64#DO_BREAK_LINES
- * @since 2.3.1
- */
- public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options) throws java.io.IOException {
-
- if (source == null) {
- throw new NullPointerException("Cannot serialize a null array.");
- } // end if: null
-
- if (off < 0) {
- throw new IllegalArgumentException("Cannot have negative offset: " + off);
- } // end if: off < 0
-
- if (len < 0) {
- throw new IllegalArgumentException("Cannot have length offset: " + len);
- } // end if: len < 0
-
- if (off + len > source.length) {
- throw new IllegalArgumentException(
- String.format("Cannot have offset of %d and length of %d with array of length %d", off, len, source.length));
- } // end if: off < 0
-
-
- // Compress?
- if ((options & GZIP) != 0) {
- java.io.ByteArrayOutputStream baos = null;
- java.util.zip.GZIPOutputStream gzos = null;
- B64OutputStream b64os = null;
-
- try {
- // GZip -> Base64 -> ByteArray
- baos = new java.io.ByteArrayOutputStream();
- b64os = new B64OutputStream(baos, ENCODE | options);
- gzos = new java.util.zip.GZIPOutputStream(b64os);
-
- gzos.write(source, off, len);
- gzos.close();
- } // end try
- catch (java.io.IOException e) {
- // Catch it and then throw it immediately so that
- // the finally{} block is called for cleanup.
- throw e;
- } // end catch
- finally {
- try {
- gzos.close();
- } catch (Exception e) {
- }
- try {
- b64os.close();
- } catch (Exception e) {
- }
- try {
- baos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return baos.toByteArray();
- } // end if: compress
-
- // Else, don't compress. Better not to use streams at all then.
- else {
- boolean breakLines = (options & DO_BREAK_LINES) != 0;
-
- //int len43 = len * 4 / 3;
- //byte[] outBuff = new byte[ ( len43 ) // Main 4:3
- // + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding
- // + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
- // Try to determine more precisely how big the array needs to be.
- // If we get it right, we don't have to do an array copy, and
- // we save a bunch of memory.
- int encLen = (len / 3) * 4 + (len % 3 > 0 ? 4 : 0); // Bytes needed for actual encoding
- if (breakLines) {
- encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters
- }
- byte[] outBuff = new byte[encLen];
-
-
- int d = 0;
- int e = 0;
- int len2 = len - 2;
- int lineLength = 0;
- for (; d < len2; d += 3, e += 4) {
- encode3to4(source, d + off, 3, outBuff, e, options);
-
- lineLength += 4;
- if (breakLines && lineLength >= MAX_LINE_LENGTH) {
- outBuff[e + 4] = NEW_LINE;
- e++;
- lineLength = 0;
- } // end if: end of line
- } // en dfor: each piece of array
-
- if (d < len) {
- encode3to4(source, d + off, len - d, outBuff, e, options);
- e += 4;
- } // end if: some padding needed
-
-
- // Only resize array if we didn't guess it right.
- if (e <= outBuff.length - 1) {
- // If breaking lines and the last byte falls right at
- // the line length (76 bytes per line), there will be
- // one extra byte, and the array will need to be resized.
- // Not too bad of an estimate on array size, I'd say.
- byte[] finalOut = new byte[e];
- System.arraycopy(outBuff, 0, finalOut, 0, e);
- //System.err.println("Having to resize array from " + outBuff.length + " to " + e );
- return finalOut;
- } else {
- //System.err.println("No need to resize array.");
- return outBuff;
- }
-
- } // end else: don't compress
-
- } // end encodeBytesToBytes
-
-
-
-
-
-/* ******** D E C O D I N G M E T H O D S ******** */
-
-
- /**
- * Decodes four bytes from array <var>source</var>
- * and writes the resulting bytes (up to three of them)
- * to <var>destination</var>.
- * The source and destination arrays can be manipulated
- * anywhere along their length by specifying
- * <var>srcOffset</var> and <var>destOffset</var>.
- * This method does not check to make sure your arrays
- * are large enough to accomodate <var>srcOffset</var> + 4 for
- * the <var>source</var> array or <var>destOffset</var> + 3 for
- * the <var>destination</var> array.
- * This method returns the actual number of bytes that
- * were converted from the Base64 encoding.
- * <p>This is the lowest level of the decoding methods with
- * all possible parameters.</p>
- *
- * @param source the array to convert
- * @param srcOffset the index where conversion begins
- * @param destination the array to hold the conversion
- * @param destOffset the index where output will be put
- * @param options alphabet type is pulled from this (standard, url-safe, ordered)
- * @return the number of decoded bytes converted
- * @throws NullPointerException if source or destination arrays are null
- * @throws IllegalArgumentException if srcOffset or destOffset are invalid
- * or there is not enough room in the array.
- * @since 1.3
- */
- private static int decode4to3(
- byte[] source, int srcOffset,
- byte[] destination, int destOffset, int options) {
-
- // Lots of error checking and exception throwing
- if (source == null) {
- throw new NullPointerException("Source array was null.");
- } // end if
- if (destination == null) {
- throw new NullPointerException("Destination array was null.");
- } // end if
- if (srcOffset < 0 || srcOffset + 3 >= source.length) {
- throw new IllegalArgumentException(String.format(
- "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset));
- } // end if
- if (destOffset < 0 || destOffset + 2 >= destination.length) {
- throw new IllegalArgumentException(String.format(
- "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset));
- } // end if
-
-
- byte[] DECODABET = getDecodabet(options);
-
- // Example: Dk==
- if (source[srcOffset + 2] == EQUALS_SIGN) {
- // Two ways to do the same thing. Don't know which way I like best.
- //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
- // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
- int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
- | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
-
- destination[destOffset] = (byte) (outBuff >>> 16);
- return 1;
- }
-
- // Example: DkL=
- else if (source[srcOffset + 3] == EQUALS_SIGN) {
- // Two ways to do the same thing. Don't know which way I like best.
- //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
- // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
- // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
- int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
- | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
- | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
-
- destination[destOffset] = (byte) (outBuff >>> 16);
- destination[destOffset + 1] = (byte) (outBuff >>> 8);
- return 2;
- }
-
- // Example: DkLE
- else {
- // Two ways to do the same thing. Don't know which way I like best.
- //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 )
- // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
- // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
- // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
- int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
- | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
- | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6)
- | ((DECODABET[source[srcOffset + 3]] & 0xFF));
-
-
- destination[destOffset] = (byte) (outBuff >> 16);
- destination[destOffset + 1] = (byte) (outBuff >> 8);
- destination[destOffset + 2] = (byte) (outBuff);
-
- return 3;
- }
- } // end decodeToBytes
-
-
- /**
- * Low-level access to decoding ASCII characters in
- * the form of a byte array. <strong>Ignores GUNZIP option, if
- * it's set.</strong> This is not generally a recommended method,
- * although it is used internally as part of the decoding process.
- * Special case: if len = 0, an empty array is returned. Still,
- * if you need more speed and reduced memory footprint (and aren't
- * gzipping), consider this method.
- *
- * @param source The Base64 encoded data
- * @return decoded data
- * @since 2.3.1
- * @throws java.io.IOException If bogus characters are contained in the input
- */
- public static byte[] decode(byte[] source)
- throws java.io.IOException {
- byte[] decoded = null;
-// try {
- decoded = decode(source, 0, source.length, Base64.NO_OPTIONS);
-// } catch( java.io.IOException ex ) {
-// assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage();
-// }
- return decoded;
- }
-
-
- /**
- * Low-level access to decoding ASCII characters in
- * the form of a byte array. <strong>Ignores GUNZIP option, if
- * it's set.</strong> This is not generally a recommended method,
- * although it is used internally as part of the decoding process.
- * Special case: if len = 0, an empty array is returned. Still,
- * if you need more speed and reduced memory footprint (and aren't
- * gzipping), consider this method.
- *
- * @param source The Base64 encoded data
- * @param off The offset of where to begin decoding
- * @param len The length of characters to decode
- * @param options Can specify options such as alphabet type to use
- * @return decoded data
- * @throws java.io.IOException If bogus characters exist in source data
- * @since 1.3
- */
- public static byte[] decode(byte[] source, int off, int len, int options)
- throws java.io.IOException {
-
- // Lots of error checking and exception throwing
- if (source == null) {
- throw new NullPointerException("Cannot decode null source array.");
- } // end if
- if (off < 0 || off + len > source.length) {
- throw new IllegalArgumentException(String.format(
- "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len));
- } // end if
-
- if (len == 0) {
- return new byte[0];
- } else if (len < 4) {
- throw new IllegalArgumentException(
- "Base64-encoded string must have at least four characters, but length specified was " + len);
- } // end if
-
- byte[] DECODABET = getDecodabet(options);
-
- int len34 = len * 3 / 4; // Estimate on array size
- byte[] outBuff = new byte[len34]; // Upper limit on size of output
- int outBuffPosn = 0; // Keep track of where we're writing
-
- byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space
- int b4Posn = 0; // Keep track of four byte input buffer
- int i = 0; // Source array counter
- byte sbiDecode = 0; // Special value from DECODABET
-
- for (i = off; i < off + len; i++) { // Loop through source
-
- sbiDecode = DECODABET[source[i] & 0xFF];
-
- // White space, Equals sign, or legit Base64 character
- // Note the values such as -5 and -9 in the
- // DECODABETs at the top of the file.
- if (sbiDecode >= WHITE_SPACE_ENC) {
- if (sbiDecode >= EQUALS_SIGN_ENC) {
- b4[b4Posn++] = source[i]; // Save non-whitespace
- if (b4Posn > 3) { // Time to decode?
- outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);
- b4Posn = 0;
-
- // If that was the equals sign, break out of 'for' loop
- if (source[i] == EQUALS_SIGN) {
- break;
- } // end if: equals sign
- } // end if: quartet built
- } // end if: equals sign or better
- } // end if: white space, equals sign or better
- else {
- // There's a bad input character in the Base64 stream.
- throw new java.io.IOException(String.format(
- "Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i));
- } // end else:
- } // each input character
-
- byte[] out = new byte[outBuffPosn];
- System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
- return out;
- } // end decode
-
-
- /**
- * Decodes data from Base64 notation, automatically
- * detecting gzip-compressed data and decompressing it.
- *
- * @param s the string to decode
- * @return the decoded data
- * @throws java.io.IOException If there is a problem
- * @since 1.4
- */
- public static byte[] decode(String s) throws java.io.IOException {
- return decode(s, NO_OPTIONS);
- }
-
-
- /**
- * Decodes data from Base64 notation, automatically
- * detecting gzip-compressed data and decompressing it.
- *
- * @param s the string to decode
- * @param options encode options such as URL_SAFE
- * @return the decoded data
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if <tt>s</tt> is null
- * @since 1.4
- */
- public static byte[] decode(String s, int options) throws java.io.IOException {
-
- if (s == null) {
- throw new NullPointerException("Input string was null.");
- } // end if
-
- byte[] bytes;
- try {
- bytes = s.getBytes(PREFERRED_ENCODING);
- } // end try
- catch (java.io.UnsupportedEncodingException uee) {
- bytes = s.getBytes();
- } // end catch
- //</change>
-
- // Decode
- bytes = decode(bytes, 0, bytes.length, options);
-
- // Check to see if it's gzip-compressed
- // GZIP Magic Two-Byte Number: 0x8b1f (35615)
- boolean dontGunzip = (options & DONT_GUNZIP) != 0;
- if ((bytes != null) && (bytes.length >= 4) && (!dontGunzip)) {
-
- int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
- if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) {
- java.io.ByteArrayInputStream bais = null;
- java.util.zip.GZIPInputStream gzis = null;
- java.io.ByteArrayOutputStream baos = null;
- byte[] buffer = new byte[2048];
- int length = 0;
-
- try {
- baos = new java.io.ByteArrayOutputStream();
- bais = new java.io.ByteArrayInputStream(bytes);
- gzis = new java.util.zip.GZIPInputStream(bais);
-
- while ((length = gzis.read(buffer)) >= 0) {
- baos.write(buffer, 0, length);
- } // end while: reading input
-
- // No error? Get new bytes.
- bytes = baos.toByteArray();
-
- } // end try
- catch (java.io.IOException e) {
- e.printStackTrace();
- // Just return originally-decoded bytes
- } // end catch
- finally {
- try {
- baos.close();
- } catch (Exception e) {
- }
- try {
- gzis.close();
- } catch (Exception e) {
- }
- try {
- bais.close();
- } catch (Exception e) {
- }
- } // end finally
-
- } // end if: gzipped
- } // end if: bytes.length >= 2
-
- return bytes;
- } // end decode
-
-
- /**
- * Attempts to decode Base64 data and deserialize a Java
- * Object within. Returns <tt>null</tt> if there was an error.
- *
- * @param encodedObject The Base64 data to decode
- * @return The decoded and deserialized object
- * @throws NullPointerException if encodedObject is null
- * @throws java.io.IOException if there is a general error
- * @throws ClassNotFoundException if the decoded object is of a
- * class that cannot be found by the JVM
- * @since 1.5
- */
- public static Object decodeToObject(String encodedObject)
- throws java.io.IOException, java.lang.ClassNotFoundException {
- return decodeToObject(encodedObject, NO_OPTIONS, null);
- }
-
-
- /**
- * Attempts to decode Base64 data and deserialize a Java
- * Object within. Returns <tt>null</tt> if there was an error.
- * If <tt>loader</tt> is not null, it will be the class loader
- * used when deserializing.
- *
- * @param encodedObject The Base64 data to decode
- * @param options Various parameters related to decoding
- * @param loader Optional class loader to use in deserializing classes.
- * @return The decoded and deserialized object
- * @throws NullPointerException if encodedObject is null
- * @throws java.io.IOException if there is a general error
- * @throws ClassNotFoundException if the decoded object is of a
- * class that cannot be found by the JVM
- * @since 2.3.4
- */
- public static Object decodeToObject(
- String encodedObject, int options, final ClassLoader loader)
- throws java.io.IOException, java.lang.ClassNotFoundException {
-
- // Decode and gunzip if necessary
- byte[] objBytes = decode(encodedObject, options);
-
- java.io.ByteArrayInputStream bais = null;
- java.io.ObjectInputStream ois = null;
- Object obj = null;
-
- try {
- bais = new java.io.ByteArrayInputStream(objBytes);
-
- // If no custom class loader is provided, use Java's builtin OIS.
- if (loader == null) {
- ois = new java.io.ObjectInputStream(bais);
- } // end if: no loader provided
-
- // Else make a customized object input stream that uses
- // the provided class loader.
- else {
- ois = new java.io.ObjectInputStream(bais) {
- @Override
- public Class<?> resolveClass(java.io.ObjectStreamClass streamClass)
- throws java.io.IOException, ClassNotFoundException {
- Class c = Class.forName(streamClass.getName(), false, loader);
- if (c == null) {
- return super.resolveClass(streamClass);
- } else {
- return c; // Class loader knows of this class.
- } // end else: not null
- } // end resolveClass
- }; // end ois
- } // end else: no custom class loader
-
- obj = ois.readObject();
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and throw in order to execute finally{}
- } // end catch
- catch (java.lang.ClassNotFoundException e) {
- throw e; // Catch and throw in order to execute finally{}
- } // end catch
- finally {
- try {
- bais.close();
- } catch (Exception e) {
- }
- try {
- ois.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return obj;
- } // end decodeObject
-
-
- /**
- * Convenience method for encoding data to a file.
- *
- * <p>As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param dataToEncode byte array of data to encode in base64 form
- * @param filename Filename for saving encoded data
- * @throws java.io.IOException if there is an error
- * @throws NullPointerException if dataToEncode is null
- * @since 2.1
- */
- public static void encodeToFile(byte[] dataToEncode, String filename)
- throws java.io.IOException {
-
- if (dataToEncode == null) {
- throw new NullPointerException("Data to encode was null.");
- } // end iff
-
- B64OutputStream bos = null;
- try {
- bos = new B64OutputStream(
- new java.io.FileOutputStream(filename), Base64.ENCODE);
- bos.write(dataToEncode);
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and throw to execute finally{} block
- } // end catch: java.io.IOException
- finally {
- try {
- bos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- } // end encodeToFile
-
-
- /**
- * Convenience method for decoding data to a file.
- *
- * <p>As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param dataToDecode Base64-encoded data as a string
- * @param filename Filename for saving decoded data
- * @throws java.io.IOException if there is an error
- * @since 2.1
- */
- public static void decodeToFile(String dataToDecode, String filename)
- throws java.io.IOException {
-
- B64OutputStream bos = null;
- try {
- bos = new B64OutputStream(
- new java.io.FileOutputStream(filename), Base64.DECODE);
- bos.write(dataToDecode.getBytes(PREFERRED_ENCODING));
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and throw to execute finally{} block
- } // end catch: java.io.IOException
- finally {
- try {
- bos.close();
- } catch (Exception e) {
- }
- } // end finally
-
- } // end decodeToFile
-
-
- /**
- * Convenience method for reading a base64-encoded
- * file and decoding it.
- *
- * <p>As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param filename Filename for reading encoded data
- * @return decoded byte array
- * @throws java.io.IOException if there is an error
- * @since 2.1
- */
- public static byte[] decodeFromFile(String filename)
- throws java.io.IOException {
-
- byte[] decodedData = null;
- B64InputStream bis = null;
- try {
- // Set up some useful variables
- java.io.File file = new java.io.File(filename);
- byte[] buffer = null;
- int length = 0;
- int numBytes = 0;
-
- // Check for size of file
- if (file.length() > Integer.MAX_VALUE) {
- throw new java.io.IOException("File is too big for this convenience method (" + file.length() + " bytes).");
- } // end if: file too big for int index
- buffer = new byte[(int) file.length()];
-
- // Open a stream
- bis = new B64InputStream(
- new java.io.BufferedInputStream(
- new java.io.FileInputStream(file)), Base64.DECODE);
-
- // Read until done
- while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {
- length += numBytes;
- } // end while
-
- // Save in a variable to return
- decodedData = new byte[length];
- System.arraycopy(buffer, 0, decodedData, 0, length);
-
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch: java.io.IOException
- finally {
- try {
- bis.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return decodedData;
- } // end decodeFromFile
-
-
- /**
- * Convenience method for reading a binary file
- * and base64-encoding it.
- *
- * <p>As of v 2.3, if there is a error,
- * the method will throw an java.io.IOException. <b>This is new to v2.3!</b>
- * In earlier versions, it just returned false, but
- * in retrospect that's a pretty poor way to handle it.</p>
- *
- * @param filename Filename for reading binary data
- * @return base64-encoded string
- * @throws java.io.IOException if there is an error
- * @since 2.1
- */
- public static String encodeFromFile(String filename)
- throws java.io.IOException {
-
- String encodedData = null;
- B64InputStream bis = null;
- try {
- // Set up some useful variables
- java.io.File file = new java.io.File(filename);
- byte[] buffer = new byte[Math.max((int) (file.length() * 1.4 + 1), 40)]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5)
- int length = 0;
- int numBytes = 0;
-
- // Open a stream
- bis = new B64InputStream(
- new java.io.BufferedInputStream(
- new java.io.FileInputStream(file)), Base64.ENCODE);
-
- // Read until done
- while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {
- length += numBytes;
- } // end while
-
- // Save in a variable to return
- encodedData = new String(buffer, 0, length, Base64.PREFERRED_ENCODING);
-
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch: java.io.IOException
- finally {
- try {
- bis.close();
- } catch (Exception e) {
- }
- } // end finally
-
- return encodedData;
- } // end encodeFromFile
-
- /**
- * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
- *
- * @param infile Input file
- * @param outfile Output file
- * @throws java.io.IOException if there is an error
- * @since 2.2
- */
- public static void encodeFileToFile(String infile, String outfile)
- throws java.io.IOException {
-
- String encoded = Base64.encodeFromFile(infile);
- java.io.OutputStream out = null;
- try {
- out = new java.io.BufferedOutputStream(
- new java.io.FileOutputStream(outfile));
- out.write(encoded.getBytes("US-ASCII")); // Strict, 7-bit output.
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch
- finally {
- try {
- out.close();
- } catch (Exception ex) {
- }
- } // end finally
- } // end encodeFileToFile
-
-
- /**
- * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
- *
- * @param infile Input file
- * @param outfile Output file
- * @throws java.io.IOException if there is an error
- * @since 2.2
- */
- public static void decodeFileToFile(String infile, String outfile)
- throws java.io.IOException {
-
- byte[] decoded = Base64.decodeFromFile(infile);
- java.io.OutputStream out = null;
- try {
- out = new java.io.BufferedOutputStream(
- new java.io.FileOutputStream(outfile));
- out.write(decoded);
- } // end try
- catch (java.io.IOException e) {
- throw e; // Catch and release to execute finally{}
- } // end catch
- finally {
- try {
- out.close();
- } catch (Exception ex) {
- }
- } // end finally
- } // end decodeFileToFile
-
-
- /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */
-
-
- /**
- * A {@link com.dd.plist.Base64.B64InputStream} will read data from another
- * <tt>java.io.InputStream</tt>, given in the constructor,
- * and encode/decode to/from Base64 notation on the fly.
- *
- * @see Base64
- * @since 1.3
- */
- public static class B64InputStream extends java.io.FilterInputStream {
-
- private boolean encode; // Encoding or decoding
- private int position; // Current position in the buffer
- private byte[] buffer; // Small buffer holding converted data
- private int bufferLength; // Length of buffer (3 or 4)
- private int numSigBytes; // Number of meaningful bytes in the buffer
- private int lineLength;
- private boolean breakLines; // Break lines at less than 80 characters
- private int options; // Record options used to create the stream.
- private byte[] decodabet; // Local copies to avoid extra method calls
-
-
- /**
- * Constructs a {@link com.dd.plist.Base64.B64InputStream} in DECODE mode.
- *
- * @param in the <tt>java.io.InputStream</tt> from which to read data.
- * @since 1.3
- */
- public B64InputStream(java.io.InputStream in) {
- this(in, DECODE);
- } // end constructor
-
-
- /**
- * Constructs a {@link com.dd.plist.Base64.B64InputStream} in
- * either ENCODE or DECODE mode.
- *
- * Valid options:<pre>
- * ENCODE or DECODE: Encode or Decode as data is read.
- * DO_BREAK_LINES: break lines at 76 characters
- * (only meaningful when encoding)
- * </pre>
- *
- * Example: <code>new Base64.B64InputStream( in, Base64.DECODE )</code>
- *
- * @param in the <tt>java.io.InputStream</tt> from which to read data.
- * @param options Specified options
- * @see Base64#ENCODE
- * @see Base64#DECODE
- * @see Base64#DO_BREAK_LINES
- * @since 2.0
- */
- public B64InputStream(java.io.InputStream in, int options) {
-
- super(in);
- this.options = options; // Record for later
- this.breakLines = (options & DO_BREAK_LINES) > 0;
- this.encode = (options & ENCODE) > 0;
- this.bufferLength = encode ? 4 : 3;
- this.buffer = new byte[bufferLength];
- this.position = -1;
- this.lineLength = 0;
- this.decodabet = getDecodabet(options);
- } // end constructor
-
- /**
- * Reads enough of the input stream to convert
- * to/from Base64 and returns the next byte.
- *
- * @return next byte
- * @since 1.3
- */
- @Override
- public int read() throws java.io.IOException {
-
- // Do we need to get data?
- if (position < 0) {
- if (encode) {
- byte[] b3 = new byte[3];
- int numBinaryBytes = 0;
- for (int i = 0; i < 3; i++) {
- int b = in.read();
-
- // If end of stream, b is -1.
- if (b >= 0) {
- b3[i] = (byte) b;
- numBinaryBytes++;
- } else {
- break; // out of for loop
- } // end else: end of stream
-
- } // end for: each needed input byte
-
- if (numBinaryBytes > 0) {
- encode3to4(b3, 0, numBinaryBytes, buffer, 0, options);
- position = 0;
- numSigBytes = 4;
- } // end if: got data
- else {
- return -1; // Must be end of stream
- } // end else
- } // end if: encoding
-
- // Else decoding
- else {
- byte[] b4 = new byte[4];
- int i = 0;
- for (i = 0; i < 4; i++) {
- // Read four "meaningful" bytes:
- int b = 0;
- do {
- b = in.read();
- }
- while (b >= 0 && decodabet[b & 0x7f] <= WHITE_SPACE_ENC);
-
- if (b < 0) {
- break; // Reads a -1 if end of stream
- } // end if: end of stream
-
- b4[i] = (byte) b;
- } // end for: each needed input byte
-
- if (i == 4) {
- numSigBytes = decode4to3(b4, 0, buffer, 0, options);
- position = 0;
- } // end if: got four characters
- else if (i == 0) {
- return -1;
- } // end else if: also padded correctly
- else {
- // Must have broken out from above.
- throw new java.io.IOException("Improperly padded Base64 input.");
- } // end
-
- } // end else: decode
- } // end else: get data
-
- // Got data?
- if (position >= 0) {
- // End of relevant data?
- if ( /*!encode &&*/ position >= numSigBytes) {
- return -1;
- } // end if: got data
-
- if (encode && breakLines && lineLength >= MAX_LINE_LENGTH) {
- lineLength = 0;
- return '\n';
- } // end if
- else {
- lineLength++; // This isn't important when decoding
- // but throwing an extra "if" seems
- // just as wasteful.
-
- int b = buffer[position++];
-
- if (position >= bufferLength) {
- position = -1;
- } // end if: end
-
- return b & 0xFF; // This is how you "cast" a byte that's
- // intended to be unsigned.
- } // end else
- } // end if: position >= 0
-
- // Else error
- else {
- throw new java.io.IOException("Error in Base64 code reading stream.");
- } // end else
- } // end read
-
-
- /**
- * Calls {@link #read()} repeatedly until the end of stream
- * is reached or <var>len</var> bytes are read.
- * Returns number of bytes read into array or -1 if
- * end of stream is encountered.
- *
- * @param dest array to hold values
- * @param off offset for array
- * @param len max number of bytes to read into array
- * @return bytes read into array or -1 if end of stream is encountered.
- * @since 1.3
- */
- @Override
- public int read(byte[] dest, int off, int len)
- throws java.io.IOException {
- int i;
- int b;
- for (i = 0; i < len; i++) {
- b = read();
-
- if (b >= 0) {
- dest[off + i] = (byte) b;
- } else if (i == 0) {
- return -1;
- } else {
- break; // Out of 'for' loop
- } // Out of 'for' loop
- } // end for: each byte read
- return i;
- } // end read
-
- } // end inner class B64InputStream
-
-
-
-
-
-
- /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */
-
-
- /**
- * A {@link com.dd.plist.Base64.B64OutputStream} will write data to another
- * <tt>java.io.OutputStream</tt>, given in the constructor,
- * and encode/decode to/from Base64 notation on the fly.
- *
- * @see Base64
- * @since 1.3
- */
- public static class B64OutputStream extends java.io.FilterOutputStream {
-
- private boolean encode;
- private int position;
- private byte[] buffer;
- private int bufferLength;
- private int lineLength;
- private boolean breakLines;
- private byte[] b4; // Scratch used in a few places
- private boolean suspendEncoding;
- private int options; // Record for later
- private byte[] decodabet; // Local copies to avoid extra method calls
-
- /**
- * Constructs a {@link com.dd.plist.Base64.B64OutputStream} in ENCODE mode.
- *
- * @param out the <tt>java.io.OutputStream</tt> to which data will be written.
- * @since 1.3
- */
- public B64OutputStream(java.io.OutputStream out) {
- this(out, ENCODE);
- } // end constructor
-
-
- /**
- * Constructs a {@link com.dd.plist.Base64.B64OutputStream} in
- * either ENCODE or DECODE mode.
- *
- * Valid options:<pre>
- * ENCODE or DECODE: Encode or Decode as data is read.
- * DO_BREAK_LINES: don't break lines at 76 characters
- * (only meaningful when encoding)
- * </pre>
- *
- * Example: <code>new Base64.B64OutputStream( out, Base64.ENCODE )</code>
- *
- * @param out the <tt>java.io.B64OutputStream</tt> to which data will be written.
- * @param options Specified options.
- * @see Base64#ENCODE
- * @see Base64#DECODE
- * @see Base64#DO_BREAK_LINES
- * @since 1.3
- */
- public B64OutputStream(java.io.OutputStream out, int options) {
- super(out);
- this.breakLines = (options & DO_BREAK_LINES) != 0;
- this.encode = (options & ENCODE) != 0;
- this.bufferLength = encode ? 3 : 4;
- this.buffer = new byte[bufferLength];
- this.position = 0;
- this.lineLength = 0;
- this.suspendEncoding = false;
- this.b4 = new byte[4];
- this.options = options;
- this.decodabet = getDecodabet(options);
- } // end constructor
-
-
- /**
- * Writes the byte to the output stream after
- * converting to/from Base64 notation.
- * When encoding, bytes are buffered three
- * at a time before the output stream actually
- * gets a write() call.
- * When decoding, bytes are buffered four
- * at a time.
- *
- * @param theByte the byte to write
- * @since 1.3
- */
- @Override
- public void write(int theByte)
- throws java.io.IOException {
- // Encoding suspended?
- if (suspendEncoding) {
- this.out.write(theByte);
- return;
- } // end if: supsended
-
- // Encode?
- if (encode) {
- buffer[position++] = (byte) theByte;
- if (position >= bufferLength) { // Enough to encode.
-
- this.out.write(encode3to4(b4, buffer, bufferLength, options));
-
- lineLength += 4;
- if (breakLines && lineLength >= MAX_LINE_LENGTH) {
- this.out.write(NEW_LINE);
- lineLength = 0;
- } // end if: end of line
-
- position = 0;
- } // end if: enough to output
- } // end if: encoding
-
- // Else, Decoding
- else {
- // Meaningful Base64 character?
- if (decodabet[theByte & 0x7f] > WHITE_SPACE_ENC) {
- buffer[position++] = (byte) theByte;
- if (position >= bufferLength) { // Enough to output.
-
- int len = Base64.decode4to3(buffer, 0, b4, 0, options);
- out.write(b4, 0, len);
- position = 0;
- } // end if: enough to output
- } // end if: meaningful base64 character
- else if (decodabet[theByte & 0x7f] != WHITE_SPACE_ENC) {
- throw new java.io.IOException("Invalid character in Base64 data.");
- } // end else: not white space either
- } // end else: decoding
- } // end write
-
-
- /**
- * Calls {@link #write(int)} repeatedly until <var>len</var>
- * bytes are written.
- *
- * @param theBytes array from which to read bytes
- * @param off offset for array
- * @param len max number of bytes to read into array
- * @since 1.3
- */
- @Override
- public void write(byte[] theBytes, int off, int len)
- throws java.io.IOException {
- // Encoding suspended?
- if (suspendEncoding) {
- this.out.write(theBytes, off, len);
- return;
- } // end if: supsended
-
- for (int i = 0; i < len; i++) {
- write(theBytes[off + i]);
- } // end for: each byte written
-
- } // end write
-
-
- /**
- * Method added by PHIL. [Thanks, PHIL. -Rob]
- * This pads the buffer without closing the stream.
- *
- * @throws java.io.IOException if there's an error.
- */
- public void flushBase64() throws java.io.IOException {
- if (position > 0) {
- if (encode) {
- out.write(encode3to4(b4, buffer, position, options));
- position = 0;
- } // end if: encoding
- else {
- throw new java.io.IOException("Base64 input not properly padded.");
- } // end else: decoding
- } // end if: buffer partially full
-
- } // end flush
-
-
- /**
- * Flushes and closes (I think, in the superclass) the stream.
- *
- * @since 1.3
- */
- @Override
- public void close() throws java.io.IOException {
- // 1. Ensure that pending characters are written
- flushBase64();
-
- // 2. Actually close the stream
- // Base class both flushes and closes.
- super.close();
-
- buffer = null;
- out = null;
- } // end close
-
-
- /**
- * Suspends encoding of the stream.
- * May be helpful if you need to embed a piece of
- * base64-encoded data in a stream.
- *
- * @throws java.io.IOException if there's an error flushing
- * @since 1.5.1
- */
- public void suspendEncoding() throws java.io.IOException {
- flushBase64();
- this.suspendEncoding = true;
- } // end suspendEncoding
-
-
- /**
- * Resumes encoding of the stream.
- * May be helpful if you need to embed a piece of
- * base64-encoded data in a stream.
- *
- * @since 1.5.1
- */
- public void resumeEncoding() {
- this.suspendEncoding = false;
- } // end resumeEncoding
-
-
- } // end inner class B64OutputStream
-
-
-} // end class Base64
diff --git a/third_party/java/dd_plist/java/com/dd/plist/BinaryPropertyListParser.java b/third_party/java/dd_plist/java/com/dd/plist/BinaryPropertyListParser.java
deleted file mode 100644
index 9b20101..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/BinaryPropertyListParser.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011-2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.*;
-import java.math.BigInteger;
-
-/**
- * Parses property lists that are in Apple's binary format.
- * Use this class when you are sure about the format of the property list.
- * Otherwise use the PropertyListParser class.
- *
- * Parsing is done by calling the static <code>parse</code> methods.
- *
- * @author Daniel Dreibrodt
- */
-public class BinaryPropertyListParser {
-
- /**
- * Major version of the property list format
- */
- @SuppressWarnings("FieldCanBeLocal") //Useful when the features of different format versions are implemented
- private int majorVersion;
-
- /**
- * Minor version of the property list format
- */
- @SuppressWarnings("FieldCanBeLocal") //Useful when the features of different format versions are implemented
- private int minorVersion;
-
- /**
- * property list in bytes
- */
- private byte[] bytes;
-
- /**
- * Length of an object reference in bytes
- */
- private int objectRefSize;
-
- /**
- * The table holding the information at which offset each object is found
- */
- private int[] offsetTable;
-
- /**
- * Protected constructor so that instantiation is fully controlled by the
- * static parse methods.
- *
- * @see BinaryPropertyListParser#parse(byte[])
- */
- protected BinaryPropertyListParser() {
- /** empty **/
- }
-
- /**
- * Parses a binary property list from a byte array.
- *
- * @param data The binary property list's data.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws PropertyListFormatException When the property list's format could not be parsed.
- * @throws java.io.UnsupportedEncodingException When a NSString object could not be decoded.
- */
- public static NSObject parse(byte[] data) throws PropertyListFormatException, UnsupportedEncodingException {
- BinaryPropertyListParser parser = new BinaryPropertyListParser();
- return parser.doParse(data);
- }
-
- /**
- * Parses a binary property list from a byte array.
- *
- * @param data The binary property list's data.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws PropertyListFormatException When the property list's format could not be parsed.
- * @throws java.io.UnsupportedEncodingException When a NSString object could not be decoded.
- */
- private NSObject doParse(byte[] data) throws PropertyListFormatException, UnsupportedEncodingException {
- bytes = data;
- String magic = new String(copyOfRange(bytes, 0, 8));
- if (!magic.startsWith("bplist")) {
- throw new IllegalArgumentException("The given data is no binary property list. Wrong magic bytes: " + magic);
- }
-
- majorVersion = magic.charAt(6) - 0x30; //ASCII number
- minorVersion = magic.charAt(7) - 0x30; //ASCII number
-
- // 0.0 - OS X Tiger and earlier
- // 0.1 - Leopard
- // 0.? - Snow Leopard
- // 1.5 - Lion
- // 2.0 - Snow Lion
-
- if (majorVersion > 0) {
- throw new IllegalArgumentException("Unsupported binary property list format: v" + majorVersion + "." + minorVersion + ". " +
- "Version 1.0 and later are not yet supported.");
- //Version 1.0+ is not even supported by OS X's own parser
- }
-
- /*
- * Handle trailer, last 32 bytes of the file
- */
- byte[] trailer = copyOfRange(bytes, bytes.length - 32, bytes.length);
- //6 null bytes (index 0 to 5)
-
- int offsetSize = (int) parseUnsignedInt(trailer, 6, 7);
- objectRefSize = (int) parseUnsignedInt(trailer, 7, 8);
- int numObjects = (int) parseUnsignedInt(trailer, 8, 16);
- int topObject = (int) parseUnsignedInt(trailer, 16, 24);
- int offsetTableOffset = (int) parseUnsignedInt(trailer, 24, 32);
-
- /*
- * Handle offset table
- */
- offsetTable = new int[numObjects];
-
- for (int i = 0; i < numObjects; i++) {
- offsetTable[i] = (int) parseUnsignedInt(bytes, offsetTableOffset + i * offsetSize, offsetTableOffset + (i + 1) * offsetSize);
- }
-
- return parseObject(topObject);
- }
-
- /**
- * Parses a binary property list from an input stream.
- *
- * @param is The input stream that points to the property list's data.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws PropertyListFormatException When the property list's format could not be parsed.
- * @throws java.io.IOException When a NSString object could not be decoded or an InputStream IO error occurs.
- */
- public static NSObject parse(InputStream is) throws IOException, PropertyListFormatException {
- byte[] buf = PropertyListParser.readAll(is);
- return parse(buf);
- }
-
- /**
- * Parses a binary property list file.
- *
- * @param f The binary property list file
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws PropertyListFormatException When the property list's format could not be parsed.
- * @throws java.io.UnsupportedEncodingException When a NSString object could not be decoded or a file IO error occurs.
- */
- public static NSObject parse(File f) throws IOException, PropertyListFormatException {
- return parse(new FileInputStream(f));
- }
-
- /**
- * Parses an object inside the currently parsed binary property list.
- * For the format specification check
- * <a href="http://www.opensource.apple.com/source/CF/CF-855.17/CFBinaryPList.c">
- * Apple's binary property list parser implementation</a>.
- *
- * @param obj The object ID.
- * @return The parsed object.
- * @throws PropertyListFormatException When the property list's format could not be parsed.
- * @throws java.io.UnsupportedEncodingException When a NSString object could not be decoded.
- */
- private NSObject parseObject(int obj) throws PropertyListFormatException, UnsupportedEncodingException {
- int offset = offsetTable[obj];
- byte type = bytes[offset];
- int objType = (type & 0xF0) >> 4; //First 4 bits
- int objInfo = (type & 0x0F); //Second 4 bits
- switch (objType) {
- case 0x0: {
- //Simple
- switch (objInfo) {
- case 0x0: {
- //null object (v1.0 and later)
- return null;
- }
- case 0x8: {
- //false
- return new NSNumber(false);
- }
- case 0x9: {
- //true
- return new NSNumber(true);
- }
- case 0xC: {
- //URL with no base URL (v1.0 and later)
- //TODO Implement binary URL parsing (not yet even implemented in Core Foundation as of revision 855.17)
- throw new UnsupportedOperationException("The given binary property list contains a URL object. Parsing of this object type is not yet implemented.");
- }
- case 0xD: {
- //URL with base URL (v1.0 and later)
- //TODO Implement binary URL parsing (not yet even implemented in Core Foundation as of revision 855.17)
- throw new UnsupportedOperationException("The given binary property list contains a URL object. Parsing of this object type is not yet implemented.");
- }
- case 0xE: {
- //16-byte UUID (v1.0 and later)
- //TODO Implement binary UUID parsing (not yet even implemented in Core Foundation as of revision 855.17)
- throw new UnsupportedOperationException("The given binary property list contains a UUID object. Parsing of this object type is not yet implemented.");
- }
- default: {
- throw new PropertyListFormatException("The given binary property list contains an object of unknown type (" + objType + ")");
- }
- }
- }
- case 0x1: {
- //integer
- int length = (int) Math.pow(2, objInfo);
- return new NSNumber(bytes, offset + 1, offset + 1 + length, NSNumber.INTEGER);
- }
- case 0x2: {
- //real
- int length = (int) Math.pow(2, objInfo);
- return new NSNumber(bytes, offset + 1, offset + 1 + length, NSNumber.REAL);
- }
- case 0x3: {
- //Date
- if (objInfo != 0x3) {
- throw new PropertyListFormatException("The given binary property list contains a date object of an unknown type ("+objInfo+")");
- }
- return new NSDate(bytes, offset + 1, offset + 9);
- }
- case 0x4: {
- //Data
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int length = lengthAndOffset[0];
- int dataOffset = lengthAndOffset[1];
- return new NSData(copyOfRange(bytes, offset + dataOffset, offset + dataOffset + length));
- }
- case 0x5: {
- //ASCII string
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int length = lengthAndOffset[0]; //Each character is 1 byte
- int strOffset = lengthAndOffset[1];
- return new NSString(bytes, offset + strOffset, offset + strOffset + length, "ASCII");
- }
- case 0x6: {
- //UTF-16-BE string
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int characters = lengthAndOffset[0];
- int strOffset = lengthAndOffset[1];
- //UTF-16 characters can have variable length, but the Core Foundation reference implementation
- //assumes 2 byte characters, thus only covering the Basic Multilingual Plane
- int length = characters * 2;
- return new NSString(bytes, offset + strOffset, offset + strOffset + length, "UTF-16BE");
- }
- case 0x7: {
- //UTF-8 string (v1.0 and later)
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int strOffset = lengthAndOffset[1];
- int characters = lengthAndOffset[0];
- //UTF-8 characters can have variable length, so we need to calculate the byte length dynamically
- //by reading the UTF-8 characters one by one
- int length = calculateUtf8StringLength(bytes, offset + strOffset, characters);
- return new NSString(bytes, offset + strOffset, offset + strOffset + length, "UTF-8");
- }
- case 0x8: {
- //UID (v1.0 and later)
- int length = objInfo + 1;
- return new UID(String.valueOf(obj), copyOfRange(bytes, offset + 1, offset + 1 + length));
- }
- case 0xA: {
- //Array
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int length = lengthAndOffset[0];
- int arrayOffset = lengthAndOffset[1];
-
- NSArray array = new NSArray(length);
- for (int i = 0; i < length; i++) {
- int objRef = (int) parseUnsignedInt(bytes, offset + arrayOffset + i * objectRefSize, offset + arrayOffset + (i + 1) * objectRefSize);
- array.setValue(i, parseObject(objRef));
- }
- return array;
- }
- case 0xB: {
- //Ordered set (v1.0 and later)
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int length = lengthAndOffset[0];
- int contentOffset = lengthAndOffset[1];
-
- NSSet set = new NSSet(true);
- for (int i = 0; i < length; i++) {
- int objRef = (int) parseUnsignedInt(bytes, offset + contentOffset + i * objectRefSize, offset + contentOffset + (i + 1) * objectRefSize);
- set.addObject(parseObject(objRef));
- }
- return set;
- }
- case 0xC: {
- //Set (v1.0 and later)
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int length = lengthAndOffset[0];
- int contentOffset = lengthAndOffset[1];
-
- NSSet set = new NSSet();
- for (int i = 0; i < length; i++) {
- int objRef = (int) parseUnsignedInt(bytes, offset + contentOffset + i * objectRefSize, offset + contentOffset + (i + 1) * objectRefSize);
- set.addObject(parseObject(objRef));
- }
- return set;
- }
- case 0xD: {
- //Dictionary
- int[] lengthAndOffset = readLengthAndOffset(objInfo, offset);
- int length = lengthAndOffset[0];
- int contentOffset = lengthAndOffset[1];
-
- NSDictionary dict = new NSDictionary();
- for (int i = 0; i < length; i++) {
- int keyRef = (int) parseUnsignedInt(bytes, offset + contentOffset + i * objectRefSize, offset + contentOffset + (i + 1) * objectRefSize);
- int valRef = (int) parseUnsignedInt(bytes, offset + contentOffset + (length * objectRefSize) + i * objectRefSize, offset + contentOffset + (length * objectRefSize) + (i + 1) * objectRefSize);
- NSObject key = parseObject(keyRef);
- NSObject val = parseObject(valRef);
- assert key != null; //Encountering a null object at this point would either be a fundamental error in the parser or an error in the property list
- dict.put(key.toString(), val);
- }
- return dict;
- }
- default: {
- throw new PropertyListFormatException("The given binary property list contains an object of unknown type (" + objType + ")");
- }
- }
- }
-
- /**
- * Reads the length for arrays, sets and dictionaries.
- *
- * @param objInfo Object information byte.
- * @param offset Offset in the byte array at which the object is located.
- * @return An array with the length two. First entry is the length, second entry the offset at which the content starts.
- */
- private int[] readLengthAndOffset(int objInfo, int offset) {
- int lengthValue = objInfo;
- int offsetValue = 1;
- if (objInfo == 0xF) {
- int int_type = bytes[offset + 1];
- int intType = (int_type & 0xF0) >> 4;
- if (intType != 0x1) {
- System.err.println("BinaryPropertyListParser: Length integer has an unexpected type" + intType + ". Attempting to parse anyway...");
- }
- int intInfo = int_type & 0x0F;
- int intLength = (int) Math.pow(2, intInfo);
- offsetValue = 2 + intLength;
- if (intLength < 3) {
- lengthValue = (int) parseUnsignedInt(bytes, offset + 2, offset + 2 + intLength);
- } else {
- lengthValue = new BigInteger(copyOfRange(bytes, offset + 2, offset + 2 + intLength)).intValue();
- }
- }
- return new int[]{lengthValue, offsetValue};
- }
-
- private int calculateUtf8StringLength(byte[] bytes, int offset, int numCharacters) {
- int length = 0;
- for(int i = 0; i < numCharacters; i++) {
- int tempOffset = offset + length;
- if(bytes.length <= tempOffset) {
- //WARNING: Invalid UTF-8 string, fall back to length = number of characters
- return numCharacters;
- }
- if(bytes[tempOffset] < 0x80) {
- length++;
- }
- if(bytes[tempOffset] < 0xC2) {
- //Invalid value (marks continuation byte), fall back to length = number of characters
- return numCharacters;
- }
- else if(bytes[tempOffset] < 0xE0) {
- if((bytes[tempOffset + 1] & 0xC0) != 0x80) {
- //Invalid continuation byte, fall back to length = number of characters
- return numCharacters;
- }
- length += 2;
- }
- else if(bytes[tempOffset] < 0xF0) {
- if((bytes[tempOffset + 1] & 0xC0) != 0x80
- || (bytes[tempOffset + 2] & 0xC0) != 0x80) {
- //Invalid continuation byte, fall back to length = number of characters
- return numCharacters;
- }
- length += 3;
- }
- else if(bytes[tempOffset] < 0xF5) {
- if((bytes[tempOffset + 1] & 0xC0) != 0x80
- || (bytes[tempOffset + 2] & 0xC0) != 0x80
- || (bytes[tempOffset + 3] & 0xC0) != 0x80) {
- //Invalid continuation byte, fall back to length = number of characters
- return numCharacters;
- }
- length += 4;
- }
- }
- return length;
- }
-
- /**
- * Parses an unsigned integers from a byte array.
- *
- * @param bytes The byte array containing the unsigned integer.
- * @return The unsigned integer represented by the given bytes.
- */
- @SuppressWarnings("unused")
- public static long parseUnsignedInt(byte[] bytes) {
- return parseUnsignedInt(bytes, 0, bytes.length);
- }
-
- /**
- * Parses an unsigned integer from a byte array.
- *
- * @param bytes The byte array containing the unsigned integer.
- * @param startIndex Beginning of the unsigned int in the byte array.
- * @param endIndex End of the unsigned int in the byte array.
- * @return The unsigned integer represented by the given bytes.
- */
- public static long parseUnsignedInt(byte[] bytes, int startIndex, int endIndex) {
- long l = 0;
- for (int i = startIndex; i < endIndex; i++) {
- l <<= 8;
- l |= bytes[i] & 0xFF;
- }
- l &= 0xFFFFFFFFL;
- return l;
- }
-
- /**
- * Parses a long from a (big-endian) byte array.
- *
- * @param bytes The bytes representing the long integer.
- * @return The long integer represented by the given bytes.
- */
- @SuppressWarnings("unused")
- public static long parseLong(byte[] bytes) {
- return parseLong(bytes, 0, bytes.length);
- }
-
- /**
- * Parses a long from a (big-endian) byte array.
- *
- * @param bytes The bytes representing the long integer.
- * @param startIndex Beginning of the long in the byte array.
- * @param endIndex End of the long in the byte array.
- * @return The long integer represented by the given bytes.
- */
- public static long parseLong(byte[] bytes, int startIndex, int endIndex) {
- long l = 0;
- for (int i = startIndex; i < endIndex; i++) {
- l <<= 8;
- l |= bytes[i] & 0xFF;
- }
- return l;
- }
-
- /**
- * Parses a double from a (big-endian) byte array.
- *
- * @param bytes The bytes representing the double.
- * @return The double represented by the given bytes.
- */
- @SuppressWarnings("unused")
- public static double parseDouble(byte[] bytes) {
- return parseDouble(bytes, 0, bytes.length);
- }
-
- /**
- * Parses a double from a (big-endian) byte array.
- *
- * @param bytes The bytes representing the double.
- * @param startIndex Beginning of the double in the byte array.
- * @param endIndex End of the double in the byte array.
- * @return The double represented by the given bytes.
- */
- public static double parseDouble(byte[] bytes, int startIndex, int endIndex) {
- if (endIndex - startIndex == 8) {
- return Double.longBitsToDouble(parseLong(bytes, startIndex, endIndex));
- } else if (endIndex - startIndex == 4) {
- return Float.intBitsToFloat((int)parseLong(bytes, startIndex, endIndex));
- } else {
- throw new IllegalArgumentException("endIndex ("+endIndex+") - startIndex ("+startIndex+") != 4 or 8");
- }
- }
-
- /**
- * Copies a part of a byte array into a new array.
- *
- * @param src The source array.
- * @param startIndex The index from which to start copying.
- * @param endIndex The index until which to copy.
- * @return The copied array.
- */
- public static byte[] copyOfRange(byte[] src, int startIndex, int endIndex) {
- int length = endIndex - startIndex;
- if (length < 0) {
- throw new IllegalArgumentException("startIndex (" + startIndex + ")" + " > endIndex (" + endIndex + ")");
- }
- byte[] dest = new byte[length];
- System.arraycopy(src, startIndex, dest, 0, length);
- return dest;
- }
-}
-
diff --git a/third_party/java/dd_plist/java/com/dd/plist/BinaryPropertyListWriter.java b/third_party/java/dd_plist/java/com/dd/plist/BinaryPropertyListWriter.java
deleted file mode 100644
index 21645be..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/BinaryPropertyListWriter.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2012 Keith Randall
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * A BinaryPropertyListWriter is a helper class for writing out
- * binary property list files. It contains an output stream and
- * various structures for keeping track of which NSObjects have
- * already been serialized, and where they were put in the file.
- *
- * @author Keith Randall
- */
-public class BinaryPropertyListWriter {
-
- public static final int VERSION_00 = 0;
- public static final int VERSION_10 = 10;
- public static final int VERSION_15 = 15;
- public static final int VERSION_20 = 20;
-
- /**
- * Finds out the minimum binary property list format version that
- * can be used to save the given NSObject tree.
- *
- * @param root Object root
- * @return Version code
- */
- private static int getMinimumRequiredVersion(NSObject root) {
- int minVersion = VERSION_00;
- if (root == null) {
- minVersion = VERSION_10;
- }
- if (root instanceof NSDictionary) {
- NSDictionary dict = (NSDictionary) root;
- for (NSObject o : dict.getHashMap().values()) {
- int v = getMinimumRequiredVersion(o);
- if (v > minVersion)
- minVersion = v;
- }
- } else if (root instanceof NSArray) {
- NSArray array = (NSArray) root;
- for (NSObject o : array.getArray()) {
- int v = getMinimumRequiredVersion(o);
- if (v > minVersion)
- minVersion = v;
- }
- } else if (root instanceof NSSet) {
- //Sets are only allowed in property lists v1+
- minVersion = VERSION_10;
- NSSet set = (NSSet) root;
- for (NSObject o : set.allObjects()) {
- int v = getMinimumRequiredVersion(o);
- if (v > minVersion)
- minVersion = v;
- }
- }
- return minVersion;
- }
-
- /**
- * Writes a binary plist file with the given object as the root.
- *
- * @param file the file to write to
- * @param root the source of the data to write to the file
- * @throws IOException When an IO error occurs while writing to the file or the object structure contains
- * data that cannot be saved.
- */
- public static void write(File file, NSObject root) throws IOException {
- OutputStream out = new FileOutputStream(file);
- write(out, root);
- out.close();
- }
-
- /**
- * Writes a binary plist serialization of the given object as the root.
- *
- * @param out the stream to write to
- * @param root the source of the data to write to the stream
- * @throws IOException When an IO error occurs while writing to the stream or the object structure contains
- * data that cannot be saved.
- */
- public static void write(OutputStream out, NSObject root) throws IOException {
- int minVersion = getMinimumRequiredVersion(root);
- if (minVersion > VERSION_00) {
- String versionString = ((minVersion == VERSION_10) ? "v1.0" : ((minVersion == VERSION_15) ? "v1.5" : ((minVersion == VERSION_20) ? "v2.0" : "v0.0")));
- throw new IOException("The given property list structure cannot be saved. " +
- "The required version of the binary format (" + versionString + ") is not yet supported.");
- }
- BinaryPropertyListWriter w = new BinaryPropertyListWriter(out, minVersion);
- w.write(root);
- }
-
- /**
- * Writes a binary plist serialization of the given object as the root
- * into a byte array.
- *
- * @param root The root object of the property list
- * @return The byte array containing the serialized property list
- * @throws IOException When an IO error occurs while writing to the stream or the object structure contains
- * data that cannot be saved.
- */
- public static byte[] writeToArray(NSObject root) throws IOException {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- write(bout, root);
- return bout.toByteArray();
- }
-
- private int version = VERSION_00;
-
- // raw output stream to result file
- private OutputStream out;
-
- // # of bytes written so far
- private long count;
-
- // map from object to its ID
- private Map<NSObject, Integer> idMap = new LinkedHashMap<NSObject, Integer>();
- private int idSizeInBytes;
-
- /**
- * Creates a new binary property list writer
- *
- * @param outStr The output stream into which the binary property list will be written
- * @throws IOException When an IO error occurs while writing to the stream or the object structure contains
- * data that cannot be saved.
- */
- BinaryPropertyListWriter(OutputStream outStr) throws IOException {
- out = new BufferedOutputStream(outStr);
- }
-
- BinaryPropertyListWriter(OutputStream outStr, int version) throws IOException {
- this.version = version;
- out = new BufferedOutputStream(outStr);
- }
-
- void write(NSObject root) throws IOException {
- // magic bytes
- write(new byte[]{'b', 'p', 'l', 'i', 's', 't'});
-
- //version
- switch (version) {
- case VERSION_00: {
- write(new byte[]{'0', '0'});
- break;
- }
- case VERSION_10: {
- write(new byte[]{'1', '0'});
- break;
- }
- case VERSION_15: {
- write(new byte[]{'1', '5'});
- break;
- }
- case VERSION_20: {
- write(new byte[]{'2', '0'});
- break;
- }
- }
-
- // assign IDs to all the objects.
- root.assignIDs(this);
-
- idSizeInBytes = computeIdSizeInBytes(idMap.size());
-
- // offsets of each object, indexed by ID
- long[] offsets = new long[idMap.size()];
-
- // write each object, save offset
- for (Map.Entry<NSObject, Integer> entry : idMap.entrySet()) {
- NSObject obj = entry.getKey();
- int id = entry.getValue();
- offsets[id] = count;
- if (obj == null) {
- write(0x00);
- } else {
- obj.toBinary(this);
- }
- }
-
- // write offset table
- long offsetTableOffset = count;
- int offsetSizeInBytes = computeOffsetSizeInBytes(count);
- for (long offset : offsets) {
- writeBytes(offset, offsetSizeInBytes);
- }
-
- if (version != VERSION_15) {
- // write trailer
- // 6 null bytes
- write(new byte[6]);
- // size of an offset
- write(offsetSizeInBytes);
- // size of a ref
- write(idSizeInBytes);
- // number of objects
- writeLong(idMap.size());
- // top object
- writeLong(idMap.get(root));
- // offset table offset
- writeLong(offsetTableOffset);
- }
-
- out.flush();
- }
-
- void assignID(NSObject obj) {
- if (!idMap.containsKey(obj)) {
- idMap.put(obj, idMap.size());
- }
- }
-
- int getID(NSObject obj) {
- return idMap.get(obj);
- }
-
- private static int computeIdSizeInBytes(int numberOfIds) {
- if (numberOfIds < 256) return 1;
- if (numberOfIds < 65536) return 2;
- return 4;
- }
-
- private int computeOffsetSizeInBytes(long maxOffset) {
- if (maxOffset < 256) return 1;
- if (maxOffset < 65536) return 2;
- if (maxOffset < 4294967296L) return 4;
- return 8;
- }
-
- void writeIntHeader(int kind, int value) throws IOException {
- assert value >= 0;
- if (value < 15) {
- write((kind << 4) + value);
- } else if (value < 256) {
- write((kind << 4) + 15);
- write(0x10);
- writeBytes(value, 1);
- } else if (value < 65536) {
- write((kind << 4) + 15);
- write(0x11);
- writeBytes(value, 2);
- } else {
- write((kind << 4) + 15);
- write(0x12);
- writeBytes(value, 4);
- }
- }
-
- void write(int b) throws IOException {
- out.write(b);
- count++;
- }
-
- void write(byte[] bytes) throws IOException {
- out.write(bytes);
- count += bytes.length;
- }
-
- void writeBytes(long value, int bytes) throws IOException {
- // write low-order bytes big-endian style
- for (int i = bytes - 1; i >= 0; i--) {
- write((int) (value >> (8 * i)));
- }
- }
-
- void writeID(int id) throws IOException {
- writeBytes(id, idSizeInBytes);
- }
-
- void writeLong(long value) throws IOException {
- writeBytes(value, 8);
- }
-
- void writeDouble(double value) throws IOException {
- writeLong(Double.doubleToRawLongBits(value));
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSArray.java b/third_party/java/dd_plist/java/com/dd/plist/NSArray.java
deleted file mode 100644
index a0b2a4d..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSArray.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-/**
- * Represents an Array.
- *
- * @author Daniel Dreibrodt
- */
-public class NSArray extends NSObject {
-
- private NSObject[] array;
-
- /**
- * Creates an empty array of the given length.
- *
- * @param length The number of elements this array will be able to hold.
- */
- public NSArray(int length) {
- array = new NSObject[length];
- }
-
- /**
- * Creates a array from an existing one
- *
- * @param a The array which should be wrapped by the NSArray
- */
- public NSArray(NSObject... a) {
- array = a;
- }
-
- /**
- * Returns the object stored at the given index.
- * Equivalent to <code>getArray()[i]</code>.
- *
- * @param i The index of the object.
- * @return The object at the given index.
- */
- public NSObject objectAtIndex(int i) {
- return array[i];
- }
-
- /**
- * Remove the i-th element from the array.
- * The array will be resized.
- *
- * @param i The index of the object
- */
- public void remove(int i) {
- if ((i >= array.length) || (i < 0))
- throw new ArrayIndexOutOfBoundsException("invalid index:" + i + ";the array length is " + array.length);
- NSObject[] newArray = new NSObject[array.length - 1];
- System.arraycopy(array, 0, newArray, 0, i);
- System.arraycopy(array, i + 1, newArray, i, array.length - i - 1);
- array = newArray;
- }
-
- /**
- * Stores an object at the specified index.
- * If there was another object stored at that index it will be replaced.
- * Equivalent to <code>getArray()[key] = value</code>.
- *
- * @param key The index where to store the object.
- * @param value The object.
- */
- public void setValue(int key, Object value) {
- array[key] = NSObject.wrap(value);
- }
-
- /**
- * Returns the array of NSObjects represented by this NSArray.
- * Any changes to the values of this array will also affect the NSArray.
- *
- * @return The actual array represented by this NSArray.
- */
- public NSObject[] getArray() {
- return array;
- }
-
- /**
- * Returns the size of the array.
- *
- * @return The number of elements that this array can store.
- */
- public int count() {
- return array.length;
- }
-
- /**
- * Checks whether an object is present in the array or whether it is equal
- * to any of the objects in the array.
- *
- * @param obj The object to look for.
- * @return <code>true</code>, when the object could be found. <code>false</code> otherwise.
- * @see Object#equals(java.lang.Object)
- */
- public boolean containsObject(Object obj) {
- NSObject nso = NSObject.wrap(obj);
- for (NSObject elem : array) {
- if(elem == null) {
- if(obj == null)
- return true;
- continue;
- }
- if (elem.equals(nso)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Searches for an object in the array. If it is found its index will be
- * returned. This method also returns an index if the object is not the same
- * as the one stored in the array but has equal contents.
- *
- * @param obj The object to look for.
- * @return The index of the object, if it was found. -1 otherwise.
- * @see Object#equals(java.lang.Object)
- * @see #indexOfIdenticalObject(Object)
- */
- public int indexOfObject(Object obj) {
- NSObject nso = NSObject.wrap(obj);
- for (int i = 0; i < array.length; i++) {
- if (array[i].equals(nso)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Searches for an object in the array. If it is found its index will be
- * returned. This method only returns the index of an object that is
- * <b>identical</b> to the given one. Thus objects that might contain the
- * same value as the given one will not be considered.
- *
- * @param obj The object to look for.
- * @return The index of the object, if it was found. -1 otherwise.
- * @see #indexOfObject(Object)
- */
- public int indexOfIdenticalObject(Object obj) {
- NSObject nso = NSObject.wrap(obj);
- for (int i = 0; i < array.length; i++) {
- if (array[i] == nso) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Returns the last object contained in this array.
- * Equivalent to <code>getArray()[getArray().length-1]</code>.
- *
- * @return The value of the highest index in the array.
- */
- public NSObject lastObject() {
- return array[array.length - 1];
- }
-
- /**
- * Returns a new array containing only the values stored at the given
- * indices. The values are sorted by their index.
- *
- * @param indexes The indices of the objects.
- * @return The new array containing the objects stored at the given indices.
- */
- public NSObject[] objectsAtIndexes(int... indexes) {
- NSObject[] result = new NSObject[indexes.length];
- Arrays.sort(indexes);
- for (int i = 0; i < indexes.length; i++)
- result[i] = array[indexes[i]];
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if(obj == null)
- return false;
- if(obj.getClass().equals(NSArray.class)) {
- return Arrays.equals(((NSArray) obj).getArray(), this.array);
- } else {
- NSObject nso = NSObject.wrap(obj);
- if(nso.getClass().equals(NSArray.class)) {
- return Arrays.equals(((NSArray) nso).getArray(), this.array);
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 89 * hash + Arrays.deepHashCode(this.array);
- return hash;
- }
-
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<array>");
- xml.append(NSObject.NEWLINE);
- for (NSObject o : array) {
- o.toXML(xml, level + 1);
- xml.append(NSObject.NEWLINE);
- }
- indent(xml, level);
- xml.append("</array>");
- }
-
- @Override
- void assignIDs(BinaryPropertyListWriter out) {
- super.assignIDs(out);
- for (NSObject obj : array) {
- obj.assignIDs(out);
- }
- }
-
- @Override
- void toBinary(BinaryPropertyListWriter out) throws IOException {
- out.writeIntHeader(0xA, array.length);
- for (NSObject obj : array) {
- out.writeID(out.getID(obj));
- }
- }
-
- /**
- * Generates a valid ASCII property list which has this NSArray as its
- * root object. The generated property list complies with the format as
- * described in <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/PropertyLists/OldStylePlists/OldStylePLists.html">
- * Property List Programming Guide - Old-Style ASCII Property Lists</a>.
- *
- * @return ASCII representation of this object.
- */
- public String toASCIIPropertyList() {
- StringBuilder ascii = new StringBuilder();
- toASCII(ascii, 0);
- ascii.append(NEWLINE);
- return ascii.toString();
- }
-
- /**
- * Generates a valid ASCII property list in GnuStep format which has this
- * NSArray as its root object. The generated property list complies with
- * the format as described in <a href="http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSPropertyList.html">
- * GnuStep - NSPropertyListSerialization class documentation
- * </a>
- *
- * @return GnuStep ASCII representation of this object.
- */
- public String toGnuStepASCIIPropertyList() {
- StringBuilder ascii = new StringBuilder();
- toASCIIGnuStep(ascii, 0);
- ascii.append(NEWLINE);
- return ascii.toString();
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.ARRAY_BEGIN_TOKEN);
- int indexOfLastNewLine = ascii.lastIndexOf(NEWLINE);
- for (int i = 0; i < array.length; i++) {
- Class<?> objClass = array[i].getClass();
- if ((objClass.equals(NSDictionary.class) || objClass.equals(NSArray.class) || objClass.equals(NSData.class))
- && indexOfLastNewLine != ascii.length()) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- array[i].toASCII(ascii, level + 1);
- } else {
- if (i != 0)
- ascii.append(" ");
- array[i].toASCII(ascii, 0);
- }
-
- if (i != array.length - 1)
- ascii.append(ASCIIPropertyListParser.ARRAY_ITEM_DELIMITER_TOKEN);
-
- if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- }
- }
- ascii.append(ASCIIPropertyListParser.ARRAY_END_TOKEN);
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.ARRAY_BEGIN_TOKEN);
- int indexOfLastNewLine = ascii.lastIndexOf(NEWLINE);
- for (int i = 0; i < array.length; i++) {
- Class<?> objClass = array[i].getClass();
- if ((objClass.equals(NSDictionary.class) || objClass.equals(NSArray.class) || objClass.equals(NSData.class))
- && indexOfLastNewLine != ascii.length()) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- array[i].toASCIIGnuStep(ascii, level + 1);
- } else {
- if (i != 0)
- ascii.append(" ");
- array[i].toASCIIGnuStep(ascii, 0);
- }
-
- if (i != array.length - 1)
- ascii.append(ASCIIPropertyListParser.ARRAY_ITEM_DELIMITER_TOKEN);
-
- if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- }
- }
- ascii.append(ASCIIPropertyListParser.ARRAY_END_TOKEN);
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSData.java b/third_party/java/dd_plist/java/com/dd/plist/NSData.java
deleted file mode 100644
index d156a2f..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSData.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * NSData objects are wrappers for byte buffers.
- *
- * @author Daniel Dreibrodt
- */
-public class NSData extends NSObject {
-
- private byte[] bytes;
-
- /**
- * Creates the NSData object from the binary representation of it.
- *
- * @param bytes The raw data contained in the NSData object.
- */
- public NSData(byte[] bytes) {
- this.bytes = bytes;
- }
-
- /**
- * Creates a NSData object from its textual representation, which is a Base64 encoded amount of bytes.
- *
- * @param base64 The Base64 encoded contents of the NSData object.
- * @throws IOException When the given string is not a proper Base64 formatted string.
- */
- public NSData(String base64) throws IOException {
- //Remove all white spaces from the string so that it is parsed completely
- //and not just until the first white space occurs.
- String data = base64.replaceAll("\\s+", "");
- bytes = Base64.decode(data);
- }
-
- /**
- * Creates a NSData object from a file. Using the files contents as the contents of this NSData object.
- *
- * @param file The file containing the data.
- * @throws FileNotFoundException If the file could not be found.
- * @throws IOException If the file could not be read.
- */
- public NSData(File file) throws IOException {
- bytes = new byte[(int) file.length()];
- RandomAccessFile raf = new RandomAccessFile(file, "r");
- raf.read(bytes);
- raf.close();
- }
-
- /**
- * The bytes contained in this NSData object.
- *
- * @return The data as bytes
- */
- public byte[] bytes() {
- return bytes;
- }
-
- /**
- * Gets the amount of data stored in this object.
- *
- * @return The number of bytes contained in this object.
- */
- public int length() {
- return bytes.length;
- }
-
- /**
- * Loads the bytes from this NSData object into a byte buffer
- *
- * @param buf The byte buffer which will contain the data
- * @param length The amount of data to copy
- */
- public void getBytes(ByteBuffer buf, int length) {
- buf.put(bytes, 0, Math.min(bytes.length, length));
- }
-
- /**
- * Loads the bytes from this NSData object into a byte buffer
- *
- * @param buf The byte buffer which will contain the data
- * @param rangeStart The start index
- * @param rangeStop The stop index
- */
- public void getBytes(ByteBuffer buf, int rangeStart, int rangeStop) {
- buf.put(bytes, rangeStart, Math.min(bytes.length, rangeStop));
- }
-
- /**
- * Gets the Base64 encoded data contained in this NSData object.
- *
- * @return The Base64 encoded data as a <code>String</code>.
- */
- public String getBase64EncodedData() {
- return Base64.encodeBytes(bytes);
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj.getClass().equals(getClass()) && Arrays.equals(((NSData) obj).bytes, bytes);
- }
-
- @Override
- public int hashCode() {
- int hash = 5;
- hash = 67 * hash + Arrays.hashCode(this.bytes);
- return hash;
- }
-
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<data>");
- xml.append(NSObject.NEWLINE);
- String base64 = getBase64EncodedData();
- for (String line : base64.split("\n")) {
- indent(xml, level + 1);
- xml.append(line);
- xml.append(NSObject.NEWLINE);
- }
- indent(xml, level);
- xml.append("</data>");
- }
-
- @Override
- void toBinary(BinaryPropertyListWriter out) throws IOException {
- out.writeIntHeader(0x4, bytes.length);
- out.write(bytes);
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.DATA_BEGIN_TOKEN);
- int indexOfLastNewLine = ascii.lastIndexOf(NEWLINE);
- for (int i = 0; i < bytes.length; i++) {
- int b = bytes[i] & 0xFF;
- if (b < 16)
- ascii.append("0");
- ascii.append(Integer.toHexString(b));
- if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- } else if ((i + 1) % 2 == 0 && i != bytes.length - 1) {
- ascii.append(" ");
- }
- }
- ascii.append(ASCIIPropertyListParser.DATA_END_TOKEN);
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- toASCII(ascii, level);
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSDate.java b/third_party/java/dd_plist/java/com/dd/plist/NSDate.java
deleted file mode 100644
index 0f4246c..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSDate.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011 Daniel Dreibrodt, Keith Randall
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * Represents a date.
- *
- * @author Daniel Dreibrodt
- */
-public class NSDate extends NSObject {
-
- private Date date;
-
- // EPOCH = new SimpleDateFormat("yyyy MM dd zzz").parse("2001 01 01 GMT").getTime();
- // ...but that's annoying in a static initializer because it can throw exceptions, ick.
- // So we just hardcode the correct value.
- private final static long EPOCH = 978307200000L;
-
- private static final SimpleDateFormat sdfDefault = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
- private static final SimpleDateFormat sdfGnuStep = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
-
- static {
- sdfDefault.setTimeZone(TimeZone.getTimeZone("GMT"));
- sdfGnuStep.setTimeZone(TimeZone.getTimeZone("GMT"));
- }
-
- /**
- * Parses the XML date string and creates a Java Date object from it.
- * This function is synchronized as SimpleDateFormat is not thread-safe.
- *
- * @param textRepresentation The date string as found in the XML property list
- * @return The parsed Date
- * @throws ParseException If the given string cannot be parsed.
- * @see SimpleDateFormat#parse(java.lang.String)
- */
- private static synchronized Date parseDateString(String textRepresentation) throws ParseException {
- try {
- return sdfDefault.parse(textRepresentation);
- } catch (ParseException ex) {
- return sdfGnuStep.parse(textRepresentation);
- }
- }
-
- /**
- * Generates a String representation of a Java Date object. The string
- * is formatted according to the specification for XML property list dates.
- *
- * @param date The date which should be represented.
- * @return The string representation of the date.
- */
- private static synchronized String makeDateString(Date date) {
- return sdfDefault.format(date);
- }
-
- /**
- * Generates a String representation of a Java Date object. The string
- * is formatted according to the specification for GnuStep ASCII property
- * list dates.
- *
- * @param date The date which should be represented.
- * @return The string representation of the date.
- */
- private static synchronized String makeDateStringGnuStep(Date date) {
- return sdfGnuStep.format(date);
- }
-
- /**
- * Creates a date from its binary representation.
- *
- * @param bytes The date bytes
- */
- public NSDate(byte[] bytes){
- this(bytes, 0, bytes.length);
- }
-
- /**
- * Creates a date from its binary representation.
- *
- * @param bytes byte array with all information
- * @param startIndex int with the starting index of the date
- * @param endIndex int with the end index of the date
- */
- public NSDate(byte[] bytes, final int startIndex, final int endIndex) {
- //dates are 8 byte big-endian double, seconds since the epoch
- date = new Date(EPOCH + (long) (1000 * BinaryPropertyListParser.parseDouble(bytes, startIndex, endIndex)));
- }
-
- /**
- * Parses a date from its textual representation.
- * That representation has the following pattern: <code>yyyy-MM-dd'T'HH:mm:ss'Z'</code>
- *
- * @param textRepresentation The textual representation of the date (ISO 8601 format)
- * @throws ParseException When the date could not be parsed, i.e. it does not match the expected pattern.
- */
- public NSDate(String textRepresentation) throws ParseException {
- date = parseDateString(textRepresentation);
- }
-
- /**
- * Creates a NSDate from a Java Date
- *
- * @param d The date
- */
- public NSDate(Date d) {
- if (d == null)
- throw new IllegalArgumentException("Date cannot be null");
- date = d;
- }
-
- /**
- * Gets the date.
- *
- * @return The date.
- */
- public Date getDate() {
- return date;
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj.getClass().equals(getClass()) && date.equals(((NSDate) obj).getDate());
- }
-
- @Override
- public int hashCode() {
- return date.hashCode();
- }
-
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<date>");
- xml.append(makeDateString(date));
- xml.append("</date>");
- }
-
- @Override
- public void toBinary(BinaryPropertyListWriter out) throws IOException {
- out.write(0x33);
- out.writeDouble((date.getTime() - EPOCH) / 1000.0);
- }
-
- /**
- * Generates a string representation of the date.
- *
- * @return A string representation of the date.
- * @see java.util.Date#toString()
- */
- @Override
- public String toString() {
- return date.toString();
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append("\"");
- ascii.append(makeDateString(date));
- ascii.append("\"");
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append("<*D");
- ascii.append(makeDateStringGnuStep(date));
- ascii.append(">");
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSDictionary.java b/third_party/java/dd_plist/java/com/dd/plist/NSDictionary.java
deleted file mode 100644
index 9beedbc..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSDictionary.java
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A NSDictionary is a collection of keys and values, essentially a Hashtable.
- * The keys are simple Strings whereas the values can be any kind of NSObject.
- *
- * You can access the keys through the function <code>allKeys()</code>. Access
- * to the objects stored for each key is given through the function
- * <code>objectoForKey(String key)</code>.
- *
- * @author Daniel Dreibrodt
- * @see java.util.Hashtable
- * @see com.dd.plist.NSObject
- */
-public class NSDictionary extends NSObject implements Map<String, NSObject> {
-
- private HashMap<String, NSObject> dict;
-
- /**
- * Creates a new empty NSDictionary.
- */
- public NSDictionary() {
- //With a linked HashMap the order of elements in the dictionary is kept.
- dict = new LinkedHashMap<String, NSObject>();
- }
-
- /**
- * Gets the hashmap which stores the keys and values of this dictionary.
- * Changes to the hashmap's contents are directly reflected in this
- * dictionary.
- *
- * @return The hashmap which is used by this dictionary to store its contents.
- */
- public HashMap<String, NSObject> getHashMap() {
- return dict;
- }
-
- /**
- * Gets the NSObject stored for the given key.
- *
- * @param key The key.
- * @return The object.
- */
- public NSObject objectForKey(String key) {
- return dict.get(key);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#size()
- */
- public int size() {
- return dict.size();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#isEmpty()
- */
- public boolean isEmpty() {
- return dict.isEmpty();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#containsKey(java.lang.Object)
- */
- public boolean containsKey(Object key) {
- return dict.containsKey(key);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#containsValue(java.lang.Object)
- */
- public boolean containsValue(Object value) {
- if(value == null)
- return false;
- NSObject wrap = NSObject.wrap(value);
- return dict.containsValue(wrap);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#get(java.lang.Object)
- */
- public NSObject get(Object key) {
- return dict.get(key);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#putAll(java.util.Map)
- */
- public void putAll(Map<? extends String, ? extends NSObject> values) {
- for (Object object : values.entrySet()) {
- @SuppressWarnings("unchecked")
- Map.Entry<String, NSObject> entry = (Map.Entry<String, NSObject>) object;
- put(entry.getKey(), entry.getValue());
- }
- }
-
- /**
- * Puts a new key-value pair into this dictionary.
- * If the value is null, no operation will be performed on the dictionary.
- *
- * @param key The key.
- * @param obj The value.
- * @return The value previously associated to the given key,
- * or null, if no value was associated to it.
- */
- public NSObject put(String key, NSObject obj) {
- if(key == null)
- return null;
- if(obj == null)
- return dict.get(key);
- return dict.put(key, obj);
- }
-
- /**
- * Puts a new key-value pair into this dictionary.
- * If key or value are null, no operation will be performed on the dictionary.
- *
- * @param key The key.
- * @param obj The value. Supported object types are numbers, byte-arrays, dates, strings and arrays or sets of those.
- * @return The value previously associated to the given key,
- * or null, if no value was associated to it.
- */
- public NSObject put(String key, Object obj) {
- return put(key, NSObject.wrap(obj));
- }
-
- /**
- * Removes a key-value pair from this dictionary.
- *
- * @param key The key
- * @return the value previously associated to the given key.
- */
- public NSObject remove(String key) {
- return dict.remove(key);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#remove(java.lang.Object)
- */
- public NSObject remove(Object key) {
- return dict.remove(key);
- }
-
- /**
- * Removes all key-value pairs from this dictionary.
- * @see java.util.Map#clear()
- */
- public void clear() {
- dict.clear();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#keySet()
- */
- public Set<String> keySet() {
- return dict.keySet();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#values()
- */
- public Collection<NSObject> values() {
- return dict.values();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.util.Map#entrySet()
- */
- public Set<Entry<String, NSObject>> entrySet() {
- return dict.entrySet();
- }
-
- /**
- * Checks whether a given key is contained in this dictionary.
- *
- * @param key The key that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsKey(String key) {
- return dict.containsKey(key);
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(NSObject val) {
- return val != null && dict.containsValue(val);
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(String val) {
- for (NSObject o : dict.values()) {
- if (o.getClass().equals(NSString.class)) {
- NSString str = (NSString) o;
- if (str.getContent().equals(val))
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(long val) {
- for (NSObject o : dict.values()) {
- if (o.getClass().equals(NSNumber.class)) {
- NSNumber num = (NSNumber) o;
- if (num.isInteger() && num.intValue() == val)
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(double val) {
- for (NSObject o : dict.values()) {
- if (o.getClass().equals(NSNumber.class)) {
- NSNumber num = (NSNumber) o;
- if (num.isReal() && num.doubleValue() == val)
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(boolean val) {
- for (NSObject o : dict.values()) {
- if (o.getClass().equals(NSNumber.class)) {
- NSNumber num = (NSNumber) o;
- if (num.isBoolean() && num.boolValue() == val)
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(Date val) {
- for (NSObject o : dict.values()) {
- if (o.getClass().equals(NSDate.class)) {
- NSDate dat = (NSDate) o;
- if (dat.getDate().equals(val))
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether a given value is contained in this dictionary.
- *
- * @param val The value that will be searched for.
- * @return Whether the key is contained in this dictionary.
- */
- public boolean containsValue(byte[] val) {
- for (NSObject o : dict.values()) {
- if (o.getClass().equals(NSData.class)) {
- NSData dat = (NSData) o;
- if (Arrays.equals(dat.bytes(), val))
- return true;
- }
- }
- return false;
- }
-
- /**
- * Counts the number of contained key-value pairs.
- *
- * @return The size of this NSDictionary.
- */
- public int count() {
- return dict.size();
- }
-
- @Override
- public boolean equals(Object obj) {
- return (obj.getClass().equals(this.getClass()) && ((NSDictionary) obj).dict.equals(dict));
- }
-
- /**
- * Gets a list of all keys used in this NSDictionary.
- *
- * @return The list of all keys used in this NSDictionary.
- */
- public String[] allKeys() {
- return dict.keySet().toArray(new String[count()]);
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 83 * hash + (this.dict != null ? this.dict.hashCode() : 0);
- return hash;
- }
-
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<dict>");
- xml.append(NSObject.NEWLINE);
- for (String key : dict.keySet()) {
- NSObject val = objectForKey(key);
- indent(xml, level + 1);
- xml.append("<key>");
- //According to http://www.w3.org/TR/REC-xml/#syntax node values must not
- //contain the characters < or &. Also the > character should be escaped.
- if (key.contains("&") || key.contains("<") || key.contains(">")) {
- xml.append("<![CDATA[");
- xml.append(key.replaceAll("]]>", "]]]]><![CDATA[>"));
- xml.append("]]>");
- } else {
- xml.append(key);
- }
- xml.append("</key>");
- xml.append(NSObject.NEWLINE);
- val.toXML(xml, level + 1);
- xml.append(NSObject.NEWLINE);
- }
- indent(xml, level);
- xml.append("</dict>");
- }
-
- @Override
- void assignIDs(BinaryPropertyListWriter out) {
- super.assignIDs(out);
- for (Map.Entry<String, NSObject> entry : dict.entrySet()) {
- new NSString(entry.getKey()).assignIDs(out);
- }
- for (Map.Entry<String, NSObject> entry : dict.entrySet()) {
- entry.getValue().assignIDs(out);
- }
- }
-
- @Override
- void toBinary(BinaryPropertyListWriter out) throws IOException {
- out.writeIntHeader(0xD, dict.size());
- Set<Map.Entry<String, NSObject>> entries = dict.entrySet();
- for (Map.Entry<String, NSObject> entry : entries) {
- out.writeID(out.getID(new NSString(entry.getKey())));
- }
- for (Map.Entry<String, NSObject> entry : entries) {
- out.writeID(out.getID(entry.getValue()));
- }
- }
-
- /**
- * Generates a valid ASCII property list which has this NSDictionary as its
- * root object. The generated property list complies with the format as
- * described in <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/PropertyLists/OldStylePlists/OldStylePLists.html">
- * Property List Programming Guide - Old-Style ASCII Property Lists</a>.
- *
- * @return ASCII representation of this object.
- */
- public String toASCIIPropertyList() {
- StringBuilder ascii = new StringBuilder();
- toASCII(ascii, 0);
- ascii.append(NEWLINE);
- return ascii.toString();
- }
-
- /**
- * Generates a valid ASCII property list in GnuStep format which has this
- * NSDictionary as its root object. The generated property list complies with
- * the format as described in <a href="http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSPropertyList.html">
- * GnuStep - NSPropertyListSerialization class documentation
- * </a>
- *
- * @return GnuStep ASCII representation of this object.
- */
- public String toGnuStepASCIIPropertyList() {
- StringBuilder ascii = new StringBuilder();
- toASCIIGnuStep(ascii, 0);
- ascii.append(NEWLINE);
- return ascii.toString();
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.DICTIONARY_BEGIN_TOKEN);
- ascii.append(NEWLINE);
- String[] keys = allKeys();
- for (String key : keys) {
- NSObject val = objectForKey(key);
- indent(ascii, level + 1);
- ascii.append("\"");
- ascii.append(NSString.escapeStringForASCII(key));
- ascii.append("\" =");
- Class<?> objClass = val.getClass();
- if (objClass.equals(NSDictionary.class) || objClass.equals(NSArray.class) || objClass.equals(NSData.class)) {
- ascii.append(NEWLINE);
- val.toASCII(ascii, level + 2);
- } else {
- ascii.append(" ");
- val.toASCII(ascii, 0);
- }
- ascii.append(ASCIIPropertyListParser.DICTIONARY_ITEM_DELIMITER_TOKEN);
- ascii.append(NEWLINE);
- }
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.DICTIONARY_END_TOKEN);
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.DICTIONARY_BEGIN_TOKEN);
- ascii.append(NEWLINE);
- String[] keys = dict.keySet().toArray(new String[dict.size()]);
- for (String key : keys) {
- NSObject val = objectForKey(key);
- indent(ascii, level + 1);
- ascii.append("\"");
- ascii.append(NSString.escapeStringForASCII(key));
- ascii.append("\" =");
- Class<?> objClass = val.getClass();
- if (objClass.equals(NSDictionary.class) || objClass.equals(NSArray.class) || objClass.equals(NSData.class)) {
- ascii.append(NEWLINE);
- val.toASCIIGnuStep(ascii, level + 2);
- } else {
- ascii.append(" ");
- val.toASCIIGnuStep(ascii, 0);
- }
- ascii.append(ASCIIPropertyListParser.DICTIONARY_ITEM_DELIMITER_TOKEN);
- ascii.append(NEWLINE);
- }
- indent(ascii, level);
- ascii.append(ASCIIPropertyListParser.DICTIONARY_END_TOKEN);
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSNumber.java b/third_party/java/dd_plist/java/com/dd/plist/NSNumber.java
deleted file mode 100644
index fab7d28..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSNumber.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011 Daniel Dreibrodt, Keith Randall
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.IOException;
-
-/**
- * A number whose value is either an integer, a real number or boolean.
- *
- * @author Daniel Dreibrodt
- */
-public class NSNumber extends NSObject implements Comparable<Object> {
-
- /**
- * Indicates that the number's value is an integer.
- * The number is stored as a Java <code>long</code>.
- * Its original value could have been char, short, int, long or even long long.
- */
- public static final int INTEGER = 0;
-
- /**
- * Indicates that the number's value is a real number.
- * The number is stored as a Java <code>double</code>.
- * Its original value could have been float or double.
- */
- public static final int REAL = 1;
-
- /**
- * Indicates that the number's value is boolean.
- */
- public static final int BOOLEAN = 2;
-
- //Holds the current type of this number
- private int type;
-
- private long longValue;
- private double doubleValue;
- private boolean boolValue;
-
- /**
- * Parses integers and real numbers from their binary representation.
- * <i>Note: real numbers are not yet supported.</i>
- *
- * @param bytes The binary representation of only this number
- * @param type The type of number
- * @see #INTEGER
- * @see #REAL
- */
- public NSNumber(byte[] bytes, int type){
- this(bytes, 0, bytes.length, type);
- }
-
- /**
- * Parses integers and real numbers from their binary representation.
- * <i>Note: real numbers are not yet supported.</i>
- *
- * @param bytes array of bytes that contains this number's binary representation
- * @param startIndex int with the position where to start reading from the byte array
- * @param endIndex int with the position where to end reading from the byte array
- * @param type The type of number
- * @see #INTEGER
- * @see #REAL
- */
- public NSNumber(byte[] bytes, final int startIndex, final int endIndex, final int type){
- switch (type) {
- case INTEGER: {
- doubleValue = longValue = BinaryPropertyListParser.parseLong(bytes, startIndex, endIndex);
- break;
- }
- case REAL: {
- doubleValue = BinaryPropertyListParser.parseDouble(bytes, startIndex, endIndex);
- longValue = Math.round(doubleValue);
- break;
- }
- default: {
- throw new IllegalArgumentException("Type argument is not valid.");
- }
- }
- this.type = type;
- }
-
- /**
- * Creates a number from its textual representation.
- *
- * @param text The textual representation of the number.
- * @throws IllegalArgumentException If the text does not represent an integer, real number or boolean value.
- * @see Boolean#parseBoolean(java.lang.String)
- * @see Long#parseLong(java.lang.String)
- * @see Double#parseDouble(java.lang.String)
- */
- public NSNumber(String text) {
- if (text == null)
- throw new IllegalArgumentException("The given string is null and cannot be parsed as number.");
- try {
- long l = Long.parseLong(text);
- doubleValue = longValue = l;
- type = INTEGER;
- } catch (Exception ex) {
- try {
- doubleValue = Double.parseDouble(text);
- longValue = Math.round(doubleValue);
- type = REAL;
- } catch (Exception ex2) {
- try {
- boolValue = text.toLowerCase().equals("true") || text.toLowerCase().equals("yes");
- if(!boolValue && !(text.toLowerCase().equals("false") || text.toLowerCase().equals("no"))) {
- throw new Exception("not a boolean");
- }
- type = BOOLEAN;
- doubleValue = longValue = boolValue ? 1 : 0;
- } catch (Exception ex3) {
- throw new IllegalArgumentException("The given string neither represents a double, an int nor a boolean value.");
- }
- }
- }
- }
-
- /**
- * Creates an integer number.
- *
- * @param i The integer value.
- */
- public NSNumber(int i) {
- doubleValue = longValue = i;
- type = INTEGER;
- }
-
- /**
- * Creates an integer number.
- *
- * @param l The long integer value.
- */
- public NSNumber(long l) {
- doubleValue = longValue = l;
- type = INTEGER;
- }
-
- /**
- * Creates a real number.
- *
- * @param d The real value.
- */
- public NSNumber(double d) {
- longValue = (long) (doubleValue = d);
- type = REAL;
- }
-
- /**
- * Creates a boolean number.
- *
- * @param b The boolean value.
- */
- public NSNumber(boolean b) {
- boolValue = b;
- doubleValue = longValue = b ? 1 : 0;
- type = BOOLEAN;
- }
-
- /**
- * Gets the type of this number's value.
- *
- * @return The type flag.
- * @see #BOOLEAN
- * @see #INTEGER
- * @see #REAL
- */
- public int type() {
- return type;
- }
-
- /**
- * Checks whether the value of this NSNumber is a boolean.
- *
- * @return Whether the number's value is a boolean.
- */
- public boolean isBoolean() {
- return type == BOOLEAN;
- }
-
- /**
- * Checks whether the value of this NSNumber is an integer.
- *
- * @return Whether the number's value is an integer.
- */
- public boolean isInteger() {
- return type == INTEGER;
- }
-
- /**
- * Checks whether the value of this NSNumber is a real number.
- *
- * @return Whether the number's value is a real number.
- */
- public boolean isReal() {
- return type == REAL;
- }
-
- /**
- * The number's boolean value.
- *
- * @return <code>true</code> if the value is true or non-zero, <code>false</code> otherwise.
- */
- public boolean boolValue() {
- if (type == BOOLEAN)
- return boolValue;
- else
- return longValue != 0;
- }
-
- /**
- * The number's long value.
- *
- * @return The value of the number as long
- */
- public long longValue() {
- return longValue;
- }
-
- /**
- * The number's int value.
- * <i>Note: Even though the number's type might be INTEGER it can be larger than a Java int.
- * Use intValue() only if you are certain that it contains a number from the int range.
- * Otherwise the value might be innaccurate.</i>
- *
- * @return The value of the number as int
- */
- public int intValue() {
- return (int) longValue;
- }
-
- /**
- * The number's double value.
- *
- * @return The value of the number as double.
- */
- public double doubleValue() {
- return doubleValue;
- }
-
- /**
- * The number's float value.
- * WARNING: Possible loss of precision if the value is outside the float range.
- *
- * @return The value of the number as float.
- */
- public float floatValue() {
- return (float) doubleValue;
- }
-
- /**
- * Checks whether the other object is a NSNumber of the same value.
- *
- * @param obj The object to compare to.
- * @return Whether the objects are equal in terms of numeric value and type.
- */
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof NSNumber)) return false;
- NSNumber n = (NSNumber) obj;
- return type == n.type && longValue == n.longValue && doubleValue == n.doubleValue && boolValue == n.boolValue;
- }
-
- @Override
- public int hashCode() {
- int hash = type;
- hash = 37 * hash + (int) (this.longValue ^ (this.longValue >>> 32));
- hash = 37 * hash + (int) (Double.doubleToLongBits(this.doubleValue) ^ (Double.doubleToLongBits(this.doubleValue) >>> 32));
- hash = 37 * hash + (boolValue() ? 1 : 0);
- return hash;
- }
-
-
- @Override
- public String toString() {
- switch (type) {
- case INTEGER: {
- return String.valueOf(longValue());
- }
- case REAL: {
- return String.valueOf(doubleValue());
- }
- case BOOLEAN: {
- return String.valueOf(boolValue());
- }
- default: {
- return super.toString();
- }
- }
- }
-
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- switch (type) {
- case INTEGER: {
- xml.append("<integer>");
- xml.append(longValue());
- xml.append("</integer>");
- break;
- }
- case REAL: {
- xml.append("<real>");
- xml.append(doubleValue());
- xml.append("</real>");
- break;
- }
- case BOOLEAN: {
- if (boolValue())
- xml.append("<true/>");
- else
- xml.append("<false/>");
- break;
- }
- }
- }
-
- @Override
- void toBinary(BinaryPropertyListWriter out) throws IOException {
- switch (type()) {
- case INTEGER: {
- if (longValue() < 0) {
- out.write(0x13);
- out.writeBytes(longValue(), 8);
- } else if (longValue() <= 0xff) {
- out.write(0x10);
- out.writeBytes(longValue(), 1);
- } else if (longValue() <= 0xffff) {
- out.write(0x11);
- out.writeBytes(longValue(), 2);
- } else if (longValue() <= 0xffffffffL) {
- out.write(0x12);
- out.writeBytes(longValue(), 4);
- } else {
- out.write(0x13);
- out.writeBytes(longValue(), 8);
- }
- break;
- }
- case REAL: {
- out.write(0x23);
- out.writeDouble(doubleValue());
- break;
- }
- case BOOLEAN: {
- out.write(boolValue() ? 0x09 : 0x08);
- break;
- }
- }
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- if (type == BOOLEAN) {
- ascii.append(boolValue ? "YES" : "NO");
- } else {
- ascii.append(toString());
- }
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- indent(ascii, level);
- switch (type) {
- case INTEGER: {
- ascii.append("<*I");
- ascii.append(toString());
- ascii.append(">");
- break;
- }
- case REAL: {
- ascii.append("<*R");
- ascii.append(toString());
- ascii.append(">");
- break;
- }
- case BOOLEAN: {
- if (boolValue) {
- ascii.append("<*BY>");
- } else {
- ascii.append("<*BN>");
- }
- }
- }
- }
-
- public int compareTo(Object o) {
- double x = doubleValue();
- double y;
- if (o instanceof NSNumber) {
- NSNumber num = (NSNumber) o;
- y = num.doubleValue();
- return (x < y) ? -1 : ((x == y) ? 0 : 1);
- } else if (o instanceof Number) {
- y = ((Number) o).doubleValue();
- return (x < y) ? -1 : ((x == y) ? 0 : 1);
- } else {
- return -1;
- }
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSObject.java b/third_party/java/dd_plist/java/com/dd/plist/NSObject.java
deleted file mode 100644
index b2c3cf0..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSObject.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2014 Daniel Dreibrodt
- *
-* Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.util.*;
-
-/**
- * Abstract interface for any object contained in a property list.
- * The names and functions of the various objects orient themselves
- * towards Apple's Cocoa API.
- *
- * @author Daniel Dreibrodt
- */
-public abstract class NSObject {
-
- /**
- * The newline character used for generating the XML output.
- * This constant will be different depending on the operating system on
- * which you use this library.
- */
- final static String NEWLINE = System.getProperty("line.separator");
-
- /**
- * The identation character used for generating the XML output. This is the
- * tabulator character.
- */
- final static String INDENT = "\t";
-
- /**
- * The maximum length of the text lines to be used when generating
- * ASCII property lists. But this number is only a guideline it is not
- * guaranteed that it will not be overstepped.
- */
- final static int ASCII_LINE_LENGTH = 80;
-
- /**
- * Generates the XML representation of the object (without XML headers or enclosing plist-tags).
- *
- * @param xml The StringBuilder onto which the XML representation is appended.
- * @param level The indentation level of the object.
- */
- abstract void toXML(StringBuilder xml, int level);
-
- /**
- * Assigns IDs to all the objects in this NSObject subtree.
- *
- * @param out The writer object that handles the binary serialization.
- */
- void assignIDs(BinaryPropertyListWriter out) {
- out.assignID(this);
- }
-
- /**
- * Generates the binary representation of the object.
- *
- * @param out The output stream to serialize the object to.
- * @throws java.io.IOException When an IO error occurs while writing to the stream or the object structure contains
- * data that cannot be saved.
- */
- abstract void toBinary(BinaryPropertyListWriter out) throws IOException;
-
- /**
- * Generates a valid XML property list including headers using this object as root.
- *
- * @return The XML representation of the property list including XML header and doctype information.
- */
- public String toXMLPropertyList() {
- StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- xml.append(NSObject.NEWLINE);
- xml.append("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
- xml.append(NSObject.NEWLINE);
- xml.append("<plist version=\"1.0\">");
- xml.append(NSObject.NEWLINE);
- toXML(xml, 0);
- xml.append(NSObject.NEWLINE);
- xml.append("</plist>");
- return xml.toString();
- }
-
- /**
- * Generates the ASCII representation of this object.
- * The generated ASCII representation does not end with a newline.
- * Complies with https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/PropertyLists/OldStylePlists/OldStylePLists.html
- *
- * @param ascii The StringBuilder onto which the ASCII representation is appended.
- * @param level The indentation level of the object.
- */
- protected abstract void toASCII(StringBuilder ascii, int level);
-
- /**
- * Generates the ASCII representation of this object in the GnuStep format.
- * The generated ASCII representation does not end with a newline.
- *
- * @param ascii The StringBuilder onto which the ASCII representation is appended.
- * @param level The indentation level of the object.
- */
- protected abstract void toASCIIGnuStep(StringBuilder ascii, int level);
-
- /**
- * Helper method that adds correct identation to the xml output.
- * Calling this method will add <code>level</code> number of tab characters
- * to the <code>xml</code> string.
- *
- * @param xml The string builder for the XML document.
- * @param level The level of identation.
- */
- void indent(StringBuilder xml, int level) {
- for (int i = 0; i < level; i++)
- xml.append(INDENT);
- }
-
- /**
- * Wraps the given value inside a NSObject.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- */
- public static NSNumber wrap(long value) {
- return new NSNumber(value);
- }
-
- /**
- * Wraps the given value inside a NSObject.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- */
- public static NSNumber wrap(double value) {
- return new NSNumber(value);
- }
-
- /**
- * Wraps the given value inside a NSObject.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- */
- public static NSNumber wrap(boolean value) {
- return new NSNumber(value);
- }
-
- /**
- * Wraps the given value inside a NSObject.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- */
- public static NSData wrap(byte[] value) {
- return new NSData(value);
- }
-
- /**
- * Creates a NSArray with the contents of the given array.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- * @throws RuntimeException When one of the objects contained in the array cannot be represented by a NSObject.
- */
- public static NSArray wrap(Object[] value) {
- NSArray arr = new NSArray(value.length);
- for (int i = 0; i < value.length; i++) {
- arr.setValue(i, wrap(value[i]));
- }
- return arr;
- }
-
- /**
- * Creates a NSDictionary with the contents of the given map.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- * @throws RuntimeException When one of the values contained in the map cannot be represented by a NSObject.
- */
- public static NSDictionary wrap(Map<String, Object> value) {
- NSDictionary dict = new NSDictionary();
- for (String key : value.keySet())
- dict.put(key, wrap(value.get(key)));
- return dict;
- }
-
- /**
- * Creates a NSSet with the contents of this set.
- *
- * @param value The value to represent as a NSObject.
- * @return A NSObject representing the given value.
- * @throws RuntimeException When one of the values contained in the set cannot be represented by a NSObject.
- */
- public static NSSet wrap(Set<Object> value) {
- NSSet set = new NSSet();
- for (Object o : value.toArray())
- set.addObject(wrap(o));
- return set;
- }
-
- /**
- * Creates a NSObject representing the given Java Object.
- *
- * Numerics of type bool, int, long, short, byte, float or double are wrapped as NSNumber objects.
- *
- * Strings are wrapped as NSString objects abd byte arrays as NSData objects.
- *
- * Date objects are wrapped as NSDate objects.
- *
- * Serializable classes are serialized and their data is stored in NSData objects.
- *
- * Arrays and Collection objects are converted to NSArrays where each array member is wrapped into a NSObject.
- *
- * Map objects are converted to NSDictionaries. Each key is converted to a string and each value wrapped into a NSObject.
- *
- * @param o The object to represent.
- * @return A NSObject equivalent to the given object.
- */
- public static NSObject wrap(Object o) {
- if(o == null)
- return null;
-
- if(o instanceof NSObject)
- return (NSObject)o;
-
- Class<?> c = o.getClass();
- if (Boolean.class.equals(c)) {
- return wrap((boolean) (Boolean) o);
- }
- if (Byte.class.equals(c)) {
- return wrap((int) (Byte) o);
- }
- if (Short.class.equals(c)) {
- return wrap((int) (Short) o);
- }
- if (Integer.class.equals(c)) {
- return wrap((int) (Integer) o);
- }
- if (Long.class.isAssignableFrom(c)) {
- return wrap((long) (Long) o);
- }
- if (Float.class.equals(c)) {
- return wrap((double) (Float) o);
- }
- if (Double.class.isAssignableFrom(c)) {
- return wrap((double) (Double) o);
- }
- if (String.class.equals(c)) {
- return new NSString((String)o);
- }
- if (Date.class.equals(c)) {
- return new NSDate((Date)o);
- }
- if(c.isArray()) {
- Class<?> cc = c.getComponentType();
- if (cc.equals(byte.class)) {
- return wrap((byte[]) o);
- }
- else if(cc.equals(boolean.class)) {
- boolean[] array = (boolean[])o;
- NSArray nsa = new NSArray(array.length);
- for(int i=0;i<array.length;i++)
- nsa.setValue(i, wrap(array[i]));
- return nsa;
- }
- else if(float.class.equals(cc)) {
- float[] array = (float[])o;
- NSArray nsa = new NSArray(array.length);
- for(int i=0;i<array.length;i++)
- nsa.setValue(i, wrap(array[i]));
- return nsa;
- }
- else if(double.class.equals(cc)) {
- double[] array = (double[])o;
- NSArray nsa = new NSArray(array.length);
- for(int i=0;i<array.length;i++)
- nsa.setValue(i, wrap(array[i]));
- return nsa;
- }
- else if(short.class.equals(cc)) {
- short[] array = (short[])o;
- NSArray nsa = new NSArray(array.length);
- for(int i=0;i<array.length;i++)
- nsa.setValue(i, wrap(array[i]));
- return nsa;
- }
- else if(int.class.equals(cc)) {
- int[] array = (int[])o;
- NSArray nsa = new NSArray(array.length);
- for(int i=0;i<array.length;i++)
- nsa.setValue(i, wrap(array[i]));
- return nsa;
- }
- else if(long.class.equals(cc)) {
- long[] array = (long[])o;
- NSArray nsa = new NSArray(array.length);
- for(int i=0;i<array.length;i++)
- nsa.setValue(i, wrap(array[i]));
- return nsa;
- }
- else {
- return wrap((Object[]) o);
- }
- }
- if (Map.class.isAssignableFrom(c)) {
- Map map = (Map)o;
- Set keys = map.keySet();
- NSDictionary dict = new NSDictionary();
- for(Object key:keys) {
- Object val = map.get(key);
- dict.put(String.valueOf(key), wrap(val));
- }
- return dict;
- }
- if (Collection.class.isAssignableFrom(c)) {
- Collection coll = (Collection)o;
- return wrap(coll.toArray());
- }
- return wrapSerialized(o);
- }
-
- /**
- * Serializes the given object using Java's default object serialization
- * and wraps the serialized object in a NSData object.
- *
- * @param o The object to serialize and wrap.
- * @return A NSData object
- * @throws RuntimeException When the object could not be serialized.
- */
- public static NSData wrapSerialized(Object o) {
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(o);
- return new NSData(baos.toByteArray());
- } catch (IOException ex) {
- throw new RuntimeException("The given object of class " + o.getClass().toString() + " could not be serialized and stored in a NSData object.");
- }
- }
-
- /**
- * Converts this NSObject into an equivalent object
- * of the Java Runtime Environment.
- * <ul>
- * <li>NSArray objects are converted to arrays.</li>
- * <li>NSDictionary objects are converted to objects extending the java.util.Map class.</li>
- * <li>NSSet objects are converted to objects extending the java.util.Set class.</li>
- * <li>NSNumber objects are converted to primitive number values (int, long, double or boolean).</li>
- * <li>NSString objects are converted to String objects.</li>
- * <li>NSData objects are converted to byte arrays.</li>
- * <li>NSDate objects are converted to java.util.Date objects.</li>
- * <li>UID objects are converted to byte arrays.</li>
- * </ul>
- * @return A native java object representing this NSObject's value.
- */
- public Object toJavaObject() {
- if(this instanceof NSArray) {
- NSObject[] arrayA = ((NSArray)this).getArray();
- Object[] arrayB = new Object[arrayA.length];
- for(int i = 0; i < arrayA.length; i++) {
- arrayB[i] = arrayA[i].toJavaObject();
- }
- return arrayB;
- } else if (this instanceof NSDictionary) {
- HashMap<String, NSObject> hashMapA = ((NSDictionary)this).getHashMap();
- HashMap<String, Object> hashMapB = new HashMap<String, Object>(hashMapA.size());
- for(String key:hashMapA.keySet()) {
- hashMapB.put(key, hashMapA.get(key).toJavaObject());
- }
- return hashMapB;
- } else if(this instanceof NSSet) {
- Set<NSObject> setA = ((NSSet)this).getSet();
- Set<Object> setB;
- if(setA instanceof LinkedHashSet) {
- setB = new LinkedHashSet<Object>(setA.size());
- } else {
- setB = new TreeSet<Object>();
- }
- for(NSObject o:setA) {
- setB.add(o.toJavaObject());
- }
- return setB;
- } else if(this instanceof NSNumber) {
- NSNumber num = (NSNumber)this;
- switch(num.type()) {
- case NSNumber.INTEGER : {
- long longVal = num.longValue();
- if(longVal > Integer.MAX_VALUE || longVal < Integer.MIN_VALUE) {
- return longVal;
- } else {
- return num.intValue();
- }
- }
- case NSNumber.REAL : {
- return num.doubleValue();
- }
- case NSNumber.BOOLEAN : {
- return num.boolValue();
- }
- default : {
- return num.doubleValue();
- }
- }
- } else if(this instanceof NSString) {
- return ((NSString)this).getContent();
- } else if(this instanceof NSData) {
- return ((NSData)this).bytes();
- } else if(this instanceof NSDate) {
- return ((NSDate)this).getDate();
- } else if(this instanceof UID) {
- return ((UID)this).getBytes();
- } else {
- return this;
- }
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSSet.java b/third_party/java/dd_plist/java/com/dd/plist/NSSet.java
deleted file mode 100644
index 6e43151..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSSet.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- * A set is an interface to an unordered collection of objects.
- * This implementation uses a <code>LinkedHashSet</code> or <code>TreeSet</code>as the underlying
- * data structure.
- *
- * @author Daniel Dreibrodt
- * @see LinkedHashSet
- */
-public class NSSet extends NSObject {
-
- private Set<NSObject> set;
-
- private boolean ordered = false;
-
- /**
- * Creates an empty unordered set.
- *
- * @see java.util.LinkedHashSet
- */
- public NSSet() {
- set = new LinkedHashSet<NSObject>();
- }
-
- /**
- * Creates an empty set.
- *
- * @param ordered Indicates whether the created set should be ordered or unordered.
- * @see java.util.LinkedHashSet
- * @see java.util.TreeSet
- */
- public NSSet(boolean ordered) {
- this.ordered = ordered;
- if (!ordered)
- set = new LinkedHashSet<NSObject>();
- else
- set = new TreeSet<NSObject>();
- }
-
- /**
- * Create a set and fill it with the given objects.
- *
- * @param objects The objects to populate the set.
- * @see java.util.LinkedHashSet
- */
- public NSSet(NSObject... objects) {
- set = new LinkedHashSet<NSObject>();
- set.addAll(Arrays.asList(objects));
- }
-
- /**
- * Create a set and fill it with the given objects.
- *
- * @param ordered Indicates whether the created set should be ordered or unordered.
- * @param objects The objects to populate the set.
- * @see java.util.LinkedHashSet
- * @see java.util.TreeSet
- */
- public NSSet(boolean ordered, NSObject... objects) {
- this.ordered = ordered;
- if (!ordered)
- set = new LinkedHashSet<NSObject>();
- else
- set = new TreeSet<NSObject>();
- set.addAll(Arrays.asList(objects));
- }
-
- /**
- * Adds an object to the set.
- *
- * @param obj The object to add.
- */
- public synchronized void addObject(NSObject obj) {
- set.add(obj);
- }
-
- /**
- * Removes an object from the set.
- *
- * @param obj The object to remove.
- */
- public synchronized void removeObject(NSObject obj) {
- set.remove(obj);
- }
-
- /**
- * Returns all objects contained in the set.
- *
- * @return An array of all objects in the set.
- */
- public synchronized NSObject[] allObjects() {
- return set.toArray(new NSObject[count()]);
- }
-
- /**
- * Returns one of the objects in the set, or <code>null</code>
- * if the set contains no objects.
- *
- * @return The first object in the set, or <code>null</code> if the set is empty.
- */
- public synchronized NSObject anyObject() {
- if (set.isEmpty())
- return null;
- else
- return set.iterator().next();
- }
-
- /**
- * Finds out whether a given object is contained in the set.
- *
- * @param obj The object to look for.
- * @return <code>true</code>, when the object was found, <code>false</code> otherwise.
- */
- public boolean containsObject(NSObject obj) {
- return set.contains(obj);
- }
-
- /**
- * Determines whether the set contains an object equal to a given object
- * and returns that object if it is present.
- *
- * @param obj The object to look for.
- * @return The object if it is present, <code>null</code> otherwise.
- */
- public synchronized NSObject member(NSObject obj) {
- for (NSObject o : set) {
- if (o.equals(obj))
- return o;
- }
- return null;
- }
-
- /**
- * Finds out whether at least one object is present in both sets.
- *
- * @param otherSet The other set.
- * @return <code>false</code> if the intersection of both sets is empty, <code>true</code> otherwise.
- */
- public synchronized boolean intersectsSet(NSSet otherSet) {
- for (NSObject o : set) {
- if (otherSet.containsObject(o))
- return true;
- }
- return false;
- }
-
- /**
- * Finds out if this set is a subset of the given set.
- *
- * @param otherSet The other set.
- * @return <code>true</code> if all elements in this set are also present in the other set, <code>false</code> otherwise.
- */
- public synchronized boolean isSubsetOfSet(NSSet otherSet) {
- for (NSObject o : set) {
- if (!otherSet.containsObject(o))
- return false;
- }
- return true;
- }
-
- /**
- * Returns an iterator object that lets you iterate over all elements of the set.
- * This is the equivalent to <code>objectEnumerator</code> in the Cocoa implementation
- * of NSSet.
- *
- * @return The iterator for the set.
- */
- public synchronized Iterator<NSObject> objectIterator() {
- return set.iterator();
- }
-
- /**
- * Gets the underlying data structure in which this NSSets stores its content.
- * @return A Set object.
- */
- Set<NSObject> getSet() {
- return set;
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 29 * hash + (this.set != null ? this.set.hashCode() : 0);
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final NSSet other = (NSSet) obj;
- return !(this.set != other.set && (this.set == null || !this.set.equals(other.set)));
- }
-
- /**
- * Gets the number of elements in the set.
- *
- * @return The number of elements in the set.
- * @see Set#size()
- */
- public synchronized int count() {
- return set.size();
- }
-
- /**
- * Returns the XML representantion for this set.
- * There is no official XML representation specified for sets.
- * In this implementation it is represented by an array.
- *
- * @param xml The XML StringBuilder
- * @param level The indentation level
- */
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<array>");
- xml.append(NSObject.NEWLINE);
- for (NSObject o : set) {
- o.toXML(xml, level + 1);
- xml.append(NSObject.NEWLINE);
- }
- indent(xml, level);
- xml.append("</array>");
- }
-
- @Override
- void assignIDs(BinaryPropertyListWriter out) {
- super.assignIDs(out);
- for (NSObject obj : set) {
- obj.assignIDs(out);
- }
- }
-
- @Override
- void toBinary(BinaryPropertyListWriter out) throws IOException {
- if (ordered) {
- out.writeIntHeader(0xB, set.size());
- } else {
- out.writeIntHeader(0xC, set.size());
- }
- for (NSObject obj : set) {
- out.writeID(out.getID(obj));
- }
- }
-
- /**
- * Returns the ASCII representation of this set.
- * There is no official ASCII representation for sets.
- * In this implementation sets are represented as arrays.
- *
- * @param ascii The ASCII file string builder
- * @param level The indentation level
- */
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- NSObject[] array = allObjects();
- ascii.append(ASCIIPropertyListParser.ARRAY_BEGIN_TOKEN);
- int indexOfLastNewLine = ascii.lastIndexOf(NEWLINE);
- for (int i = 0; i < array.length; i++) {
- Class<?> objClass = array[i].getClass();
- if ((objClass.equals(NSDictionary.class) || objClass.equals(NSArray.class) || objClass.equals(NSData.class))
- && indexOfLastNewLine != ascii.length()) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- array[i].toASCII(ascii, level + 1);
- } else {
- if (i != 0)
- ascii.append(" ");
- array[i].toASCII(ascii, 0);
- }
-
- if (i != array.length - 1)
- ascii.append(ASCIIPropertyListParser.ARRAY_ITEM_DELIMITER_TOKEN);
-
- if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- }
- }
- ascii.append(ASCIIPropertyListParser.ARRAY_END_TOKEN);
- }
-
- /**
- * Returns the ASCII representation of this set according to the GnuStep format.
- * There is no official ASCII representation for sets.
- * In this implementation sets are represented as arrays.
- *
- * @param ascii The ASCII file string builder
- * @param level The indentation level
- */
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- indent(ascii, level);
- NSObject[] array = allObjects();
- ascii.append(ASCIIPropertyListParser.ARRAY_BEGIN_TOKEN);
- int indexOfLastNewLine = ascii.lastIndexOf(NEWLINE);
- for (int i = 0; i < array.length; i++) {
- Class<?> objClass = array[i].getClass();
- if ((objClass.equals(NSDictionary.class) || objClass.equals(NSArray.class) || objClass.equals(NSData.class))
- && indexOfLastNewLine != ascii.length()) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- array[i].toASCIIGnuStep(ascii, level + 1);
- } else {
- if (i != 0)
- ascii.append(" ");
- array[i].toASCIIGnuStep(ascii, 0);
- }
-
- if (i != array.length - 1)
- ascii.append(ASCIIPropertyListParser.ARRAY_ITEM_DELIMITER_TOKEN);
-
- if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) {
- ascii.append(NEWLINE);
- indexOfLastNewLine = ascii.length();
- }
- }
- ascii.append(ASCIIPropertyListParser.ARRAY_END_TOKEN);
- }
-
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/NSString.java b/third_party/java/dd_plist/java/com/dd/plist/NSString.java
deleted file mode 100644
index e5f5e6c..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/NSString.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-
-/**
- * A NSString contains a string.
- *
- * @author Daniel Dreibrodt
- */
-public class NSString extends NSObject implements Comparable<Object> {
-
- private String content;
-
- /**
- * Creates an NSString from its binary representation.
- *
- * @param bytes The binary representation.
- * @param encoding The encoding of the binary representation, the name of a supported charset.
- * @throws UnsupportedEncodingException When the given encoding is not supported by the JRE.
- * @see java.lang.String#String(byte[], String)
- */
- public NSString(byte[] bytes, String encoding) throws UnsupportedEncodingException {
- this(bytes, 0, bytes.length, encoding);
- }
-
- /**
- * Creates an NSString from its binary representation.
- *
- * @param bytes The binary representation.
- * @param startIndex int with the index where to start (offset)
- * @param endIndex int with the index where to stop reading (offset + string length)
- * @param encoding The encoding of the binary representation, the name of a supported charset.
- * @throws UnsupportedEncodingException When the given encoding is not supported by the JRE.
- * @see java.lang.String#String(byte[], String)
- */
- public NSString(byte[] bytes, final int startIndex, final int endIndex, String encoding) throws UnsupportedEncodingException {
- content = new String(bytes, startIndex, endIndex - startIndex, encoding);
- }
-
- /**
- * Creates a NSString from a string.
- *
- * @param string The string that will be contained in the NSString.
- */
- public NSString(String string) {
- content = string;
- }
-
- /**
- * Gets this strings content.
- *
- * @return This NSString as Java String object.
- */
- public String getContent() {
- return content;
- }
-
- /**
- * Sets the contents of this string.
- *
- * @param c The new content of this string object.
- */
- public void setContent(String c) {
- content = c;
- }
-
- /**
- * Appends a string to this string.
- *
- * @param s The string to append.
- */
- public void append(NSString s) {
- append(s.getContent());
- }
-
- /**
- * Appends a string to this string.
- *
- * @param s The string to append.
- */
- public void append(String s) {
- content += s;
- }
-
- /**
- * Prepends a string to this string.
- *
- * @param s The string to prepend.
- */
- public void prepend(String s) {
- content = s + content;
- }
-
- /**
- * Prepends a string to this string.
- *
- * @param s The string to prepend.
- */
- public void prepend(NSString s) {
- prepend(s.getContent());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof NSString)) return false;
- return content.equals(((NSString) obj).content);
- }
-
- @Override
- public int hashCode() {
- return content.hashCode();
- }
-
- /**
- * The textual representation of this NSString.
- *
- * @return The NSString's contents.
- */
- @Override
- public String toString() {
- return content;
- }
-
- private static CharsetEncoder asciiEncoder, utf16beEncoder, utf8Encoder;
-
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<string>");
-
- //Make sure that the string is encoded in UTF-8 for the XML output
- synchronized (NSString.class) {
- if (utf8Encoder == null)
- utf8Encoder = Charset.forName("UTF-8").newEncoder();
- else
- utf8Encoder.reset();
-
- try {
- ByteBuffer byteBuf = utf8Encoder.encode(CharBuffer.wrap(content));
- byte[] bytes = new byte[byteBuf.remaining()];
- byteBuf.get(bytes);
- content = new String(bytes, "UTF-8");
- } catch (Exception ex) {
- throw new RuntimeException("Could not encode the NSString into UTF-8: " + String.valueOf(ex.getMessage()));
- }
- }
-
- //According to http://www.w3.org/TR/REC-xml/#syntax node values must not
- //contain the characters < or &. Also the > character should be escaped.
- if (content.contains("&") || content.contains("<") || content.contains(">")) {
- xml.append("<![CDATA[");
- xml.append(content.replaceAll("]]>", "]]]]><![CDATA[>"));
- xml.append("]]>");
- } else {
- xml.append(content);
- }
- xml.append("</string>");
- }
-
-
- @Override
- public void toBinary(BinaryPropertyListWriter out) throws IOException {
- CharBuffer charBuf = CharBuffer.wrap(content);
- int kind;
- ByteBuffer byteBuf;
- synchronized (NSString.class) {
- if (asciiEncoder == null)
- asciiEncoder = Charset.forName("ASCII").newEncoder();
- else
- asciiEncoder.reset();
-
- if (asciiEncoder.canEncode(charBuf)) {
- kind = 0x5; // standard ASCII
- byteBuf = asciiEncoder.encode(charBuf);
- } else {
- if (utf16beEncoder == null)
- utf16beEncoder = Charset.forName("UTF-16BE").newEncoder();
- else
- utf16beEncoder.reset();
-
- kind = 0x6; // UTF-16-BE
- byteBuf = utf16beEncoder.encode(charBuf);
- }
- }
- byte[] bytes = new byte[byteBuf.remaining()];
- byteBuf.get(bytes);
- out.writeIntHeader(kind, content.length());
- out.write(bytes);
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append("\"");
- //According to https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/PropertyLists/OldStylePlists/OldStylePLists.html
- //non-ASCII characters are not escaped but simply written into the
- //file, thus actually violating the ASCII plain text format.
- //We will escape the string anyway because current Xcode project files (ASCII property lists) also escape their strings.
- ascii.append(escapeStringForASCII(content));
- ascii.append("\"");
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append("\"");
- ascii.append(escapeStringForASCII(content));
- ascii.append("\"");
- }
-
- /**
- * Escapes a string for use in ASCII property lists.
- *
- * @param s The unescaped string.
- * @return The escaped string.
- */
- static String escapeStringForASCII(String s) {
- String out = "";
- char[] cArray = s.toCharArray();
- for (int i = 0; i < cArray.length; i++) {
- char c = cArray[i];
- if (c > 127) {
- //non-ASCII Unicode
- out += "\\U";
- String hex = Integer.toHexString(c);
- while (hex.length() < 4)
- hex = "0" + hex;
- out += hex;
- } else if (c == '\\') {
- out += "\\\\";
- } else if (c == '\"') {
- out += "\\\"";
- } else if (c == '\b') {
- out += "\\b";
- } else if (c == '\n') {
- out += "\\n";
- } else if (c == '\r') {
- out += "\\r";
- } else if (c == '\t') {
- out += "\\t";
- } else {
- out += c;
- }
- }
- return out;
- }
-
- public int compareTo(Object o) {
- if (o instanceof NSString) {
- return getContent().compareTo(((NSString) o).getContent());
- } else if (o instanceof String) {
- return getContent().compareTo(((String) o));
- } else {
- return -1;
- }
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/PropertyListFormatException.java b/third_party/java/dd_plist/java/com/dd/plist/PropertyListFormatException.java
deleted file mode 100644
index 13988a0..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/PropertyListFormatException.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.dd.plist;
-
-/**
- * A PropertyListFormatException is thrown by the various property list format parsers
- * when an error in the format of the given property list is encountered.
- * @author Daniel Dreibrodt
- */
-public class PropertyListFormatException extends Exception {
-
- /**
- * Creates a new exception with the given message.
- * @param message A message containing information about the nature of the exception.
- */
- public PropertyListFormatException(String message) {
- super(message);
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/PropertyListParser.java b/third_party/java/dd_plist/java/com/dd/plist/PropertyListParser.java
deleted file mode 100644
index 0f307dc..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/PropertyListParser.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011-2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.text.ParseException;
-
-/**
- * This class provides methods to parse property lists. It can handle files,
- * input streams and byte arrays. All known property list formats are supported.
- *
- * This class also provides methods to save and convert property lists.
- *
- * @author Daniel Dreibrodt
- */
-public class PropertyListParser {
-
- private static final int TYPE_XML = 0;
- private static final int TYPE_BINARY = 1;
- private static final int TYPE_ASCII = 2;
- private static final int TYPE_ERROR_BLANK = 10;
- private static final int TYPE_ERROR_UNKNOWN = 11;
-
- private static final int READ_BUFFER_LENGTH = 2048;
-
- /**
- * Prevent instantiation.
- */
- protected PropertyListParser() {
- /** empty **/
- }
-
- /**
- * Determines the type of a property list by means of the first bytes of its data
- * @param dataBeginning The very first bytes of data of the property list (minus any whitespace) as a string
- * @return The type of the property list
- */
- private static int determineType(String dataBeginning) {
- dataBeginning = dataBeginning.trim();
- if(dataBeginning.length() == 0) {
- return TYPE_ERROR_BLANK;
- }
- if(dataBeginning.startsWith("bplist")) {
- return TYPE_BINARY;
- }
- if(dataBeginning.startsWith("(") || dataBeginning.startsWith("{") || dataBeginning.startsWith("/")) {
- return TYPE_ASCII;
- }
- if(dataBeginning.startsWith("<")) {
- return TYPE_XML;
- }
- return TYPE_ERROR_UNKNOWN;
- }
-
- /**
- * Determines the type of a property list by means of the first bytes of its data
- * @param bytes The very first bytes of data of the property list (minus any whitespace)
- * @return The type of the property list
- */
- private static int determineType(byte[] bytes) {
- //Skip any possible whitespace at the beginning of the file
- int offset = 0;
- if(bytes.length >= 3 && (bytes[0] & 0xFF) == 0xEF && (bytes[1] & 0xFF) == 0xBB && (bytes[2] & 0xFF) == 0xBF) {
- //Skip Unicode byte order mark (BOM)
- offset += 3;
- }
- while(offset < bytes.length && (bytes[offset] == ' ' || bytes[offset] == '\t' || bytes[offset] == '\r' || bytes[offset] == '\n' || bytes[offset] == '\f')) {
- offset++;
- }
- return determineType(new String(bytes, offset, Math.min(8, bytes.length - offset)));
- }
-
- /**
- * Determines the type of a property list by means of the first bytes of its data
- * @param is An input stream pointing to the beginning of the property list data.
- * If the stream supports marking it will be reset to the beginning of the property
- * list data after the type has been determined.
- * @return The type of the property list
- */
- private static int determineType(InputStream is) throws IOException {
- //Skip any possible whitespace at the beginning of the file
- byte[] magicBytes = new byte[8];
- int b;
- long index = -1;
- boolean bom = false;
- do {
- if(is.markSupported())
- is.mark(16);
- b = is.read();
- index++;
- //Check if we are reading the Unicode byte order mark (BOM) and skip it
- bom = index < 3 && ((index == 0 && b == 0xEF) || (bom && ((index == 1 && b == 0xBB) || (index == 2 && b == 0xBF))));
- }
- while(b != -1 && b == ' ' || b == '\t' || b == '\r' || b == '\n' || b == '\f' || bom);
- magicBytes[0] = (byte)b;
- int read = is.read(magicBytes, 1, 7);
- int type = determineType(new String(magicBytes, 0, read));
- if(is.markSupported())
- is.reset();
- return type;
- }
-
- /**
- * Reads all bytes from an InputStream and stores them in an array, up to
- * a maximum count.
- *
- * @param in The InputStream pointing to the data that should be stored in the array.
- * @return An array containing all bytes that were read from the input stream.
- * @throws java.io.IOException When an IO error while reading from the input stream.
- */
- protected static byte[] readAll(InputStream in) throws IOException {
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- byte[] buf = new byte[READ_BUFFER_LENGTH];
- int read;
- while ((read = in.read(buf, 0, READ_BUFFER_LENGTH)) != -1) {
- outputStream.write(buf, 0, read);
- }
- return outputStream.toByteArray();
- }
-
- /**
- * Parses a property list from a file.
- *
- * @param filePath Path to the property list file.
- * @return The root object in the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(String filePath) throws ParserConfigurationException, ParseException, SAXException, PropertyListFormatException, IOException {
- return parse(new File(filePath));
- }
-
- /**
- * Parses a property list from a file.
- *
- * @param f The property list file.
- * @return The root object in the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(File f) throws IOException, PropertyListFormatException, ParseException, ParserConfigurationException, SAXException {
- FileInputStream fis = new FileInputStream(f);
- int type = determineType(fis);
- fis.close();
- switch(type) {
- case TYPE_BINARY:
- return BinaryPropertyListParser.parse(f);
- case TYPE_XML:
- return XMLPropertyListParser.parse(f);
- case TYPE_ASCII:
- return ASCIIPropertyListParser.parse(f);
- default:
- throw new PropertyListFormatException("The given file is not a property list of a supported format.");
- }
- }
-
- /**
- * Parses a property list from a byte array.
- *
- * @param bytes The property list data as a byte array.
- * @return The root object in the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the byte array.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(byte[] bytes) throws IOException, PropertyListFormatException, ParseException, ParserConfigurationException, SAXException {
- switch(determineType(bytes)) {
- case TYPE_BINARY:
- return BinaryPropertyListParser.parse(bytes);
- case TYPE_XML:
- return XMLPropertyListParser.parse(bytes);
- case TYPE_ASCII:
- return ASCIIPropertyListParser.parse(bytes);
- default:
- throw new PropertyListFormatException("The given data is not a property list of a supported format.");
- }
- }
-
- /**
- * Parses a property list from an InputStream.
- *
- * @param is The InputStream delivering the property list data.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the input stream.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(InputStream is) throws IOException, PropertyListFormatException, ParseException, ParserConfigurationException, SAXException {
- return parse(readAll(is));
- }
-
- /**
- * Saves a property list with the given object as root into a XML file.
- *
- * @param root The root object.
- * @param out The output file.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsXML(NSObject root, File out) throws IOException {
- File parent = out.getParentFile();
- if (!parent.exists())
- if(!parent.mkdirs())
- throw new IOException("The output directory does not exist and could not be created.");
- FileOutputStream fous = new FileOutputStream(out);
- saveAsXML(root, fous);
- fous.close();
- }
-
- /**
- * Saves a property list with the given object as root in XML format into an output stream.
- *
- * @param root The root object.
- * @param out The output stream.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsXML(NSObject root, OutputStream out) throws IOException {
- OutputStreamWriter w = new OutputStreamWriter(out, "UTF-8");
- w.write(root.toXMLPropertyList());
- w.close();
- }
-
- /**
- * Converts a given property list file into the OS X and iOS XML format.
- *
- * @param in The source file.
- * @param out The target file.
- *
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the input file or writing the output file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static void convertToXml(File in, File out) throws ParserConfigurationException, ParseException, SAXException, PropertyListFormatException, IOException {
- NSObject root = parse(in);
- saveAsXML(root, out);
- }
-
- /**
- * Saves a property list with the given object as root into a binary file.
- *
- * @param root The root object.
- * @param out The output file.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsBinary(NSObject root, File out) throws IOException {
- File parent = out.getParentFile();
- if (!parent.exists())
- if(!parent.mkdirs())
- throw new IOException("The output directory does not exist and could not be created.");
- BinaryPropertyListWriter.write(out, root);
- }
-
- /**
- * Saves a property list with the given object as root in binary format into an output stream.
- *
- * @param root The root object.
- * @param out The output stream.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsBinary(NSObject root, OutputStream out) throws IOException {
- BinaryPropertyListWriter.write(out, root);
- }
-
- /**
- * Converts a given property list file into the OS X and iOS binary format.
- *
- * @param in The source file.
- * @param out The target file.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the input file or writing the output file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static void convertToBinary(File in, File out) throws IOException, ParserConfigurationException, ParseException, SAXException, PropertyListFormatException {
- NSObject root = parse(in);
- saveAsBinary(root, out);
- }
-
- /**
- * Saves a property list with the given object as root into a ASCII file.
- *
- * @param root The root object.
- * @param out The output file.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsASCII(NSDictionary root, File out) throws IOException {
- File parent = out.getParentFile();
- if (!parent.exists())
- if(!parent.mkdirs())
- throw new IOException("The output directory does not exist and could not be created.");
- OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(out), "ASCII");
- w.write(root.toASCIIPropertyList());
- w.close();
- }
-
- /**
- * Saves a property list with the given object as root into a ASCII file.
- *
- * @param root The root object.
- * @param out The output file.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsASCII(NSArray root, File out) throws IOException {
- OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(out), "ASCII");
- w.write(root.toASCIIPropertyList());
- w.close();
- }
-
- /**
- * Converts a given property list file into ASCII format.
- *
- * @param in The source file.
- * @param out The target file.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the input file or writing the output file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static void convertToASCII(File in, File out) throws ParserConfigurationException, ParseException, SAXException, PropertyListFormatException, IOException {
- NSObject root = parse(in);
- if(root instanceof NSDictionary) {
- saveAsASCII((NSDictionary) root, out);
- }
- else if(root instanceof NSArray) {
- saveAsASCII((NSArray) root, out);
- }
- else {
- throw new PropertyListFormatException("The root of the given input property list "
- + "is neither a Dictionary nor an Array!");
- }
- }
-
- /**
- * Saves a property list with the given object as root into a ASCII file.
- *
- * @param root The root object.
- * @param out The output file.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsGnuStepASCII(NSDictionary root, File out) throws IOException {
- File parent = out.getParentFile();
- if (!parent.exists())
- if(!parent.mkdirs())
- throw new IOException("The output directory does not exist and could not be created.");
- OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(out), "ASCII");
- w.write(root.toGnuStepASCIIPropertyList());
- w.close();
- }
-
- /**
- * Saves a property list with the given object as root into a ASCII file.
- *
- * @param root The root object.
- * @param out The output file.
- * @throws IOException When an error occurs during the writing process.
- */
- public static void saveAsGnuStepASCII(NSArray root, File out) throws IOException {
- File parent = out.getParentFile();
- if (!parent.exists())
- if(!parent.mkdirs())
- throw new IOException("The output directory does not exist and could not be created.");
- OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(out), "ASCII");
- w.write(root.toGnuStepASCIIPropertyList());
- w.close();
- }
-
- /**
- * Converts a given property list file into ASCII format.
- *
- * @param in The source file.
- * @param out The target file.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the input file or writing the output file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static void convertToGnuStepASCII(File in, File out) throws ParserConfigurationException, ParseException, SAXException, PropertyListFormatException, IOException {
- NSObject root = parse(in);
- if(root instanceof NSDictionary) {
- saveAsGnuStepASCII((NSDictionary) root, out);
- }
- else if(root instanceof NSArray) {
- saveAsGnuStepASCII((NSArray) root, out);
- }
- else {
- throw new PropertyListFormatException("The root of the given input property list "
- + "is neither a Dictionary nor an Array!");
- }
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/UID.java b/third_party/java/dd_plist/java/com/dd/plist/UID.java
deleted file mode 100644
index 9dde01c..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/UID.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2011 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import java.io.IOException;
-
-/**
- * A UID. Only found in binary property lists that are keyed archives.
- *
- * @author Daniel Dreibrodt
- */
-public class UID extends NSObject {
-
- private byte[] bytes;
- private String name;
-
- public UID(String name, byte[] bytes) {
- this.name = name;
- this.bytes = bytes;
- }
-
- public byte[] getBytes() {
- return bytes;
- }
-
- public String getName() {
- return name;
- }
-
- /**
- * There is no XML representation specified for UIDs.
- * In this implementation UIDs are represented as strings in the XML output.
- *
- * @param xml The xml StringBuilder
- * @param level The indentation level
- */
- @Override
- void toXML(StringBuilder xml, int level) {
- indent(xml, level);
- xml.append("<string>");
- for (int i = 0; i < bytes.length; i++) {
- byte b = bytes[i];
- if (b < 16)
- xml.append("0");
- xml.append(Integer.toHexString(b));
- }
- xml.append("</string>");
- }
-
- @Override
- void toBinary(BinaryPropertyListWriter out) throws IOException {
- out.write(0x80 + bytes.length - 1);
- out.write(bytes);
- }
-
- @Override
- protected void toASCII(StringBuilder ascii, int level) {
- indent(ascii, level);
- ascii.append("\"");
- for (int i = 0; i < bytes.length; i++) {
- byte b = bytes[i];
- if (b < 16)
- ascii.append("0");
- ascii.append(Integer.toHexString(b));
- }
- ascii.append("\"");
- }
-
- @Override
- protected void toASCIIGnuStep(StringBuilder ascii, int level) {
- toASCII(ascii, level);
- }
-}
diff --git a/third_party/java/dd_plist/java/com/dd/plist/XMLPropertyListParser.java b/third_party/java/dd_plist/java/com/dd/plist/XMLPropertyListParser.java
deleted file mode 100644
index 6fcb7f9..0000000
--- a/third_party/java/dd_plist/java/com/dd/plist/XMLPropertyListParser.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * plist - An open source library to parse and generate property lists
- * Copyright (C) 2014 Daniel Dreibrodt
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package com.dd.plist;
-
-import org.w3c.dom.*;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Parses XML property lists.
- *
- * @author Daniel Dreibrodt
- */
-public class XMLPropertyListParser {
-
- /**
- * Instantiation is prohibited by outside classes.
- */
- protected XMLPropertyListParser() {
- /** empty **/
- }
-
- private static DocumentBuilderFactory docBuilderFactory = null;
-
- /**
- * Initialize the document builder factory so that it can be reused and does not need to
- * be reinitialized for each parse action.
- */
- private static synchronized void initDocBuilderFactory() {
- docBuilderFactory = DocumentBuilderFactory.newInstance();
- docBuilderFactory.setIgnoringComments(true);
- docBuilderFactory.setCoalescing(true);
- }
-
- /**
- * Gets a DocumentBuilder to parse a XML property list.
- * As DocumentBuilders are not thread-safe a new DocBuilder is generated for each request.
- *
- * @return A new DocBuilder that can parse property lists w/o an internet connection.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- */
- private static synchronized DocumentBuilder getDocBuilder() throws ParserConfigurationException {
- if (docBuilderFactory == null)
- initDocBuilderFactory();
- DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
- docBuilder.setEntityResolver(new EntityResolver() {
- public InputSource resolveEntity(String publicId, String systemId) {
- if ("-//Apple Computer//DTD PLIST 1.0//EN".equals(publicId) || // older publicId
- "-//Apple//DTD PLIST 1.0//EN".equals(publicId)) { // newer publicId
- // return a dummy, zero length DTD so we don't have to fetch
- // it from the network.
- return new InputSource(new ByteArrayInputStream(new byte[0]));
- }
- return null;
- }
- });
- return docBuilder;
- }
-
- /**
- * Parses a XML property list file.
- *
- * @param f The XML property list file.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @see javax.xml.parsers.DocumentBuilder#parse(java.io.File)
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(File f) throws ParserConfigurationException, IOException, SAXException, PropertyListFormatException, ParseException {
- DocumentBuilder docBuilder = getDocBuilder();
-
- Document doc = docBuilder.parse(f);
-
- return parse(doc);
- }
-
- /**
- * Parses a XML property list from a byte array.
- *
- * @param bytes The byte array containing the property list's data.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(final byte[] bytes) throws ParserConfigurationException, ParseException, SAXException, PropertyListFormatException, IOException {
- ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
- return parse(bis);
- }
-
- /**
- * Parses a XML property list from an input stream.
- *
- * @param is The input stream pointing to the property list's data.
- * @return The root object of the property list. This is usually a NSDictionary but can also be a NSArray.
- * @see javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)
- * @throws javax.xml.parsers.ParserConfigurationException If a document builder for parsing a XML property list
- * could not be created. This should not occur.
- * @throws java.io.IOException If any IO error occurs while reading the file.
- * @throws org.xml.sax.SAXException If any parse error occurs.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(InputStream is) throws ParserConfigurationException, IOException, SAXException, PropertyListFormatException, ParseException {
- DocumentBuilder docBuilder = getDocBuilder();
-
- Document doc = docBuilder.parse(is);
-
- return parse(doc);
- }
-
- /**
- * Parses a property list from an XML document.
- *
- * @param doc The XML document.
- * @return The root NSObject of the property list contained in the XML document.
- * @throws java.io.IOException If any IO error occurs while reading the file.
- * @throws com.dd.plist.PropertyListFormatException If the given property list has an invalid format.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- public static NSObject parse(Document doc) throws PropertyListFormatException, IOException, ParseException {
- DocumentType docType = doc.getDoctype();
- if (docType == null) {
- if (!doc.getDocumentElement().getNodeName().equals("plist")) {
- throw new UnsupportedOperationException("The given XML document is not a property list.");
- }
- } else if (!docType.getName().equals("plist")) {
- throw new UnsupportedOperationException("The given XML document is not a property list.");
- }
-
- Node rootNode;
-
- if (doc.getDocumentElement().getNodeName().equals("plist")) {
- //Root element wrapped in plist tag
- List<Node> rootNodes = filterElementNodes(doc.getDocumentElement().getChildNodes());
- if (rootNodes.isEmpty()) {
- throw new PropertyListFormatException("The given XML property list has no root element!");
- } else if (rootNodes.size() == 1) {
- rootNode = rootNodes.get(0);
- } else {
- throw new PropertyListFormatException("The given XML property list has more than one root element!");
- }
- } else {
- //Root NSObject not wrapped in plist-tag
- rootNode = doc.getDocumentElement();
- }
-
- return parseObject(rootNode);
- }
-
- /**
- * Parses a node in the XML structure and returns the corresponding NSObject
- *
- * @param n The XML node.
- * @return The corresponding NSObject.
- * @throws java.io.IOException If any IO error occurs while parsing a Base64 encoded NSData object.
- * @throws java.text.ParseException If a date string could not be parsed.
- */
- private static NSObject parseObject(Node n) throws ParseException, IOException {
- String type = n.getNodeName();
- if (type.equals("dict")) {
- NSDictionary dict = new NSDictionary();
- List<Node> children = filterElementNodes(n.getChildNodes());
- for (int i = 0; i < children.size(); i += 2) {
- Node key = children.get(i);
- Node val = children.get(i + 1);
-
- String keyString = getNodeTextContents(key);
-
- dict.put(keyString, parseObject(val));
- }
- return dict;
- } else if (type.equals("array")) {
- List<Node> children = filterElementNodes(n.getChildNodes());
- NSArray array = new NSArray(children.size());
- for (int i = 0; i < children.size(); i++) {
- array.setValue(i, parseObject(children.get(i)));
- }
- return array;
- } else if (type.equals("true")) {
- return new NSNumber(true);
- } else if (type.equals("false")) {
- return new NSNumber(false);
- } else if (type.equals("integer")) {
- return new NSNumber(getNodeTextContents(n));
- } else if (type.equals("real")) {
- return new NSNumber(getNodeTextContents(n));
- } else if (type.equals("string")) {
- return new NSString(getNodeTextContents(n));
- } else if (type.equals("data")) {
- return new NSData(getNodeTextContents(n));
- } else if (type.equals("date")) {
- return new NSDate(getNodeTextContents(n));
- }
- return null;
- }
-
- /**
- * Returns all element nodes that are contained in a list of nodes.
- *
- * @param list The list of nodes to search.
- * @return The sub-list containing only nodes representing actual elements.
- */
- private static List<Node> filterElementNodes(NodeList list) {
- List<Node> result = new ArrayList<Node>(list.getLength());
- for (int i = 0; i < list.getLength(); i++) {
- if (list.item(i).getNodeType() == Node.ELEMENT_NODE) {
- result.add(list.item(i));
- }
- }
- return result;
- }
-
- /**
- * Returns a node's text content.
- * This method will return the text value represented by the node's direct children.
- * If the given node is a TEXT or CDATA node, then its value is returned.
- *
- * @param n The node.
- * @return The node's text content.
- */
- private static String getNodeTextContents(Node n) {
- if (n.getNodeType() == Node.TEXT_NODE || n.getNodeType() == Node.CDATA_SECTION_NODE) {
- Text txtNode = (Text) n;
- String content = txtNode.getWholeText(); //This concatenates any adjacent text/cdata/entity nodes
- if (content == null)
- return "";
- else
- return content;
- } else {
- if (n.hasChildNodes()) {
- NodeList children = n.getChildNodes();
-
- for (int i = 0; i < children.getLength(); i++) {
- //Skip any non-text nodes, like comments or entities
- Node child = children.item(i);
- if (child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_SECTION_NODE) {
- Text txtNode = (Text) child;
- String content = txtNode.getWholeText(); //This concatenates any adjacent text/cdata/entity nodes
- if (content == null)
- return "";
- else
- return content;
- }
- }
-
- return "";
- } else {
- return "";
- }
- }
- }
-}