Mercurial > hg > RemoteEditor > Eclipse
view src/rep/REPCommandPacker.java @ 203:fce2776071d4
package rep copy
author | one |
---|---|
date | Sat, 18 Dec 2010 13:18:54 +0900 |
parents | 3133040ee4f4 |
children |
line wrap: on
line source
package rep; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import rep.channel.REPPack; /* //+-------+--------+--------+-------+--------+---------+------+ //| cmd | session| editor | seqid | lineno | textsiz | text | //| | id | id | | | | | //+-------+--------+--------+-------+--------+---------+------+ //o-------header section (network order)-------------o int cmd; // command int sid; // session ID : uniqu to editing file int eid; // editor ID : owner editor ID = 1。Session に対して unique int seqno; // Sequence number : sequence number はエディタごとに管理 int lineno; // line number int textsize; // textsize : bytesize byte[] text; */ public class REPCommandPacker implements REPPack<REPCommand> { private static final int TEXTSIZELIMIT = 0x7000000; private static final int HEADER_SIZE = 24; // JIS/S-JIS = 2, UTF-8 = 3, UTF-?? = 5 private static final int CHARSIZE = 5; Charset charset = Charset.forName("UTF-8"); CharsetEncoder encoder = charset.newEncoder(); CharsetDecoder decoder = charset.newDecoder(); /* (non-Javadoc) * @see rep.REPPack#packUConv(rep.REPCommand) */ public ByteBuffer packUConv(REPCommand command){ int size = 0; if (command.string!=null) size = command.string.length()*CHARSIZE; ByteBuffer buffer = ByteBuffer.allocateDirect(HEADER_SIZE+size); buffer.clear(); // position = 0 buffer.putInt(command.cmd.id); buffer.putInt(command.sid); buffer.putInt(command.eid); buffer.putInt(command.seq); buffer.putInt(command.lineno); int pos = buffer.position(); buffer.putInt(0); int pos1 = buffer.position(); if (command.string!=null) { //Encode to UTF8 CharBuffer cb = CharBuffer.wrap(command.string); try { encoder.encode(cb, buffer, true); } catch (IllegalStateException e) { buffer.position(pos1); } } //Encoded string length set int length = buffer.position() -pos1 ; buffer.putInt(pos, length); buffer.limit(HEADER_SIZE+length); buffer.rewind(); return buffer; } public REPCommand unpackUConv(SocketChannel sc) throws IOException { ByteBuffer header = ByteBuffer.allocateDirect(HEADER_SIZE); header.clear(); while(header.remaining()>0){ if (sc.read(header)<0) throw new IOException(); } header.rewind(); // position = 0 int cmd = header.getInt(); int sid = header.getInt(); int eid = header.getInt(); int seqid = header.getInt(); int lineno = header.getInt(); int textsiz = header.getInt(); /** * We should avoid large reading here. Large command should be * broke in smaller one. It should be easy. */ if (textsiz>TEXTSIZELIMIT||textsiz<0) { // corrupted packet throw new IOException(); } ByteBuffer textBuffer = ByteBuffer.allocateDirect(textsiz); while(textBuffer.remaining()>0){ if (sc.read(textBuffer)<0) throw new IOException(); } textBuffer.rewind(); //Decode UTF-8 to System Encoding(UTF-16) String string; try { CharBuffer cb; cb = decoder.decode(textBuffer); cb.rewind(); string = cb.toString(); } catch (CharacterCodingException e) { string = ""; } textsiz = string.length(); REPCommand repcommand = new REPCommand(cmd, sid, eid, seqid, lineno, textsiz, string); //if (isLogging) //System.out.println("Reading: "+repcommand); return repcommand; } }