25 import java.util.Vector; |
25 import java.util.Vector; |
26 |
26 |
27 |
27 |
28 public class OSCJavaToByteArrayConverter { |
28 public class OSCJavaToByteArrayConverter { |
29 |
29 |
30 protected ByteArrayOutputStream stream = new ByteArrayOutputStream(); |
30 protected ByteArrayOutputStream stream = new ByteArrayOutputStream(); |
31 private byte[] intBytes = new byte[4]; |
31 private byte[] intBytes = new byte[4]; |
32 |
32 |
33 /*public OSCJavaToByteArrayConverter() { |
33 /*public OSCJavaToByteArrayConverter() { |
34 super(); |
34 super(); |
35 }*/ |
35 }*/ |
36 |
36 |
37 /** |
37 /** |
38 * Creation date: (2/23/2001 2:43:25 AM) |
38 * Creation date: (2/23/2001 2:43:25 AM) |
39 * @param anArray java.lang.Object[] |
39 * @param anArray java.lang.Object[] |
40 * |
40 * |
41 */ |
41 */ |
42 public void appendNullCharToAlignStream() { |
42 public void appendNullCharToAlignStream() { |
43 int mod = stream.size() % 4; |
43 int mod = stream.size() % 4; |
44 int pad = 4 - mod; |
44 int pad = 4 - mod; |
45 for (int i = 0; i < pad; i++) |
45 for (int i = 0; i < pad; i++) |
46 stream.write(0); |
46 stream.write(0); |
47 } |
47 } |
48 |
48 |
49 /** |
49 /** |
50 * Creation date: (2/23/2001 2:21:53 AM) |
50 * Creation date: (2/23/2001 2:21:53 AM) |
51 * @return byte[] |
51 * @return byte[] |
52 */ |
52 */ |
53 public byte[] toByteArray() { |
53 public byte[] toByteArray() { |
54 return stream.toByteArray(); |
54 return stream.toByteArray(); |
55 } |
55 } |
56 |
56 |
57 /** |
57 /** |
58 * Creation date: (2/23/2001 2:14:23 AM) |
58 * Creation date: (2/23/2001 2:14:23 AM) |
59 * @param bytes byte[] |
59 * @param bytes byte[] |
60 */ |
60 */ |
61 public void write(byte[] bytes) { |
61 public void write(byte[] bytes) { |
62 writeBigEndToFourByteBoundry(bytes); |
62 writeBigEndToFourByteBoundry(bytes); |
63 } |
63 } |
64 |
64 |
65 /** |
65 /** |
66 * Creation date: (2/23/2001 2:21:04 AM) |
66 * Creation date: (2/23/2001 2:21:04 AM) |
67 * @param i int |
67 * @param i int |
68 */ |
68 */ |
69 public void write(int i) { |
69 public void write(int i) { |
70 writeIntegerToByteArray(i); |
70 writeIntegerToByteArray(i); |
71 } |
71 } |
72 |
72 |
73 /** |
73 /** |
74 * Creation date: (2/23/2001 2:03:57 AM) |
74 * Creation date: (2/23/2001 2:03:57 AM) |
75 * @param f java.lang.Float |
75 * @param f java.lang.Float |
76 */ |
76 */ |
77 public void write(Float f) { |
77 public void write(Float f) { |
78 writeIntegerToByteArray(Float.floatToIntBits(f.floatValue())); |
78 writeIntegerToByteArray(Float.floatToIntBits(f.floatValue())); |
79 } |
79 } |
80 |
80 |
81 /** |
81 /** |
82 * Creation date: (2/23/2001 2:08:36 AM) |
82 * Creation date: (2/23/2001 2:08:36 AM) |
83 * @param i java.lang.Integer |
83 * @param i java.lang.Integer |
84 */ |
84 */ |
85 public void write(Integer i) { |
85 public void write(Integer i) { |
86 writeIntegerToByteArray(i.intValue()); |
86 writeIntegerToByteArray(i.intValue()); |
87 } |
87 } |
88 |
88 |
89 /** |
89 /** |
90 * Creation date: (2/23/2001 1:57:35 AM) |
90 * Creation date: (2/23/2001 1:57:35 AM) |
91 * @param str java.lang.String |
91 * @param str java.lang.String |
92 */ |
92 */ |
93 public void write(String str) { |
93 public void write(String str) { |
94 writeLittleEndToFourByteBoundry(str.getBytes()); |
94 writeLittleEndToFourByteBoundry(str.getBytes()); |
95 } |
95 } |
96 |
96 |
97 /** |
97 /** |
98 * Creation date: (2/23/2001 2:08:36 AM) |
98 * Creation date: (2/23/2001 2:08:36 AM) |
99 * @param c char |
99 * @param c char |
100 */ |
100 */ |
101 public void write(char c) { |
101 public void write(char c) { |
102 stream.write(c); |
102 stream.write(c); |
103 } |
103 } |
104 |
104 |
105 /** |
105 /** |
106 * Creation date: (2/23/2001 2:02:54 AM) |
106 * Creation date: (2/23/2001 2:02:54 AM) |
107 * @param anObject java.lang.Object |
107 * @param anObject java.lang.Object |
108 */ |
108 */ |
109 public void write(Object anObject) { |
109 public void write(Object anObject) { |
110 // Can't do switch on class |
110 // Can't do switch on class |
111 if (null == anObject) |
111 if (null == anObject) |
112 return; |
112 return; |
113 if (anObject instanceof Float) { |
113 if (anObject instanceof Float) { |
114 write((Float) anObject); |
114 write((Float) anObject); |
115 return; |
115 return; |
116 } |
116 } |
117 if (anObject instanceof String) { |
117 if (anObject instanceof String) { |
118 write((String) anObject); |
118 write((String) anObject); |
119 return; |
119 return; |
120 } |
120 } |
121 if (anObject instanceof Integer) { |
121 if (anObject instanceof Integer) { |
122 write((Integer) anObject); |
122 write((Integer) anObject); |
123 return; |
123 return; |
124 } |
124 } |
125 } |
125 } |
126 |
126 |
127 /** |
127 /** |
128 * Creation date: (2/23/2001 2:43:25 AM) |
128 * Creation date: (2/23/2001 2:43:25 AM) |
129 * @param aClass Class |
129 * @param aClass Class |
130 */ |
130 */ |
131 public void writeType(Class c) { |
131 public void writeType(Class c) { |
132 // A big ol' case statement -- what's polymorphism mean, again? |
132 // A big ol' case statement -- what's polymorphism mean, again? |
133 // I really wish I could extend the base classes! |
133 // I really wish I could extend the base classes! |
134 |
134 |
135 // use the appropriate flags to tell SuperCollider what kind of |
135 // use the appropriate flags to tell SuperCollider what kind of |
136 // thing it is looking at |
136 // thing it is looking at |
137 |
137 |
138 if (Integer.class.equals(c)) { |
138 if (Integer.class.equals(c)) { |
139 stream.write('i'); |
139 stream.write('i'); |
140 return; |
140 return; |
141 } |
141 } |
142 if (java.math.BigInteger.class.equals(c)) { |
142 if (java.math.BigInteger.class.equals(c)) { |
143 stream.write('h'); |
143 stream.write('h'); |
144 return; |
144 return; |
145 } |
145 } |
146 if (Float.class.equals(c)) { |
146 if (Float.class.equals(c)) { |
147 stream.write('f'); |
147 stream.write('f'); |
148 return; |
148 return; |
149 } |
149 } |
150 if (Double.class.equals(c)) { |
150 if (Double.class.equals(c)) { |
151 stream.write('d'); |
151 stream.write('d'); |
152 return; |
152 return; |
153 } |
153 } |
154 if (String.class.equals(c)) { |
154 if (String.class.equals(c)) { |
155 stream.write('s'); |
155 stream.write('s'); |
156 return; |
156 return; |
157 } |
157 } |
158 if (Character.class.equals(c)) { |
158 if (Character.class.equals(c)) { |
159 stream.write('c'); |
159 stream.write('c'); |
160 return; |
160 return; |
161 } |
161 } |
162 } |
162 } |
163 |
163 |
164 /** |
164 /** |
165 * Creation date: (2/23/2001 2:43:25 AM) |
165 * Creation date: (2/23/2001 2:43:25 AM) |
166 * @param anArray java.lang.Object[] |
166 * @param anArray java.lang.Object[] |
167 */ |
167 */ |
168 public void writeTypesArray(Object[] array) { |
168 public void writeTypesArray(Object[] array) { |
169 // A big ol' case statement in a for loop -- what's polymorphism mean, again? |
169 // A big ol' case statement in a for loop -- what's polymorphism mean, again? |
170 // I really wish I could extend the base classes! |
170 // I really wish I could extend the base classes! |
171 |
171 |
172 for (int i = 0; i < array.length; i++) { |
172 for (int i = 0; i < array.length; i++) { |
173 if (null == array[i]) |
173 if (null == array[i]) |
174 continue; |
174 continue; |
175 // if the array at i is a type of array write a [ |
175 // if the array at i is a type of array write a [ |
176 // This is used for nested arguments |
176 // This is used for nested arguments |
177 if (array[i].getClass().isArray()) { |
177 if (array[i].getClass().isArray()) { |
178 stream.write('['); |
178 stream.write('['); |
179 // fill the [] with the SuperCollider types corresponding to the object |
179 // fill the [] with the SuperCollider types corresponding to the object |
180 // (i.e. Object of type String needs -s). |
180 // (i.e. Object of type String needs -s). |
181 writeTypesArray((Object[]) array[i]); |
181 writeTypesArray((Object[]) array[i]); |
182 // close the array |
182 // close the array |
183 stream.write(']'); |
183 stream.write(']'); |
184 continue; |
184 continue; |
185 } |
185 } |
186 // Create a way to deal with Boolean type objects |
186 // Create a way to deal with Boolean type objects |
187 if (Boolean.TRUE.equals(array[i])) { |
187 if (Boolean.TRUE.equals(array[i])) { |
188 stream.write('T'); |
188 stream.write('T'); |
189 continue; |
189 continue; |
190 } |
190 } |
191 if (Boolean.FALSE.equals(array[i])) { |
191 if (Boolean.FALSE.equals(array[i])) { |
192 stream.write('F'); |
192 stream.write('F'); |
193 continue; |
193 continue; |
194 } |
194 } |
195 // go through the array and write the superCollider types as shown in the |
195 // go through the array and write the superCollider types as shown in the |
196 // above method. the Classes derived here are used as the arg to the above method |
196 // above method. the Classes derived here are used as the arg to the above method |
197 writeType(array[i].getClass()); |
197 writeType(array[i].getClass()); |
198 } |
198 } |
199 // align the stream with padded bytes |
199 // align the stream with padded bytes |
200 appendNullCharToAlignStream(); |
200 appendNullCharToAlignStream(); |
201 } |
201 } |
202 |
202 |
203 /** |
203 /** |
204 * Same as writeSuperColliderTypes(Object[]), just that it takes a vector (for jdk1.1 |
204 * Same as writeSuperColliderTypes(Object[]), just that it takes a vector (for jdk1.1 |
205 * compatibility), rather than an array. |
205 * compatibility), rather than an array. |
206 * @param vector the collection I am to write out types for |
206 * @param vector the collection I am to write out types for |
207 */ |
207 */ |
208 public void writeTypes(Vector vector) { |
208 public void writeTypes(Vector vector) { |
209 // A big ol' case statement in a for loop -- what's polymorphism mean, again? |
209 // A big ol' case statement in a for loop -- what's polymorphism mean, again? |
210 // I really wish I could extend the base classes! |
210 // I really wish I could extend the base classes! |
211 |
211 |
212 Enumeration enm = vector.elements(); |
212 Enumeration enm = vector.elements(); |
213 Object nextObject; |
213 Object nextObject; |
214 while (enm.hasMoreElements()) { |
214 while (enm.hasMoreElements()) { |
215 nextObject = enm.nextElement(); |
215 nextObject = enm.nextElement(); |
216 if (null == nextObject) |
216 if (null == nextObject) |
217 continue; |
217 continue; |
218 // if the array at i is a type of array write a [ |
218 // if the array at i is a type of array write a [ |
219 // This is used for nested arguments |
219 // This is used for nested arguments |
220 if (nextObject.getClass().isArray()) { |
220 if (nextObject.getClass().isArray()) { |
221 stream.write('['); |
221 stream.write('['); |
222 // fill the [] with the SuperCollider types corresponding to the object |
222 // fill the [] with the SuperCollider types corresponding to the object |
223 // (e.g., Object of type String needs -s). |
223 // (e.g., Object of type String needs -s). |
224 writeTypesArray((Object[]) nextObject); |
224 writeTypesArray((Object[]) nextObject); |
225 // close the array |
225 // close the array |
226 stream.write(']'); |
226 stream.write(']'); |
227 continue; |
227 continue; |
228 } |
228 } |
229 // Create a way to deal with Boolean type objects |
229 // Create a way to deal with Boolean type objects |
230 if (Boolean.TRUE.equals(nextObject)) { |
230 if (Boolean.TRUE.equals(nextObject)) { |
231 stream.write('T'); |
231 stream.write('T'); |
232 continue; |
232 continue; |
233 } |
233 } |
234 if (Boolean.FALSE.equals(nextObject)) { |
234 if (Boolean.FALSE.equals(nextObject)) { |
235 stream.write('F'); |
235 stream.write('F'); |
236 continue; |
236 continue; |
237 } |
237 } |
238 // go through the array and write the superCollider types as shown in the |
238 // go through the array and write the superCollider types as shown in the |
239 // above method. the Classes derived here are used as the arg to the above method |
239 // above method. the Classes derived here are used as the arg to the above method |
240 writeType(nextObject.getClass()); |
240 writeType(nextObject.getClass()); |
241 } |
241 } |
242 // align the stream with padded bytes |
242 // align the stream with padded bytes |
243 appendNullCharToAlignStream(); |
243 appendNullCharToAlignStream(); |
244 } |
244 } |
245 |
245 |
246 /** |
246 /** |
247 * convert an integer to byte array |
247 * convert an integer to byte array |
248 * |
248 * |
249 * @param value int |
249 * @param value int |
250 */ |
250 */ |
251 private void writeIntegerToByteArray(int value) { |
251 private void writeIntegerToByteArray(int value) { |
252 byte[] intBytes = new byte[4]; |
252 byte[] intBytes = new byte[4]; |
253 |
253 |
254 intBytes[3] = (byte)value; value>>>=8; |
254 intBytes[3] = (byte)value; value>>>=8; |
255 intBytes[2] = (byte)value; value>>>=8; |
255 intBytes[2] = (byte)value; value>>>=8; |
256 intBytes[1] = (byte)value; value>>>=8; |
256 intBytes[1] = (byte)value; value>>>=8; |
257 intBytes[0] = (byte)value; |
257 intBytes[0] = (byte)value; |
258 |
258 |
259 try { |
259 try { |
260 stream.write(intBytes); |
260 stream.write(intBytes); |
261 } catch (IOException e) { |
261 } catch (IOException e) { |
262 throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); |
262 throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); |
263 } |
263 } |
264 } |
264 } |
265 |
265 |
266 /** |
266 /** |
267 * Line up the BigEnd of the bytes to a 4 byte boundry |
267 * Line up the BigEnd of the bytes to a 4 byte boundry |
268 * |
268 * |
269 * @param bytes byte[] |
269 * @param bytes byte[] |
270 */ |
270 */ |
271 private void writeBigEndToFourByteBoundry(byte[] bytes) { |
271 private void writeBigEndToFourByteBoundry(byte[] bytes) { |
272 int mod = bytes.length % 4; |
272 int mod = bytes.length % 4; |
273 // if the remainder == 0 write the bytes |
273 // if the remainder == 0 write the bytes |
274 if (mod == 0) { |
274 if (mod == 0) { |
275 try { stream.write(bytes); } catch (IOException e) |
275 try { stream.write(bytes); } catch (IOException e) |
276 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
276 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
277 return; |
277 return; |
278 } |
278 } |
279 // pad the bytes to lineup correctly |
279 // pad the bytes to lineup correctly |
280 int pad = 4 - mod; |
280 int pad = 4 - mod; |
281 byte[] newBytes = new byte[pad + bytes.length]; |
281 byte[] newBytes = new byte[pad + bytes.length]; |
282 System.arraycopy(bytes,0,newBytes,pad,bytes.length); |
282 System.arraycopy(bytes,0,newBytes,pad,bytes.length); |
283 |
283 |
284 try { stream.write(newBytes); } catch (IOException e) |
284 try { stream.write(newBytes); } catch (IOException e) |
285 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
285 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
286 } |
286 } |
287 |
287 |
288 /** |
288 /** |
289 * Line up the LittleEnd of the bytes to a 4 byte boundry |
289 * Line up the LittleEnd of the bytes to a 4 byte boundry |
290 * |
290 * |
291 * @param bytes byte[] |
291 * @param bytes byte[] |
292 */ |
292 */ |
293 private void writeLittleEndToFourByteBoundry(byte[] bytes) { |
293 private void writeLittleEndToFourByteBoundry(byte[] bytes) { |
294 int mod = bytes.length % 4; |
294 int mod = bytes.length % 4; |
295 // if the remainder == 0 write the bytes |
295 // if the remainder == 0 write the bytes |
296 if (mod == 4) { |
296 if (mod == 4) { |
297 try { stream.write(bytes); } catch (IOException e) |
297 try { stream.write(bytes); } catch (IOException e) |
298 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
298 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
299 return; |
299 return; |
300 } |
300 } |
301 // pad the bytes to lineup correctly |
301 // pad the bytes to lineup correctly |
302 int pad = 4 - mod; |
302 int pad = 4 - mod; |
303 byte[] newBytes = new byte[pad + bytes.length]; |
303 byte[] newBytes = new byte[pad + bytes.length]; |
304 System.arraycopy(bytes,0,newBytes,0,bytes.length); |
304 System.arraycopy(bytes,0,newBytes,0,bytes.length); |
305 |
305 |
306 try { stream.write(newBytes); } catch (IOException e) |
306 try { stream.write(newBytes); } catch (IOException e) |
307 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
307 { throw new RuntimeException("You're screwed: IOException writing to a ByteArrayOutputStream"); } |
308 } |
308 } |
309 |
309 |
310 } |
310 } |