From 86217fe94a22667126956d62cf80064de4f47488 Mon Sep 17 00:00:00 2001 From: Daniel Dreibrodt Date: Thu, 20 Jul 2017 17:42:32 +0200 Subject: [PATCH] Improve documentation and apply some code styling --- .../com/dd/plist/ASCIIPropertyListParser.java | 245 ++++++++++-------- .../dd/plist/BinaryPropertyListParser.java | 2 +- .../dd/plist/BinaryPropertyListWriter.java | 79 +++--- src/main/java/com/dd/plist/NSArray.java | 106 ++++---- src/main/java/com/dd/plist/NSData.java | 52 ++-- src/main/java/com/dd/plist/NSDate.java | 42 +-- src/main/java/com/dd/plist/NSDictionary.java | 136 +++------- src/main/java/com/dd/plist/NSNumber.java | 185 +++++++------ src/main/java/com/dd/plist/NSSet.java | 16 +- src/main/java/com/dd/plist/NSString.java | 58 ++--- src/main/java/com/dd/plist/UID.java | 20 +- .../java/com/dd/plist/test/NSStringTest.java | 1 + 12 files changed, 459 insertions(+), 483 deletions(-) diff --git a/src/main/java/com/dd/plist/ASCIIPropertyListParser.java b/src/main/java/com/dd/plist/ASCIIPropertyListParser.java index c68f7d5..b8e9157 100644 --- a/src/main/java/com/dd/plist/ASCIIPropertyListParser.java +++ b/src/main/java/com/dd/plist/ASCIIPropertyListParser.java @@ -158,8 +158,9 @@ public static NSObject parse(byte[] bytes) throws ParseException { */ private boolean acceptSequence(char... sequence) { for (int i = 0; i < sequence.length; i++) { - if (data[index + i] != sequence[i]) + if (this.data[this.index + i] != sequence[i]) { return false; + } } return true; @@ -175,9 +176,11 @@ private boolean acceptSequence(char... sequence) { private boolean accept(char... acceptableSymbols) { boolean symbolPresent = false; for (char c : acceptableSymbols) { - if (data[index] == c) + if (this.data[this.index] == c) { symbolPresent = true; + } } + return symbolPresent; } @@ -189,7 +192,7 @@ private boolean accept(char... acceptableSymbols) { * @return Whether the symbol can be accepted or not. */ private boolean accept(char acceptableSymbol) { - return data[index] == acceptableSymbol; + return this.data[this.index] == acceptableSymbol; } /** @@ -199,14 +202,15 @@ private boolean accept(char acceptableSymbol) { * @throws ParseException If none of the expected symbols could be found. */ private void expect(char... expectedSymbols) throws ParseException { - if (!accept(expectedSymbols)) { + if (!this.accept(expectedSymbols)) { StringBuilder excString = new StringBuilder(); excString.append("Expected '").append(expectedSymbols[0]).append("'"); for (int i = 1; i < expectedSymbols.length; i++) { excString.append(" or '").append(expectedSymbols[i]).append("'"); } - excString.append(" but found '").append((char) data[index]).append("'"); - throw new ParseException(excString.toString(), index); + + excString.append(" but found '").append((char) this.data[this.index]).append("'"); + throw new ParseException(excString.toString(), this.index); } } @@ -217,8 +221,9 @@ private void expect(char... expectedSymbols) throws ParseException { * @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); + if (!this.accept(expectedSymbol)) { + throw new ParseException("Expected '" + expectedSymbol + "' but found '" + (char) this.data[this.index] + "'", this.index); + } } /** @@ -229,14 +234,14 @@ private void expect(char expectedSymbol) throws ParseException { */ private void read(char symbol) throws ParseException { expect(symbol); - index++; + this.index++; } /** * Skips the current symbol. */ private void skip() { - index++; + this.index++; } /** @@ -245,7 +250,7 @@ private void skip() { * @param numSymbols The amount of symbols to skip. */ private void skip(int numSymbols) { - index += numSymbols; + this.index += numSymbols; } /** @@ -257,25 +262,27 @@ private void skipWhitespacesAndComments() { commentSkipped = false; //Skip whitespaces - while (accept(WHITESPACE_CARRIAGE_RETURN, WHITESPACE_NEWLINE, WHITESPACE_SPACE, WHITESPACE_TAB)) { - skip(); + while (this.accept(WHITESPACE_CARRIAGE_RETURN, WHITESPACE_NEWLINE, WHITESPACE_SPACE, WHITESPACE_TAB)) { + this.skip(); } //Skip single line comments "//..." - if (acceptSequence(COMMENT_BEGIN_TOKEN, SINGLELINE_COMMENT_SECOND_TOKEN)) { - skip(2); - readInputUntil(WHITESPACE_CARRIAGE_RETURN, WHITESPACE_NEWLINE); + if (this.acceptSequence(COMMENT_BEGIN_TOKEN, SINGLELINE_COMMENT_SECOND_TOKEN)) { + this.skip(2); + this.readInputUntil(WHITESPACE_CARRIAGE_RETURN, WHITESPACE_NEWLINE); commentSkipped = true; } + //Skip multi line comments "/* ... */" - else if (acceptSequence(COMMENT_BEGIN_TOKEN, MULTILINE_COMMENT_SECOND_TOKEN)) { + else if (this.acceptSequence(COMMENT_BEGIN_TOKEN, MULTILINE_COMMENT_SECOND_TOKEN)) { skip(2); while (true) { - if (acceptSequence(MULTILINE_COMMENT_SECOND_TOKEN, MULTILINE_COMMENT_END_TOKEN)) { - skip(2); + if (this.acceptSequence(MULTILINE_COMMENT_SECOND_TOKEN, MULTILINE_COMMENT_END_TOKEN)) { + this.skip(2); break; } - skip(); + + this.skip(); } commentSkipped = true; } @@ -291,10 +298,11 @@ else if (acceptSequence(COMMENT_BEGIN_TOKEN, MULTILINE_COMMENT_SECOND_TOKEN)) { */ private String readInputUntil(char... symbols) { StringBuilder strBuf = new StringBuilder(); - while (!accept(symbols)) { - strBuf.append((char) data[index]); - skip(); + while (!this.accept(symbols)) { + strBuf.append((char) this.data[this.index]); + this.skip(); } + return strBuf.toString(); } @@ -306,9 +314,9 @@ private String readInputUntil(char... symbols) { */ private String readInputUntil(char symbol) { StringBuilder strBuf = new StringBuilder(); - while (!accept(symbol)) { - strBuf.append((char) data[index]); - skip(); + while (!this.accept(symbol)) { + strBuf.append((char) this.data[this.index]); + this.skip(); } return strBuf.toString(); } @@ -321,16 +329,18 @@ private String readInputUntil(char symbol) { * @throws ParseException When an error occured during parsing */ public NSObject parse() throws ParseException { - index = 0; + this.index = 0; //Skip Unicode byte order mark (BOM) - if(data.length >= 3 && (data[0] & 0xFF) == 0xEF && (data[1] & 0xFF) == 0xBB && (data[2] & 0xFF) == 0xBF) - skip(3); - skipWhitespacesAndComments(); - expect(DICTIONARY_BEGIN_TOKEN, ARRAY_BEGIN_TOKEN, COMMENT_BEGIN_TOKEN); + if (this.data.length >= 3 && (this.data[0] & 0xFF) == 0xEF && (this.data[1] & 0xFF) == 0xBB && (this.data[2] & 0xFF) == 0xBF) { + this.skip(3); + } + + this.skipWhitespacesAndComments(); + this.expect(DICTIONARY_BEGIN_TOKEN, ARRAY_BEGIN_TOKEN, COMMENT_BEGIN_TOKEN); try { - return parseObject(); + return this.parseObject(); } catch (ArrayIndexOutOfBoundsException ex) { - throw new ParseException("Reached end of input unexpectedly.", index); + throw new ParseException("Reached end of input unexpectedly.", this.index); } } @@ -342,18 +352,18 @@ public NSObject parse() throws ParseException { * @see ASCIIPropertyListParser#index */ private NSObject parseObject() throws ParseException { - switch (data[index]) { + switch (this.data[this.index]) { case ARRAY_BEGIN_TOKEN: { - return parseArray(); + return this.parseArray(); } case DICTIONARY_BEGIN_TOKEN: { - return parseDictionary(); + return this.parseDictionary(); } case DATA_BEGIN_TOKEN: { - return parseData(); + return this.parseData(); } case QUOTEDSTRING_BEGIN_TOKEN: { - String quotedString = parseQuotedString(); + String quotedString = this.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 { @@ -368,13 +378,12 @@ private NSObject parseObject() throws ParseException { } default: { //0-9 - if (data[index] > 0x2F && data[index] < 0x3A) { + if (this.data[this.index] > 0x2F && this.data[this.index] < 0x3A) { //could be a date or just a string - return parseDateString(); + return this.parseDateString(); } else { //non-numerical -> string or boolean - String parsedString = parseString(); - return new NSString(parsedString); + return new NSString(this.parseString()); } } } @@ -388,21 +397,22 @@ private NSObject parseObject() throws ParseException { */ private NSArray parseArray() throws ParseException { //Skip begin token - skip(); - skipWhitespacesAndComments(); + this.skip(); + this.skipWhitespacesAndComments(); List objects = new LinkedList(); - while (!accept(ARRAY_END_TOKEN)) { - objects.add(parseObject()); - skipWhitespacesAndComments(); - if (accept(ARRAY_ITEM_DELIMITER_TOKEN)) { - skip(); + while (!this.accept(ARRAY_END_TOKEN)) { + objects.add(this.parseObject()); + this.skipWhitespacesAndComments(); + if (this.accept(ARRAY_ITEM_DELIMITER_TOKEN)) { + this.skip(); } else { break; //must have reached end of array } - skipWhitespacesAndComments(); + + this.skipWhitespacesAndComments(); } //parse end token - read(ARRAY_END_TOKEN); + this.read(ARRAY_END_TOKEN); return new NSArray(objects.toArray(new NSObject[objects.size()])); } @@ -414,31 +424,34 @@ private NSArray parseArray() throws ParseException { */ private NSDictionary parseDictionary() throws ParseException { //Skip begin token - skip(); - skipWhitespacesAndComments(); + this.skip(); + this.skipWhitespacesAndComments(); NSDictionary dict = new NSDictionary(); - while (!accept(DICTIONARY_END_TOKEN)) { + while (!this.accept(DICTIONARY_END_TOKEN)) { //Parse key String keyString; - if (accept(QUOTEDSTRING_BEGIN_TOKEN)) { - keyString = parseQuotedString(); + if (this.accept(QUOTEDSTRING_BEGIN_TOKEN)) { + keyString = this.parseQuotedString(); } else { - keyString = parseString(); + keyString = this.parseString(); } - skipWhitespacesAndComments(); + + this.skipWhitespacesAndComments(); //Parse assign token - read(DICTIONARY_ASSIGN_TOKEN); - skipWhitespacesAndComments(); + this.read(DICTIONARY_ASSIGN_TOKEN); + this.skipWhitespacesAndComments(); - NSObject object = parseObject(); + NSObject object = this.parseObject(); dict.put(keyString, object); - skipWhitespacesAndComments(); - read(DICTIONARY_ITEM_DELIMITER_TOKEN); - skipWhitespacesAndComments(); + this.skipWhitespacesAndComments(); + this.read(DICTIONARY_ITEM_DELIMITER_TOKEN); + this.skipWhitespacesAndComments(); } + //skip end token - skip(); + this.skip(); + return dict; } @@ -452,36 +465,36 @@ private NSDictionary parseDictionary() throws ParseException { 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)) { + this.skip(); + if (this.accept(DATA_GSOBJECT_BEGIN_TOKEN)) { + this.skip(); + this.expect(DATA_GSBOOL_BEGIN_TOKEN, DATA_GSDATE_BEGIN_TOKEN, DATA_GSINT_BEGIN_TOKEN, DATA_GSREAL_BEGIN_TOKEN); + if (this.accept(DATA_GSBOOL_BEGIN_TOKEN)) { //Boolean - skip(); - expect(DATA_GSBOOL_TRUE_TOKEN, DATA_GSBOOL_FALSE_TOKEN); - if (accept(DATA_GSBOOL_TRUE_TOKEN)) { + this.skip(); + this.expect(DATA_GSBOOL_TRUE_TOKEN, DATA_GSBOOL_FALSE_TOKEN); + if (this.accept(DATA_GSBOOL_TRUE_TOKEN)) { obj = new NSNumber(true); } else { obj = new NSNumber(false); } //Skip the parsed boolean token - skip(); + this.skip(); } else if (accept(DATA_GSDATE_BEGIN_TOKEN)) { //Date - skip(); - String dateString = readInputUntil(DATA_END_TOKEN); + this.skip(); + String dateString = this.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); + this.skip(); + String numberString = this.readInputUntil(DATA_END_TOKEN); obj = new NSNumber(numberString); } //parse data end token - read(DATA_END_TOKEN); + this.read(DATA_END_TOKEN); } else { - String dataString = readInputUntil(DATA_END_TOKEN); + String dataString = this.readInputUntil(DATA_END_TOKEN); dataString = dataString.replaceAll("\\s+", ""); int numBytes = dataString.length() / 2; @@ -491,10 +504,11 @@ private NSObject parseData() throws ParseException { int byteValue = Integer.parseInt(byteString, 16); bytes[i] = (byte) byteValue; } + obj = new NSData(bytes); //skip end token - skip(); + this.skip(); } return obj; @@ -506,7 +520,7 @@ private NSObject parseData() throws ParseException { * @return A NSDate if the string represents such an object. Otherwise a NSString is returned. */ private NSObject parseDateString() { - String numericalString = parseString(); + String numericalString = this.parseString(); if (numericalString.length() > 4 && numericalString.charAt(4) == DATE_DATE_FIELD_DELIMITER) { try { return new NSDate(numericalString); @@ -514,6 +528,7 @@ private NSObject parseDateString() { //An exception occurs if the string is not a date but just a string } } + return new NSString(numericalString); } @@ -524,7 +539,7 @@ private NSObject parseDateString() { * @return The string found at the current parsing position. */ private String parseString() { - return readInputUntil(WHITESPACE_SPACE, WHITESPACE_TAB, WHITESPACE_NEWLINE, WHITESPACE_CARRIAGE_RETURN, + return this.readInputUntil(WHITESPACE_SPACE, WHITESPACE_TAB, WHITESPACE_NEWLINE, WHITESPACE_CARRIAGE_RETURN, ARRAY_ITEM_DELIMITER_TOKEN, DICTIONARY_ITEM_DELIMITER_TOKEN, DICTIONARY_ASSIGN_TOKEN, ARRAY_END_TOKEN); } @@ -537,16 +552,17 @@ private String parseString() { */ private String parseQuotedString() throws ParseException { //Skip begin token - skip(); + this.skip(); List strBytes = new LinkedList(); 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)) { - strBytes.add(data[index]); - if (accept(QUOTEDSTRING_ESCAPE_TOKEN)) { - unescapedBackslash = !(data[index - 1] == QUOTEDSTRING_ESCAPE_TOKEN && unescapedBackslash); + while (this.data[this.index] != QUOTEDSTRING_END_TOKEN || (this.data[this.index - 1] == QUOTEDSTRING_ESCAPE_TOKEN && unescapedBackslash)) { + strBytes.add(this.data[this.index]); + if (this.accept(QUOTEDSTRING_ESCAPE_TOKEN)) { + unescapedBackslash = !(this.data[this.index - 1] == QUOTEDSTRING_ESCAPE_TOKEN && unescapedBackslash); } - skip(); + + this.skip(); } byte[] bytArr = new byte[strBytes.size()]; @@ -559,12 +575,14 @@ private String parseQuotedString() throws ParseException { String unescapedString; try { - unescapedString = parseQuotedString(new String(bytArr, "UTF-8")); + unescapedString = this.parseQuotedString(new String(bytArr, "UTF-8")); } catch (Exception ex) { - throw new ParseException("The quoted string could not be parsed.", index); + throw new ParseException("The quoted string could not be parsed.", this.index); } + //skip end token - skip(); + this.skip(); + return unescapedString; } @@ -613,29 +631,28 @@ private static char parseEscapedSequence(StringCharacterIterator iterator) throw char c = iterator.next(); switch (c) { - case '\\': - case '"': - case 'b': - case 'n': - case 'r': - case 't': - return c; - - case 'U': - case 'u': - { - //4 digit hex Unicode value - String unicodeValue = new String(new char[] {iterator.next(), iterator.next(), iterator.next(), iterator.next()}); - return (char)Integer.parseInt(unicodeValue, 16); - } + case '\\': + case '"': + case 'b': + case 'n': + case 'r': + case 't': + return c; + + case 'U': + case 'u': + { + //4 digit hex Unicode value + String unicodeValue = new String(new char[] {iterator.next(), iterator.next(), iterator.next(), iterator.next()}); + return (char)Integer.parseInt(unicodeValue, 16); + } - default: - { - //3 digit octal ASCII value - String num = new String(new char[] {c, iterator.next(), iterator.next()}); - return (char)Integer.parseInt(num, 8); - } + default: + { + //3 digit octal ASCII value + String num = new String(new char[] {c, iterator.next(), iterator.next()}); + return (char)Integer.parseInt(num, 8); + } } } - } diff --git a/src/main/java/com/dd/plist/BinaryPropertyListParser.java b/src/main/java/com/dd/plist/BinaryPropertyListParser.java index b3e3eed..e8f1ed3 100644 --- a/src/main/java/com/dd/plist/BinaryPropertyListParser.java +++ b/src/main/java/com/dd/plist/BinaryPropertyListParser.java @@ -50,7 +50,7 @@ public final class BinaryPropertyListParser { private int minorVersion; /** - * property list in bytes + * The property list data. */ private byte[] bytes; diff --git a/src/main/java/com/dd/plist/BinaryPropertyListWriter.java b/src/main/java/com/dd/plist/BinaryPropertyListWriter.java index a0f05d7..da83e8c 100644 --- a/src/main/java/com/dd/plist/BinaryPropertyListWriter.java +++ b/src/main/java/com/dd/plist/BinaryPropertyListWriter.java @@ -67,12 +67,12 @@ public final class BinaryPropertyListWriter { * data that cannot be saved. */ BinaryPropertyListWriter(OutputStream outStr) throws IOException { - out = new BufferedOutputStream(outStr); + this.out = new BufferedOutputStream(outStr); } BinaryPropertyListWriter(OutputStream outStr, int version) throws IOException { this.version = version; - out = new BufferedOutputStream(outStr); + this.out = new BufferedOutputStream(outStr); } /** @@ -143,6 +143,7 @@ public static void write(OutputStream out, NSObject root) throws IOException { 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); } @@ -164,24 +165,24 @@ public static byte[] writeToArray(NSObject root) throws IOException { void write(NSObject root) throws IOException { // magic bytes - write(new byte[]{'b', 'p', 'l', 'i', 's', 't'}); + this.write(new byte[]{'b', 'p', 'l', 'i', 's', 't'}); //version switch (version) { case VERSION_00: { - write(new byte[]{'0', '0'}); + this.write(new byte[]{'0', '0'}); break; } case VERSION_10: { - write(new byte[]{'1', '0'}); + this.write(new byte[]{'1', '0'}); break; } case VERSION_15: { - write(new byte[]{'1', '5'}); + this.write(new byte[]{'1', '5'}); break; } case VERSION_20: { - write(new byte[]{'2', '0'}); + this.write(new byte[]{'2', '0'}); break; } default: @@ -191,13 +192,13 @@ void write(NSObject root) throws IOException { // assign IDs to all the objects. root.assignIDs(this); - idSizeInBytes = computeIdSizeInBytes(idMap.size()); + idSizeInBytes = computeIdSizeInBytes(this.idMap.size()); // offsets of each object, indexed by ID - long[] offsets = new long[idMap.size()]; + long[] offsets = new long[this.idMap.size()]; // write each object, save offset - for (Map.Entry entry : idMap.entrySet()) { + for (Map.Entry entry : this.idMap.entrySet()) { NSObject obj = entry.getKey(); int id = entry.getValue(); offsets[id] = count; @@ -212,36 +213,36 @@ void write(NSObject root) throws IOException { long offsetTableOffset = count; int offsetSizeInBytes = computeOffsetSizeInBytes(count); for (long offset : offsets) { - writeBytes(offset, offsetSizeInBytes); + this.writeBytes(offset, offsetSizeInBytes); } if (version != VERSION_15) { // write trailer // 6 null bytes - write(new byte[6]); + this.write(new byte[6]); // size of an offset - write(offsetSizeInBytes); + this.write(offsetSizeInBytes); // size of a ref - write(idSizeInBytes); + this.write(this.idSizeInBytes); // number of objects - writeLong(idMap.size()); + this.writeLong(this.idMap.size()); // top object - writeLong(idMap.get(root)); + this.writeLong(this.idMap.get(root)); // offset table offset - writeLong(offsetTableOffset); + this.writeLong(offsetTableOffset); } - out.flush(); + this.out.flush(); } void assignID(NSObject obj) { - if (!idMap.containsKey(obj)) { - idMap.put(obj, idMap.size()); + if (!this.idMap.containsKey(obj)) { + this.idMap.put(obj, this.idMap.size()); } } int getID(NSObject obj) { - return idMap.get(obj); + return this.idMap.get(obj); } private static int computeIdSizeInBytes(int numberOfIds) { @@ -260,48 +261,48 @@ private int computeOffsetSizeInBytes(long maxOffset) { void writeIntHeader(int kind, int value) throws IOException { assert value >= 0; if (value < 15) { - write((kind << 4) + value); + this.write((kind << 4) + value); } else if (value < 256) { - write((kind << 4) + 15); - write(0x10); - writeBytes(value, 1); + this.write((kind << 4) + 15); + this.write(0x10); + this.writeBytes(value, 1); } else if (value < 65536) { - write((kind << 4) + 15); - write(0x11); - writeBytes(value, 2); + this.write((kind << 4) + 15); + this.write(0x11); + this.writeBytes(value, 2); } else { - write((kind << 4) + 15); - write(0x12); - writeBytes(value, 4); + this.write((kind << 4) + 15); + this.write(0x12); + this.writeBytes(value, 4); } } void write(int b) throws IOException { - out.write(b); - count++; + this.out.write(b); + this.count++; } void write(byte[] bytes) throws IOException { - out.write(bytes); - count += bytes.length; + this.out.write(bytes); + this.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))); + this.write((int) (value >> (8 * i))); } } void writeID(int id) throws IOException { - writeBytes(id, idSizeInBytes); + this.writeBytes(id, this.idSizeInBytes); } void writeLong(long value) throws IOException { - writeBytes(value, 8); + this.writeBytes(value, 8); } void writeDouble(double value) throws IOException { - writeLong(Double.doubleToRawLongBits(value)); + this.writeLong(Double.doubleToRawLongBits(value)); } } diff --git a/src/main/java/com/dd/plist/NSArray.java b/src/main/java/com/dd/plist/NSArray.java index 473412d..d07feab 100644 --- a/src/main/java/com/dd/plist/NSArray.java +++ b/src/main/java/com/dd/plist/NSArray.java @@ -27,30 +27,31 @@ import java.util.Arrays; /** - * Represents an Array. + * The NSArray class is a wrapper for an array of NSObject instances. * * @author Daniel Dreibrodt + * @see Foundation NSArray documentation */ public class NSArray extends NSObject { private NSObject[] array; /** - * Creates an empty array of the given length. + * Creates a new NSArray instance of the specified size. * - * @param length The number of elements this array will be able to hold. + * @param length The number of elements the NSArray instance will be able to hold. */ public NSArray(int length) { - array = new NSObject[length]; + this.array = new NSObject[length]; } /** - * Creates a array from an existing one + * Creates a new NSArray instance containing the specified elements. * - * @param a The array which should be wrapped by the NSArray + * @param a The elements to be contained by the NSArray instance. */ public NSArray(NSObject... a) { - array = a; + this.array = a; } /** @@ -61,22 +62,22 @@ public NSArray(NSObject... a) { * @return The object at the given index. */ public NSObject objectAtIndex(int i) { - return array[i]; + return this.array[i]; } /** - * Remove the i-th element from the array. + * Removes 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; + if((i >= this.array.length) || (i < 0)) + throw new ArrayIndexOutOfBoundsException("invalid index:" + i + ";the array length is " + this.array.length); + NSObject[] newArray = new NSObject[this.array.length - 1]; + System.arraycopy(this.array, 0, newArray, 0, i); + System.arraycopy(this.array, i + 1, newArray, i, this.array.length - i - 1); + this.array = newArray; } /** @@ -88,7 +89,7 @@ public void remove(int i) { * @param value The object. */ public void setValue(int key, Object value) { - array[key] = NSObject.fromJavaObject(value); + this.array[key] = NSObject.fromJavaObject(value); } /** @@ -98,7 +99,7 @@ public void setValue(int key, Object value) { * @return The actual array represented by this NSArray. */ public NSObject[] getArray() { - return array; + return this.array; } /** @@ -107,7 +108,7 @@ public NSObject[] getArray() { * @return The number of elements that this array can store. */ public int count() { - return array.length; + return this.array.length; } /** @@ -120,13 +121,13 @@ public int count() { */ public boolean containsObject(Object obj) { NSObject nso = NSObject.fromJavaObject(obj); - for (NSObject elem : array) { + for(NSObject elem : this.array) { if(elem == null) { if(obj == null) return true; continue; } - if (elem.equals(nso)) { + if(elem.equals(nso)) { return true; } } @@ -134,9 +135,8 @@ public boolean containsObject(Object obj) { } /** - * 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. + * Searches for an object in the array. If the specified object or an object equal to it is found, + * its index is returned. Otherwise, -1 is returned. * * @param obj The object to look for. * @return The index of the object, if it was found. -1 otherwise. @@ -145,8 +145,8 @@ public boolean containsObject(Object obj) { */ public int indexOfObject(Object obj) { NSObject nso = NSObject.fromJavaObject(obj); - for (int i = 0; i < array.length; i++) { - if (array[i].equals(nso)) { + for(int i = 0; i < this.array.length; i++) { + if(this.array[i].equals(nso)) { return i; } } @@ -154,10 +154,8 @@ public int indexOfObject(Object obj) { } /** - * 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 - * identical to the given one. Thus objects that might contain the - * same value as the given one will not be considered. + * Searches for a specific object in the array. If the specified object is found (reference equality), + * its index is returned. Otherwise, -1 is returned. * * @param obj The object to look for. * @return The index of the object, if it was found. -1 otherwise. @@ -165,8 +163,8 @@ public int indexOfObject(Object obj) { */ public int indexOfIdenticalObject(Object obj) { NSObject nso = NSObject.fromJavaObject(obj); - for (int i = 0; i < array.length; i++) { - if (array[i] == nso) { + for(int i = 0; i < this.array.length; i++) { + if(this.array[i] == nso) { return i; } } @@ -180,7 +178,7 @@ public int indexOfIdenticalObject(Object obj) { * @return The value of the highest index in the array. */ public NSObject lastObject() { - return array[array.length - 1]; + return this.array[this.array.length - 1]; } /** @@ -193,8 +191,8 @@ public NSObject lastObject() { 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]]; + for(int i = 0; i < indexes.length; i++) + result[i] = this.array[indexes[i]]; return result; } @@ -225,7 +223,7 @@ void toXML(StringBuilder xml, int level) { indent(xml, level); xml.append(""); xml.append(NSObject.NEWLINE); - for (NSObject o : array) { + for(NSObject o : this.array) { o.toXML(xml, level + 1); xml.append(NSObject.NEWLINE); } @@ -236,15 +234,15 @@ void toXML(StringBuilder xml, int level) { @Override void assignIDs(BinaryPropertyListWriter out) { super.assignIDs(out); - for (NSObject obj : array) { + for(NSObject obj : this.array) { obj.assignIDs(out); } } @Override void toBinary(BinaryPropertyListWriter out) throws IOException { - out.writeIntHeader(0xA, array.length); - for (NSObject obj : array) { + out.writeIntHeader(0xA, this.array.length); + for(NSObject obj : this.array) { out.writeID(out.getID(obj)); } } @@ -285,23 +283,23 @@ 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)) + for(int i = 0; i < this.array.length; i++) { + Class objClass = this.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); + this.array[i].toASCII(ascii, level + 1); } else { - if (i != 0) + if(i != 0) ascii.append(' '); - array[i].toASCII(ascii, 0); + this.array[i].toASCII(ascii, 0); } - if (i != array.length - 1) + if(i != this.array.length - 1) ascii.append(ASCIIPropertyListParser.ARRAY_ITEM_DELIMITER_TOKEN); - if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) { + if(ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) { ascii.append(NEWLINE); indexOfLastNewLine = ascii.length(); } @@ -314,23 +312,23 @@ 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)) + for(int i = 0; i < this.array.length; i++) { + Class objClass = this.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); + this.array[i].toASCIIGnuStep(ascii, level + 1); } else { - if (i != 0) + if(i != 0) ascii.append(' '); - array[i].toASCIIGnuStep(ascii, 0); + this.array[i].toASCIIGnuStep(ascii, 0); } - if (i != array.length - 1) + if(i != this.array.length - 1) ascii.append(ASCIIPropertyListParser.ARRAY_ITEM_DELIMITER_TOKEN); - if (ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) { + if(ascii.length() - indexOfLastNewLine > ASCII_LINE_LENGTH) { ascii.append(NEWLINE); indexOfLastNewLine = ascii.length(); } diff --git a/src/main/java/com/dd/plist/NSData.java b/src/main/java/com/dd/plist/NSData.java index 6368d16..010b24d 100644 --- a/src/main/java/com/dd/plist/NSData.java +++ b/src/main/java/com/dd/plist/NSData.java @@ -1,6 +1,6 @@ /* * plist - An open source library to parse and generate property lists - * Copyright (C) 2011 Daniel Dreibrodt + * Copyright (C) 2011-2017 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 @@ -30,8 +30,8 @@ import java.util.Arrays; /** - * NSData objects are wrappers for byte buffers. - * + * The NSData class is a wrapper for a byte buffer. + * @see Foundation NSData documentation * @author Daniel Dreibrodt */ public class NSData extends NSObject { @@ -39,84 +39,84 @@ public class NSData extends NSObject { private final byte[] bytes; /** - * Creates the NSData object from the binary representation of it. + * Creates a new NSData instance with the specified content. * - * @param bytes The raw data contained in the NSData object. + * @param bytes The data content. */ public NSData(byte[] bytes) { this.bytes = bytes; } /** - * Creates a NSData object from its textual representation, which is a Base64 encoded amount of bytes. + * Creates a new NSData instance with the specified Base64 encoded content. * - * @param base64 The Base64 encoded contents of the NSData object. + * @param base64 The Base64 encoded data content. * @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, Base64.DONT_GUNZIP); + this.bytes = Base64.decode(data, Base64.DONT_GUNZIP); } /** - * Creates a NSData object from a file. Using the files contents as the contents of this NSData object. + * Creates a new NSData instance with the specified file as content. * * @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()]; + this.bytes = new byte[(int) file.length()]; RandomAccessFile raf = new RandomAccessFile(file, "r"); - raf.read(bytes); + raf.read(this.bytes); raf.close(); } /** - * The bytes contained in this NSData object. + * Returns the bytes contained in this instance. * * @return The data as bytes */ public byte[] bytes() { - return bytes; + return this.bytes; } /** - * Gets the amount of data stored in this object. + * Returns the number of bytes stored in this instance. * * @return The number of bytes contained in this object. */ public int length() { - return bytes.length; + return this.bytes.length; } /** - * Loads the bytes from this NSData object into a byte buffer + * Copies data from this instance into the specified buffer. * - * @param buf The byte buffer which will contain the data - * @param length The amount of data to copy + * @param buf The byte buffer which will contain the data. + * @param length The number of bytes to copy. */ public void getBytes(ByteBuffer buf, int length) { - buf.put(bytes, 0, Math.min(bytes.length, length)); + buf.put(this.bytes, 0, Math.min(this.bytes.length, length)); } /** - * Loads the bytes from this NSData object into a byte buffer + * Copies data from this instance into the specified buffer. * - * @param buf The byte buffer which will contain the data - * @param rangeStart The start index - * @param rangeStop The stop index + * @param buf The byte buffer which will contain the data. + * @param rangeStart The index from which to start copying. + * @param rangeStop The index at which to stop copying. */ public void getBytes(ByteBuffer buf, int rangeStart, int rangeStop) { - buf.put(bytes, rangeStart, Math.min(bytes.length, rangeStop)); + buf.put(this.bytes, rangeStart, Math.min(this.bytes.length, rangeStop)); } /** - * Gets the Base64 encoded data contained in this NSData object. + * Gets the Base64 encoded data contained in this instance. * - * @return The Base64 encoded data as a String. + * @return The data as a Base64 encoded String. */ public String getBase64EncodedData() { return Base64.encodeBytes(bytes); diff --git a/src/main/java/com/dd/plist/NSDate.java b/src/main/java/com/dd/plist/NSDate.java index d510e2a..665c3f4 100644 --- a/src/main/java/com/dd/plist/NSDate.java +++ b/src/main/java/com/dd/plist/NSDate.java @@ -1,6 +1,6 @@ /* * plist - An open source library to parse and generate property lists - * Copyright (C) 2011 Daniel Dreibrodt, Keith Randall + * Copyright (C) 2011-2017 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 @@ -30,8 +30,8 @@ import java.util.TimeZone; /** - * Represents a date. - * + * The NSDate class wraps a date. + * @see Foundation NSDate documentation * @author Daniel Dreibrodt */ public class NSDate extends NSObject { @@ -47,20 +47,20 @@ public class NSDate extends NSObject { private static final SimpleDateFormat sdfGnuStep = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); /** - * Creates a date from its binary representation. + * Creates new NSDate instance from its binary representation. * - * @param bytes The date bytes + * @param bytes The binary date representation. */ public NSDate(byte[] bytes){ this(bytes, 0, bytes.length); } /** - * Creates a date from its binary representation. + * Creates a new NSDate instance 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 + * @param bytes The byte array containing the date data. + * @param startIndex The index within the array at which the date data begins. + * @param endIndex The index within the array at which the data date ends. */ public NSDate(byte[] bytes, final int startIndex, final int endIndex) { //dates are 8 byte big-endian double, seconds since the epoch @@ -68,20 +68,22 @@ public NSDate(byte[] bytes, final int startIndex, final int endIndex) { } /** - * Parses a date from its textual representation. - * That representation has the following pattern: yyyy-MM-dd'T'HH:mm:ss'Z' + * Creates a new NSDate instance from is textual representation. + * The textual representation must adhere to one of the following patterns. + * For XML property lists: yyyy-MM-dd'T'HH:mm:ss'Z' + * For ASCII property lists: yyyy-MM-dd HH:mm:ss Z * - * @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. + * @param textRepresentation The textual representation of the date. + * @throws ParseException If 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 + * Creates a new NSDate instance. * - * @param d The date + * @param d The date. */ public NSDate(Date d) { if (d == null) @@ -95,10 +97,10 @@ public NSDate(Date d) { } /** - * Parses the XML date string and creates a Java Date object from it. - * This function is synchronized as SimpleDateFormat is not thread-safe. + * Parses a date string and creates a Java Date object from it. + * This function is synchronized because the underlying SimpleDateFormat instances are not thread-safe. * - * @param textRepresentation The date string as found in the XML property list + * @param textRepresentation The date string as found in an ASCII or XML property list * @return The parsed Date * @throws ParseException If the given string cannot be parsed. * @see SimpleDateFormat#parse(java.lang.String) @@ -112,7 +114,7 @@ private static synchronized Date parseDateString(String textRepresentation) thro } /** - * Generates a String representation of a Java Date object. The string + * 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. @@ -123,7 +125,7 @@ private static synchronized String makeDateString(Date date) { } /** - * Generates a String representation of a Java Date object. The string + * Generates a string representation of a Java Date object. The string * is formatted according to the specification for GnuStep ASCII property * list dates. * diff --git a/src/main/java/com/dd/plist/NSDictionary.java b/src/main/java/com/dd/plist/NSDictionary.java index e0bd873..67c741a 100644 --- a/src/main/java/com/dd/plist/NSDictionary.java +++ b/src/main/java/com/dd/plist/NSDictionary.java @@ -33,38 +33,36 @@ 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. + * The NSDictionary class is a collection of NSObject instances that are identified by strings. + * It represents a hash map where the keys are strings and the values NSObject instances. + * The implementation is based on a linked hash map, so that the order of the elements in the dictionary is preserved. * - * You can access the keys through the function allKeys(). Access - * to the objects stored for each key is given through the function - * objectoForKey(String key). + * You can access the keys through the function allKeys(). + * Access to the objects stored for each key is given through the function objectForKey(String key). * * @author Daniel Dreibrodt - * @see java.util.Hashtable - * @see com.dd.plist.NSObject + * @see Foundation NSDictionary documentation + * @see java.util.LinkedHashMap */ public class NSDictionary extends NSObject implements Map { private final HashMap dict; /** - * Creates a new empty NSDictionary. + * Creates a new NSDictionary instance. */ public NSDictionary() { - //With a linked HashMap the order of elements in the dictionary is kept. - dict = new LinkedHashMap(); + this.dict = new LinkedHashMap(); } /** - * Gets the hashmap which stores the keys and values of this dictionary. - * Changes to the hashmap's contents are directly reflected in this - * dictionary. + * Gets the hash map which stores the keys and values of this dictionary. + * Changes to the hash map are directly reflected in this dictionary. * - * @return The hashmap which is used by this dictionary to store its contents. + * @return The hash map which is used by this dictionary to store its contents. */ public HashMap getHashMap() { - return dict; + return this.dict; } /** @@ -74,67 +72,37 @@ public HashMap getHashMap() { * @return The object. */ public NSObject objectForKey(String key) { - return dict.get(key); + return this.dict.get(key); } - /* - * (non-Javadoc) - * - * @see java.util.Map#size() - */ public int size() { - return dict.size(); + return this.dict.size(); } - /* - * (non-Javadoc) - * - * @see java.util.Map#isEmpty() - */ public boolean isEmpty() { - return dict.isEmpty(); + return this.dict.isEmpty(); } - /* - * (non-Javadoc) - * - * @see java.util.Map#containsKey(java.lang.Object) - */ public boolean containsKey(Object key) { - return dict.containsKey(key); + return this.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.fromJavaObject(value); - return dict.containsValue(wrap); + return this.dict.containsValue(wrap); } - /* - * (non-Javadoc) - * - * @see java.util.Map#get(java.lang.Object) - */ public NSObject get(Object key) { - return dict.get(key); + return this.dict.get(key); } - /* - * (non-Javadoc) - * - * @see java.util.Map#putAll(java.util.Map) - */ public void putAll(Map values) { for (Object object : values.entrySet()) { @SuppressWarnings("unchecked") Map.Entry entry = (Map.Entry) object; - put(entry.getKey(), entry.getValue()); + this.put(entry.getKey(), entry.getValue()); } } @@ -151,8 +119,8 @@ public NSObject put(String key, NSObject obj) { if(key == null) return null; if(obj == null) - return dict.get(key); - return dict.put(key, obj); + return this.dict.get(key); + return this.dict.put(key, obj); } /** @@ -165,7 +133,7 @@ public NSObject put(String key, NSObject obj) { * or null, if no value was associated to it. */ public NSObject put(String key, Object obj) { - return put(key, NSObject.fromJavaObject(obj)); + return this.put(key, NSObject.fromJavaObject(obj)); } /** @@ -175,16 +143,11 @@ public NSObject put(String key, Object obj) { * @return the value previously associated to the given key. */ public NSObject remove(String key) { - return dict.remove(key); + return this.dict.remove(key); } - /* - * (non-Javadoc) - * - * @see java.util.Map#remove(java.lang.Object) - */ public NSObject remove(Object key) { - return dict.remove(key); + return this.dict.remove(key); } /** @@ -192,32 +155,17 @@ public NSObject remove(Object key) { * @see java.util.Map#clear() */ public void clear() { - dict.clear(); + this.dict.clear(); } - /* - * (non-Javadoc) - * - * @see java.util.Map#keySet() - */ public Set keySet() { - return dict.keySet(); + return this.dict.keySet(); } - /* - * (non-Javadoc) - * - * @see java.util.Map#values() - */ public Collection values() { return dict.values(); } - /* - * (non-Javadoc) - * - * @see java.util.Map#entrySet() - */ public Set> entrySet() { return dict.entrySet(); } @@ -239,7 +187,7 @@ public boolean containsKey(String key) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(NSObject val) { - return val != null && dict.containsValue(val); + return val != null && this.dict.containsValue(val); } /** @@ -249,7 +197,7 @@ public boolean containsValue(NSObject val) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(String val) { - for (NSObject o : dict.values()) { + for (NSObject o : this.dict.values()) { if (o.getClass().equals(NSString.class)) { NSString str = (NSString) o; if (str.getContent().equals(val)) @@ -266,7 +214,7 @@ public boolean containsValue(String val) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(long val) { - for (NSObject o : dict.values()) { + for (NSObject o : this.dict.values()) { if (o.getClass().equals(NSNumber.class)) { NSNumber num = (NSNumber) o; if (num.isInteger() && num.intValue() == val) @@ -283,7 +231,7 @@ public boolean containsValue(long val) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(double val) { - for (NSObject o : dict.values()) { + for (NSObject o : this.dict.values()) { if (o.getClass().equals(NSNumber.class)) { NSNumber num = (NSNumber) o; if (num.isReal() && num.doubleValue() == val) @@ -300,7 +248,7 @@ public boolean containsValue(double val) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(boolean val) { - for (NSObject o : dict.values()) { + for (NSObject o : this.dict.values()) { if (o.getClass().equals(NSNumber.class)) { NSNumber num = (NSNumber) o; if (num.isBoolean() && num.boolValue() == val) @@ -317,7 +265,7 @@ public boolean containsValue(boolean val) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(Date val) { - for (NSObject o : dict.values()) { + for (NSObject o : this.dict.values()) { if (o.getClass().equals(NSDate.class)) { NSDate dat = (NSDate) o; if (dat.getDate().equals(val)) @@ -334,7 +282,7 @@ public boolean containsValue(Date val) { * @return Whether the key is contained in this dictionary. */ public boolean containsValue(byte[] val) { - for (NSObject o : dict.values()) { + for (NSObject o : this.dict.values()) { if (o.getClass().equals(NSData.class)) { NSData dat = (NSData) o; if (Arrays.equals(dat.bytes(), val)) @@ -350,12 +298,12 @@ public boolean containsValue(byte[] val) { * @return The size of this NSDictionary. */ public int count() { - return dict.size(); + return this.dict.size(); } @Override public boolean equals(Object obj) { - return obj.getClass().equals(this.getClass()) && ((NSDictionary) obj).dict.equals(dict); + return obj.getClass().equals(this.getClass()) && ((NSDictionary) obj).dict.equals(this.dict); } /** @@ -364,7 +312,7 @@ public boolean equals(Object obj) { * @return The list of all keys used in this NSDictionary. */ public String[] allKeys() { - return dict.keySet().toArray(new String[count()]); + return this.dict.keySet().toArray(new String[count()]); } @Override @@ -379,7 +327,7 @@ void toXML(StringBuilder xml, int level) { indent(xml, level); xml.append(""); xml.append(NSObject.NEWLINE); - for (String key : dict.keySet()) { + for (String key : this.dict.keySet()) { NSObject val = objectForKey(key); indent(xml, level + 1); xml.append(""); @@ -405,19 +353,19 @@ void toXML(StringBuilder xml, int level) { void assignIDs(BinaryPropertyListWriter out) { super.assignIDs(out); - for (Map.Entry entry : dict.entrySet()) { + for (Map.Entry entry : this.dict.entrySet()) { new NSString(entry.getKey()).assignIDs(out); } - for (Map.Entry entry : dict.entrySet()) { + for (Map.Entry entry : this.dict.entrySet()) { entry.getValue().assignIDs(out); } } @Override void toBinary(BinaryPropertyListWriter out) throws IOException { - out.writeIntHeader(0xD, dict.size()); - Set> entries = dict.entrySet(); + out.writeIntHeader(0xD, this.dict.size()); + Set> entries = this.dict.entrySet(); for (Map.Entry entry : entries) { out.writeID(out.getID(new NSString(entry.getKey()))); } diff --git a/src/main/java/com/dd/plist/NSNumber.java b/src/main/java/com/dd/plist/NSNumber.java index 32fa086..7265afa 100644 --- a/src/main/java/com/dd/plist/NSNumber.java +++ b/src/main/java/com/dd/plist/NSNumber.java @@ -1,6 +1,6 @@ /* * plist - An open source library to parse and generate property lists - * Copyright (C) 2011 Daniel Dreibrodt, Keith Randall + * Copyright (C) 2011-2017 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 @@ -26,8 +26,8 @@ import java.io.IOException; /** - * A number whose value is either an integer, a real number or boolean. - * + * The NSNumber class wraps a numeric value. The value can be an integer a floating point number or a boolean value. + * @see Foundation NSNumber documentation * @author Daniel Dreibrodt */ public class NSNumber extends NSObject implements Comparable { @@ -51,7 +51,7 @@ public class NSNumber extends NSObject implements Comparable { */ public static final int BOOLEAN = 2; - //Holds the current type of this number + /** Holds the current type of this number */ private int type; private long longValue; @@ -59,28 +59,28 @@ public class NSNumber extends NSObject implements Comparable { private boolean boolValue; /** - * Parses integers and real numbers from their binary representation. - * Note: real numbers are not yet supported. + * Creates a new NSNumber instance from its binary representation. * - * @param bytes The binary representation of only this number - * @param type The type of number + * @param bytes The binary representation of this number. + * @param type The type of number. * @see #INTEGER * @see #REAL + * @see #BOOLEAN */ public NSNumber(byte[] bytes, int type){ this(bytes, 0, bytes.length, type); } /** - * Parses integers and real numbers from their binary representation. - * Note: real numbers are not yet supported. + * Creates a new NSNumber instance from its binary representation. * - * @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 + * @param bytes An array of bytes containing the binary representation of the number. + * @param startIndex The position in the array at which the number is stored. + * @param endIndex The position in the array at which the number's data ends. + * @param type The type of number * @see #INTEGER * @see #REAL + * @see #BOOLEAN */ public NSNumber(byte[] bytes, final int startIndex, final int endIndex, final int type){ switch (type) { @@ -101,7 +101,7 @@ public NSNumber(byte[] bytes, final int startIndex, final int endIndex, final in } /** - * Creates a number from its textual representation. + * Create a NSNumber instance 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. @@ -119,21 +119,21 @@ public NSNumber(String text) { } else { l = Long.parseLong(text); } - doubleValue = longValue = l; - type = INTEGER; + this.doubleValue = this.longValue = l; + this.type = INTEGER; } catch (Exception ex) { try { - doubleValue = Double.parseDouble(text); - longValue = Math.round(doubleValue); - type = REAL; + this.doubleValue = Double.parseDouble(text); + this.longValue = Math.round(doubleValue); + this.type = REAL; } catch (Exception ex2) { try { - boolValue = text.equalsIgnoreCase("true") || text.equalsIgnoreCase("yes"); + this.boolValue = text.equalsIgnoreCase("true") || text.equalsIgnoreCase("yes"); if(!boolValue && !(text.equalsIgnoreCase("false") || text.equalsIgnoreCase("no"))) { throw new Exception("not a boolean"); } - type = BOOLEAN; - doubleValue = longValue = boolValue ? 1 : 0; + this.type = BOOLEAN; + this.doubleValue = this.longValue = this.boolValue ? 1 : 0; } catch (Exception ex3) { throw new IllegalArgumentException("The given string neither represents a double, an int nor a boolean value."); } @@ -142,48 +142,48 @@ public NSNumber(String text) { } /** - * Creates an integer number. + * Creates a new NSNumber instance with the specified value. * * @param i The integer value. */ public NSNumber(int i) { - doubleValue = longValue = i; - type = INTEGER; + this.doubleValue = this.longValue = i; + this.type = INTEGER; } /** - * Creates an integer number. + * Creates a new NSNumber instance with the specified value. * * @param l The long integer value. */ public NSNumber(long l) { - doubleValue = longValue = l; - type = INTEGER; + this.doubleValue = this.longValue = l; + this.type = INTEGER; } /** - * Creates a real number. + * Creates a new NSNumber instance with the specified value. * * @param d The real value. */ public NSNumber(double d) { - longValue = (long) (doubleValue = d); - type = REAL; + this.longValue = (long) (this.doubleValue = d); + this.type = REAL; } /** - * Creates a boolean number. + * Creates a new NSNumber instance with the specified value. * * @param b The boolean value. */ public NSNumber(boolean b) { - boolValue = b; - doubleValue = longValue = b ? 1 : 0; - type = BOOLEAN; + this.boolValue = b; + this.doubleValue = this.longValue = b ? 1 : 0; + this.type = BOOLEAN; } /** - * Gets the type of this number's value. + * Gets the type of this instance's value. * * @return The type flag. * @see #BOOLEAN @@ -191,102 +191,102 @@ public NSNumber(boolean b) { * @see #REAL */ public int type() { - return type; + return this.type; } /** - * Checks whether the value of this NSNumber is a boolean. + * Gets a value indicating whether the value of this NSNumber is a boolean. * * @return Whether the number's value is a boolean. */ public boolean isBoolean() { - return type == BOOLEAN; + return this.type == BOOLEAN; } /** - * Checks whether the value of this NSNumber is an integer. + * Gets a value indicating whether the value of this NSNumber is an integer. * * @return Whether the number's value is an integer. */ public boolean isInteger() { - return type == INTEGER; + return this.type == INTEGER; } /** - * Checks whether the value of this NSNumber is a real number. + * Gets a value indicating 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; + return this.type == REAL; } /** - * Gets the number's boolean value. + * Gets this instance's boolean value. * * @return true if the value is true or non-zero, false otherwise. */ public boolean boolValue() { - if (type == BOOLEAN) - return boolValue; + if (this.type == BOOLEAN) + return this.boolValue; else - return longValue != 0; + return this.doubleValue() != 0; } /** - * The number's long value. + * Gets this instance's long integer value. * - * @return The value of the number as long + * @return The value of the number as a long. */ public long longValue() { - return longValue; + return this.longValue; } /** - * Gets the number's int value. + * Gets this instance's integer value. * 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. + * Otherwise the value might be inaccurate. * - * @return The value of the number as int + * @return The value of the number as an int. */ public int intValue() { - return (int) longValue; + return (int) this.longValue; } /** - * Gets the number's double value. + * Gets this instance's double value. * - * @return The value of the number as double. + * @return The value of the number as a double. */ public double doubleValue() { - return doubleValue; + return this.doubleValue; } /** - * Gets the number's float value. + * Gets this instance's float value. * WARNING: Possible loss of precision if the value is outside the float range. * - * @return The value of the number as float. + * @return The value of the number as a float. */ public float floatValue() { - return (float) doubleValue; + return (float) this.doubleValue; } /** - * Gets the number's value expressed as a human-readable string. + * Gets this instance's value expressed as a human-readable string. * @return The human-readable string representation of this number. */ public String stringValue() { - switch (type) { + switch (this.type()) { case INTEGER: { - return String.valueOf(longValue()); + return String.valueOf(this.longValue()); } case REAL: { - return String.valueOf(doubleValue()); + return String.valueOf(this.doubleValue()); } case BOOLEAN: { - return String.valueOf(boolValue()); + return String.valueOf(this.boolValue()); } default: { throw new IllegalStateException(); @@ -305,7 +305,7 @@ public boolean equals(Object obj) { if (obj == null) return false; if (this.getClass() != obj.getClass()) return false; NSNumber n = (NSNumber) obj; - return type == n.type && longValue == n.longValue && doubleValue == n.doubleValue && boolValue == n.boolValue; + return this.type == n.type && this.longValue == n.longValue && this.doubleValue == n.doubleValue && this.boolValue == n.boolValue; } @Override @@ -317,18 +317,17 @@ public int hashCode() { return hash; } - @Override public String toString() { - switch (type) { + switch (this.type()) { case INTEGER: { - return String.valueOf(longValue()); + return String.valueOf(this.longValue()); } case REAL: { - return String.valueOf(doubleValue()); + return String.valueOf(this.doubleValue()); } case BOOLEAN: { - return String.valueOf(boolValue()); + return String.valueOf(this.boolValue()); } default: { return super.toString(); @@ -339,16 +338,16 @@ public String toString() { @Override void toXML(StringBuilder xml, int level) { indent(xml, level); - switch (type) { + switch (this.type()) { case INTEGER: { xml.append(""); - xml.append(longValue()); + xml.append(this.longValue()); xml.append(""); break; } case REAL: { xml.append(""); - xml.append(doubleValue()); + xml.append(this.doubleValue()); xml.append(""); break; } @@ -366,33 +365,33 @@ void toXML(StringBuilder xml, int level) { @Override void toBinary(BinaryPropertyListWriter out) throws IOException { - switch (type()) { + switch (this.type()) { case INTEGER: { if (longValue() < 0) { out.write(0x13); - out.writeBytes(longValue(), 8); - } else if (longValue() <= 0xff) { + out.writeBytes(this.longValue(), 8); + } else if (this.longValue() <= 0xff) { out.write(0x10); - out.writeBytes(longValue(), 1); - } else if (longValue() <= 0xffff) { + out.writeBytes(this.longValue(), 1); + } else if (this.longValue() <= 0xffff) { out.write(0x11); - out.writeBytes(longValue(), 2); - } else if (longValue() <= 0xffffffffL) { + out.writeBytes(this.longValue(), 2); + } else if (this.longValue() <= 0xffffffffL) { out.write(0x12); - out.writeBytes(longValue(), 4); + out.writeBytes(this.longValue(), 4); } else { out.write(0x13); - out.writeBytes(longValue(), 8); + out.writeBytes(this.longValue(), 8); } break; } case REAL: { out.write(0x23); - out.writeDouble(doubleValue()); + out.writeDouble(this.doubleValue()); break; } case BOOLEAN: { - out.write(boolValue() ? 0x09 : 0x08); + out.write(this.boolValue() ? 0x09 : 0x08); break; } default: @@ -403,8 +402,8 @@ void toBinary(BinaryPropertyListWriter out) throws IOException { @Override protected void toASCII(StringBuilder ascii, int level) { indent(ascii, level); - if (type == BOOLEAN) { - ascii.append(boolValue ? "YES" : "NO"); + if (this.isBoolean()) { + ascii.append(this.boolValue() ? "YES" : "NO"); } else { ascii.append(toString()); } @@ -413,21 +412,21 @@ protected void toASCII(StringBuilder ascii, int level) { @Override protected void toASCIIGnuStep(StringBuilder ascii, int level) { indent(ascii, level); - switch (type) { + switch (this.type()) { case INTEGER: { ascii.append("<*I"); - ascii.append(toString()); + ascii.append(this.toString()); ascii.append('>'); break; } case REAL: { ascii.append("<*R"); - ascii.append(toString()); + ascii.append(this.toString()); ascii.append('>'); break; } case BOOLEAN: { - if (boolValue) { + if (this.boolValue()) { ascii.append("<*BY>"); } else { ascii.append("<*BN>"); @@ -439,7 +438,7 @@ protected void toASCIIGnuStep(StringBuilder ascii, int level) { } public int compareTo(Object o) { - double x = doubleValue(); + double x = this.doubleValue(); double y; if (o instanceof NSNumber) { NSNumber num = (NSNumber) o; diff --git a/src/main/java/com/dd/plist/NSSet.java b/src/main/java/com/dd/plist/NSSet.java index 8ed3a23..9179732 100644 --- a/src/main/java/com/dd/plist/NSSet.java +++ b/src/main/java/com/dd/plist/NSSet.java @@ -27,7 +27,7 @@ import java.util.*; /** - * A set is an interface to an unordered collection of objects. + * The NSSet class is an unordered collection of NSObject instances. * This implementation uses a LinkedHashSet or TreeSetas the underlying * data structure. * @@ -41,7 +41,7 @@ public class NSSet extends NSObject { private boolean ordered = false; /** - * Creates an empty unordered set. + * Creates a new NSSet instance. The created set is unordered. * * @see java.util.LinkedHashSet */ @@ -50,7 +50,7 @@ public NSSet() { } /** - * Creates an empty set. + * Creates a new NSSet instance. * * @param ordered Indicates whether the created set should be ordered or unordered. * @see java.util.LinkedHashSet @@ -65,7 +65,7 @@ public NSSet(boolean ordered) { } /** - * Create a set and fill it with the given objects. + * Creates a new NSSet instance with the specified content. The created set is unordered. * * @param objects The objects to populate the set. * @see java.util.LinkedHashSet @@ -76,7 +76,7 @@ public NSSet(NSObject... objects) { } /** - * Create a set and fill it with the given objects. + * Create a new NSSet instance with the specified content. * * @param ordered Indicates whether the created set should be ordered or unordered. * @param objects The objects to populate the set. @@ -133,7 +133,7 @@ public synchronized NSObject anyObject() { } /** - * Finds out whether a given object is contained in the set. + * Finds out whether the given object is contained in the set. * * @param obj The object to look for. * @return true, when the object was found, false otherwise. @@ -143,7 +143,7 @@ public boolean containsObject(NSObject obj) { } /** - * Determines whether the set contains an object equal to a given object + * Determines whether the set contains an object equal to the given object * and returns that object if it is present. * * @param obj The object to look for. @@ -234,7 +234,7 @@ public synchronized int count() { } /** - * Returns the XML representantion for this set. + * Returns the XML representation for this set. * There is no official XML representation specified for sets. * In this implementation it is represented by an array. * diff --git a/src/main/java/com/dd/plist/NSString.java b/src/main/java/com/dd/plist/NSString.java index b2d098e..9590380 100644 --- a/src/main/java/com/dd/plist/NSString.java +++ b/src/main/java/com/dd/plist/NSString.java @@ -1,6 +1,6 @@ /* * plist - An open source library to parse and generate property lists - * Copyright (C) 2011 Daniel Dreibrodt + * Copyright (C) 2011-2017 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 @@ -32,9 +32,10 @@ import java.util.Scanner; /** - * A NSString contains a string. + * The NSString class is a wrapper for a string. * * @author Daniel Dreibrodt + * @see Foundation NSString documentation */ public class NSString extends NSObject implements Comparable { @@ -43,10 +44,10 @@ public class NSString extends NSObject implements Comparable { private static CharsetEncoder asciiEncoder, utf16beEncoder, utf8Encoder; /** - * Creates an NSString from its binary representation. + * Creates a new NSString instance from its binary representation. * * @param bytes The binary representation. - * @param encoding The encoding of the binary representation, the name of a supported charset. + * @param encoding The string encoding (name of the charset). * @throws UnsupportedEncodingException When the given encoding is not supported by the JRE. * @see java.lang.String#String(byte[], String) */ @@ -55,21 +56,21 @@ public NSString(byte[] bytes, String encoding) throws UnsupportedEncodingExcepti } /** - * Creates an NSString from its binary representation. + * Creates a new NSString instance 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. + * @param bytes An array containing the binary representation of the string. + * @param startIndex The offset inside the array at which the string data starts. + * @param endIndex The offset inside the array at which the string data ends. + * @param encoding The string encoding (name of the charset). * @throws UnsupportedEncodingException When the given encoding is not supported by the JRE. - * @see java.lang.String#String(byte[], String) + * @see java.lang.String#String(byte[], int, int, 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. + * Creates a new NSString instance with the specified content. * * @param string The string that will be contained in the NSString. */ @@ -101,7 +102,7 @@ public int intValue() { } /** - * Gets the float value of this string. + * Gets the floating-point value of this string. * * @return The floating-point value of this string, assuming a decimal representation * and skipping whitespace at the beginning of the string. If the string @@ -124,7 +125,7 @@ public float floatValue() { } /** - * Gets the float value of this string. + * Gets the floating-point value (double precision) of this string. * * @return The floating-point value of this string, assuming a decimal representation * and skipping whitespace at the beginning of the string. If the string does not contain @@ -168,16 +169,16 @@ public boolean boolValue() { } /** - * Gets this string's content. + * Gets the string content of this instance. * - * @return This NSString as Java String object. + * @return This string contained in this instance. */ public String getContent() { return content; } /** - * Sets the contents of this string. + * Sets the string content of this instance. * * @param c The new content of this string object. */ @@ -233,11 +234,6 @@ public int hashCode() { return content.hashCode(); } - /** - * The textual representation of this NSString. - * - * @return The NSString's contents. - */ @Override public String toString() { return content; @@ -328,6 +324,16 @@ protected void toASCIIGnuStep(StringBuilder ascii, int level) { ascii.append("\""); } + 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; + } + } + /** * Escapes a string for use in ASCII property lists. * @@ -364,14 +370,4 @@ static String escapeStringForASCII(String s) { } return out.toString(); } - - 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/src/main/java/com/dd/plist/UID.java b/src/main/java/com/dd/plist/UID.java index 11f8d21..252c610 100644 --- a/src/main/java/com/dd/plist/UID.java +++ b/src/main/java/com/dd/plist/UID.java @@ -25,7 +25,8 @@ import java.io.IOException; /** - * A UID. Only found in binary property lists that are keyed archives. + * The UID class holds a unique identifier. + * Only found in binary property lists that are keyed archives. * * @author Daniel Dreibrodt */ @@ -34,24 +35,37 @@ public class UID extends NSObject { private final byte[] bytes; private final String name; + /** + * Creates a new UID instance. + * @param name The UID name. + * @param bytes The UID value. + */ public UID(String name, byte[] bytes) { this.name = name; this.bytes = bytes; } + /** + * Gets this instance's value. + * @return The UID's value. + */ public byte[] getBytes() { return bytes; } + /** + * Gets this instance's name. + * @return The UID's name. + */ 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. + * In this implementation UIDs are represented as hexadecimal strings in the XML output. * - * @param xml The xml StringBuilder + * @param xml The XML StringBuilder * @param level The indentation level */ @Override diff --git a/src/test/java/com/dd/plist/test/NSStringTest.java b/src/test/java/com/dd/plist/test/NSStringTest.java index 2291c4c..dc6705a 100644 --- a/src/test/java/com/dd/plist/test/NSStringTest.java +++ b/src/test/java/com/dd/plist/test/NSStringTest.java @@ -9,6 +9,7 @@ import static org.junit.Assert.assertFalse; /** + * Tests for the NSString class. * @author Daniel Dreibrodt */ public class NSStringTest {