Mercurial > hg > Members > you > TreeVNC
annotate src/treeVnc/MyRfbProtoProxy.java @ 51:a14076dac503
add DataInputStream2.java
author | one |
---|---|
date | Sun, 06 May 2012 20:35:51 +0900 |
parents | f77309fa8a9c |
children |
rev | line source |
---|---|
15 | 1 package treeVnc; |
2 | |
3 import static org.junit.Assert.*; | |
4 | |
5 import java.awt.Graphics; | |
6 import java.awt.Image; | |
7 import java.awt.image.BufferedImage; | |
8 import java.io.BufferedOutputStream; | |
9 import java.io.BufferedReader; | |
10 import java.io.ByteArrayInputStream; | |
11 import java.io.ByteArrayOutputStream; | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
12 import java.io.DataOutputStream; |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
13 import java.io.FileOutputStream; |
15 | 14 import java.io.IOException; |
15 import java.io.InputStream; | |
16 import java.io.InputStreamReader; | |
17 import java.net.BindException; | |
50 | 18 import java.net.DatagramPacket; |
19 import java.net.InetAddress; | |
20 import java.net.MulticastSocket; | |
15 | 21 import java.net.ServerSocket; |
22 import java.net.Socket; | |
23 import java.nio.ByteBuffer; | |
24 import java.util.Iterator; | |
25 import java.util.LinkedList; | |
26 | |
27 import javax.imageio.ImageIO; | |
28 | |
29 import org.junit.Test; | |
30 | |
31 //import myVncProxy.MulticastQueue.Client; | |
32 | |
33 import java.util.concurrent.ExecutorService; | |
34 import java.util.concurrent.atomic.AtomicInteger; | |
35 import java.util.zip.DataFormatException; | |
36 import java.util.zip.Deflater; | |
37 import java.util.zip.Inflater; | |
38 import java.io.OutputStream; | |
39 | |
31 | 40 public class MyRfbProtoProxy extends RfbProto implements MyRfbProto { |
15 | 41 final static String versionMsg_3_855 = "RFB 003.855\n"; |
42 /** | |
31 | 43 * CheckMillis is one of new msgType for RFB 3.855. |
15 | 44 */ |
45 final static byte SpeedCheckMillis = 4; | |
46 | |
47 // Secyrity type of OS X | |
48 final static int SecTypeReqAccess = 32; | |
49 | |
50 // Supported authentication types | |
51 final static int AuthAccess = 32; | |
52 | |
31 | 53 private static final int INFLATE_BUFSIZE = 1024 * 100; |
15 | 54 boolean printStatusFlag = false; |
55 long startCheckTime; | |
56 private int messageType; | |
57 private int rectangles; | |
58 private int rectX; | |
59 private int rectY; | |
60 private int rectW; | |
61 private int rectH; | |
62 private int encoding; | |
63 private int zLen; | |
64 private boolean clicomp = false; | |
65 | |
66 private ServerSocket servSock; | |
67 protected int acceptPort; | |
31 | 68 // private byte initData[]; |
15 | 69 byte initData[]; |
70 private LinkedList<Socket> cliListTmp; | |
71 private LinkedList<Socket> cliList; | |
72 boolean createBimgFlag; | |
73 boolean proxyFlag = true; | |
74 | |
75 ExecutorService executor; | |
76 | |
77 byte[] pngBytes; | |
78 | |
31 | 79 // private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new |
80 // MostRecentMultiCast<LinkedList<ByteBuffer>>(10); | |
15 | 81 private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>(); |
82 private int clients = 0; | |
83 private Inflater inflater = new Inflater(); | |
84 private Deflater deflater = new Deflater(); | |
85 private CreateThread geth; | |
31 | 86 // private Thread requestThread; |
15 | 87 private RequestScreenThread rThread; |
88 private Thread requestThread; | |
31 | 89 |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
90 public MyRfbProtoProxy() { |
15 | 91 } |
31 | 92 |
15 | 93 MyRfbProtoProxy(String h, int p, VncViewer v) throws IOException { |
94 super(h, p, v); | |
95 | |
31 | 96 rThread = new RequestScreenThread(this); |
15 | 97 requestThread = new Thread(rThread); |
31 | 98 // requestThread = new Thread(new RequestScreenThread(this)); |
15 | 99 } |
100 | |
101 MyRfbProtoProxy(String h, int p, CreateThread geth) throws IOException { | |
102 super(h, p); | |
103 this.geth = geth; | |
104 proxyFlag = true; | |
105 | |
31 | 106 rThread = new RequestScreenThread(this); |
15 | 107 requestThread = new Thread(rThread); |
31 | 108 // requestThread = new Thread(new RequestScreenThread(this)); |
15 | 109 } |
31 | 110 |
15 | 111 MyRfbProtoProxy(String h, int p) throws IOException { |
112 super(h, p); | |
113 | |
31 | 114 rThread = new RequestScreenThread(this); |
15 | 115 requestThread = new Thread(rThread); |
31 | 116 // requestThread = new Thread(new RequestScreenThread(this)); |
15 | 117 } |
31 | 118 |
40 | 119 public MyRfbProtoProxy(String h, int p, boolean b) throws IOException { |
120 super(h, p, b); | |
121 rThread = new RequestScreenThread(this); | |
122 requestThread = new Thread(rThread); | |
123 } | |
124 | |
15 | 125 // over write |
126 void writeVersionMsg() throws IOException { | |
127 clientMajor = 3; | |
128 if (serverMinor == 855) { | |
31 | 129 clientMinor = 855; |
130 os.write(versionMsg_3_855.getBytes()); | |
15 | 131 } else if (serverMajor > 3 || serverMinor >= 8) { |
132 clientMinor = 8; | |
133 os.write(versionMsg_3_8.getBytes()); | |
134 } else if (serverMinor >= 7) { | |
135 clientMinor = 7; | |
136 os.write(versionMsg_3_7.getBytes()); | |
137 } else { | |
138 clientMinor = 3; | |
139 os.write(versionMsg_3_3.getBytes()); | |
140 } | |
141 protocolTightVNC = false; | |
142 initCapabilities(); | |
143 } | |
144 | |
145 void initServSock(int port) throws IOException { | |
146 servSock = new ServerSocket(port); | |
147 acceptPort = port; | |
148 } | |
31 | 149 |
15 | 150 void authenticationRequestAccess() throws IOException { |
151 | |
152 byte[] headBuf = new byte[2]; | |
153 is.read(headBuf); | |
31 | 154 if (headBuf[1] == 2) { |
15 | 155 byte[] b = new byte[258]; |
156 is.read(b); | |
157 | |
158 byte[] outBuf = new byte[256]; | |
159 os.write(outBuf); | |
160 os.flush(); | |
31 | 161 } else if (headBuf[1] == 23) { |
15 | 162 byte[] b = new byte[130]; |
163 is.read(b); | |
164 byte[] outBuf = new byte[192]; | |
165 os.write(outBuf); | |
166 os.flush(); | |
167 } | |
168 | |
169 int result = readU32(); | |
31 | 170 if (result != 0) { |
15 | 171 System.out.println("faild authentication "); |
172 throw new IOException(); | |
173 } | |
31 | 174 |
15 | 175 } |
176 | |
177 /* | |
31 | 178 * default port number is 5999. |
15 | 179 */ |
19 | 180 public void selectPort(int p) { |
31 | 181 if (servSock != null) |
182 return; | |
15 | 183 int port = p; |
184 while (true) { | |
185 try { | |
186 initServSock(port); | |
187 break; | |
188 } catch (BindException e) { | |
189 port++; | |
190 continue; | |
191 } catch (IOException e) { | |
192 | |
193 } | |
194 } | |
195 System.out.println("accept port = " + port); | |
196 } | |
197 | |
198 int getAcceptPort() { | |
199 return acceptPort; | |
200 } | |
201 | |
202 void setSoTimeout(int num) throws IOException { | |
203 servSock.setSoTimeout(num); | |
204 } | |
205 | |
19 | 206 public Socket accept() throws IOException { |
15 | 207 return servSock.accept(); |
208 } | |
209 | |
210 void addSock(Socket sock) { | |
211 cliList.add(sock); | |
212 } | |
213 | |
214 void addSockTmp(Socket sock) { | |
215 System.out.println("connected " + sock.getInetAddress()); | |
216 cliListTmp.add(sock); | |
217 } | |
218 | |
219 boolean markSupported() { | |
220 return is.markSupported(); | |
221 } | |
222 | |
223 void readServerInit() throws IOException { | |
224 | |
225 is.mark(255); | |
226 skipBytes(20); | |
227 int nlen = readU32(); | |
228 int blen = 20 + 4 + nlen; | |
229 initData = new byte[blen]; | |
230 is.reset(); | |
231 | |
232 is.mark(blen); | |
233 readFully(initData); | |
234 is.reset(); | |
235 | |
236 framebufferWidth = readU16(); | |
237 framebufferHeight = readU16(); | |
238 bitsPerPixel = readU8(); | |
239 depth = readU8(); | |
240 bigEndian = (readU8() != 0); | |
241 trueColour = (readU8() != 0); | |
242 redMax = readU16(); | |
243 greenMax = readU16(); | |
244 blueMax = readU16(); | |
245 redShift = readU8(); | |
246 greenShift = readU8(); | |
247 blueShift = readU8(); | |
248 byte[] pad = new byte[3]; | |
249 readFully(pad); | |
250 int nameLength = readU32(); | |
251 byte[] name = new byte[nameLength]; | |
252 readFully(name); | |
253 desktopName = new String(name); | |
254 | |
255 // Read interaction capabilities (TightVNC protocol extensions) | |
256 if (protocolTightVNC) { | |
257 int nServerMessageTypes = readU16(); | |
258 int nClientMessageTypes = readU16(); | |
259 int nEncodingTypes = readU16(); | |
260 readU16(); | |
261 readCapabilityList(serverMsgCaps, nServerMessageTypes); | |
262 readCapabilityList(clientMsgCaps, nClientMessageTypes); | |
263 readCapabilityList(encodingCaps, nEncodingTypes); | |
264 } | |
265 | |
266 inNormalProtocol = true; | |
267 } | |
268 | |
269 void sendRfbVersion(OutputStream os) throws IOException { | |
31 | 270 // os.write(versionMsg_3_8.getBytes()); |
15 | 271 os.write(versionMsg_3_855.getBytes()); |
272 } | |
273 | |
274 int readVersionMsg(InputStream is, OutputStream os) throws IOException { | |
275 | |
276 byte[] b = new byte[12]; | |
277 | |
278 is.read(b); | |
279 | |
280 if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') | |
281 || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') | |
282 || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') | |
283 || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') | |
284 || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { | |
285 throw new IOException("Host " + host + " port " + port | |
286 + " is not an RFB server"); | |
287 } | |
288 | |
289 int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); | |
290 int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); | |
291 | |
292 if (rfbMajor < 3) { | |
293 throw new IOException( | |
31 | 294 "RFB server does not support protocol version 3"); |
15 | 295 } |
296 | |
297 if (rfbMinor == 855) { | |
298 sendProxyFlag(os); | |
31 | 299 if (proxyFlag) |
300 sendPortNumber(os); | |
15 | 301 } |
302 return rfbMinor; | |
303 } | |
31 | 304 |
15 | 305 void sendProxyFlag(OutputStream os) throws IOException { |
31 | 306 if (proxyFlag) |
307 os.write(1); | |
308 else | |
309 os.write(0); | |
15 | 310 } |
31 | 311 |
312 boolean readProxyFlag() throws IOException { | |
15 | 313 int flag = readU8(); |
31 | 314 if (flag == 1) |
15 | 315 return true; |
316 else | |
317 return false; | |
318 } | |
31 | 319 |
15 | 320 void sendPortNumber(OutputStream os) throws IOException { |
321 byte[] b = new byte[4]; | |
322 b = castIntByte(geth.port); | |
323 os.write(b); | |
324 } | |
325 | |
326 void sendSecurityType(OutputStream os) throws IOException { | |
327 // number-of-security-types | |
328 os.write(1); | |
329 // security-types | |
330 // 1:None | |
331 os.write(1); | |
332 | |
31 | 333 /* |
334 * os.write(4); os.write(30); os.write(31); os.write(32); os.write(35); | |
335 * os.flush(); | |
336 */ | |
15 | 337 } |
338 | |
339 void readSecType(InputStream is) throws IOException { | |
340 byte[] b = new byte[1]; | |
341 is.read(b); | |
342 } | |
343 | |
344 void readSecType(InputStream is, OutputStream os) throws IOException { | |
345 byte[] b = new byte[1]; | |
346 is.read(b); | |
347 | |
348 int count = 260; | |
31 | 349 int[] data = { 0, 2, 0, -128, -1, -1, -1, -1, -1, -1, -1, -1, -55, 15, |
350 -38, -94, 33, 104, -62, 52, -60, -58, 98, -117, -128, -36, 28, | |
351 -47, 41, 2, 78, 8, -118, 103, -52, 116, 2, 11, -66, -90, 59, | |
352 19, -101, 34, 81, 74, 8, 121, -114, 52, 4, -35, -17, -107, 25, | |
353 -77, -51, 58, 67, 27, 48, 43, 10, 109, -14, 95, 20, 55, 79, | |
354 -31, 53, 109, 109, 81, -62, 69, -28, -123, -75, 118, 98, 94, | |
355 126, -58, -12, 76, 66, -23, -90, 55, -19, 107, 11, -1, 92, -74, | |
356 -12, 6, -73, -19, -18, 56, 107, -5, 90, -119, -97, -91, -82, | |
357 -97, 36, 17, 124, 75, 31, -26, 73, 40, 102, 81, -20, -26, 83, | |
358 -127, -1, -1, -1, -1, -1, -1, -1, -1, -111, 73, -29, 30, 57, | |
359 -67, -75, -77, -49, -50, -99, -76, -80, -80, 14, 65, 57, -105, | |
360 -103, -54, -102, 3, 39, -44, 39, 35, 118, -84, -64, 37, -117, | |
361 -21, 89, -31, -68, 70, 5, 122, -92, -119, 9, 121, 63, -112, | |
362 -60, 122, -46, -69, -36, 92, -103, -92, 74, 92, -73, 87, 120, | |
363 -8, 116, -47, 111, 20, -41, 110, 122, -3, -94, 14, 42, -51, | |
364 -59, 48, -54, -125, 117, 60, 77, -52, -31, 98, 32, -2, -102, | |
365 -15, -29, 58, -14, -106, -116, -32, -86, 50, -32, -16, -3, | |
366 -123, 87, 88, -118, 10, 120, -107, -37, 125, -110, 59, 87, 93, | |
367 -24, 124, -99, 18, 78, -13, -49, -34, -24, -27, 1, 114, -67, | |
368 -98, -56, -3, 85, -67, -126, 77 }; | |
369 for (int i = 0; i < count; i++) { | |
370 os.write((byte) data[i]); | |
15 | 371 os.flush(); |
372 } | |
31 | 373 |
15 | 374 byte[] c = new byte[256]; |
375 is.read(c); | |
31 | 376 |
15 | 377 System.out.println(new String(c)); |
378 | |
379 } | |
380 | |
381 void sendSecResult(OutputStream os) throws IOException { | |
382 byte[] b = castIntByte(0); | |
383 os.write(b); | |
384 } | |
385 | |
386 void readClientInit(InputStream in) throws IOException { | |
387 byte[] b = new byte[0]; | |
388 in.read(b); | |
389 } | |
390 | |
391 void sendInitData(OutputStream os) throws IOException { | |
392 os.write(initData); | |
393 } | |
394 | |
395 void sendPngImage() { | |
396 try { | |
397 for (Socket cli : cliListTmp) { | |
398 try { | |
399 sendPngData(cli); | |
400 addSock(cli); | |
401 } catch (IOException e) { | |
402 // if socket closed | |
403 cliListTmp.remove(cli); | |
404 } | |
405 } | |
406 // System.out.println("cliSize="+cliSize()); | |
407 } catch (Exception e) { | |
408 } | |
409 cliListTmp.clear(); | |
410 } | |
411 | |
45 | 412 // boolean ready() throws IOException { |
413 // BufferedReader br = new BufferedReader(new InputStreamReader(is)); | |
414 // return br.ready(); | |
415 // } | |
15 | 416 |
417 int cliSize() { | |
418 return cliList.size(); | |
419 } | |
420 | |
421 void printNumBytesRead() { | |
422 System.out.println("numBytesRead=" + numBytesRead); | |
423 } | |
424 | |
425 void regiFramebufferUpdate() throws IOException { | |
426 is.mark(20); | |
31 | 427 messageType = readU8(); // 0 |
428 skipBytes(1); // 1 | |
429 rectangles = readU16(); // 2 | |
430 rectX = readU16(); // 4 | |
431 rectY = readU16(); // 6 | |
432 rectW = readU16(); // 8 | |
433 rectH = readU16(); // 10 | |
434 encoding = readU32(); // 12 | |
435 // System.out.println("encoding = "+encoding); | |
436 if (encoding == EncodingZRLE || encoding == EncodingZRLEE | |
437 || encoding == EncodingZlib) | |
15 | 438 zLen = readU32(); |
439 else | |
440 zLen = 0; | |
45 | 441 // System.out.println(zLen); |
15 | 442 is.reset(); |
443 | |
444 } | |
445 | |
446 int checkAndMark() throws IOException { | |
447 int dataLen; | |
448 switch (encoding) { | |
449 case RfbProto.EncodingRaw: | |
450 dataLen = rectW * rectH * 4 + 16; | |
31 | 451 // is.mark(dataLen); |
15 | 452 break; |
453 case RfbProto.EncodingCopyRect: | |
454 dataLen = 16 + 4; | |
31 | 455 // is.mark(dataLen); |
15 | 456 break; |
457 case RfbProto.EncodingRRE: | |
458 case RfbProto.EncodingCoRRE: | |
459 case RfbProto.EncodingHextile: | |
460 case RfbProto.EncodingTight: | |
461 dataLen = zLen + 20; | |
31 | 462 // is.mark(dataLen); |
15 | 463 break; |
464 case RfbProto.EncodingZlib: | |
465 case RfbProto.EncodingZRLE: | |
466 case RfbProto.EncodingZRLEE: | |
467 dataLen = zLen + 20; | |
31 | 468 // is.mark(dataLen); |
15 | 469 break; |
470 case RfbProto.EncodingXCursor: | |
471 case RfbProto.EncodingRichCursor: | |
472 int pixArray = rectW * rectH * 4; | |
31 | 473 int u8Array = (int) Math.floor((rectW + 7) / 8) * rectH; |
15 | 474 dataLen = pixArray + u8Array; |
475 printFramebufferUpdate(); | |
31 | 476 // is.mark(dataLen); |
15 | 477 break; |
478 default: | |
479 dataLen = 1000000; | |
31 | 480 // is.mark(dataLen); |
15 | 481 } |
482 return dataLen; | |
483 } | |
484 | |
485 void sendDataToClient() throws Exception { | |
486 regiFramebufferUpdate(); | |
487 printFramebufferUpdate(); | |
488 int dataLen = checkAndMark(); | |
31 | 489 readSendData(dataLen); |
15 | 490 } |
491 | |
492 BufferedImage createBufferedImage(Image img) { | |
493 BufferedImage bimg = new BufferedImage(img.getWidth(null), | |
494 img.getHeight(null), BufferedImage.TYPE_INT_RGB); | |
495 | |
496 Graphics g = bimg.getGraphics(); | |
497 g.drawImage(img, 0, 0, null); | |
498 g.dispose(); | |
499 return bimg; | |
500 } | |
501 | |
502 void createPngBytes(BufferedImage bimg) throws IOException { | |
503 pngBytes = getImageBytes(bimg, "png"); | |
504 } | |
505 | |
506 byte[] getBytes(BufferedImage img) throws IOException { | |
507 byte[] b = getImageBytes(img, "png"); | |
508 return b; | |
509 } | |
510 | |
511 byte[] getImageBytes(BufferedImage image, String imageFormat) | |
512 throws IOException { | |
513 ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |
514 BufferedOutputStream os = new BufferedOutputStream(bos); | |
515 image.flush(); | |
516 ImageIO.write(image, imageFormat, os); | |
517 os.flush(); | |
518 os.close(); | |
519 return bos.toByteArray(); | |
520 } | |
521 | |
522 void sendPngData(Socket sock) throws IOException { | |
523 byte[] dataLength = castIntByte(pngBytes.length); | |
524 sock.getOutputStream().write(dataLength); | |
525 sock.getOutputStream().write(pngBytes); | |
526 } | |
527 | |
528 byte[] castIntByte(int len) { | |
529 byte[] b = new byte[4]; | |
530 b[0] = (byte) ((len >>> 24) & 0xFF); | |
531 b[1] = (byte) ((len >>> 16) & 0xFF); | |
532 b[2] = (byte) ((len >>> 8) & 0xFF); | |
533 b[3] = (byte) ((len >>> 0) & 0xFF); | |
534 return b; | |
535 } | |
536 | |
537 BufferedImage createBimg() throws IOException { | |
538 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); | |
539 return bimg; | |
540 } | |
541 | |
542 void printFramebufferUpdate() { | |
543 /* | |
31 | 544 * System.out.println("messageType=" + messageType); |
545 * System.out.println("rectangles=" + rectangles); | |
546 * System.out.println("encoding=" + encoding); | |
547 * System.out.println("rectX = "+rectX+": rectY = "+rectY); | |
548 * System.out.println("rectW = "+rectW+": rectH = "+rectH); | |
549 */ | |
15 | 550 switch (encoding) { |
551 case RfbProto.EncodingRaw: | |
552 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 | |
553 + 16); | |
554 break; | |
555 default: | |
556 } | |
557 } | |
31 | 558 |
15 | 559 int returnMsgtype() { |
560 return messageType; | |
561 } | |
31 | 562 |
15 | 563 void readSpeedCheck() throws IOException { |
564 byte[] b = new byte[1]; | |
565 readFully(b); | |
566 } | |
31 | 567 |
15 | 568 void startSpeedCheck() { |
569 ByteBuffer b = ByteBuffer.allocate(10); | |
31 | 570 b.put((byte) SpeedCheckMillis); |
15 | 571 b.flip(); |
572 startCheckTime = System.currentTimeMillis(); | |
31 | 573 System.out.println("startChckTime = " + startCheckTime); |
574 LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); | |
15 | 575 bufs.add(b); |
576 multicastqueue.put(bufs); | |
577 } | |
578 | |
579 void endSpeedCheck() { | |
580 long accTime = System.currentTimeMillis(); | |
581 long time = accTime - startCheckTime; | |
582 System.out.println("checkMillis: " + time); | |
583 } | |
584 | |
585 synchronized void changeStatusFlag() { | |
586 printStatusFlag = true; | |
587 } | |
588 | |
589 void printMills() { | |
31 | 590 if (printStatusFlag) { |
15 | 591 |
592 changeStatusFlag(); | |
593 } else { | |
594 changeStatusFlag(); | |
595 } | |
596 } | |
31 | 597 |
15 | 598 void speedCheckMillis() { |
31 | 599 Runnable stdin = new Runnable() { |
15 | 600 public void run() { |
601 int c; | |
602 try { | |
31 | 603 while ((c = System.in.read()) != -1) { |
604 switch (c) { | |
605 case 's': | |
606 break; | |
607 default: | |
608 startSpeedCheck(); | |
609 break; | |
15 | 610 } |
611 } | |
31 | 612 } catch (IOException e) { |
15 | 613 System.out.println(e); |
614 } | |
615 } | |
616 }; | |
31 | 617 |
15 | 618 new Thread(stdin).start(); |
619 } | |
31 | 620 |
15 | 621 void requestThreadStart() { |
622 requestThread.start(); | |
623 } | |
624 | |
625 public synchronized void requestThreadNotify() { | |
626 rThread.reStart(); | |
627 } | |
628 | |
629 /** | |
630 * gzip byte arrays | |
31 | 631 * |
15 | 632 * @param deflater |
633 * @param inputs | |
634 * byte data[] | |
31 | 635 * @param inputIndex |
15 | 636 * @param outputs |
637 * byte data[] | |
31 | 638 * @return byte length in last byte array |
15 | 639 * @throws IOException |
640 */ | |
31 | 641 public int zip(Deflater deflater, LinkedList<ByteBuffer> inputs, |
642 int inputIndex, LinkedList<ByteBuffer> outputs) throws IOException { | |
15 | 643 int len = 0; |
31 | 644 ByteBuffer c1 = ByteBuffer.allocate(INFLATE_BUFSIZE); |
645 while (inputIndex < inputs.size()) { | |
15 | 646 ByteBuffer b1 = inputs.get(inputIndex++); |
31 | 647 deflater.setInput(b1.array(), b1.position(), b1.remaining()); |
15 | 648 /** |
31 | 649 * If we finish() stream and reset() it, Deflater start new gzip |
650 * stream, this makes continuous zlib reader unhappy. if we remove | |
651 * finish(), Deflater.deflate() never flushes its output. The | |
652 * original zlib deflate has flush flag. I'm pretty sure this a kind | |
653 * of bug of Java library. | |
15 | 654 */ |
31 | 655 if (inputIndex == inputs.size()) |
15 | 656 deflater.finish(); |
657 int len1 = 0; | |
658 do { | |
31 | 659 len1 = deflater.deflate(c1.array(), c1.position(), |
660 c1.remaining()); | |
661 if (len1 > 0) { | |
15 | 662 len += len1; |
31 | 663 c1.position(c1.position() + len1); |
664 if (c1.remaining() == 0) { | |
665 c1.flip(); | |
666 outputs.addLast(c1); | |
15 | 667 c1 = ByteBuffer.allocate(INFLATE_BUFSIZE); |
668 } | |
669 } | |
31 | 670 } while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished()); |
15 | 671 } |
31 | 672 if (c1.position() != 0) { |
673 c1.flip(); | |
674 outputs.addLast(c1); | |
15 | 675 } |
676 deflater.reset(); | |
677 return len; | |
678 } | |
31 | 679 |
15 | 680 /** |
681 * gunzip byte arrays | |
31 | 682 * |
15 | 683 * @param inflater |
684 * @param inputs | |
685 * byte data[] | |
686 * @param outputs | |
687 * byte data[] | |
31 | 688 * @return number of total bytes |
15 | 689 * @throws IOException |
690 */ | |
31 | 691 public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs, |
692 int inputIndex, LinkedList<ByteBuffer> outputs, int bufSize) | |
693 throws DataFormatException { | |
694 int len = 0; | |
15 | 695 ByteBuffer buf = ByteBuffer.allocate(bufSize); |
696 while (inputIndex < inputs.size()) { | |
697 ByteBuffer input = inputs.get(inputIndex++); | |
31 | 698 inflater.setInput(input.array(), input.position(), input.limit()); |
699 // if (inputIndex==inputs.size()) if inflater/deflater has symmetry, | |
700 // we need this | |
701 // inflater.end(); but this won't work | |
15 | 702 do { |
31 | 703 int len0 = inflater.inflate(buf.array(), buf.position(), |
704 buf.remaining()); | |
705 if (len0 > 0) { | |
706 buf.position(buf.position() + len0); | |
15 | 707 len += len0; |
31 | 708 if (buf.remaining() == 0) { |
15 | 709 buf.flip(); |
710 outputs.addLast(buf); | |
711 buf = ByteBuffer.allocate(bufSize); | |
712 } | |
713 } | |
714 } while (!inflater.needsInput()); | |
31 | 715 } |
716 if (buf.position() != 0) { | |
15 | 717 buf.flip(); |
718 outputs.addLast(buf); | |
719 } | |
720 return len; | |
721 } | |
722 | |
723 float maxMag = 1; | |
31 | 724 |
15 | 725 /** |
726 * send data to clients | |
31 | 727 * |
15 | 728 * @param dataLen |
729 * @throws IOException | |
730 * @throws DataFormatException | |
731 * | |
31 | 732 * Zlibed packet is compressed in context dependent way, that |
733 * is, it have to send from the beginning. But this is | |
734 * impossible. So we have to compress it again for each clients. | |
735 * Separate deflater for each clients is necessary. | |
15 | 736 * |
31 | 737 * Java's deflater does not support flush. This means to get the |
738 * result, we have to finish the compression. Reseting start new | |
739 * compression, but it is not accepted well in zlib continuous | |
740 * reading. So we need new Encoding ZRLEE which reset decoder | |
741 * for each packet. ZRLEE can be invisible from user, but it | |
742 * have to be implemented in the clients. ZRLEE compression is | |
743 * not context dependent, so no recompression is necessary. | |
15 | 744 */ |
28 | 745 void sendDataCheckDelay() { |
31 | 746 LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); |
28 | 747 ByteBuffer b = ByteBuffer.allocate(1); |
31 | 748 b.put((byte) CheckDelay); |
28 | 749 b.position(0); |
750 bufs.add(b); | |
751 multicastqueue.put(bufs); | |
752 } | |
31 | 753 |
15 | 754 void readSendData(int dataLen) throws IOException, DataFormatException { |
31 | 755 LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); |
15 | 756 ByteBuffer header = ByteBuffer.allocate(16); |
31 | 757 readFully(header.array(), 0, 16); |
15 | 758 header.limit(16); |
31 | 759 if (header.get(0) == RfbProto.FramebufferUpdate) { |
15 | 760 int encoding = header.getInt(12); |
31 | 761 if (encoding == RfbProto.EncodingZRLE |
762 || encoding == RfbProto.EncodingZlib) { // ZRLEE is already | |
763 // recompressed | |
15 | 764 ByteBuffer len = ByteBuffer.allocate(4); |
31 | 765 readFully(len.array(), 0, 4); |
766 len.limit(4); | |
767 ByteBuffer inputData = ByteBuffer.allocate(dataLen - 20); | |
15 | 768 |
769 startTiming(); | |
31 | 770 readFully(inputData.array(), 0, inputData.capacity()); |
45 | 771 // System.out.println(dataLen); |
31 | 772 inputData.limit(dataLen - 20); |
15 | 773 stopTiming(); |
774 | |
31 | 775 LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>(); |
15 | 776 inputs.add(inputData); |
777 | |
31 | 778 header.putInt(12, RfbProto.EncodingZRLEE); // means recompress |
779 // every time | |
780 // using new Deflecter every time is incompatible with the | |
781 // protocol, clients have to be modified. | |
15 | 782 Deflater nDeflater = deflater; // new Deflater(); |
783 LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>(); | |
31 | 784 unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE); |
15 | 785 // dump32(inputs); |
45 | 786 |
787 if (dataLen > 64000) { | |
788 splitData(out, header); | |
789 } else { | |
15 | 790 |
45 | 791 int len2 = zip(nDeflater, out, 0, bufs); |
792 ByteBuffer blen = ByteBuffer.allocate(4); | |
793 blen.putInt(len2); | |
794 blen.flip(); | |
795 bufs.addFirst(blen); | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
796 if(header.getShort(10) > 1080) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
797 System.out.println("error"); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
798 } |
45 | 799 bufs.addFirst(header); |
33
74195a7722be
add src/BlockingUpdateRectangle.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
31
diff
changeset
|
800 multicastqueue.put(bufs); |
45 | 801 } |
31 | 802 // is.reset(); |
15 | 803 |
31 | 804 /* |
805 * System.out.println("ZRLE = "+dataLen); | |
806 * System.out.println("ZRLEE = "+(len2+20)); float mag = | |
807 * (float)dataLen / (float)(len2 + 20); | |
808 * System.out.println("ZRLE / ZRLEE = "+ mag); if(mag > maxMag) | |
809 * maxMag = mag; System.out.println("maxMag = "+maxMag); | |
810 */ | |
811 return; | |
15 | 812 } |
31 | 813 bufs.add(header); |
814 if (dataLen > 16) { | |
815 ByteBuffer b = ByteBuffer.allocate(dataLen - 16); | |
816 startTiming(); | |
817 readFully(b.array(), 0, dataLen - 16); | |
818 b.limit(dataLen - 16); | |
819 stopTiming(); | |
820 bufs.add(b); | |
821 } | |
822 multicastqueue.put(bufs); | |
823 // is.reset(); | |
824 return; | |
15 | 825 } |
31 | 826 is.reset(); |
15 | 827 |
31 | 828 // It may be compressed. We can inflate here to avoid repeating clients |
829 // decompressing here, | |
830 // but it may generate too many large data. It is better to do it in | |
831 // each client. | |
832 // But we have do inflation for all input data, so we have to do it | |
833 // here. | |
15 | 834 } |
835 | |
19 | 836 public void newClient(AcceptThread acceptThread, final Socket newCli, |
15 | 837 final OutputStream os, final InputStream is) throws IOException { |
838 // createBimgFlag = true; | |
839 // rfb.addSockTmp(newCli); | |
31 | 840 // addSock(newCli); |
841 final int myId = clients; | |
842 final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue | |
843 .newClient(); | |
15 | 844 final AtomicInteger writerRunning = new AtomicInteger(); |
845 writerRunning.set(1); | |
846 /** | |
31 | 847 * Timeout thread. If a client is suspended, it has top of queue |
848 * indefinitely, which caused memory overflow. After the timeout, we | |
849 * poll the queue and discard it. Start long wait if writer is running. | |
15 | 850 */ |
851 final Runnable timer = new Runnable() { | |
852 public void run() { | |
853 int count = 0; | |
31 | 854 for (;;) { |
855 long timeout = 50000 / 8; | |
15 | 856 try { |
31 | 857 synchronized (this) { |
858 int state, flag; | |
15 | 859 writerRunning.set(0); |
860 wait(timeout); | |
861 flag = 0; | |
31 | 862 while ((state = writerRunning.get()) == 0) { |
15 | 863 c.poll(); // discard, should be timeout |
864 count++; | |
31 | 865 if (flag == 0) { |
866 System.out.println("Discarding " + myId | |
867 + " count=" + count); | |
868 flag = 1; | |
15 | 869 } |
31 | 870 wait(10); // if this is too short, writer cannot |
871 // take the poll, if this is too | |
872 // long, memory will overflow... | |
15 | 873 } |
31 | 874 if (flag == 1) |
875 System.out.println("Resuming " + myId | |
876 + " count=" + count); | |
877 if (state != 1) { | |
878 System.out.println("Client died " + myId); | |
15 | 879 break; |
880 } | |
881 } | |
882 } catch (InterruptedException e) { | |
883 } | |
884 } | |
885 } | |
886 }; | |
887 new Thread(timer).start(); | |
888 /** | |
889 * discard all incoming from clients | |
890 */ | |
891 final Runnable reader = new Runnable() { | |
892 public void run() { | |
893 byte b[] = new byte[4096]; | |
31 | 894 for (;;) { |
15 | 895 try { |
896 int c = is.read(b); | |
31 | 897 if (c <= 0) |
898 throw new IOException(); | |
15 | 899 // System.out.println("client read "+c); |
900 } catch (IOException e) { | |
901 try { | |
902 writerRunning.set(2); | |
903 os.close(); | |
904 is.close(); | |
905 } catch (IOException e1) { | |
906 } | |
907 return; | |
908 } | |
909 } | |
910 } | |
911 }; | |
912 /** | |
913 * send packets to a client | |
914 */ | |
915 Runnable sender = new Runnable() { | |
916 public void run() { | |
917 writerRunning.set(1); | |
918 try { | |
919 requestThreadNotify(); | |
31 | 920 // rThread.checkDelay(); |
15 | 921 |
922 /** | |
31 | 923 * initial connection of RFB protocol |
15 | 924 */ |
925 sendRfbVersion(os); | |
31 | 926 // readVersionMsg(is); |
927 int rfbMinor = readVersionMsg(is, os); | |
15 | 928 sendSecurityType(os); |
929 readSecType(is); | |
930 sendSecResult(os); | |
931 readClientInit(is); | |
932 sendInitData(os); | |
31 | 933 new Thread(reader).start(); // discard incoming packet here |
934 // after. | |
935 // writeFramebufferUpdateRequest(0,0, framebufferWidth, | |
936 // framebufferHeight, false ); | |
45 | 937 int i = 0; |
15 | 938 for (;;) { |
939 LinkedList<ByteBuffer> bufs = c.poll(); | |
940 int inputIndex = 0; | |
941 ByteBuffer header = bufs.get(inputIndex); | |
31 | 942 if (header == null) |
943 continue; | |
33
74195a7722be
add src/BlockingUpdateRectangle.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
31
diff
changeset
|
944 else if (header.get(0) == RfbProto.CheckDelay) { |
28 | 945 writeToClient(os, bufs, inputIndex); |
946 continue; | |
33
74195a7722be
add src/BlockingUpdateRectangle.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
31
diff
changeset
|
947 } else if (header.get(0) == RfbProto.FramebufferUpdate) { |
15 | 948 // System.out.println("client "+ myId); |
949 } | |
31 | 950 /* |
45 | 951 * if(i%20==0){ sendDataCheckDelay(); } i++; |
952 */ | |
15 | 953 writeToClient(os, bufs, inputIndex); |
31 | 954 writerRunning.set(1); // yes my client is awaking. |
15 | 955 } |
956 } catch (IOException e) { | |
957 try { | |
958 writerRunning.set(2); | |
959 os.close(); | |
960 } catch (IOException e1) { | |
961 } | |
31 | 962 /* if socket closed cliList.remove(newCli); */ |
15 | 963 } |
964 } | |
50 | 965 |
966 void broadcastCommunication(byte[] buf, int off ,int len) { | |
967 String mcastAddr = "224.0.0.1"; | |
968 int port = 8192; | |
969 | |
970 try { | |
971 InetAddress mAddr = InetAddress.getByName(mcastAddr); | |
972 MulticastSocket soc = new MulticastSocket(); | |
973 DatagramPacket sendPacket = null; | |
974 soc.setTimeToLive(100); | |
975 | |
976 // System.out.println("Multicast = " + mcastAddr); | |
977 // while(buf != null) { | |
978 // int len = System.in.read(buf); | |
51 | 979 sendPacket = new DatagramPacket(buf, len - off, mAddr, port); |
50 | 980 soc.send(sendPacket); |
981 // } | |
982 soc.close(); | |
983 } catch (IOException e) { | |
984 e.printStackTrace(); | |
985 } | |
986 | |
987 } | |
15 | 988 |
989 public void writeToClient(final OutputStream os, | |
990 LinkedList<ByteBuffer> bufs, int inputIndex) | |
991 throws IOException { | |
31 | 992 while (inputIndex < bufs.size()) { |
15 | 993 ByteBuffer b = bufs.get(inputIndex++); |
51 | 994 if(b.limit()-b.position()<64000) |
995 broadcastCommunication(b.array(),b.position(),b.limit());System.out.println("send"); | |
50 | 996 //os.write(b.array(), b.position(), b.limit()); |
15 | 997 } |
998 os.flush(); | |
999 } | |
1000 }; | |
1001 clients++; | |
1002 new Thread(sender).start(); | |
1003 | |
1004 } | |
1005 | |
31 | 1006 public void dump32(LinkedList<ByteBuffer> bufs) { |
1007 int len = 0; | |
1008 for (ByteBuffer b : bufs) | |
1009 len += b.remaining(); | |
15 | 1010 ByteBuffer top = bufs.getFirst(); |
1011 ByteBuffer end = bufs.getLast(); | |
31 | 1012 System.err.println("length: " + len); |
15 | 1013 System.err.print("head 0: "); |
31 | 1014 for (int i = 0; i < 16 && i < top.remaining(); i++) { |
1015 System.err.print(" " + top.get(i)); | |
1016 } | |
15 | 1017 System.err.print("tail 0: "); |
31 | 1018 for (int i = 0; i < 16 && i < end.remaining(); i++) { |
1019 System.err.print(" " + end.get(i)); | |
15 | 1020 } |
1021 System.err.println(); | |
1022 } | |
1023 | |
1024 @Test | |
1025 public void test1() { | |
1026 try { | |
1027 LinkedList<ByteBuffer> in = new LinkedList<ByteBuffer>(); | |
1028 LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>(); | |
1029 LinkedList<ByteBuffer> out2 = new LinkedList<ByteBuffer>(); | |
31 | 1030 // if (false) { |
1031 // for(int i=0;i<10;i++) { | |
1032 // in.add(ByteBuffer.wrap("test1".getBytes())); | |
1033 // in.add(ByteBuffer.wrap("test2".getBytes())); | |
1034 // in.add(ByteBuffer.wrap("test3".getBytes())); | |
1035 // in.add(ByteBuffer.wrap("test44".getBytes())); | |
1036 // } | |
1037 // } else | |
15 | 1038 { |
1039 String t = ""; | |
31 | 1040 for (int i = 0; i < 10; i++) { |
15 | 1041 t += "test1"; |
1042 t += "test2"; | |
1043 t += "test3"; | |
1044 t += "test44"; | |
1045 } | |
1046 in.add(ByteBuffer.wrap(t.getBytes())); | |
1047 } | |
31 | 1048 |
15 | 1049 LinkedList<ByteBuffer> in1 = clone(in); |
1050 | |
1051 Deflater deflater = new Deflater(); | |
31 | 1052 zip(deflater, in, 0, out); |
1053 // LinkedList<ByteBuffer> out3 = clone(out); zipped result is depend | |
1054 // on deflator's state | |
1055 unzip(inflater, out, 0, out2, INFLATE_BUFSIZE); | |
1056 // inflater.reset(); | |
15 | 1057 equalByteBuffers(in1, out2); |
1058 LinkedList<ByteBuffer> out4 = new LinkedList<ByteBuffer>(); | |
1059 deflater = new Deflater(); | |
31 | 1060 zip(deflater, out2, 0, out4); |
15 | 1061 LinkedList<ByteBuffer> out5 = new LinkedList<ByteBuffer>(); |
31 | 1062 unzip(inflater, out4, 0, out5, INFLATE_BUFSIZE); |
1063 int len = equalByteBuffers(in1, out5); | |
1064 | |
1065 System.out.println("Test Ok. " + len); | |
15 | 1066 } catch (Exception e) { |
31 | 1067 assertEquals(0, 1); |
15 | 1068 } |
1069 } | |
1070 | |
1071 private LinkedList<ByteBuffer> clone(LinkedList<ByteBuffer> in) { | |
1072 LinkedList<ByteBuffer> copy = new LinkedList<ByteBuffer>(); | |
31 | 1073 for (ByteBuffer b : in) { |
15 | 1074 ByteBuffer c = b.duplicate(); |
1075 copy.add(c); | |
1076 } | |
1077 return copy; | |
1078 } | |
1079 | |
1080 public int equalByteBuffers(LinkedList<ByteBuffer> in, | |
1081 LinkedList<ByteBuffer> out2) { | |
1082 int len = 0; | |
1083 Iterable<Byte> i = byteBufferIterator(in); | |
1084 Iterator<Byte> o = byteBufferIterator(out2).iterator(); | |
1085 | |
31 | 1086 for (int b : i) { |
1087 len++; | |
15 | 1088 if (o.hasNext()) { |
1089 int c = o.next(); | |
31 | 1090 assertEquals(b, c); |
1091 } else | |
1092 assertEquals(0, 1); | |
15 | 1093 } |
31 | 1094 if (o.hasNext()) |
1095 assertEquals(0, 1); | |
15 | 1096 // System.out.println(); |
1097 return len; | |
1098 } | |
1099 | |
1100 private Iterable<Byte> byteBufferIterator(final LinkedList<ByteBuffer> in) { | |
1101 return new Iterable<Byte>() { | |
1102 public Iterator<Byte> iterator() { | |
1103 return new Iterator<Byte>() { | |
1104 int bytes = 0; | |
1105 int buffers = 0; | |
31 | 1106 |
15 | 1107 public boolean hasNext() { |
31 | 1108 for (;;) { |
1109 if (buffers >= in.size()) | |
1110 return false; | |
15 | 1111 ByteBuffer b = in.get(buffers); |
31 | 1112 if (!(bytes < b.remaining())) { |
1113 buffers++; | |
1114 bytes = 0; | |
1115 } else | |
1116 return true; | |
15 | 1117 } |
1118 } | |
31 | 1119 |
15 | 1120 public Byte next() { |
31 | 1121 ByteBuffer bf = in.get(buffers); |
1122 byte b = bf.get(bytes++); | |
1123 if (bf.remaining() <= bytes) { | |
15 | 1124 buffers++; |
1125 bytes = 0; | |
1126 } | |
1127 // System.out.print(b); | |
1128 return b; | |
1129 } | |
31 | 1130 |
15 | 1131 public void remove() { |
1132 } | |
1133 }; | |
1134 } | |
1135 }; | |
1136 } | |
1137 | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1138 public LinkedList<ByteBuffer> splitBuffer(LinkedList<ByteBuffer> input, |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1139 ByteBuffer header) throws IOException { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1140 /* |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1141 ByteBuffer testBuffer = ByteBuffer.allocate(16); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1142 header.get(testBuffer.array()); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1143 LinkedList<ByteBuffer> testB = new LinkedList<ByteBuffer>(); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1144 int t = 0; |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1145 while(input.size()>t) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1146 testB.addLast(input.get(t)); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1147 t++; |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1148 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1149 */ |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1150 |
45 | 1151 LinkedList<ByteBuffer> output = new LinkedList<ByteBuffer>(); |
1152 // int high = rectH / 4; | |
1153 // System.out.println(INFLATE_BUFSIZE * (input.size() - 1)+ | |
1154 // input.getLast().limit()); | |
51 | 1155 int dataSize = 64; |
47 | 1156 int width = header.getShort(8); |
1157 int height = header.getShort(10); | |
1158 int y = header.getShort(6); | |
51 | 1159 int dataLen = width * 64 * 3; |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1160 int temp = 0, preserv = 0; |
51 | 1161 int count = height / dataSize; |
45 | 1162 |
47 | 1163 if (width % 64 == 0) |
51 | 1164 dataLen += (width / 64); |
45 | 1165 else |
51 | 1166 dataLen += (width / 64) + 1; |
45 | 1167 |
1168 for (int i = 0; i < count; i++) { | |
1169 int tempDataLen = dataLen - temp; | |
1170 | |
1171 while (tempDataLen > INFLATE_BUFSIZE) { | |
1172 output.addLast(input.poll()); | |
1173 tempDataLen -= INFLATE_BUFSIZE; | |
1174 } | |
1175 if (tempDataLen == INFLATE_BUFSIZE) { | |
1176 output.addLast(input.poll()); | |
51 | 1177 createHeader(header, i, height, y,dataSize); |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1178 if(header.getShort(10) > 1080) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1179 System.out.println("error"); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1180 } |
47 | 1181 zipSplitData(header, output); |
1182 output.clear(); | |
45 | 1183 temp = INFLATE_BUFSIZE; |
1184 } else { | |
1185 // System.out.println("THROWIO"); | |
1186 ByteBuffer tempBuf = input.poll(); | |
1187 | |
1188 // System.out.println(tempBuf.remaining()); | |
1189 ByteBuffer buf1 = ByteBuffer.allocate(INFLATE_BUFSIZE); | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1190 if(tempBuf.remaining()>tempDataLen) |
45 | 1191 tempBuf.get(buf1.array(), 0, tempDataLen); |
1192 buf1.limit(tempDataLen); | |
47 | 1193 output.addLast(buf1); |
51 | 1194 createHeader(header, i, height, y,dataSize); |
47 | 1195 zipSplitData(header, output); |
1196 output.clear(); | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1197 // checkPallet(output); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1198 |
45 | 1199 // insert into createHeader |
1200 // insert into this area zipcode and buf1 clear | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1201 buf1 = ByteBuffer.allocate(INFLATE_BUFSIZE); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1202 tempBuf.get(buf1.array(), 0, tempBuf.remaining()); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1203 if(buf1.get(0)!=0) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1204 System.out.println("error"); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1205 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1206 buf1.limit(INFLATE_BUFSIZE - tempDataLen); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1207 output.addLast(buf1); |
45 | 1208 temp = INFLATE_BUFSIZE - tempDataLen; |
1209 } | |
47 | 1210 preserv = i; |
45 | 1211 } |
1212 | |
1213 while (input.size() != 0) { | |
1214 output.addLast(input.poll()); | |
1215 } | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1216 // checkPallet(output); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1217 if(count==0) |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1218 preserv -= 1; |
51 | 1219 createHeader(header, preserv + 1, height, y,dataSize); |
49 | 1220 zipSplitData(header, output); |
47 | 1221 output.clear(); |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1222 |
45 | 1223 return output; |
1224 } | |
1225 | |
1226 private void splitData(LinkedList<ByteBuffer> input, ByteBuffer header) | |
1227 throws IOException, DataFormatException { | |
1228 | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1229 splitBuffer(input, header); |
51 | 1230 |
45 | 1231 } |
1232 | |
47 | 1233 private void zipSplitData(ByteBuffer header, LinkedList<ByteBuffer> tempBuf) |
1234 throws IOException { | |
1235 Deflater nDeflater = new Deflater(); | |
1236 LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); | |
1237 | |
1238 int len2 = zip(nDeflater, tempBuf, 0, bufs); | |
51 | 1239 //if(len2 > 64000) |
1240 //System.out.println("too long"+len2); | |
47 | 1241 ByteBuffer blen = ByteBuffer.allocate(4); |
1242 blen.putInt(len2); | |
1243 blen.flip(); | |
1244 bufs.addFirst(blen); | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1245 // createHeader(header, i); |
47 | 1246 |
1247 bufs.addFirst(header); | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1248 checkHW(header); |
47 | 1249 // broadcastqueue.put(bufs); |
1250 multicastqueue.put(bufs); | |
1251 } | |
1252 | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1253 static void checkHW(ByteBuffer header) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1254 int w = header.getShort(8); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1255 int h = header.getShort(10); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1256 // System.err.println("p:w="+w+" h="+h); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1257 assert(w>0); |
51 | 1258 assert(h>0); |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1259 |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1260 |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1261 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1262 |
51 | 1263 private void createHeader(ByteBuffer header, int count, int h, int y,int size) { |
1264 int rH = Math.min(size, h - (size * count)); | |
1265 int rY = y + (size * count); | |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1266 if(rH<0) { |
51 | 1267 rY += size; |
48
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1268 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1269 header.putShort(10, (short)rH); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1270 header.putShort(6, (short)rY); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1271 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1272 |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1273 private void checkPallet(LinkedList<ByteBuffer> output) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1274 int check = 64 * 64 * 3 + 1; |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1275 |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1276 for (ByteBuffer b : output) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1277 while (true) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1278 if (b.remaining() <= check) { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1279 check -= b.limit(); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1280 break; |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1281 } else { |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1282 // System.out.println(b.get(check)); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1283 if(b.get(check)!=0) |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1284 b.put(check,(byte)0); |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1285 check += 64 * 64 * 3 + 1; |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1286 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1287 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1288 } |
e6d5ec9ec15e
add splitBufferTest.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1289 |
45 | 1290 } |
1291 | |
15 | 1292 } |