提交 e3fcb84b9918ab28b797241fb6da0852dc076def

作者 LJH 李佳桓
1 个父辈 933300bc

add

正在显示 1 个修改的文件 包含 296 行增加0 行删除
  1 +/*
  2 + * Copyright 2007 Stephen Liu
  3 + * For license terms, see the file COPYING along with this library.
  4 + */
  5 +
  6 +#include <string.h>
  7 +#include <assert.h>
  8 +#include <stdio.h>
  9 +
  10 +#include "spmsgdecoder.hpp"
  11 +
  12 +#include "spbuffer.hpp"
  13 +#include "sputils.hpp"
  14 +
  15 +//-------------------------------------------------------------------
  16 +
  17 +SP_MsgDecoder :: ~SP_MsgDecoder()
  18 +{
  19 +}
  20 +
  21 +//-------------------------------------------------------------------
  22 +
  23 +SP_DefaultMsgDecoder :: SP_DefaultMsgDecoder()
  24 +{
  25 + mBuffer = new SP_Buffer();
  26 +}
  27 +
  28 +SP_DefaultMsgDecoder :: ~SP_DefaultMsgDecoder()
  29 +{
  30 + if( NULL != mBuffer ) delete mBuffer;
  31 + mBuffer = NULL;
  32 +}
  33 +
  34 +int SP_DefaultMsgDecoder :: decode( SP_Buffer * inBuffer )
  35 +{
  36 + if( inBuffer->getSize() > 0 ) {
  37 + mBuffer->reset();
  38 + mBuffer->append( inBuffer );
  39 + inBuffer->reset();
  40 +
  41 + return eOK;
  42 + }
  43 +
  44 + return eMoreData;
  45 +}
  46 +
  47 +SP_Buffer * SP_DefaultMsgDecoder :: getMsg()
  48 +{
  49 + return mBuffer;
  50 +}
  51 +
  52 +//-------------------------------------------------------------------
  53 +
  54 +SP_LineMsgDecoder :: SP_LineMsgDecoder()
  55 +{
  56 + mLine = NULL;
  57 +}
  58 +
  59 +SP_LineMsgDecoder :: ~SP_LineMsgDecoder()
  60 +{
  61 + if( NULL != mLine ) {
  62 + free( mLine );
  63 + mLine = NULL;
  64 + }
  65 +}
  66 +
  67 +int SP_LineMsgDecoder :: decode( SP_Buffer * inBuffer )
  68 +{
  69 + if( NULL != mLine ) free( mLine );
  70 + mLine = inBuffer->getLine();
  71 +
  72 + return NULL == mLine ? eMoreData : eOK;
  73 +}
  74 +
  75 +const char * SP_LineMsgDecoder :: getMsg()
  76 +{
  77 + return mLine;
  78 +}
  79 +
  80 +//-------------------------------------------------------------------
  81 +
  82 +SP_MultiLineMsgDecoder :: SP_MultiLineMsgDecoder()
  83 +{
  84 + mQueue = new SP_CircleQueue();
  85 +}
  86 +
  87 +SP_MultiLineMsgDecoder :: ~SP_MultiLineMsgDecoder()
  88 +{
  89 + for( ; NULL != mQueue->top(); ) {
  90 + free( (void*)mQueue->pop() );
  91 + }
  92 +
  93 + delete mQueue;
  94 + mQueue = NULL;
  95 +}
  96 +
  97 +int SP_MultiLineMsgDecoder :: decode( SP_Buffer * inBuffer )
  98 +{
  99 + int ret = eMoreData;
  100 +
  101 + for( ; ; ) {
  102 + char * line = inBuffer->getLine();
  103 + if( NULL == line ) break;
  104 + mQueue->push( line );
  105 + ret = eOK;
  106 + }
  107 +
  108 + return ret;
  109 +}
  110 +
  111 +SP_CircleQueue * SP_MultiLineMsgDecoder :: getQueue()
  112 +{
  113 + return mQueue;
  114 +}
  115 +
  116 +//-------------------------------------------------------------------
  117 +
  118 +SP_DotTermMsgDecoder :: SP_DotTermMsgDecoder()
  119 +{
  120 + mBuffer = NULL;
  121 +}
  122 +
  123 +SP_DotTermMsgDecoder :: ~SP_DotTermMsgDecoder()
  124 +{
  125 + if( NULL != mBuffer ) {
  126 + free( mBuffer );
  127 + }
  128 + mBuffer = NULL;
  129 +}
  130 +
  131 +int SP_DotTermMsgDecoder :: decode( SP_Buffer * inBuffer )
  132 +{
  133 + if( NULL != mBuffer ) {
  134 + free( mBuffer );
  135 + mBuffer = NULL;
  136 + }
  137 +
  138 + const char * pos = (char*)inBuffer->find( "\r\n.\r\n", 5 );
  139 +
  140 + if( NULL == pos ) {
  141 + pos = (char*)inBuffer->find( "\n.\n", 3 );
  142 + }
  143 +
  144 + if( NULL != pos ) {
  145 + int len = pos - (char*)inBuffer->getRawBuffer();
  146 +
  147 + mBuffer = (char*)malloc( len + 1 );
  148 + memcpy( mBuffer, inBuffer->getBuffer(), len );
  149 + mBuffer[ len ] = '\0';
  150 +
  151 + inBuffer->erase( len );
  152 +
  153 + /* remove with the "\n.." */
  154 + char * src, * des;
  155 + for( src = des = mBuffer + 1; * src != '\0'; ) {
  156 + if( '.' == *src && '\n' == * ( src - 1 ) ) src++ ;
  157 + * des++ = * src++;
  158 + }
  159 + * des = '\0';
  160 +
  161 + if( 0 == strncmp( (char*)pos, "\n.\n", 3 ) ) {
  162 + inBuffer->erase( 3 );
  163 + } else {
  164 + inBuffer->erase( 5 );
  165 + }
  166 + return eOK;
  167 + } else {
  168 + return eMoreData;
  169 + }
  170 +}
  171 +
  172 +const char * SP_DotTermMsgDecoder :: getMsg()
  173 +{
  174 + return mBuffer;
  175 +}
  176 +
  177 +//-------------------------------------------------------------------
  178 +
  179 +SP_DotTermChunkMsgDecoder :: SP_DotTermChunkMsgDecoder()
  180 +{
  181 + mList = new SP_ArrayList();
  182 +}
  183 +
  184 +SP_DotTermChunkMsgDecoder :: ~SP_DotTermChunkMsgDecoder()
  185 +{
  186 + for( int i = 0; i < mList->getCount(); i++ ) {
  187 + SP_Buffer * item = (SP_Buffer*)mList->getItem( i );
  188 + delete item;
  189 + }
  190 +
  191 + delete mList, mList = NULL;
  192 +}
  193 +
  194 +int SP_DotTermChunkMsgDecoder :: decode( SP_Buffer * inBuffer )
  195 +{
  196 + if( inBuffer->getSize() <= 0 ) return eMoreData;
  197 +
  198 + const char * pos = (char*)inBuffer->find( "\r\n.\r\n", 5 );
  199 +
  200 + if( NULL == pos ) {
  201 + pos = (char*)inBuffer->find( "\n.\n", 3 );
  202 + }
  203 +
  204 + if( NULL != pos ) {
  205 + if( pos != inBuffer->getRawBuffer() ) {
  206 + int len = pos - (char*)inBuffer->getRawBuffer();
  207 +
  208 + SP_Buffer * last = new SP_Buffer();
  209 + last->append( inBuffer->getBuffer(), len );
  210 + mList->append( last );
  211 +
  212 + inBuffer->erase( len );
  213 + }
  214 +
  215 + if( 0 == strncmp( (char*)pos, "\n.\n", 3 ) ) {
  216 + inBuffer->erase( 3 );
  217 + } else {
  218 + inBuffer->erase( 5 );
  219 + }
  220 +
  221 + return eOK;
  222 + } else {
  223 + if( mList->getCount() > 0 ) {
  224 + char dotTerm[ 16 ] = { 0 };
  225 +
  226 + SP_Buffer * prevBuffer = (SP_Buffer*)mList->getItem( SP_ArrayList::LAST_INDEX );
  227 + pos = ((char*)prevBuffer->getRawBuffer()) + prevBuffer->getSize() - 5;
  228 + memcpy( dotTerm, pos, 5 );
  229 +
  230 + if( inBuffer->getSize() > 5 ) {
  231 + memcpy( dotTerm + 5, inBuffer->getRawBuffer(), 5 );
  232 + } else {
  233 + memcpy( dotTerm + 5, inBuffer->getRawBuffer(), inBuffer->getSize() );
  234 + }
  235 +
  236 + pos = strstr( dotTerm, "\r\n.\r\n" );
  237 + if( NULL == pos ) pos = strstr( dotTerm, "\n.\n" );
  238 +
  239 + if( NULL != pos ) {
  240 + int prevLen = 5 - ( pos - dotTerm );
  241 + int lastLen = 5 - prevLen;
  242 + if( 0 == strncmp( (char*)pos, "\n.\n", 3 )) lastLen = 3 - prevLen;
  243 +
  244 + assert( prevLen < 5 && lastLen < 5 );
  245 +
  246 + prevBuffer->truncate( prevBuffer->getSize() - prevLen );
  247 + inBuffer->erase( lastLen );
  248 +
  249 + return eOK;
  250 + }
  251 + }
  252 +
  253 + if( inBuffer->getSize() >= ( MAX_SIZE_PER_CHUNK - 1024 * 4 ) ) {
  254 + mList->append( inBuffer->take() );
  255 + }
  256 + inBuffer->reserve( MAX_SIZE_PER_CHUNK );
  257 + }
  258 +
  259 + return eMoreData;
  260 +}
  261 +
  262 +char * SP_DotTermChunkMsgDecoder :: getMsg()
  263 +{
  264 + int i = 0, totalSize = 0;
  265 + for( i = 0; i < mList->getCount(); i++ ) {
  266 + SP_Buffer * item = (SP_Buffer*)mList->getItem( i );
  267 + totalSize += item->getSize();
  268 + }
  269 +
  270 + char * ret = (char*)malloc( totalSize + 1 );
  271 + ret[ totalSize ] = '\0';
  272 +
  273 + char * des = ret, * src = NULL;
  274 +
  275 + for( i = 0; i < mList->getCount(); i++ ) {
  276 + SP_Buffer * item = (SP_Buffer*)mList->getItem( i );
  277 + memcpy( des, item->getRawBuffer(), item->getSize() );
  278 + des += item->getSize();
  279 + }
  280 +
  281 + for( i = 0; i < mList->getCount(); i++ ) {
  282 + SP_Buffer * item = (SP_Buffer*)mList->getItem( i );
  283 + delete item;
  284 + }
  285 + mList->clean();
  286 +
  287 + /* remove with the "\n.." */
  288 + for( src = des = ret + 1; * src != '\0'; ) {
  289 + if( '.' == *src && '\n' == * ( src - 1 ) ) src++ ;
  290 + * des++ = * src++;
  291 + }
  292 + * des = '\0';
  293 +
  294 + return ret;
  295 +}
  296 +
... ...
注册登录 后发表评论