comparison src/myVncProxy/MyRfbProto.java @ 87:a8c33757ac99

refactoring zip/unzip
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 03 Aug 2011 08:33:55 +0900
parents b7225991184b
children 9b3b1e3e7db5
comparison
equal deleted inserted replaced
86:b7225991184b 87:a8c33757ac99
485 changeStatusFlag(); 485 changeStatusFlag();
486 } else { 486 } else {
487 changeStatusFlag(); 487 changeStatusFlag();
488 } 488 }
489 } 489 }
490 490
491 public int zip(Deflater deflater,LinkedList<byte[]> inputs, byte[] header, LinkedList<byte[]> outputs) throws IOException {
492 int clen = u32(inputs.poll(),0);
493
494 int len = 0, count = 0;
495 int len2=0;
496 //int bufSize = bufs.size();
497 //int bufCount = 0;
498 deflater.reset();
499 do {
500 byte[] b1 = inputs.poll();
501 if (inputs.size()==0) {
502 deflater.setInput(b1,0,clen);
503 deflater.finish();
504 } else
505 deflater.setInput(b1);
506 int len1=0;
507 do {
508 byte[] c1 = new byte[INFLATE_BUFSIZE];
509 len2 = len1;
510 len1 = deflater.deflate(c1);
511 if (len1>0) {
512 outputs.addLast(c1);
513 count ++;
514 len += len1;
515 }
516 } while (len1 > 0);
517 } while(inputs.size()>0);
518 byte[] blen = castIntByte(len);
519 outputs.addFirst(blen);
520 outputs.addFirst(header);
521 return len2;
522
523 }
524
525 public void unzip(Inflater inflater, byte[] input, LinkedList<byte[]> outputs)
526 throws DataFormatException {
527 int len=0,len0;
528 inflater.setInput(input, 20, input.length-20);
529 do {
530 byte buf[] = new byte[INFLATE_BUFSIZE];
531 len0 = inflater.inflate(buf);
532 len += len0;
533 outputs.addLast(buf);
534 } while (len0 ==INFLATE_BUFSIZE);
535 byte [] blen = castIntByte(len0);
536 outputs.addFirst(blen);
537 byte inf[] = new byte[16];
538 for(int i = 0;i<16;i++) inf[i] = input[i];
539 outputs.addFirst(inf);
540 }
541
542 void readSendData(int dataLen) throws IOException, DataFormatException {
543 byte b[] = new byte[dataLen];
544 readFully(b);
545 LinkedList<byte[]>bufs = new LinkedList<byte[]>();
546 if (b[0]==RfbProto.FramebufferUpdate) {
547 int encoding = u32(b,12);
548 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) {
549 unzip(inflater, b, bufs);
550 multicastqueue.put(bufs);
551 is.reset();
552 return ;
553 }
554 }
555 bufs.add(b);
556 multicastqueue.put(bufs);
557 is.reset();
558
559 // It may be compressed. We can inflate here to avoid repeating clients decompressing here,
560 // but it may generate too many large data. It is better to do it in each client.
561 // But we have do inflation for all input data, so we have to do it here.
562 /*
563 for (Socket cli : cliList) {
564 try {
565 OutputStream out = cli.getOutputStream();
566 executor.execute(new SendThread(out, buffer));
567 } catch (IOException e) {
568 // if client socket closed
569 cliListTmp.remove(cli);
570 } catch (Exception e) {
571
572 }
573
574 }
575 */
576 }
577
578 void newClient(AcceptThread acceptThread, final Socket newCli,
579 final OutputStream os, final InputStream is) throws IOException {
580 // createBimgFlag = true;
581 // rfb.addSockTmp(newCli);
582 // addSock(newCli);
583 final Client <LinkedList<byte[]>> c = multicastqueue.newClient();
584 Runnable sender = new Runnable() {
585 public void run() {
586
587 Deflater deflater = new Deflater();
588 try {
589 /**
590 * initial connection of RFB protocol
591 */
592 sendRfbVersion(os);
593 readVersionMsg(is);
594 sendSecurityType(os);
595 readSecType(is);
596 sendSecResult(os);
597 readClientInit(is);
598 sendInitData(os);
599
600 for (;;) {
601 LinkedList<byte[]> bufs = c.poll();
602 byte[] b = bufs.poll();
603 if (b[0]==RfbProto.FramebufferUpdate) {
604 int encoding = u32(b,12);
605 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) {
606 LinkedList<byte[]> outs = new LinkedList<byte[]>();
607 int len2 = zip(deflater, bufs, b, outs);
608 while(!outs.isEmpty()) {
609 byte [] out= outs.poll();
610 if (outs.isEmpty())
611 os.write(out,0,len2);
612 else
613 os.write(out);
614 }
615 }
616 } else {
617 os.write(b, 0, b.length);
618 }
619 os.flush();
620 }
621 } catch (IOException e) {
622 /**
623 * if socket closed
624 */
625 // cliList.remove(newCli);
626 }
627
628 }
629
630
631
632 };
633 clients++;
634 new Thread(sender).start();
635
636 }
637
638 private int u32(byte[] b, int i) {
639 int ret = 0;
640 for(int j = 0;j<4;j++) {
641 ret *= 256;
642 ret += b[i+j] & 0xff;
643 }
644 return ret;
645 }
646 void speedCheckMillis() { 491 void speedCheckMillis() {
647 492 Runnable stdin = new Runnable() {
648 Runnable stdin = new Runnable() {
649 public void run() { 493 public void run() {
650 int c; 494 int c;
651 try { 495 try {
652 while( (c = System.in.read()) != -1 ) { 496 while( (c = System.in.read()) != -1 ) {
653 switch(c) { 497 switch(c) {
665 }; 509 };
666 510
667 new Thread(stdin).start(); 511 new Thread(stdin).start();
668 } 512 }
669 513
514 /**
515 * gzip byte arrays
516 * @param deflater
517 * @param inputs
518 * byte len[4] total byte length
519 * byte data[]
520 * @param outputs
521 * byte len[4] total byte length
522 * byte data[]
523 * @return byte length in last byte array
524 * @throws IOException
525 */
526 public int zip(Deflater deflater,LinkedList<byte[]> inputs, LinkedList<byte[]> outputs) throws IOException {
527 int clen = u32(inputs.poll(),0);
528 int len = 0, count = 0;
529 int len2=0;
530 deflater.reset();
531 do {
532 byte[] b1 = inputs.poll();
533 if (inputs.size()==0) {
534 deflater.setInput(b1,0,clen);
535 deflater.finish();
536 } else {
537 deflater.setInput(b1);
538 clen -= b1.length;
539 }
540 int len1=0;
541 do {
542 byte[] c1 = new byte[INFLATE_BUFSIZE];
543 len2 = len1;
544 len1 = deflater.deflate(c1);
545 if (len1>0) {
546 outputs.addLast(c1);
547 count ++;
548 len += len1;
549 }
550 } while (len1 > 0);
551 } while(inputs.size()>0);
552 byte[] blen = castIntByte(len);
553 outputs.addFirst(blen);
554 return len2;
555 }
556
557 /**
558 * gunzip byte arrays
559 * @param inflater
560 * @param inputs
561 * byte len[4] total byte length
562 * byte data[]
563 * @param outputs
564 * byte len[4] total byte length
565 * byte data[]
566 * @throws IOException
567 */
568 public void unzip(Inflater inflater, byte[] input, LinkedList<byte[]> outputs)
569 throws DataFormatException {
570 int len=0,len0;
571 inflater.setInput(input);
572 do {
573 byte buf[] = new byte[INFLATE_BUFSIZE];
574 len0 = inflater.inflate(buf);
575 len += len0;
576 outputs.addLast(buf);
577 } while (len0 ==INFLATE_BUFSIZE);
578 byte [] blen = castIntByte(len);
579 outputs.addFirst(blen);
580 }
581
582 void readSendData(int dataLen) throws IOException, DataFormatException {
583 LinkedList<byte[]>bufs = new LinkedList<byte[]>();
584 byte header[] = new byte[16];
585 readFully(header,0,16);
586 if (header[0]==RfbProto.FramebufferUpdate) {
587 int encoding = u32(header,12);
588 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) {
589 byte[] len = new byte[4];
590 readFully(len,0,4);
591 byte inputData[] = new byte[dataLen-20];
592 readFully(inputData);
593 unzip(inflater, inputData, bufs);
594 bufs.addFirst(header);
595 multicastqueue.put(bufs);
596 is.reset();
597 return ;
598 }
599 }
600 bufs.add(header);
601 if (dataLen>16) {
602 byte b[] = new byte[dataLen-16];
603 readFully(b);
604 bufs.add(b);
605 }
606 multicastqueue.put(bufs);
607 is.reset();
608
609 // It may be compressed. We can inflate here to avoid repeating clients decompressing here,
610 // but it may generate too many large data. It is better to do it in each client.
611 // But we have do inflation for all input data, so we have to do it here.
612 }
613
614 void newClient(AcceptThread acceptThread, final Socket newCli,
615 final OutputStream os, final InputStream is) throws IOException {
616 // createBimgFlag = true;
617 // rfb.addSockTmp(newCli);
618 // addSock(newCli);
619 final Client <LinkedList<byte[]>> c = multicastqueue.newClient();
620 Runnable sender = new Runnable() {
621 public void run() {
622
623 Deflater deflater = new Deflater();
624 try {
625 /**
626 * initial connection of RFB protocol
627 */
628 sendRfbVersion(os);
629 readVersionMsg(is);
630 sendSecurityType(os);
631 readSecType(is);
632 sendSecResult(os);
633 readClientInit(is);
634 sendInitData(os);
635
636 for (;;) {
637 LinkedList<byte[]> bufs = c.poll();
638 byte[] header = bufs.poll();
639 if (header[0]==RfbProto.FramebufferUpdate) {
640 int encoding = u32(header,12);
641 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) {
642 LinkedList<byte[]> outs = new LinkedList<byte[]>();
643 int len2 = zip(deflater, bufs, outs);
644 outs.addFirst(header);
645 while(!outs.isEmpty()) {
646 byte [] out= outs.poll();
647 if (outs.isEmpty())
648 os.write(out,0,len2);
649 else
650 os.write(out);
651 }
652 }
653 os.flush();
654 return;
655 }
656 os.write(header);
657 for(byte [] b : bufs) {
658 os.write(b, 0, b.length);
659 }
660 os.flush();
661 }
662 } catch (IOException e) {
663 /* if socket closed cliList.remove(newCli); */
664 }
665 }
666 };
667 clients++;
668 new Thread(sender).start();
669
670 }
671
672 private int u32(byte[] b, int i) {
673 int ret = 0;
674 for(int j = 0;j<4;j++) {
675 ret *= 256;
676 ret += b[i+j] & 0xff;
677 }
678 return ret;
679 }
680
670 } 681 }
671 682
672 683