CAtomList *DecodeList( const string &x, unsigned long iStart ) { unsigned long i = iStart + 1; CAtomList *pList = new CAtomList( ); while( i < x.size( ) && x[i] != 'e' ) { CAtom *pAtom = Decode( x, i ); if( pAtom ) { i += pAtom->EncodedLength( ); pList->addItem( pAtom ); } else { UTIL_LogPrint( "error decoding list - error decoding list item, discarding list\n" ); delete pList; return NULL; } } return pList; }
string EncodeList( const CAtomList &x ) { vector<CAtom *> v = x.getValue( ); string strDest; strDest += "l"; for( vector<CAtom *> :: iterator i = v.begin( ); i != v.end( ); i++ ) { if( dynamic_cast<CAtomInt *>( *i ) ) strDest += EncodeInt( *dynamic_cast<CAtomInt *>( *i ) ); else if( dynamic_cast<CAtomLong *>( *i ) ) strDest += EncodeLong( *dynamic_cast<CAtomLong *>( *i ) ); else if( dynamic_cast<CAtomString *>( *i ) ) strDest += EncodeString( *dynamic_cast<CAtomString *>( *i ) ); else if( dynamic_cast<CAtomList *>( *i ) ) strDest += EncodeList( *dynamic_cast<CAtomList *>( *i ) ); else if( dynamic_cast<CAtomDicti *>( *i ) ) strDest += EncodeDicti( *dynamic_cast<CAtomDicti *>( *i ) ); } strDest += "e"; return strDest; }
CAtomList :: CAtomList( const CAtomList &c ) { // copy constructor vector<CAtom *> *pvecList = c.getValuePtr( ); for( vector<CAtom *> :: iterator itAtom = pvecList->begin( ); itAtom != pvecList->end( ); itAtom++ ) { if( dynamic_cast<CAtomInt *>( *itAtom ) ) addItem( new CAtomInt( *dynamic_cast<CAtomInt *>( *itAtom ) ) ); else if( dynamic_cast<CAtomLong *>( *itAtom ) ) addItem( new CAtomLong( *dynamic_cast<CAtomLong *>( *itAtom ) ) ); else if( dynamic_cast<CAtomString *>( *itAtom ) ) addItem( new CAtomString( *dynamic_cast<CAtomString *>( *itAtom ) ) ); else if( dynamic_cast<CAtomList *>( *itAtom ) ) addItem( new CAtomList( *dynamic_cast<CAtomList *>( *itAtom ) ) ); else if( dynamic_cast<CAtomDicti *>( *itAtom ) ) addItem( new CAtomDicti( *dynamic_cast<CAtomDicti *>( *itAtom ) ) ); else UTIL_LogPrint( ( gmapLANG_CFG["atomlist_copy_warning"] + "\n" ).c_str( ) ); } }
CAtomList :: CAtomList( const CAtomList &c ) { // copy constructor vector<CAtom *> *pvecList = c.getValuePtr( ); for( vector<CAtom *> :: iterator i = pvecList->begin( ); i != pvecList->end( ); i++ ) { if( dynamic_cast<CAtomInt *>( *i ) ) addItem( new CAtomInt( *dynamic_cast<CAtomInt *>( *i ) ) ); else if( dynamic_cast<CAtomLong *>( *i ) ) addItem( new CAtomLong( *dynamic_cast<CAtomLong *>( *i ) ) ); else if( dynamic_cast<CAtomString *>( *i ) ) addItem( new CAtomString( *dynamic_cast<CAtomString *>( *i ) ) ); else if( dynamic_cast<CAtomList *>( *i ) ) addItem( new CAtomList( *dynamic_cast<CAtomList *>( *i ) ) ); else if( dynamic_cast<CAtomDicti *>( *i ) ) addItem( new CAtomDicti( *dynamic_cast<CAtomDicti *>( *i ) ) ); else UTIL_LogPrint( "error copying list - found invalid atom, ignoring\n" ); } }
inline CAtomList *UTIL_DecodeHTTPPost( const string &cstrPost ) { // find the boundary string :: size_type iBoundary = cstrPost.find( C_STR_BOUNDARY ); if( iBoundary == string :: npos ) return 0; iBoundary += ( sizeof(C_STR_BOUNDARY) - 1 ); string strBoundary = cstrPost.substr( iBoundary ); const string :: size_type ciBoundEnd( strBoundary.find( C_STR_NEWLINE ) ); if( ciBoundEnd == string :: npos ) return 0; strBoundary = strBoundary.substr( 0, ciBoundEnd ); // strBoundary now contains the boundary string :: size_type iContent = cstrPost.find( C_STR_DOUBLE_NEWLINE ); if( iContent == string :: npos ) return 0; iContent += ( sizeof(C_STR_DOUBLE_NEWLINE) - 1 ); const string cstrContent( cstrPost.substr( iContent ) ); // decode CAtomList *pList = new CAtomList( ); CAtomDicti *pSegment = 0; string :: size_type iSegStart = 0; string :: size_type iSegEnd = 0; string :: size_type iDispPrev = 0; string :: size_type iDispPos = 0; CAtomDicti *pDisp = 0; string strSeg = string( ); string strDisp = string( ); string :: size_type iDispStart = 0; string :: size_type iDispEnd = 0; string strCurr = string( ); string :: size_type iSplit = 0; string :: size_type iKeyStart = 0; string strKey = string( ); string strValue = string( ); string :: size_type iDataStart = 0; bool bDoSegmentLoop = true; while( bDoSegmentLoop ) { // segment start iSegStart = cstrContent.find( strBoundary, iSegStart ); if( iSegStart == string :: npos ) return pList; iSegStart += strBoundary.size( ); if( cstrContent.substr( iSegStart, 2 ) == C_STR_SEGSTART ) return pList; iSegStart += ( sizeof(C_STR_SEGSTART) - 1 ); // segment end iSegEnd = cstrContent.find( strBoundary, iSegStart ); if( iSegEnd == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_end"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } iSegEnd -= ( sizeof(C_STR_SEGEND) - 1 ); // found segment pSegment = new CAtomDicti( ); pList->addItem( pSegment ); // this could do with some serious optimizing... strSeg = cstrContent.substr( iSegStart, iSegEnd - iSegStart ); iDispStart = strSeg.find( C_STR_DISPSTART ); if( iDispStart == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_notfound"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } iDispStart += ( sizeof(C_STR_DISPSTART) - 1 ); iDispEnd = strSeg.find( C_STR_NEWLINE, iDispStart ); if( iDispEnd == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_disposition"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } strDisp = strSeg.substr( iDispStart, iDispEnd - iDispStart ); iDispPrev = 0; iDispPos = 0; pDisp = new CAtomDicti( ); pSegment->setItem( "disposition", pDisp ); bool bDoItemLoop = true; while( bDoItemLoop ) { // assume a semicolon indicates the end of the item and will never appear inside the item (probably a bad assumption) iDispPrev = iDispPos; iDispPos = strDisp.find( C_STR_ITEMEND, iDispPos ); if( iDispPos == string :: npos ) { // decode last item iDispPos = strDisp.size( ); } strCurr = strDisp.substr( iDispPrev, iDispPos - iDispPrev ); iSplit = strCurr.find( C_STR_ITEMEQ ); if( iSplit == string :: npos ) { // found a key without value, i.e. "form-data", useless so ignore it if( iDispPos == strDisp.size( ) ) break; // + strlen( ";" ) iDispPos++; continue; } // strip whitespace iKeyStart = strCurr.find_first_not_of( C_STR_WSPACE ); if( iKeyStart == string :: npos || iKeyStart > iSplit ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_disposition"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } strKey = strCurr.substr( iKeyStart, iSplit - iKeyStart ); strValue = strCurr.substr( iSplit + 1 ); // strip quotes if( strValue.size( ) > 1 && strValue[0] == CHAR_QUOTE ) strValue = strValue.substr( 1, strValue.size( ) - 2 ); pDisp->setItem( strKey, new CAtomString( strValue ) ); if( iDispPos == strDisp.size( ) ) bDoItemLoop = false; // + strlen( ";" ) iDispPos++; } // data iDataStart = strSeg.find( C_STR_DOUBLE_NEWLINE ); if( iDataStart == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_segment"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } iDataStart += ( sizeof(C_STR_DOUBLE_NEWLINE) - 1 ); pSegment->setItem( "data", new CAtomString( strSeg.substr( iDataStart ) ) ); } // this should never happen, so who cares delete pList; pList = 0; return 0; }