package ns.foundation; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.util.Arrays; public class NSData implements Serializable, Cloneable { public static final NSData EmptyData = new NSData(); protected byte[] _bytes; protected NSRange _range; public NSData() { this(new byte[0], NSRange.ZeroRange, false); } public NSData(byte[] bytes) { this(bytes, new NSRange(0, bytes.length), false); } public NSData(byte[] bytes, int offset, int count) { this(bytes,new NSRange(offset, count), false); } public NSData(byte[] bytes, NSRange range) { this(bytes, range, false); } public NSData(byte[] bytes, NSRange range, boolean noCopy) { if (noCopy) { _bytes = bytes; _range = range; } else { _bytes = new byte[range.length()]; for (int i = 0, j = range.location(); i < bytes.length; i++, j++) { _bytes[i] = bytes[j]; } _range = new NSRange(0, _bytes.length); } } public NSData(NSData otherData) { this(otherData.bytes()); } // private static byte[] bytesWithEncoding(String value, String encoding) { // try { // return value.getBytes(encoding); // } catch (UnsupportedEncodingException e) { // throw new RuntimeException(e); // } // } // // public NSData(String value, String encoding) throws UnsupportedEncodingException { // this(bytesWithEncoding(value, encoding)); // } public byte[] bytes() { return bytes(0, _range.length()); } public byte[] bytes(int offset, int length) { byte[] result = new byte[length]; for (int i = 0, j = _range.location() + offset; i < result.length; i++, j++) { result[i] = _bytes[j]; } return result; } public byte[] bytes(NSRange range) { return bytes(range.location(), range.length()); } protected byte[] bytesNoCopy() { return _bytes; } public int _offset() { return _range.location(); } public void writeToStream(OutputStream stream) throws IOException { stream.write(bytesNoCopy(), _offset(), length()); } @Override public Object clone() { return this; } protected byte[] immutableBytes() { return _bytes; } protected NSRange immutableRange() { return _range; } public boolean isEqualToData(NSData otherData) { return this.equals(otherData); } public int length() { return _range.length(); } public NSData subdataWithRange(NSRange range) { return new NSData(bytes(range)); } // public void writeToStream(OutputStream stream) throws IOException { // stream.write(_bytes); // } @Override public String toString() { return Arrays.toString(bytes()); } public String _hexString() { byte bytes[] = bytes(); StringBuilder result = new StringBuilder(2 * length()); for(int i = 0; i < length(); i++) { int b = bytes[i] & 255; result.append(Integer.toHexString(b).toUpperCase()); } return result.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(_bytes); result = prime * result + ((_range == null) ? 0 : _range.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final NSData other = (NSData) obj; if (!Arrays.equals(_bytes, other._bytes)) { return false; } if (_range == null) { if (other._range != null) { return false; } } else if (!_range.equals(other._range)) { return false; } return true; } }