00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "BENode.h"
00026 #include "Buffer.h"
00027 #include "SHA.h"
00028
00029 #ifdef _DEBUG
00030 #undef THIS_FILE
00031 static char THIS_FILE[]=__FILE__;
00032 #define new DEBUG_NEW
00033 #endif
00034
00035
00037
00038
00039 CBENode::CBENode()
00040 {
00041 m_nType = beNull;
00042 m_pValue = NULL;
00043 m_nValue = 0;
00044 }
00045
00046 CBENode::~CBENode()
00047 {
00048 if ( m_pValue != NULL ) Clear();
00049 }
00050
00052
00053
00054 void CBENode::Clear()
00055 {
00056 if ( m_pValue != NULL )
00057 {
00058 if ( m_nType == beString )
00059 {
00060 delete [] (LPSTR)m_pValue;
00061 }
00062 else if ( m_nType == beList )
00063 {
00064 CBENode** pNode = (CBENode**)m_pValue;
00065 for ( ; m_nValue-- ; pNode++ ) delete *pNode;
00066 delete [] (CBENode**)m_pValue;
00067 }
00068 else if ( m_nType == beDict )
00069 {
00070 CBENode** pNode = (CBENode**)m_pValue;
00071 for ( ; m_nValue-- ; pNode++ )
00072 {
00073 delete *pNode++;
00074 delete [] (LPBYTE)*pNode;
00075 }
00076 delete [] (CBENode**)m_pValue;
00077 }
00078 }
00079
00080 m_nType = beNull;
00081 m_pValue = NULL;
00082 m_nValue = 0;
00083 }
00084
00086
00087
00088 CBENode* CBENode::Add(const LPBYTE pKey, int nKey)
00089 {
00090 switch ( m_nType )
00091 {
00092 case beNull:
00093 m_nType = ( pKey != NULL && nKey > 0 ) ? beDict : beList;
00094 m_pValue = NULL;
00095 m_nValue = 0;
00096 break;
00097 case beList:
00098 ASSERT( pKey == NULL && nKey == 0 );
00099 break;
00100 case beDict:
00101 ASSERT( pKey != NULL && nKey > 0 );
00102 break;
00103 default:
00104 ASSERT( FALSE );
00105 break;
00106 }
00107
00108 CBENode* pNew = new CBENode();
00109
00110 if ( m_nType == beList )
00111 {
00112 CBENode** pList = new CBENode*[ (DWORD)m_nValue + 1 ];
00113
00114 if ( m_pValue != NULL )
00115 {
00116 CopyMemory( pList, m_pValue, 4 * (DWORD)m_nValue );
00117 delete [] (CBENode**)m_pValue;
00118 }
00119
00120 pList[ m_nValue++ ] = pNew;
00121 m_pValue = pList;
00122 }
00123 else
00124 {
00125 CBENode** pList = new CBENode*[ (DWORD)m_nValue * 2 + 2 ];
00126
00127 if ( m_pValue != NULL )
00128 {
00129 CopyMemory( pList, m_pValue, 8 * (DWORD)m_nValue );
00130 delete [] (CBENode**)m_pValue;
00131 }
00132
00133 BYTE* pxKey = new BYTE[ nKey + 1 ];
00134 CopyMemory( pxKey, pKey, nKey );
00135 pxKey[ nKey ] = 0;
00136
00137 pList[ m_nValue * 2 ] = pNew;
00138 pList[ m_nValue * 2 + 1 ] = (CBENode*)pxKey;
00139
00140 m_pValue = pList;
00141 m_nValue ++;
00142 }
00143
00144 return pNew;
00145 }
00146
00148
00149
00150 CBENode* CBENode::GetNode(LPCSTR pszKey) const
00151 {
00152 if ( m_nType != beDict ) return NULL;
00153
00154 CBENode** pNode = (CBENode**)m_pValue;
00155
00156 for ( DWORD nNode = (DWORD)m_nValue ; nNode ; nNode--, pNode += 2 )
00157 {
00158 if ( strcmp( pszKey, (LPCSTR)pNode[1] ) == 0 ) return *pNode;
00159 }
00160
00161 return NULL;
00162 }
00163
00164 CBENode* CBENode::GetNode(const LPBYTE pKey, int nKey) const
00165 {
00166 if ( m_nType != beDict ) return NULL;
00167
00168 CBENode** pNode = (CBENode**)m_pValue;
00169
00170 for ( DWORD nNode = (DWORD)m_nValue ; nNode ; nNode--, pNode += 2 )
00171 {
00172 if ( memcmp( pKey, (LPBYTE)pNode[1], nKey ) == 0 ) return *pNode;
00173 }
00174
00175 return NULL;
00176 }
00177
00178
00180
00181
00182 CString CBENode::GetStringFromSubNode(LPCSTR pszKey, UINT nEncoding, BOOL* pEncodingError)
00183 {
00184 CBENode* pSubNode;
00185 CString strValue;
00186
00187 if ( Settings.BitTorrent.TorrentExtraKeys )
00188 {
00189
00190 char* pszUTF8Key;
00191 UINT nUTF8Len = strlen( pszKey ) + 8;
00192
00193 pszUTF8Key = new char[ nUTF8Len ];
00194 strncpy( pszUTF8Key, pszKey, nUTF8Len );
00195 strncat( pszUTF8Key, ".utf-8", nUTF8Len );
00196
00197
00198 pSubNode = GetNode( pszUTF8Key );
00199
00200
00201 if ( ( pSubNode ) && ( pSubNode->m_nType == CBENode::beString ) )
00202 {
00203
00204 strValue = pSubNode->GetString();
00205 }
00206 delete [] pszUTF8Key;
00207 }
00208
00209
00210 pSubNode = GetNode( pszKey );
00211
00212 if ( ( pSubNode ) && ( pSubNode->m_nType == CBENode::beString ) )
00213 {
00214 if ( ! IsValid( strValue ) )
00215 {
00216
00217 strValue = pSubNode->GetString();
00218 }
00219 else
00220 {
00221
00222 CString strCheck = pSubNode->GetString();
00223 if ( strCheck != strValue ) *pEncodingError = TRUE;
00224 }
00225 }
00226
00227 if ( ! IsValid( strValue ) )
00228 {
00229
00230 pSubNode = GetNode( pszKey );
00231 if ( ( pSubNode ) && ( pSubNode->m_nType == CBENode::beString ) )
00232 {
00233 strValue = pSubNode->DecodeString( nEncoding );
00234
00235 if ( IsValid( strValue ) ) *pEncodingError = TRUE;
00236 }
00237 }
00238
00239 if ( _tcsicmp( strValue , _T("#ERROR#") ) == 0 ) strValue.Empty();
00240
00241 return strValue;
00242 }
00243
00244
00245
00246 CString CBENode::GetStringFromSubNode(int nItem, UINT nEncoding, BOOL* pEncodingError)
00247 {
00248 CBENode* pSubNode;
00249 CString strValue;
00250
00251
00252 if ( m_nType != beList && m_nType != beDict ) return strValue;
00253
00254 pSubNode = GetNode( nItem );
00255
00256 if ( ( pSubNode ) && ( pSubNode->m_nType == CBENode::beString ) )
00257 {
00258
00259 strValue = pSubNode->GetString();
00260 }
00261
00262 if ( ! IsValid( strValue ) )
00263 {
00264
00265 if ( ( pSubNode ) && ( pSubNode->m_nType == CBENode::beString ) )
00266 {
00267 *pEncodingError = TRUE;
00268 strValue = pSubNode->DecodeString( nEncoding );
00269 }
00270 }
00271
00272 return strValue;
00273 }
00274
00276
00277
00278 void CBENode::GetSHA1(SHA1* pSHA1) const
00279 {
00280 ASSERT( this != NULL );
00281
00282 CBuffer pBuffer;
00283 Encode( &pBuffer );
00284
00285 CSHA pSHA;
00286 pSHA.Add( pBuffer.m_pBuffer, pBuffer.m_nLength );
00287 pSHA.Finish();
00288 pSHA.GetHash( pSHA1 );
00289 }
00290
00292
00293
00294 void CBENode::Encode(CBuffer* pBuffer) const
00295 {
00296 CHAR szBuffer[64];
00297
00298 ASSERT( this != NULL );
00299 ASSERT( pBuffer != NULL );
00300 CString str;
00301
00302 if ( m_nType == beString )
00303 {
00304 sprintf( szBuffer, "%u:", (DWORD)m_nValue );
00305 pBuffer->Print( szBuffer );
00306 pBuffer->Add( m_pValue, (DWORD)m_nValue );
00307 }
00308 else if ( m_nType == beInt )
00309 {
00310 sprintf( szBuffer, "i%I64ie", m_nValue );
00311 pBuffer->Print( szBuffer );
00312 }
00313 else if ( m_nType == beList )
00314 {
00315 CBENode** pNode = (CBENode**)m_pValue;
00316
00317 pBuffer->Print( "l" );
00318
00319 for ( DWORD nItem = 0 ; nItem < (DWORD)m_nValue ; nItem++, pNode++ )
00320 {
00321 (*pNode)->Encode( pBuffer );
00322 }
00323
00324 pBuffer->Print( "e" );
00325 }
00326 else if ( m_nType == beDict )
00327 {
00328 CBENode** pNode = (CBENode**)m_pValue;
00329
00330 pBuffer->Print( "d" );
00331
00332 for ( DWORD nItem = 0 ; nItem < m_nValue ; nItem++, pNode += 2 )
00333 {
00334 LPCSTR pszKey = (LPCSTR)pNode[1];
00335 sprintf( szBuffer, "%i:", strlen( pszKey ) );
00336 pBuffer->Print( szBuffer );
00337 pBuffer->Print( pszKey );
00338 (*pNode)->Encode( pBuffer );
00339 }
00340
00341 pBuffer->Print( "e" );
00342 }
00343 else
00344 {
00345 ASSERT( FALSE );
00346 }
00347 }
00348
00350
00351
00352 CBENode* CBENode::Decode(CBuffer* pBuffer)
00353 {
00354 ASSERT( pBuffer != NULL );
00355
00356 CBENode* pNode = new CBENode();
00357 LPBYTE pInput = pBuffer->m_pBuffer;
00358 DWORD nInput = pBuffer->m_nLength;
00359
00360 try
00361 {
00362 pNode->Decode( pInput, nInput );
00363 }
00364 catch ( CException* pException )
00365 {
00366 pException->Delete();
00367 delete pNode;
00368 pNode = NULL;
00369 }
00370
00371 return pNode;
00372 }
00373
00374 #define INC(x) { pInput += (x); nInput -= (x); }
00375
00376 void CBENode::Decode(LPBYTE& pInput, DWORD& nInput)
00377 {
00378 ASSERT( m_nType == beNull );
00379 ASSERT( pInput != NULL );
00380
00381 if ( nInput < 1 ) AfxThrowUserException();
00382
00383 if ( *pInput == 'i' )
00384 {
00385 INC( 1 );
00386
00387 DWORD nSeek = 1;
00388 for ( ; nSeek < 40 ; nSeek++ )
00389 {
00390 if ( nSeek >= nInput ) AfxThrowUserException();
00391 if ( pInput[nSeek] == 'e' ) break;
00392 }
00393
00394 if ( nSeek >= 40 ) AfxThrowUserException();
00395
00396 pInput[nSeek] = 0;
00397 if ( sscanf( (LPCSTR)pInput, "%I64i", &m_nValue ) != 1 ) AfxThrowUserException();
00398 pInput[nSeek] = 'e';
00399
00400 INC( nSeek + 1 );
00401 m_nType = beInt;
00402 }
00403 else if ( *pInput == 'l' )
00404 {
00405 m_nType = beList;
00406 INC( 1 );
00407
00408 while ( TRUE )
00409 {
00410 if ( nInput < 1 ) AfxThrowUserException();
00411 if ( *pInput == 'e' ) break;
00412 Add()->Decode( pInput, nInput );
00413 }
00414
00415 INC( 1 );
00416 }
00417 else if ( *pInput == 'd' )
00418 {
00419 m_nType = beDict;
00420 INC( 1 );
00421
00422 while ( TRUE )
00423 {
00424 if ( nInput < 1 ) AfxThrowUserException();
00425 if ( *pInput == 'e' ) break;
00426
00427 int nLen = DecodeLen( pInput, nInput );
00428 LPBYTE pKey = pInput;
00429 INC( nLen );
00430
00431 Add( pKey, nLen )->Decode( pInput, nInput );
00432 }
00433
00434 INC( 1 );
00435 }
00436 else if ( *pInput >= '0' && *pInput <= '9' )
00437 {
00438 m_nType = beString;
00439 m_nValue = DecodeLen( pInput, nInput );
00440 m_pValue = new CHAR[ (DWORD)m_nValue + 1 ];
00441 CopyMemory( m_pValue, pInput, (DWORD)m_nValue );
00442 ((LPBYTE)m_pValue)[ m_nValue ] = 0;
00443
00444 INC( (DWORD)m_nValue );
00445 }
00446 else
00447 {
00448 AfxThrowUserException();
00449 }
00450 }
00451
00452 int CBENode::DecodeLen(LPBYTE& pInput, DWORD& nInput)
00453 {
00454 DWORD nSeek = 1;
00455 for ( ; nSeek < 32 ; nSeek++ )
00456 {
00457 if ( nSeek >= nInput ) AfxThrowUserException();
00458 if ( pInput[ nSeek ] == ':' ) break;
00459 }
00460
00461 if ( nSeek >= 32 ) AfxThrowUserException();
00462 int nLen = 0;
00463
00464 pInput[ nSeek ] = 0;
00465 if ( sscanf( (LPCSTR)pInput, "%i", &nLen ) != 1 ) AfxThrowUserException();
00466 pInput[ nSeek ] = ':';
00467 INC( nSeek + 1 );
00468
00469 if ( nInput < (DWORD)nLen ) AfxThrowUserException();
00470
00471 return nLen;
00472 }