1 /* 2 * MsgTrans - Message Transport Framework for DLang. Based on TCP, WebSocket, UDP transmission protocol. 3 * 4 * Copyright (C) 2019 HuntLabs 5 * 6 * Website: https://www.msgtrans.org 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module msgtrans.channel.tcp.TcpDecoder; 13 14 import msgtrans.PacketParser; 15 import msgtrans.MessageBuffer; 16 17 import hunt.io.ByteBuffer; 18 import hunt.io.BufferUtils; 19 import hunt.io.channel.Common; 20 import hunt.Exceptions; 21 import hunt.logging.ConsoleLogger; 22 import hunt.net; 23 24 import std.algorithm; 25 import std.conv; 26 27 28 class TcpDecoder : DecoderChain { 29 private enum string PARSER = "PacketParser"; 30 31 /** The default maximum buffer length. Default to 128 chars. */ 32 private int bufferLength = 128; 33 34 /** The default maximum Line length. Default to 1024. */ 35 private int maxLineLength = 8*1024; 36 37 38 this() { 39 super(null); 40 } 41 42 43 /** 44 * @return the allowed maximum size of the line to be decoded. 45 * If the size of the line to be decoded exceeds this value, the 46 * decoder will throw a {@link BufferDataException}. The default 47 * value is <tt>1024</tt> (1KB). 48 */ 49 int getMaxLineLength() { 50 return maxLineLength; 51 } 52 53 /** 54 * Sets the allowed maximum size of the line to be decoded. 55 * If the size of the line to be decoded exceeds this value, the 56 * decoder will throw a {@link BufferDataException}. The default 57 * value is <tt>1024</tt> (1KB). 58 * 59 * @param maxLineLength The maximum line length 60 */ 61 void setMaxLineLength(int maxLineLength) { 62 if (maxLineLength <= 0) { 63 throw new IllegalArgumentException("maxLineLength (" ~ 64 maxLineLength.to!string() ~ ") should be a positive value"); 65 } 66 67 this.maxLineLength = maxLineLength; 68 } 69 70 /** 71 * Sets the default buffer size. This buffer is used in the Context 72 * to store the decoded line. 73 * 74 * @param bufferLength The default bufer size 75 */ 76 void setBufferLength(int bufferLength) { 77 if (bufferLength <= 0) { 78 throw new IllegalArgumentException("bufferLength (" ~ 79 maxLineLength.to!string() ~ ") should be a positive value"); 80 81 } 82 83 this.bufferLength = bufferLength; 84 } 85 86 /** 87 * @return the allowed buffer size used to store the decoded line 88 * in the Context instance. 89 */ 90 int getBufferLength() { 91 return bufferLength; 92 } 93 94 override 95 DataHandleStatus decode(ByteBuffer buf, Connection connection) { 96 version(HUNT_MESSAGE_DEBUG) tracef("connection %d: %s", connection.getId(), buf.toString()); 97 PacketParser parser = getParser(connection); 98 99 MessageBuffer[] msgBuffers = parser.parse(buf); 100 if(msgBuffers is null) { 101 warning("No frame parsed."); 102 return DataHandleStatus.Done; 103 } 104 105 NetConnectionHandler handler = connection.getHandler(); 106 if(handler is null) { 107 warning("No handler found."); 108 return DataHandleStatus.Done; 109 } 110 111 foreach(MessageBuffer msg; msgBuffers) { 112 handler.messageReceived(connection, msg); 113 } 114 115 116 return DataHandleStatus.Done; 117 } 118 119 private PacketParser getParser(Connection connection) { 120 PacketParser ctx; 121 ctx = cast(PacketParser) connection.getAttribute(PARSER); 122 123 if (ctx is null) { 124 ctx = new PacketParser(bufferLength); 125 connection.setAttribute(PARSER, ctx); 126 } 127 128 return ctx; 129 } 130 131 132 void dispose(Connection connection) { 133 PacketParser ctx = cast(PacketParser) connection.getAttribute(PARSER); 134 135 if (ctx !is null) { 136 connection.removeAttribute(PARSER); 137 } 138 } 139 140 } 141