View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Blacksmith, Inc.
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.foundation;
20  
21  import java.io.ByteArrayOutputStream;
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.InputStream;
25  
26  /***
27  * A pure java implementation of NSData, which
28  * is basically a wrapper on a byte array.
29  *
30  * @author michael@mpowers.net
31  * @author $Author: cgruber $
32  * @version $Revision: 893 $
33  */
34  public class NSData
35  {
36      public static final NSData EmptyData = new NSData();
37  
38      protected byte[] bytes;
39  
40      /***
41      * Default constructor creates a zero-data object.
42      */
43      public NSData ()
44      {
45      	bytes = new byte[0];
46      }
47  
48      /***
49      * Creates an object containing a copy of the specified bytes.
50      */
51      public NSData (byte[] data)
52      {
53      	this( data, 0, data.length );
54      }
55  
56      /***
57      * Creates an object containing a copy of the bytes from the specified 
58      * array within the specified range.
59      */
60      public NSData (byte[] data, int start, int length)
61      {
62      	bytes = new byte[ length ];
63  	    for ( int i = 0; i < length; i++ )
64  	    {
65  	    	bytes[i] = data[ start+i ];
66  	    }
67      }
68  
69      /***
70      * Creates an object containing the bytes of the specified string.
71      */
72      public NSData (String aString)
73      {
74      	this( aString.getBytes() );
75      }
76  
77      /***
78      * Creates an object containing the contents of the specified file.
79      * Errors reading the file will produce an empty or partially blank array.
80      */
81      public NSData (File aFile)
82      {
83      	int len = (int) aFile.length();
84  	    byte[] data = new byte[ len ];
85  	    try
86  	    {
87  	    	new java.io.FileInputStream( aFile ).read( data );
88  	    }
89  	    catch ( Exception exc )
90  	    {	
91  	    	// produce an empty or partially blank array
92  	    }
93  		bytes = data;
94      }
95  
96      /***
97      * Creates an object containing the contents of the specified URL.
98      */
99      public NSData (java.net.URL aURL)
100     {
101     	throw new RuntimeException( "Not Implemented" );
102     }
103 
104     /***
105     * Creates an object containing a copy of the contents of the 
106     * specified NSData object.
107     */
108     public NSData (NSData aData)
109     {
110     	this( aData.bytes() );
111     }
112 
113 	/***
114 	 * Creates a new NSData object from the bytes in the input stream.
115 	 * The input stream is read fully and is not closed.
116 	 * @param stream The stream to read from.
117 	 * @param chunkSize The buffer size used to read from the stream.
118 	 * @throws IOException if the stream cannot be read from.
119 	 */
120 	public NSData(InputStream stream, int chunkSize) throws IOException {
121 		super();
122 		byte[] b = new byte[chunkSize];
123 		ByteArrayOutputStream bout = new ByteArrayOutputStream();
124 		int read = 0;
125 		do {
126 			read = stream.read(b);
127 			if (read > 0)
128 				bout.write(b, 0, read);
129 		} while (read > 0);
130 		bytes = bout.toByteArray();
131 	}
132 
133     /***
134     * Returns the length of the contained data.
135     */
136     public int length ()
137     {
138     	return bytes.length;
139     }
140 
141     /***
142     * Returns whether the specified data is equivalent to these data.
143     */
144     public boolean isEqualToData (NSData aData)
145     {
146     	if (length() != aData.length())
147     		return false;
148     	byte[] a = bytes();
149     	byte[] b = aData.bytes();
150 	    
151 	    for ( int i = 0; i < a.length; i++ ) {
152 			if ( a[i] != b[i] )
153 				return false;
154 		}
155 		return true;
156     }
157 
158     /***
159     * Return the bytes within the data that fall within the specified range.
160     */
161     public NSData subdataWithRange (NSRange aRange)
162     {
163     	int loc = aRange.location();
164     	byte[] src = bytes();
165     	byte[] data = new byte[ aRange.length() ];
166     	System.arraycopy(src, loc, data, 0, data.length);
167 	    return new NSData( data );
168     }
169 
170     /***
171     * Writes the contents of this data to the specified URL.
172     * If atomically is true, then the data is written to a temporary
173     * file and then renamed to the name specified by the URL when
174     * the data transfer is complete.
175     */
176     public boolean writeToURL (java.net.URL aURL, boolean atomically)
177     {
178     	throw new RuntimeException( "Not Implemented" );
179     }
180 
181     /***
182     * Convenience to return the contents of the specified file.
183     */
184     public static NSData dataWithContentsOfMappedFile (java.io.File aFile)
185     {
186     	return new NSData( aFile );
187     }
188 
189     /***
190     * Returns a copy of the bytes starting at the specified location 
191     * and ranging for the specified length.
192     */
193     public byte[] bytes (int location, int length)
194     {
195     	byte[] data = new byte[ length ];
196 	    for ( int i = 0; i < length; i++ )
197 	    {
198 	    	data[i] = bytes[ location + i ];
199 	    }
200 	    return data;
201     }
202     
203     /***
204     * Returns a copy of the bytes backing this data object.
205     * NOTE: This method is not in the NSData spec and is
206     * included for convenience only.
207     */
208     public byte[] bytes()
209     {
210     	return bytes( 0, length() );
211     }
212 
213     public String toString() {
214         String hex = "0123456789ABCDEF";
215         StringBuffer buf = new StringBuffer();
216         buf.append(NSPropertyListSerialization.TOKEN_BEGIN[NSPropertyListSerialization.PLIST_DATA]);
217         for (int i = 0; i < bytes.length; i++) {
218             byte b = bytes[i];
219             buf.append(hex.charAt((b & 0xf0) >> 4));
220             buf.append(hex.charAt(b & 0x0f));
221             if (i % 5 == 4)
222                 buf.append(' ');
223         }
224         buf.append(NSPropertyListSerialization.TOKEN_END[NSPropertyListSerialization.PLIST_DATA]);
225         return buf.toString();
226     }
227 
228 	public boolean isEqual(Object obj) {
229 		if (obj == this)
230 			return true;
231 		if (obj instanceof NSData)
232 			return isEqualToData((NSData)obj);
233 		return false;
234 	}
235 
236 }
237 
238 /*
239  * $Log$
240  * Revision 1.2  2006/02/16 13:15:00  cgruber
241  * Check in all sources in eclipse-friendly maven-enabled packages.
242  *
243  * Revision 1.5  2003/08/19 01:53:52  chochos
244  * added constructor with an InputStream
245  *
246  * Revision 1.4  2003/08/05 00:51:31  chochos
247  * get the enclosing tokens from NSPropertyListSerialization
248  *
249  * Revision 1.3  2003/08/04 22:45:47  chochos
250  * toString() prints out the bytes in hex (in property list format)
251  *
252  * Revision 1.2  2003/08/02 01:52:00  chochos
253  * added EmptyData
254  *
255  * Revision 1.1.1.1  2000/12/21 15:47:26  mpowers
256  * Contributing wotonomy.
257  *
258  * Revision 1.3  2000/12/20 16:25:38  michael
259  * Added log to all files.
260  *
261  *
262  */
263