comparison src/rep/REPCommandPacker.java @ 205:540d7a8a9e33

add sessionmanager's file
author one
date Sat, 18 Dec 2010 17:35:25 +0900
parents
children
comparison
equal deleted inserted replaced
204:aaab17635d0c 205:540d7a8a9e33
1 package rep;
2
3
4 import java.io.IOException;
5 import java.nio.ByteBuffer;
6 import java.nio.CharBuffer;
7 import java.nio.channels.SocketChannel;
8 import java.nio.charset.CharacterCodingException;
9 import java.nio.charset.Charset;
10 import java.nio.charset.CharsetDecoder;
11 import java.nio.charset.CharsetEncoder;
12
13 import rep.channel.REPPack;
14
15 /*
16 //+-------+--------+--------+-------+--------+---------+------+
17 //| cmd | session| editor | seqid | lineno | textsiz | text |
18 //| | id | id | | | | |
19 //+-------+--------+--------+-------+--------+---------+------+
20 //o-------header section (network order)-------------o
21 int cmd; // command
22 int sid; // session ID : uniqu to editing file
23 int eid; // editor ID : owner editor ID = 1。Session に対して unique
24 int seqno; // Sequence number : sequence number はエディタごとに管理
25 int lineno; // line number
26 int textsize; // textsize : bytesize
27 byte[] text;
28 */
29
30
31 public class REPCommandPacker implements REPPack<REPCommand> {
32 private static final int TEXTSIZELIMIT = 0x7000000;
33 private static final int HEADER_SIZE = 24;
34 // JIS/S-JIS = 2, UTF-8 = 3, UTF-?? = 5
35 private static final int CHARSIZE = 5;
36
37 Charset charset = Charset.forName("UTF-8");
38 CharsetEncoder encoder = charset.newEncoder();
39 CharsetDecoder decoder = charset.newDecoder();
40
41 /* (non-Javadoc)
42 * @see rep.REPPack#packUConv(rep.REPCommand)
43 */
44 public ByteBuffer packUConv(REPCommand command){
45 int size = 0;
46 if (command.string!=null) size = command.string.length()*CHARSIZE;
47 ByteBuffer buffer = ByteBuffer.allocateDirect(HEADER_SIZE+size);
48 buffer.clear(); // position = 0
49 buffer.putInt(command.cmd.id);
50 buffer.putInt(command.sid);
51 buffer.putInt(command.eid);
52 buffer.putInt(command.seq);
53 buffer.putInt(command.lineno);
54
55 int pos = buffer.position();
56 buffer.putInt(0);
57 int pos1 = buffer.position();
58
59 if (command.string!=null) {
60 //Encode to UTF8
61 CharBuffer cb = CharBuffer.wrap(command.string);
62 try {
63 encoder.encode(cb, buffer, true);
64 } catch (IllegalStateException e) {
65 buffer.position(pos1);
66 }
67 }
68
69 //Encoded string length set
70 int length = buffer.position() -pos1 ;
71 buffer.putInt(pos, length);
72 buffer.limit(HEADER_SIZE+length);
73 buffer.rewind();
74
75 return buffer;
76 }
77
78
79 public REPCommand unpackUConv(SocketChannel sc) throws IOException {
80 ByteBuffer header = ByteBuffer.allocateDirect(HEADER_SIZE);
81 header.clear();
82
83 while(header.remaining()>0){
84 if (sc.read(header)<0) throw new IOException();
85 }
86
87 header.rewind(); // position = 0
88
89 int cmd = header.getInt();
90 int sid = header.getInt();
91 int eid = header.getInt();
92 int seqid = header.getInt();
93 int lineno = header.getInt();
94 int textsiz = header.getInt();
95
96 /**
97 * We should avoid large reading here. Large command should be
98 * broke in smaller one. It should be easy.
99 */
100 if (textsiz>TEXTSIZELIMIT||textsiz<0) {
101 // corrupted packet
102 throw new IOException();
103 }
104 ByteBuffer textBuffer = ByteBuffer.allocateDirect(textsiz);
105
106 while(textBuffer.remaining()>0){
107 if (sc.read(textBuffer)<0) throw new IOException();
108 }
109 textBuffer.rewind();
110
111 //Decode UTF-8 to System Encoding(UTF-16)
112 String string;
113 try {
114 CharBuffer cb;
115 cb = decoder.decode(textBuffer);
116 cb.rewind();
117 string = cb.toString();
118 } catch (CharacterCodingException e) {
119 string = "";
120 }
121 textsiz = string.length();
122 REPCommand repcommand = new REPCommand(cmd, sid, eid, seqid, lineno, textsiz, string);
123 //if (isLogging)
124 //System.out.println("Reading: "+repcommand);
125 return repcommand;
126 }
127
128 }