Example #1
0
// ---
AVP_dword DATA_PARAM PROP_Set_Val( HPROP prop, AVP_size_t val, AVP_dword size ) {
  if ( !prop ) {
    _RPT0( _CRT_ASSERT, "Property handle is zero" );
    return 0;
  }

  if ( ((AVP_Property*)prop)->array ) {
    if ( val == 0 || size == 0 ) 
      return PROP_Arr_Free( (AVP_Arr_Property*)prop );
    else
      return PROP_Arr_Insert( prop, PROP_ARR_LAST, (void*)val, size );
  }
  else {
    switch( ((AVP_Property*)prop)->type ) {
      case avpt_nothing : 
        //_RPT0( _CRT_ASSERT, "Cannot set value for empty property" );
        return 0;
      case avpt_char : 
        if ( size == 0 || size == sizeof(AVP_char) ) {
          size = sizeof(AVP_char);
          ((AVP_CHAR_Property*)prop)->val = (AVP_char)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_wchar : 
        if ( size == 0 || size == sizeof(AVP_wchar) ) {
          size = sizeof(AVP_wchar);
          ((AVP_WCHAR_Property*)prop)->val = (AVP_wchar)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_short : 
        if ( size == 0 || size == sizeof(AVP_short) ) {
          size = sizeof(AVP_short);
          ((AVP_SHORT_Property*)prop)->val = (AVP_short)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_long : 
        if ( size == 0 || size == sizeof(AVP_long) ) {
          size = sizeof(AVP_long);
          ((AVP_LONG_Property*)prop)->val = (AVP_long)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_byte : 
        if ( size == 0 || size == sizeof(AVP_byte) ) {
          size = sizeof(AVP_byte);
          ((AVP_BYTE_Property*)prop)->val = (AVP_byte)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_group : 
        if ( size == 0 || size == sizeof(AVP_group) ) {
          size = sizeof(AVP_group);
          ((AVP_GROUP_Property*)prop)->val = (AVP_group)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_word : 
        if ( size == 0 || size == sizeof(AVP_word) ) {
          size = sizeof(AVP_word);
          ((AVP_WORD_Property*)prop)->val = (AVP_word)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_dword : 
        if ( size == 0 || size == sizeof(AVP_dword) ) {
          size = sizeof(AVP_dword);
          ((AVP_DWORD_Property*)prop)->val = (AVP_dword)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_qword : 
      case avpt_longlong : 
        if ( val ) {
          if ( size == 0 || size == sizeof(AVP_qword) ) {
            size = sizeof(AVP_qword);
            memcpy( &((AVP_QWORD_Property*)prop)->val, (void*)val, sizeof(AVP_qword) ); 
            break;
          }
          else {
            _RPT0( _CRT_ASSERT, "Bad data size" );
            return 0;
          }
        }
        else {
          memset( &((AVP_QWORD_Property*)prop)->val, 0, sizeof(AVP_qword) ); 
          size = sizeof(AVP_qword);
          break;
        }
      case avpt_size_t : 
        if ( size == 0 || size == sizeof(AVP_size_t) ) {
          size = sizeof(AVP_size_t);
          ((AVP_SIZE_T_Property*)prop)->val = (AVP_size_t)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_int : 
        if ( size == 0 || size == sizeof(AVP_int) ) {
          size = sizeof(AVP_int);
          ((AVP_INT_Property*)prop)->val = (AVP_int)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_uint : 
        if ( size == 0 || size == sizeof(AVP_uint) ) {
          size = sizeof(AVP_uint);
          ((AVP_UINT_Property*)prop)->val = (AVP_uint)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_bool :
        if ( size == 0 || size == sizeof(AVP_dword) ) {
          size = sizeof(AVP_bool);
          ((AVP_BOOL_Property*)prop)->val = (AVP_bool)val;
          break;
        }
        else {
          _RPT0( _CRT_ASSERT, "Bad data size" );
          return 0;
        }
      case avpt_date : 
        if ( val ) {
          if ( size == 0 || size == sizeof(AVP_date) ) {
            size = sizeof(AVP_date);
            memcpy( ((AVP_DATE_Property*)prop)->val, (void*)val, sizeof(AVP_date) ); 
            break;
          }
          else {
            _RPT0( _CRT_ASSERT, "Bad data size" );
            return 0;
          }
        }
        else {
          memset( ((AVP_DATE_Property*)prop)->val, 0, sizeof(AVP_date) ); 
          size = sizeof(AVP_date);
          break;
        }

      case avpt_time : 
        if ( val ) {
          if ( size == 0 || size == sizeof(AVP_time) ) {
            size = sizeof(AVP_time);
            memcpy( ((AVP_TIME_Property*)prop)->val, (void*)val, sizeof(AVP_time) ); 
            break;
          }
          else {
            _RPT0( _CRT_ASSERT, "Bad data size" );
            return 0;
          }
        }
        else {
          memset( ((AVP_TIME_Property*)prop)->val, 0, sizeof(AVP_time) ); 
          size = sizeof(AVP_time);
          break;
        }

      case avpt_datetime : 
        if ( val ) {
          if ( size == 0 || size == sizeof(AVP_datetime) ) {
            size = sizeof(AVP_datetime);
            memcpy( ((AVP_DATETIME_Property*)prop)->val, (void*)val, sizeof(AVP_datetime) ); 
            break;
          }
          else {
            _RPT0( _CRT_ASSERT, "Bad data size" );
            return 0;
          }
        }
        else {
          memset( ((AVP_DATETIME_Property*)prop)->val, 0, sizeof(AVP_datetime) ); 
          size = sizeof(AVP_datetime);
          break;
        }

      case avpt_str : 
      
        _ASSERTE( allocator && liberator );

        if ( val ) {
          if ( size == 0 )
            size = (AVP_dword)strlen( (AVP_str)val ) + sizeof(AVP_char);

          if ( ((AVP_STR_Property*)prop)->val == 0 ) 
            ((AVP_STR_Property*)prop)->val = allocator( size );
          else {
            AVP_dword now = (AVP_dword)strlen( ((AVP_STR_Property*)prop)->val ) + sizeof(AVP_char);
            if ( now != size ) {
              liberator( ((AVP_STR_Property*)prop)->val );
              ((AVP_STR_Property*)prop)->val = (AVP_str)allocator( size );
            }
          }

          _ASSERT( ((AVP_STR_Property*)prop)->val );
          memcpy( ((AVP_STR_Property*)prop)->val, (AVP_str)val, size-sizeof(AVP_char) );
          ((AVP_STR_Property*)prop)->val[size-1] = 0;
        }
        else {
          size = 0;
          if ( ((AVP_STR_Property*)prop)->val != 0 ) {
            liberator( ((AVP_STR_Property*)prop)->val );
            ((AVP_STR_Property*)prop)->val = 0;
          }
        }

        break;

      case avpt_wstr : 

        _ASSERTE( allocator && liberator );
        if ( val ) {
          if ( size == 0 )
            size = (AVP_dword)wcslen( (wchar_t*)(AVP_wstr)val ) + 1;

          if ( ((AVP_WSTR_Property*)prop)->val == 0 ) 
            ((AVP_WSTR_Property*)prop)->val = allocator( sizeof(AVP_wchar) * size );
          else {
            AVP_dword now = (AVP_dword)wcslen( (wchar_t*)((AVP_WSTR_Property*)prop)->val ) + 1;
            if ( now != size ) {
              liberator( ((AVP_WSTR_Property*)prop)->val );
              ((AVP_WSTR_Property*)prop)->val = (AVP_wstr)allocator( sizeof(AVP_wchar) * size );
            }
          }

          _ASSERT( ((AVP_WSTR_Property*)prop)->val );
          memcpy( ((AVP_WSTR_Property*)prop)->val, (AVP_wstr)val, (size-1)*sizeof(AVP_wchar) );
          ((AVP_WSTR_Property*)prop)->val[size-1] = 0;
        }
        else {
          size = 0;
          if ( ((AVP_WSTR_Property*)prop)->val != 0 ) {
            liberator( ((AVP_WSTR_Property*)prop)->val );
            ((AVP_WSTR_Property*)prop)->val = 0;
          }
        }

        break;

      case avpt_bin : 
        _ASSERTE( allocator && liberator );

        if ( val && size ) {
          if ( ((AVP_BIN_Property*)prop)->val.size != size ) {
            if ( ((AVP_BIN_Property*)prop)->val.data )
              liberator( ((AVP_BIN_Property*)prop)->val.data );
            ((AVP_BIN_Property*)prop)->val.data = (AVP_byte*)allocator( size );
            _ASSERT( ((AVP_BIN_Property*)prop)->val.data );
            ((AVP_BIN_Property*)prop)->val.size = size;
          }
          memcpy( ((AVP_BIN_Property*)prop)->val.data, (void*)val, size );        
        }
        else {
          if ( ((AVP_BIN_Property*)prop)->val.data )
            liberator( ((AVP_BIN_Property*)prop)->val.data );
          ((AVP_BIN_Property*)prop)->val.data = 0;
          ((AVP_BIN_Property*)prop)->val.size = 0;
        }

        break;

      default : 
        _RPT0( _CRT_ASSERT, "Bad property type" );
        return 0;
    };
    return size;
  }
}
Example #2
0
// ---
static AVP_dword DATA_PARAM PROP_Arr_Get( Serialize* sz, AVP_Arr_Property* prop ) {

	AVP_dword i, c;
	AVP_dword size;
	AVP_dword vsize;
	AVP_word  tmpvsize;
	AVP_byte* s;
	AVP_byte  arr[10];
	AVP_bool  res;

	if ( !prop || !prop->prop.array || !prop->prop.type == avpt_nothing ) {
		_RPT0( _CRT_ASSERT, "Property is not an array" );
		return 0;
	}

	vsize = 0;

	if ( 
		(sizeof( AVP_word ) == get_word( sz, &tmpvsize )) &&
		(sizeof( prop->delta ) == get_word( sz, &prop->delta ))
	) {
		vsize = tmpvsize;
		size = sizeof( prop->count ) + sizeof( prop->delta );
	}
	else
		return 0;

	if ( !vsize )
		return size;

	res = PROP_Arr_Catch_Mem( PROP_HANDLE(prop), vsize );

	_ASSERT( res );

	prop->count = vsize;

	switch( prop->prop.type ) {
		case avpt_bool    : 
			c = (vsize / 8) + ( (vsize % 8) > 0 );
			if ( c > sizeof(arr) )
				s = allocator( c );
			else
				s = arr;
			if ( c == get_bytes(sz,s,c) ) {
				for( i=0; i<vsize; i++ ) {
					AVP_dword byte = i / 8;
					AVP_dword bit = i % 8;
					((AVP_bool*)prop->val)[i] = (s[byte] & (1 << bit)) != 0;
				}
			}
			else
				size = 0;
			if ( c > sizeof(arr) )
				liberator( s );
			return size;

		case avpt_char    :
		case avpt_wchar   :
		case avpt_short   :
		case avpt_long    :
		case avpt_byte    :
		case avpt_group   :
		case avpt_word    :
		case avpt_dword   :
		case avpt_qword   :
		case avpt_longlong:
		case avpt_size_t  :
		case avpt_int     :
		case avpt_uint    :
		case avpt_date    :
		case avpt_time    :
		case avpt_datetime:
		case avpt_str     :
		case avpt_wstr :
		case avpt_bin :
			break;

		case avpt_nothing : 
		default :
			_RPT0( _CRT_ASSERT, "Bad property type" );
			return 0;
	}

	for ( i = 0; i < prop->count; i++ ) 
	{
		if ( (c = ReadPropertyItem( sz, prop->prop.type, ((char *) prop->val) + i * prop->isize)) == 0 )
		{
			size = 0;
			break;
		}

		size += c;
	}

	return size;
}
Example #3
0
/////////////////////////////////////////////
// CED2KFileLink implementation
/////////////////////////////////////////////
CED2KFileLink::CED2KFileLink(const TCHAR* pszName, const TCHAR* pszSize, const TCHAR* pszHash, 
							 const CStringArray& astrParams, const TCHAR* pszSources)
	: m_size(pszSize)
{
	// Here we have a little problem.. Actually the proper solution would be to decode from UTF8,
	// only if the string does contain escape sequences. But if user pastes a raw UTF8 encoded
	// string (for whatever reason), we would miss to decode that string. On the other side, 
	// always decoding UTF8 can give flaws in case the string is valid for Unicode and UTF8
	// at the same time. However, to avoid the pasting of raw UTF8 strings (which would lead
	// to a greater mess in the network) we always try to decode from UTF8, even if the string
	// did not contain escape sequences.
	m_name = OptUtf8ToStr(URLDecode(pszName));
	m_name.Trim();
	if (m_name.IsEmpty())
		throw GetResString(IDS_ERR_NOTAFILELINK);

	SourcesList = NULL;
	m_hashset = NULL;
	m_bAICHHashValid = false;

	if (_tcslen(pszHash) != 32)
		throw GetResString(IDS_ERR_ILLFORMEDHASH);

	if (_tstoi64(pszSize)>=4294967295)
		throw GetResString(IDS_ERR_TOOLARGEFILE);
	if (_tstoi64(pszSize)<=0)
		throw GetResString(IDS_ERR_NOTAFILELINK);
	
	for (int idx = 0; idx < 16; ++idx) {
		m_hash[idx] = FromHexDigit(*pszHash++)*16;
		m_hash[idx] += FromHexDigit(*pszHash++);
	}

	bool bError = false;
	for (int i = 0; !bError && i < astrParams.GetCount(); i++)
	{
		const CString& strParam = astrParams.GetAt(i);
		ASSERT( !strParam.IsEmpty() );

		CString strTok;
		int iPos = strParam.Find(_T('='));
		if (iPos != -1)
			strTok = strParam.Left(iPos);
		if (strTok == _T("s"))
		{
			CString strURL = strParam.Mid(iPos + 1);
			if (!strURL.IsEmpty())
			{
				TCHAR szScheme[INTERNET_MAX_SCHEME_LENGTH];
				TCHAR szHostName[INTERNET_MAX_HOST_NAME_LENGTH];
				TCHAR szUrlPath[INTERNET_MAX_PATH_LENGTH];
				TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH];
				TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH];
				TCHAR szExtraInfo[INTERNET_MAX_URL_LENGTH];
				URL_COMPONENTS Url = {0};
				Url.dwStructSize = sizeof(Url);
				Url.lpszScheme = szScheme;
				Url.dwSchemeLength = ARRSIZE(szScheme);
				Url.lpszHostName = szHostName;
				Url.dwHostNameLength = ARRSIZE(szHostName);
				Url.lpszUserName = szUserName;
				Url.dwUserNameLength = ARRSIZE(szUserName);
				Url.lpszPassword = szPassword;
				Url.dwPasswordLength = ARRSIZE(szPassword);
				Url.lpszUrlPath = szUrlPath;
				Url.dwUrlPathLength = ARRSIZE(szUrlPath);
				Url.lpszExtraInfo = szExtraInfo;
				Url.dwExtraInfoLength = ARRSIZE(szExtraInfo);
				if (InternetCrackUrl(strURL, 0, 0, &Url) && Url.dwHostNameLength > 0)
				{
					SUnresolvedHostname* hostname = new SUnresolvedHostname;
					hostname->strURL = strURL;
					hostname->strHostname = szHostName;
					m_HostnameSourcesList.AddTail(hostname);
				}
			}
			else
				ASSERT(0);
		}
		else if (strTok == _T("p"))
		{
			CString strPartHashs = strParam.Tokenize(_T("="), iPos);

			if (m_hashset != NULL){
				ASSERT(0);
				bError = true;
				break;
			}

			m_hashset = new CSafeMemFile(256);
			m_hashset->WriteHash16(m_hash);
			m_hashset->WriteUInt16(0);

			int iPartHashs = 0;
			int iPosPH = 0;
			CString strHash = strPartHashs.Tokenize(_T(":"), iPosPH);
			while (!strHash.IsEmpty())
			{
				uchar aucPartHash[16];
				if (!strmd4(strHash, aucPartHash)){
					bError = true;
					break;
				}
				m_hashset->WriteHash16(aucPartHash);
				iPartHashs++;
				strHash = strPartHashs.Tokenize(_T(":"), iPosPH);
			}
			if (bError)
				break;

			m_hashset->Seek(16, CFile::begin);
			m_hashset->WriteUInt16(iPartHashs);
			m_hashset->Seek(0, CFile::begin);
		}
		else if (strTok == _T("h"))
		{
			CString strHash = strParam.Mid(iPos + 1);
			if (!strHash.IsEmpty())
			{
				if (DecodeBase32(strHash, m_AICHHash.GetRawHash(), CAICHHash::GetHashSize()) == CAICHHash::GetHashSize()){
					m_bAICHHashValid = true;
					ASSERT( m_AICHHash.GetString().CompareNoCase(strHash) == 0 );
				}
				else
					ASSERT( false );
			}
			else
				ASSERT( false );
		}
		else
			ASSERT(0);
	}

	if (bError)
	{
		delete m_hashset;
		m_hashset = NULL;
	}

	if (pszSources)
	{
		TCHAR* pNewString = _tcsdup(pszSources);
		autoFree liberator(pNewString);
		TCHAR* pCh = pNewString;
		TCHAR* pEnd;
		TCHAR* pIP;
		TCHAR* pPort;

		bool bAllowSources;
		TCHAR date[3];
		COleDateTime expirationDate;
		int nYear,nMonth,nDay;

		uint16 nCount = 0;
		uint32 dwID;
		uint16 nPort;
		uint32 dwServerIP = 0; 
		uint16 nServerPort = 0;
		unsigned long ul;

		int nInvalid = 0;

		pCh = _tcsstr( pCh, _T("sources") );
		if( pCh != NULL ) {
			pCh = pCh + 7; // point to char after "sources"
			pEnd = pCh;
			while( *pEnd ) pEnd++; // make pEnd point to the terminating NULL
			bAllowSources=true;
			// if there's an expiration date...
			if( *pCh == _T('@') && (pEnd-pCh) > 7 )
			{
				pCh++; // after '@'
				date[2] = 0; // terminate the two character string
				date[0] = *(pCh++); date[1] = *(pCh++);
				nYear = _tcstol( date, 0, 10 ) + 2000;
				date[0] = *(pCh++); date[1] = *(pCh++);
				nMonth = _tcstol( date, 0, 10 );
				date[0] = *(pCh++); date[1] = *(pCh++);
				nDay = _tcstol( date, 0, 10 );
				bAllowSources = ( expirationDate.SetDate(nYear,nMonth,nDay) == 0 );
				if (bAllowSources) bAllowSources=(COleDateTime::GetCurrentTime() < expirationDate);
			}

			// increment pCh to point to the first "ip:port" and check for sources
			if ( bAllowSources && ++pCh < pEnd ) {
				SourcesList = new CSafeMemFile(256);
				SourcesList->WriteUInt16(nCount); // init to 0, we'll fix this at the end.
				// for each "ip:port" source string until the end
				// limit to prevent overflow (uint16 due to CPartFile::AddClientSources)
				while( *pCh != 0 && nCount < MAXSHORT ) {
					pIP = pCh;
					// find the end of this ip:port string & start of next ip:port string.
					if( (pCh = _tcschr(pCh, _T(','))) != NULL ) {
						*pCh = 0; // terminate current "ip:port"
						pCh++; // point to next "ip:port"
					}
					else
						pCh = pEnd;

					// if port is not present for this ip, go to the next ip.
					if( (pPort = _tcschr(pIP, _T(':'))) == NULL )
					{	nInvalid++;	continue;	}

					*pPort = 0;	// terminate ip string
					pPort++;	// point pPort to port string.

					dwID = inet_addr(CStringA(pIP));
					ul = _tcstoul( pPort, 0, 10 );
					nPort = static_cast<uint16>(ul);

					// skip bad ips / ports
					if (ul > 0xFFFF || ul == 0 )	// port
					{	nInvalid++;	continue;	}
					if( dwID == INADDR_NONE) {	// hostname?
						if (_tcslen(pIP) > 512)
						{	nInvalid++;	continue;	}
						SUnresolvedHostname* hostname = new SUnresolvedHostname;
						hostname->nPort = nPort;
						hostname->strHostname = pIP;
						m_HostnameSourcesList.AddTail(hostname);
						continue;
					}
					//TODO: This will filter out *.*.*.0 clients. Is there a nice way to fix?
					if( IsLowID(dwID) )	// ip
					{	nInvalid++;	continue;	}

					SourcesList->WriteUInt32(dwID);
					SourcesList->WriteUInt16(nPort);
					SourcesList->WriteUInt32(dwServerIP);
					SourcesList->WriteUInt16(nServerPort);
					nCount++;
				}
				SourcesList->SeekToBegin();
				SourcesList->WriteUInt16(nCount);
				SourcesList->SeekToBegin();
				if (nCount==0) {
					delete SourcesList;
					SourcesList=NULL;
				}
			}
		}
	}
}
Example #4
0
// ---
DATA_PROC AVP_dword DATA_PARAM PROP_Arr_Set_Items( HPROP prop, AVP_dword pos, void* from, AVP_dword count ) {
	AVP_dword size;
	AVP_dword c_count;

	if ( !prop || !((AVP_Property*)prop)->array || ((AVP_Property*)prop)->type == avpt_nothing ) {
		_RPT0( _CRT_ASSERT, "Property is not an array" );
		return 0;
	}

	if ( !from || pos > ((AVP_Arr_Property*)prop)->count ) {
		_RPT0( _CRT_ASSERT, "Bad parameters" );
		return 0;
	}

	switch( ((AVP_Property*)prop)->type ) {
		case avpt_char     :
		case avpt_wchar    :
		case avpt_short    :
		case avpt_long     :
		case avpt_byte     :
		case avpt_group    :
		case avpt_word     :
		case avpt_dword    :
		case avpt_qword    :
		case avpt_longlong :
		case avpt_size_t   :
		case avpt_int      :
		case avpt_uint     :
		case avpt_bool     :
		case avpt_date     :
		case avpt_time     :
		case avpt_datetime :
			count /= ((AVP_Arr_Property*)prop)->isize;
			if ( count == 0 ) {
				_RPT0( _CRT_ASSERT, "Bad parameters" );
				return 0;
			}
			size = 0;
			if ( pos + count > ((AVP_Arr_Property*)prop)->count ) {
				c_count = ((AVP_Arr_Property*)prop)->count - pos;
				count -= c_count;
			}
			else {
				c_count = count;
				count = 0;
			}
			if ( c_count ) {
				size += c_count * ((AVP_Arr_Property*)prop)->isize;
				memcpy( ((AVP_byte*)((AVP_Arr_Property*)prop)->val)+pos*((AVP_Arr_Property*)prop)->isize, from, size );
			}
			if ( count ) 
				size += PROP_Arr_Insert( prop, PROP_ARR_LAST, ((AVP_byte*)from)+c_count*((AVP_Arr_Property*)prop)->isize, count*((AVP_Arr_Property*)prop)->isize );
			break;
		case avpt_str   : 
			if ( pos <= ((AVP_Arr_Property*)prop)->count ) {
				AVP_str* dst;
				if ( !count )
					count = (AVP_dword)strlen( from ) + sizeof(AVP_char);
				dst = &((AVP_str*)((AVP_Arr_Property*)prop)->val)[ pos ];
				if ( *dst ) {
					size = (AVP_dword)strlen( *dst ) + sizeof(AVP_char);
					if ( size != count ) {
						liberator( *dst );
						*dst = allocator( count );
						_ASSERT( *dst );
					}
				}
				else 
					*dst = allocator( count );
				memcpy( *dst, from, count-sizeof(AVP_char) );
				(*dst)[count-1] = 0;
				size = count;
			}
			else 
				size = PROP_Arr_Insert( prop, PROP_ARR_LAST, from, count );
			break;
		case avpt_wstr  : 
			if ( pos <= ((AVP_Arr_Property*)prop)->count ) {
				AVP_wstr* dst;
				if ( !count )
					count = (AVP_dword)( wcslen( from ) + 1 ) * sizeof(AVP_wchar);
				dst = &((AVP_wstr*)((AVP_Arr_Property*)prop)->val)[ pos ];
				if ( *dst ) {
					size = (AVP_dword)( wcslen( (wchar_t *)*dst ) + 1 ) * sizeof(AVP_wchar);
					if ( size != count ) {
						liberator( *dst );
						*dst = allocator( count );
						_ASSERT( *dst );
					}
				}
				else 
					*dst = allocator( count );
				memcpy( *dst, from, count-sizeof(AVP_wchar) );
				(*dst)[count/sizeof(AVP_wchar)-1] = 0;
				size = count;
			}
			else 
				size = PROP_Arr_Insert( prop, PROP_ARR_LAST, from, count );
			break;
		case avpt_bin   : 
			if ( pos <= ((AVP_Arr_Property*)prop)->count ) {
				AVP_Bin_Item* dst;
				if ( !count ) {
					_RPT0( _CRT_ASSERT, "Bad parameters" );
					return 0;
				}
				dst = ((AVP_Bin_Item*)((AVP_Arr_Property*)prop)->val) + pos;
				if ( dst ) {
					if ( dst->size != count ) {
						dst->size = count;
						liberator( dst->data );
						dst->data = allocator( count );
						_ASSERT( dst->data );
					}
				}
				else {
					dst->size = count;
					dst->data = allocator( count );
				}
				memcpy( dst->data, from, count );
				size = count;
			}
			else 
				size = PROP_Arr_Insert( prop, PROP_ARR_LAST, from, count );
			break;
		default : 
			_RPT0( _CRT_ASSERT, "Bad property array type" );
			return 0;
	}
	return size;
}
Example #5
0
// ---
static AVP_dword DATA_PARAM PROP_Arr_Put( Serialize* sz, AVP_Arr_Property* prop ) {

  AVP_dword i, c;
  AVP_dword size;
  AVP_word wput;
  AVP_byte* s;
  AVP_byte  arr[10];

  if ( !prop || !prop->prop.array || prop->prop.type == avpt_nothing ) {
    _RPT0( _CRT_ASSERT, "Property is not an array" );
    return 0;
  }

  if ( prop->count > USHRT_MAX ) {
    _RPT0( _CRT_ASSERT, "Property array is too large" );
    return 0;
  }

  wput = (AVP_word)prop->count;
  
  if ( 
    sizeof( AVP_Property ) == put_avp_property (sz, &prop->prop) &&
    sizeof( AVP_word ) == put_word (sz, &wput) &&
    sizeof( prop->delta ) == put_word (sz, &prop->delta)
  ) 
    size = 
      sizeof( AVP_Property ) + 
      sizeof( AVP_word ) + 
      sizeof( prop->delta );
  else
    return 0;

  switch( prop->prop.type ) {
    case avpt_bool    :
      c = (prop->count / 8) + ( (prop->count % 8) > 0 );
      if ( c > sizeof(arr) )
        s = allocator( c );
      else
        s = arr;
      memset( s, 0, c );
      for( i=0; i<prop->count; i++ ) {
        if ( ((AVP_bool*)prop->val)[i] ) {
          AVP_dword byte = i / 8;
          AVP_dword bit = i % 8;
          s[byte] |= 1 << bit;
        }
      }
      if ( c == put_bytes(sz,s,c) )
        size += c;
      else
        size = 0;
      if ( c > sizeof(arr) )
        liberator( s );
	  return size;        

    case avpt_char    : 
    case avpt_wchar   : 
    case avpt_short   : 
    case avpt_long    : 
    case avpt_byte    : 
    case avpt_group   : 
    case avpt_word    : 
    case avpt_dword   : 
    case avpt_qword   : 
    case avpt_longlong: 
		case avpt_size_t  :
    case avpt_int     : 
    case avpt_uint    : 
    case avpt_date    : 
    case avpt_time    : 
    case avpt_datetime: 
    case avpt_str	  :
    case avpt_wstr	  :
    case avpt_bin	  :
      break;
      
    case avpt_nothing : 
    default :
      _RPT0( _CRT_ASSERT, "Bad array property type" );
      return size;
  }
  
  for ( i = 0; i < prop->count; i++ ) {
   	if ( (c = WritePropertyItem(sz,prop->prop.type,((char*)prop->val)+i*prop->isize)) == 0 ) {
  		size = 0;
  		break;
  	}
  	size += c;
  }
  
  return size;
}