CAtomDicti *DecodeDicti( const string &x, unsigned long iStart ) { unsigned long i = iStart + 1; CAtomDicti *pDicti = new CAtomDicti( ); while( i < x.size( ) && x[i] != 'e' ) { CAtom *pKey = Decode( x, i ); if( pKey && dynamic_cast<CAtomString *>( pKey ) ) { i += pKey->EncodedLength( ); string strKey = pKey->toString( ); delete pKey; if( i < x.size( ) ) { CAtom *pValue = Decode( x, i ); if( pValue ) { i += pValue->EncodedLength( ); pDicti->setItem( strKey, pValue ); } else { UTIL_LogPrint( "error decoding dictionary - error decoding value, discarding dictionary\n" ); delete pDicti; return NULL; } } } else { UTIL_LogPrint( "error decoding dictionary - error decoding key, discarding dictionary\n" ); delete pDicti; return NULL; } } return pDicti; }
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; }