/* * 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); } }