propane 3.4.0-java → 3.4.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -2
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +2 -0
  5. data/README.md +12 -7
  6. data/Rakefile +2 -2
  7. data/lib/propane.rb +2 -2
  8. data/lib/propane/app.rb +18 -9
  9. data/lib/propane/helper_methods.rb +1 -1
  10. data/lib/propane/runner.rb +1 -1
  11. data/lib/propane/version.rb +1 -1
  12. data/library/color_group/color_group.rb +26 -0
  13. data/library/dxf/dxf.rb +4 -0
  14. data/library/net/net.rb +5 -0
  15. data/library/video_event/video_event.rb +2 -1
  16. data/pom.rb +3 -3
  17. data/pom.xml +3 -3
  18. data/propane.gemspec +1 -1
  19. data/src/main/java/japplemenubar/JAppleMenuBar.java +3 -3
  20. data/src/main/java/monkstone/ColorUtil.java +14 -0
  21. data/src/main/java/monkstone/MathToolModule.java +243 -194
  22. data/src/main/java/monkstone/filechooser/Chooser.java +1 -0
  23. data/src/main/java/monkstone/slider/WheelHandler.java +6 -5
  24. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +3 -2
  25. data/src/main/java/monkstone/videoevent/CaptureEvent.java +27 -0
  26. data/src/main/java/monkstone/videoevent/{VideoInterface.java → MovieEvent.java} +10 -26
  27. data/src/main/java/processing/awt/PSurfaceAWT.java +1 -1
  28. data/src/main/java/processing/core/PApplet.java +1236 -599
  29. data/src/main/java/processing/core/PGraphics.java +59 -59
  30. data/src/main/java/processing/core/PImage.java +528 -129
  31. data/src/main/java/processing/core/PShape.java +10 -10
  32. data/src/main/java/processing/core/PVector.java +2 -2
  33. data/src/main/java/processing/core/ThinkDifferent.java +5 -7
  34. data/src/main/java/processing/dxf/RawDXF.java +404 -0
  35. data/src/main/java/processing/net/Client.java +744 -0
  36. data/src/main/java/processing/net/Server.java +388 -0
  37. data/src/main/java/processing/opengl/FontTexture.java +19 -20
  38. data/src/main/java/processing/opengl/FrameBuffer.java +27 -17
  39. data/src/main/java/processing/opengl/LinePath.java +512 -508
  40. data/src/main/java/processing/opengl/PGL.java +3106 -3066
  41. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +4 -4
  42. data/src/main/java/processing/opengl/PShader.java +1442 -1341
  43. data/vendors/Rakefile +3 -27
  44. metadata +12 -25
  45. data/src/main/java/processing/core/util/image/ImageLoadFacade.java +0 -161
  46. data/src/main/java/processing/core/util/image/ImageSaveFacade.java +0 -169
  47. data/src/main/java/processing/core/util/image/constants/TifConstants.java +0 -45
  48. data/src/main/java/processing/core/util/image/load/AwtImageLoadStrategy.java +0 -80
  49. data/src/main/java/processing/core/util/image/load/Base64StringImageLoadStrategy.java +0 -73
  50. data/src/main/java/processing/core/util/image/load/FallbackImageLoadStrategy.java +0 -70
  51. data/src/main/java/processing/core/util/image/load/ImageIoImageLoadStrategy.java +0 -132
  52. data/src/main/java/processing/core/util/image/load/ImageLoadStrategy.java +0 -48
  53. data/src/main/java/processing/core/util/image/load/ImageLoadUtil.java +0 -45
  54. data/src/main/java/processing/core/util/image/load/TgaImageLoadStrategy.java +0 -255
  55. data/src/main/java/processing/core/util/image/load/TiffImageLoadStrategy.java +0 -98
  56. data/src/main/java/processing/core/util/image/save/ImageSaveStrategy.java +0 -49
  57. data/src/main/java/processing/core/util/image/save/ImageSaveUtil.java +0 -48
  58. data/src/main/java/processing/core/util/image/save/ImageWriterImageSaveStrategy.java +0 -179
  59. data/src/main/java/processing/core/util/image/save/SaveImageException.java +0 -41
  60. data/src/main/java/processing/core/util/image/save/TgaImageSaveStrategy.java +0 -198
  61. data/src/main/java/processing/core/util/image/save/TiffImageSaveStrategy.java +0 -91
  62. data/src/main/java/processing/core/util/image/save/TiffNakedFilenameImageSaveStrategy.java +0 -57
  63. data/src/main/java/processing/core/util/io/InputFactory.java +0 -285
  64. data/src/main/java/processing/core/util/io/PathUtil.java +0 -109
@@ -0,0 +1,744 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Client - basic network client implementation
5
+ Part of the Processing project - http://processing.org
6
+
7
+ Copyright (c) 2004-2007 Ben Fry and Casey Reas
8
+ The previous version of this code was developed by Hernando Barragan
9
+
10
+ This library is free software; you can redistribute it and/or
11
+ modify it under the terms of the GNU Lesser General Public
12
+ License as published by the Free Software Foundation; either
13
+ version 2.1 of the License, or (at your option) any later version.
14
+
15
+ This library is distributed in the hope that it will be useful,
16
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
+ Lesser General Public License for more details.
19
+
20
+ You should have received a copy of the GNU Lesser General
21
+ Public License along with this library; if not, write to the
22
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23
+ Boston, MA 02111-1307 USA
24
+ */
25
+
26
+ package processing.net;
27
+ import processing.core.*;
28
+
29
+ import java.io.*;
30
+ import java.lang.reflect.*;
31
+ import java.net.*;
32
+
33
+ /**
34
+ * ( begin auto-generated from Client.xml )
35
+ *
36
+ * A client connects to a server and sends data back and forth. If anything
37
+ * goes wrong with the connection, for example the host is not there or is
38
+ * listening on a different port, an exception is thrown.
39
+ *
40
+ * ( end auto-generated )
41
+ * @webref net
42
+ * @brief The client class is used to create client Objects which connect to a server to exchange data.
43
+ * @instanceName client any variable of type Client
44
+ * @usage Application
45
+ * @see_external LIB_net/clientEvent
46
+ */
47
+ public class Client implements Runnable {
48
+
49
+ protected static final int MAX_BUFFER_SIZE = 1 << 27; // 128 MB
50
+
51
+ PApplet parent;
52
+ Method clientEventMethod;
53
+ Method disconnectEventMethod;
54
+
55
+ volatile Thread thread;
56
+ Socket socket;
57
+ int port;
58
+ String host;
59
+
60
+ public InputStream input;
61
+ public OutputStream output;
62
+
63
+ final Object bufferLock = new Object[0];
64
+
65
+ byte buffer[] = new byte[32768];
66
+ int bufferIndex;
67
+ int bufferLast;
68
+
69
+ boolean disposeRegistered = false;
70
+
71
+
72
+ /**
73
+ * @param parent typically use "this"
74
+ * @param host address of the server
75
+ * @param port port to read/write from on the server
76
+ */
77
+ public Client(PApplet parent, String host, int port) {
78
+ this.parent = parent;
79
+ this.host = host;
80
+ this.port = port;
81
+
82
+ try {
83
+ socket = new Socket(this.host, this.port);
84
+ input = socket.getInputStream();
85
+ output = socket.getOutputStream();
86
+
87
+ thread = new Thread(this);
88
+ thread.start();
89
+
90
+ parent.registerMethod("dispose", this);
91
+ disposeRegistered = true;
92
+
93
+ // reflection to check whether host sketch has a call for
94
+ // public void clientEvent(processing.net.Client)
95
+ // which would be called each time an event comes in
96
+ try {
97
+ clientEventMethod =
98
+ parent.getClass().getMethod("clientEvent", Client.class);
99
+ } catch (Exception e) {
100
+ // no such method, or an error.. which is fine, just ignore
101
+ }
102
+ // do the same for disconnectEvent(Client c);
103
+ try {
104
+ disconnectEventMethod =
105
+ parent.getClass().getMethod("disconnectEvent", Client.class);
106
+ } catch (Exception e) {
107
+ // no such method, or an error.. which is fine, just ignore
108
+ }
109
+
110
+ } catch (IOException e) {
111
+ e.printStackTrace();
112
+ dispose();
113
+ }
114
+ }
115
+
116
+
117
+ /**
118
+ * @param socket any object of type Socket
119
+ * @throws IOException
120
+ */
121
+ public Client(PApplet parent, Socket socket) throws IOException {
122
+ this.parent = parent;
123
+ this.socket = socket;
124
+
125
+ input = socket.getInputStream();
126
+ output = socket.getOutputStream();
127
+
128
+ thread = new Thread(this);
129
+ thread.start();
130
+
131
+ // reflection to check whether host sketch has a call for
132
+ // public void clientEvent(processing.net.Client)
133
+ // which would be called each time an event comes in
134
+ try {
135
+ clientEventMethod =
136
+ parent.getClass().getMethod("clientEvent", Client.class);
137
+ } catch (Exception e) {
138
+ // no such method, or an error.. which is fine, just ignore
139
+ }
140
+ // do the same for disconnectEvent(Client c);
141
+ try {
142
+ disconnectEventMethod =
143
+ parent.getClass().getMethod("disconnectEvent", Client.class);
144
+ } catch (Exception e) {
145
+ // no such method, or an error.. which is fine, just ignore
146
+ }
147
+ }
148
+
149
+
150
+ /**
151
+ * ( begin auto-generated from Client_stop.xml )
152
+ *
153
+ * Disconnects from the server. Use to shut the connection when you're
154
+ * finished with the Client.
155
+ *
156
+ * ( end auto-generated )
157
+ * @webref client:client
158
+ * @brief Disconnects from the server
159
+ * @usage application
160
+ */
161
+ public void stop() {
162
+ if (disconnectEventMethod != null && thread != null){
163
+ try {
164
+ disconnectEventMethod.invoke(parent, this);
165
+ } catch (Exception e) {
166
+ Throwable cause = e;
167
+ // unwrap the exception if it came from the user code
168
+ if (e instanceof InvocationTargetException && e.getCause() != null) {
169
+ cause = e.getCause();
170
+ }
171
+ cause.printStackTrace();
172
+ disconnectEventMethod = null;
173
+ }
174
+ }
175
+ if (disposeRegistered) {
176
+ parent.unregisterMethod("dispose", this);
177
+ disposeRegistered = false;
178
+ }
179
+ dispose();
180
+ }
181
+
182
+
183
+ /**
184
+ * Disconnect from the server: internal use only.
185
+ * <P>
186
+ * This should only be called by the internal functions in PApplet,
187
+ * use stop() instead from within your own applets.
188
+ */
189
+ public void dispose() {
190
+ thread = null;
191
+ try {
192
+ if (input != null) {
193
+ input.close();
194
+ input = null;
195
+ }
196
+ } catch (Exception e) {
197
+ e.printStackTrace();
198
+ }
199
+
200
+ try {
201
+ if (output != null) {
202
+ output.close();
203
+ output = null;
204
+ }
205
+ } catch (Exception e) {
206
+ e.printStackTrace();
207
+ }
208
+
209
+ try {
210
+ if (socket != null) {
211
+ socket.close();
212
+ socket = null;
213
+ }
214
+ } catch (Exception e) {
215
+ e.printStackTrace();
216
+ }
217
+ }
218
+
219
+
220
+ @Override
221
+ public void run() {
222
+ byte[] readBuffer;
223
+ { // make the read buffer same size as socket receive buffer so that
224
+ // we don't waste cycles calling listeners when there is more data waiting
225
+ int readBufferSize = 1 << 16; // 64 KB (default socket receive buffer size)
226
+ try {
227
+ readBufferSize = socket.getReceiveBufferSize();
228
+ } catch (SocketException ignore) { }
229
+ readBuffer = new byte[readBufferSize];
230
+ }
231
+ while (Thread.currentThread() == thread) {
232
+ try {
233
+ while (input != null) {
234
+ int readCount;
235
+
236
+ // try to read a byte using a blocking read.
237
+ // An exception will occur when the sketch is exits.
238
+ try {
239
+ readCount = input.read(readBuffer, 0, readBuffer.length);
240
+ } catch (SocketException e) {
241
+ System.err.println("Client SocketException: " + e.getMessage());
242
+ // the socket had a problem reading so don't try to read from it again.
243
+ stop();
244
+ return;
245
+ }
246
+
247
+ // read returns -1 if end-of-stream occurs (for example if the host disappears)
248
+ if (readCount == -1) {
249
+ System.err.println("Client got end-of-stream.");
250
+ stop();
251
+ return;
252
+ }
253
+
254
+ synchronized (bufferLock) {
255
+ int freeBack = buffer.length - bufferLast;
256
+ if (readCount > freeBack) {
257
+ // not enough space at the back
258
+ int bufferLength = bufferLast - bufferIndex;
259
+ byte[] targetBuffer = buffer;
260
+ if (bufferLength + readCount > buffer.length) {
261
+ // can't fit even after compacting, resize the buffer
262
+ // find the next power of two which can fit everything in
263
+ int newSize = Integer.highestOneBit(bufferLength + readCount - 1) << 1;
264
+ if (newSize > MAX_BUFFER_SIZE) {
265
+ // buffer is full because client is not reading (fast enough)
266
+ System.err.println("Client: can't receive more data, buffer is full. " +
267
+ "Make sure you read the data from the client.");
268
+ stop();
269
+ return;
270
+ }
271
+ targetBuffer = new byte[newSize];
272
+ }
273
+ // compact the buffer (either in-place or into the new bigger buffer)
274
+ System.arraycopy(buffer, bufferIndex, targetBuffer, 0, bufferLength);
275
+ bufferLast -= bufferIndex;
276
+ bufferIndex = 0;
277
+ buffer = targetBuffer;
278
+ }
279
+ // copy all newly read bytes into the buffer
280
+ System.arraycopy(readBuffer, 0, buffer, bufferLast, readCount);
281
+ bufferLast += readCount;
282
+ }
283
+
284
+ // now post an event
285
+ if (clientEventMethod != null) {
286
+ try {
287
+ clientEventMethod.invoke(parent, this);
288
+ } catch (Exception e) {
289
+ System.err.println("error, disabling clientEvent() for " + host);
290
+ Throwable cause = e;
291
+ // unwrap the exception if it came from the user code
292
+ if (e instanceof InvocationTargetException && e.getCause() != null) {
293
+ cause = e.getCause();
294
+ }
295
+ cause.printStackTrace();
296
+ clientEventMethod = null;
297
+ }
298
+ }
299
+ }
300
+ } catch (IOException e) {
301
+ //errorMessage("run", e);
302
+ e.printStackTrace();
303
+ }
304
+ }
305
+ }
306
+
307
+
308
+ /**
309
+ * ( begin auto-generated from Client_active.xml )
310
+ *
311
+ * Returns true if this client is still active and hasn't run
312
+ * into any trouble.
313
+ *
314
+ * ( end auto-generated )
315
+ * @webref client:client
316
+ * @brief Returns true if this client is still active
317
+ * @usage application
318
+ */
319
+ public boolean active() {
320
+ return (thread != null);
321
+ }
322
+
323
+
324
+ /**
325
+ * ( begin auto-generated from Client_ip.xml )
326
+ *
327
+ * Returns the IP address of the computer to which the Client is attached.
328
+ *
329
+ * ( end auto-generated )
330
+ * @webref client:client
331
+ * @usage application
332
+ * @brief Returns the IP address of the machine as a String
333
+ */
334
+ public String ip() {
335
+ if (socket != null){
336
+ return socket.getInetAddress().getHostAddress();
337
+ }
338
+ return null;
339
+ }
340
+
341
+
342
+ /**
343
+ * ( begin auto-generated from Client_available.xml )
344
+ *
345
+ * Returns the number of bytes available. When any client has bytes
346
+ * available from the server, it returns the number of bytes.
347
+ *
348
+ * ( end auto-generated )
349
+ * @webref client:client
350
+ * @usage application
351
+ * @brief Returns the number of bytes in the buffer waiting to be read
352
+ */
353
+ public int available() {
354
+ synchronized (bufferLock) {
355
+ return (bufferLast - bufferIndex);
356
+ }
357
+ }
358
+
359
+
360
+ /**
361
+ * ( begin auto-generated from Client_clear.xml )
362
+ *
363
+ * Empty the buffer, removes all the data stored there.
364
+ *
365
+ * ( end auto-generated )
366
+ * @webref client:client
367
+ * @usage application
368
+ * @brief Clears the buffer
369
+ */
370
+ public void clear() {
371
+ synchronized (bufferLock) {
372
+ bufferLast = 0;
373
+ bufferIndex = 0;
374
+ }
375
+ }
376
+
377
+
378
+ /**
379
+ * ( begin auto-generated from Client_read.xml )
380
+ *
381
+ * Returns a number between 0 and 255 for the next byte that's waiting in
382
+ * the buffer. Returns -1 if there is no byte, although this should be
383
+ * avoided by first cheacking <b>available()</b> to see if any data is available.
384
+ *
385
+ * ( end auto-generated )
386
+ * @webref client:client
387
+ * @usage application
388
+ * @brief Returns a value from the buffer
389
+ */
390
+ public int read() {
391
+ synchronized (bufferLock) {
392
+ if (bufferIndex == bufferLast) return -1;
393
+
394
+ int outgoing = buffer[bufferIndex++] & 0xff;
395
+ if (bufferIndex == bufferLast) { // rewind
396
+ bufferIndex = 0;
397
+ bufferLast = 0;
398
+ }
399
+ return outgoing;
400
+ }
401
+ }
402
+
403
+
404
+ /**
405
+ * ( begin auto-generated from Client_readChar.xml )
406
+ *
407
+ * Returns the next byte in the buffer as a char. Returns -1 or 0xffff if
408
+ * nothing is there.
409
+ *
410
+ * ( end auto-generated )
411
+ * @webref client:client
412
+ * @usage application
413
+ * @brief Returns the next byte in the buffer as a char
414
+ */
415
+ public char readChar() {
416
+ synchronized (bufferLock) {
417
+ if (bufferIndex == bufferLast) return (char) (-1);
418
+ return (char) read();
419
+ }
420
+ }
421
+
422
+
423
+ /**
424
+ * ( begin auto-generated from Client_readBytes.xml )
425
+ *
426
+ * Reads a group of bytes from the buffer. The version with no parameters
427
+ * returns a byte array of all data in the buffer. This is not efficient,
428
+ * but is easy to use. The version with the <b>byteBuffer</b> parameter is
429
+ * more memory and time efficient. It grabs the data in the buffer and puts
430
+ * it into the byte array passed in and returns an int value for the number
431
+ * of bytes read. If more bytes are available than can fit into the
432
+ * <b>byteBuffer</b>, only those that fit are read.
433
+ *
434
+ * ( end auto-generated )
435
+ * <h3>Advanced</h3>
436
+ * Return a byte array of anything that's in the serial buffer.
437
+ * Not particularly memory/speed efficient, because it creates
438
+ * a byte array on each read, but it's easier to use than
439
+ * readBytes(byte b[]) (see below).
440
+ *
441
+ * @webref client:client
442
+ * @usage application
443
+ * @brief Reads everything in the buffer
444
+ */
445
+ public byte[] readBytes() {
446
+ synchronized (bufferLock) {
447
+ if (bufferIndex == bufferLast) return null;
448
+
449
+ int length = bufferLast - bufferIndex;
450
+ byte outgoing[] = new byte[length];
451
+ System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
452
+
453
+ bufferIndex = 0; // rewind
454
+ bufferLast = 0;
455
+ return outgoing;
456
+ }
457
+ }
458
+
459
+
460
+ /**
461
+ * <h3>Advanced</h3>
462
+ * Return a byte array of anything that's in the serial buffer
463
+ * up to the specified maximum number of bytes.
464
+ * Not particularly memory/speed efficient, because it creates
465
+ * a byte array on each read, but it's easier to use than
466
+ * readBytes(byte b[]) (see below).
467
+ *
468
+ * @param max the maximum number of bytes to read
469
+ */
470
+ public byte[] readBytes(int max) {
471
+ synchronized (bufferLock) {
472
+ if (bufferIndex == bufferLast) return null;
473
+
474
+ int length = bufferLast - bufferIndex;
475
+ if (length > max) length = max;
476
+ byte outgoing[] = new byte[length];
477
+ System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
478
+
479
+ bufferIndex += length;
480
+ if (bufferIndex == bufferLast) {
481
+ bufferIndex = 0; // rewind
482
+ bufferLast = 0;
483
+ }
484
+
485
+ return outgoing;
486
+ }
487
+ }
488
+
489
+
490
+ /**
491
+ * <h3>Advanced</h3>
492
+ * Grab whatever is in the serial buffer, and stuff it into a
493
+ * byte buffer passed in by the user. This is more memory/time
494
+ * efficient than readBytes() returning a byte[] array.
495
+ *
496
+ * Returns an int for how many bytes were read. If more bytes
497
+ * are available than can fit into the byte array, only those
498
+ * that will fit are read.
499
+ *
500
+ * @param bytebuffer passed in byte array to be altered
501
+ */
502
+ public int readBytes(byte bytebuffer[]) {
503
+ synchronized (bufferLock) {
504
+ if (bufferIndex == bufferLast) return 0;
505
+
506
+ int length = bufferLast - bufferIndex;
507
+ if (length > bytebuffer.length) length = bytebuffer.length;
508
+ System.arraycopy(buffer, bufferIndex, bytebuffer, 0, length);
509
+
510
+ bufferIndex += length;
511
+ if (bufferIndex == bufferLast) {
512
+ bufferIndex = 0; // rewind
513
+ bufferLast = 0;
514
+ }
515
+ return length;
516
+ }
517
+ }
518
+
519
+
520
+ /**
521
+ * ( begin auto-generated from Client_readBytesUntil.xml )
522
+ *
523
+ * Reads from the port into a buffer of bytes up to and including a
524
+ * particular character. If the character isn't in the buffer, 'null' is
525
+ * returned. The version with no <b>byteBuffer</b> parameter returns a byte
526
+ * array of all data up to and including the <b>interesting</b> byte. This
527
+ * is not efficient, but is easy to use. The version with the
528
+ * <b>byteBuffer</b> parameter is more memory and time efficient. It grabs
529
+ * the data in the buffer and puts it into the byte array passed in and
530
+ * returns an int value for the number of bytes read. If the byte buffer is
531
+ * not large enough, -1 is returned and an error is printed to the message
532
+ * area. If nothing is in the buffer, 0 is returned.
533
+ *
534
+ * ( end auto-generated )
535
+ * @webref client:client
536
+ * @usage application
537
+ * @brief Reads from the buffer of bytes up to and including a particular character
538
+ * @param interesting character designated to mark the end of the data
539
+ */
540
+ public byte[] readBytesUntil(int interesting) {
541
+ byte what = (byte)interesting;
542
+
543
+ synchronized (bufferLock) {
544
+ if (bufferIndex == bufferLast) return null;
545
+
546
+ int found = -1;
547
+ for (int k = bufferIndex; k < bufferLast; k++) {
548
+ if (buffer[k] == what) {
549
+ found = k;
550
+ break;
551
+ }
552
+ }
553
+ if (found == -1) return null;
554
+
555
+ int length = found - bufferIndex + 1;
556
+ byte outgoing[] = new byte[length];
557
+ System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
558
+
559
+ bufferIndex += length;
560
+ if (bufferIndex == bufferLast) {
561
+ bufferIndex = 0; // rewind
562
+ bufferLast = 0;
563
+ }
564
+ return outgoing;
565
+ }
566
+ }
567
+
568
+
569
+ /**
570
+ * <h3>Advanced</h3>
571
+ * Reads from the serial port into a buffer of bytes until a
572
+ * particular character. If the character isn't in the serial
573
+ * buffer, then 'null' is returned.
574
+ *
575
+ * If outgoing[] is not big enough, then -1 is returned,
576
+ * and an error message is printed on the console.
577
+ * If nothing is in the buffer, zero is returned.
578
+ * If 'interesting' byte is not in the buffer, then 0 is returned.
579
+ *
580
+ * @param byteBuffer passed in byte array to be altered
581
+ */
582
+ public int readBytesUntil(int interesting, byte byteBuffer[]) {
583
+ byte what = (byte)interesting;
584
+
585
+ synchronized (bufferLock) {
586
+ if (bufferIndex == bufferLast) return 0;
587
+
588
+ int found = -1;
589
+ for (int k = bufferIndex; k < bufferLast; k++) {
590
+ if (buffer[k] == what) {
591
+ found = k;
592
+ break;
593
+ }
594
+ }
595
+ if (found == -1) return 0;
596
+
597
+ int length = found - bufferIndex + 1;
598
+ if (length > byteBuffer.length) {
599
+ System.err.println("readBytesUntil() byte buffer is" +
600
+ " too small for the " + length +
601
+ " bytes up to and including char " + interesting);
602
+ return -1;
603
+ }
604
+ //byte outgoing[] = new byte[length];
605
+ System.arraycopy(buffer, bufferIndex, byteBuffer, 0, length);
606
+
607
+ bufferIndex += length;
608
+ if (bufferIndex == bufferLast) {
609
+ bufferIndex = 0; // rewind
610
+ bufferLast = 0;
611
+ }
612
+ return length;
613
+ }
614
+ }
615
+
616
+
617
+ /**
618
+ * ( begin auto-generated from Client_readString.xml )
619
+ *
620
+ * Returns the all the data from the buffer as a String. This method
621
+ * assumes the incoming characters are ASCII. If you want to transfer
622
+ * Unicode data, first convert the String to a byte stream in the
623
+ * representation of your choice (i.e. UTF8 or two-byte Unicode data), and
624
+ * send it as a byte array.
625
+ *
626
+ * ( end auto-generated )
627
+ * @webref client:client
628
+ * @usage application
629
+ * @brief Returns the buffer as a String
630
+ */
631
+ public String readString() {
632
+ byte b[] = readBytes();
633
+ if (b == null) return null;
634
+ return new String(b);
635
+ }
636
+
637
+
638
+ /**
639
+ * ( begin auto-generated from Client_readStringUntil.xml )
640
+ *
641
+ * Combination of <b>readBytesUntil()</b> and <b>readString()</b>. Returns
642
+ * <b>null</b> if it doesn't find what you're looking for.
643
+ *
644
+ * ( end auto-generated )
645
+ * <h3>Advanced</h3>
646
+ * <p/>
647
+ * If you want to move Unicode data, you can first convert the
648
+ * String to a byte stream in the representation of your choice
649
+ * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
650
+ *
651
+ * @webref client:client
652
+ * @usage application
653
+ * @brief Returns the buffer as a String up to and including a particular character
654
+ * @param interesting character designated to mark the end of the data
655
+ */
656
+ public String readStringUntil(int interesting) {
657
+ byte b[] = readBytesUntil(interesting);
658
+ if (b == null) return null;
659
+ return new String(b);
660
+ }
661
+
662
+
663
+ /**
664
+ * ( begin auto-generated from Client_write.xml )
665
+ *
666
+ * Writes data to a server specified when constructing the client.
667
+ *
668
+ * ( end auto-generated )
669
+ * @webref client:client
670
+ * @usage application
671
+ * @brief Writes bytes, chars, ints, bytes[], Strings
672
+ * @param data data to write
673
+ */
674
+ public void write(int data) { // will also cover char
675
+ try {
676
+ output.write(data & 0xff); // for good measure do the &
677
+ output.flush(); // hmm, not sure if a good idea
678
+
679
+ } catch (Exception e) { // null pointer or serial port dead
680
+ //errorMessage("write", e);
681
+ //e.printStackTrace();
682
+ //dispose();
683
+ //disconnect(e);
684
+ e.printStackTrace();
685
+ stop();
686
+ }
687
+ }
688
+
689
+
690
+ public void write(byte data[]) {
691
+ try {
692
+ output.write(data);
693
+ output.flush(); // hmm, not sure if a good idea
694
+
695
+ } catch (Exception e) { // null pointer or serial port dead
696
+ //errorMessage("write", e);
697
+ //e.printStackTrace();
698
+ //disconnect(e);
699
+ e.printStackTrace();
700
+ stop();
701
+ }
702
+ }
703
+
704
+
705
+ /**
706
+ * <h3>Advanced</h3>
707
+ * Write a String to the output. Note that this doesn't account
708
+ * for Unicode (two bytes per char), nor will it send UTF8
709
+ * characters.. It assumes that you mean to send a byte buffer
710
+ * (most often the case for networking and serial i/o) and
711
+ * will only use the bottom 8 bits of each char in the string.
712
+ * (Meaning that internally it uses String.getBytes)
713
+ *
714
+ * If you want to move Unicode data, you can first convert the
715
+ * String to a byte stream in the representation of your choice
716
+ * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
717
+ */
718
+ public void write(String data) {
719
+ write(data.getBytes());
720
+ }
721
+
722
+
723
+ /**
724
+ * Handle disconnect due to an Exception being thrown.
725
+ */
726
+ /*
727
+ protected void disconnect(Exception e) {
728
+ dispose();
729
+ if (e != null) {
730
+ e.printStackTrace();
731
+ }
732
+ }
733
+ */
734
+
735
+
736
+ /**
737
+ * General error reporting, all corralled here just in case
738
+ * I think of something slightly more intelligent to do.
739
+ */
740
+ //public void errorMessage(String where, Exception e) {
741
+ //parent.die("Error inside Client." + where + "()", e);
742
+ //e.printStackTrace(System.err);
743
+ //}
744
+ }