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 "Schema.h"
00026 #include "SchemaMember.h"
00027 #include "XML.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 CSchemaMember::CSchemaMember(CSchema* pSchema)
00040 {
00041 m_pSchema = pSchema;
00042 m_bNumeric = FALSE;
00043 m_bIndexed = FALSE;
00044 m_bSearched = FALSE;
00045 m_nMinOccurs = 0;
00046 m_nMaxOccurs = 0;
00047 m_nMaxLength = 128;
00048
00049 m_bPrompt = FALSE;
00050 m_nFormat = smfNone;
00051 m_nColumnWidth = 60;
00052 m_nColumnAlign = LVCFMT_LEFT;
00053 }
00054
00055 CSchemaMember::~CSchemaMember()
00056 {
00057 }
00058
00060
00061
00062 POSITION CSchemaMember::GetItemIterator() const
00063 {
00064 return m_pItems.GetHeadPosition();
00065 }
00066
00067 CString CSchemaMember::GetNextItem(POSITION& pos) const
00068 {
00069 return m_pItems.GetNext( pos );
00070 }
00071
00072 int CSchemaMember::GetItemCount() const
00073 {
00074 return m_pItems.GetCount();
00075 }
00076
00078
00079
00080 CString CSchemaMember::GetValueFrom(CXMLElement* pBase, LPCTSTR pszDefault, BOOL bFormat) const
00081 {
00082
00083 CString strValue;
00084
00085 if ( pBase != NULL )
00086 {
00087 if ( CXMLElement* pElement = pBase->GetElementByName( m_sName ) )
00088 {
00089 strValue = pElement->GetValue();
00090 }
00091 else
00092 {
00093 strValue = pBase->GetAttributeValue( m_sName, pszDefault );
00094 }
00095 }
00096 else if ( pszDefault != NULL )
00097 {
00098 strValue = pszDefault;
00099 }
00100
00101
00102 if ( m_bNumeric )
00103 {
00104 float nNumber = 0.0;
00105 _stscanf( strValue, _T("%f"), &nNumber );
00106 if ( nNumber < (float)m_nMinOccurs || nNumber > (float)m_nMaxOccurs )
00107 strValue.Empty();
00108 }
00109
00110 if ( strValue.IsEmpty() ) return strValue;
00111
00112 if ( bFormat && m_bNumeric )
00113 {
00114 BOOL bInvalid = FALSE;
00115
00116 if ( m_nFormat == smfTimeMMSS )
00117 {
00118 DWORD nSeconds = 0;
00119 _stscanf( strValue, _T("%lu"), &nSeconds );
00120 bInvalid = ( nSeconds < (DWORD)m_nMinOccurs || nSeconds > (DWORD)m_nMaxOccurs );
00121 strValue.Format( _T("%.2u:%.2u"), nSeconds / 60, nSeconds % 60 );
00122 }
00123 else if ( m_nFormat == smfTimeHHMMSSdec )
00124 {
00125 float nMinutes = 0;
00126 _stscanf( strValue, _T("%f"), &nMinutes );
00127 bInvalid = ( nMinutes < (DWORD)m_nMinOccurs || nMinutes > (DWORD)m_nMaxOccurs );
00128 strValue.Format( _T("%.2u:%.2u:%.2u"), (int)nMinutes / 60,
00129 (int)nMinutes % 60, (int)( ( nMinutes - (int)nMinutes ) * 60 ) );
00130 }
00131 else if ( m_nFormat == smfFrequency )
00132 {
00133 DWORD nRate = 0;
00134 _stscanf( strValue, _T("%lu"), &nRate );
00135 bInvalid = ( nRate < (DWORD)m_nMinOccurs || nRate > (DWORD)m_nMaxOccurs );
00136 strValue.Format( _T("%.1f kHz"), nRate / 1000.0 );
00137 }
00138 else if ( m_nFormat == smfBitrate )
00139 {
00140 BOOL bVariable = _tcschr( strValue, '~' ) != NULL;
00141 DWORD nBitrate = 0;
00142 _stscanf( strValue, _T("%lu"), &nBitrate );
00143 bInvalid = ( nBitrate < (DWORD)m_nMinOccurs || nBitrate > (DWORD)m_nMaxOccurs );
00144 strValue.Format( bVariable ? _T("%luk~") : _T("%luk"), nBitrate );
00145 }
00146 if ( bInvalid ) strValue.Empty();
00147 }
00148
00149 return strValue;
00150 }
00151
00153
00154
00155 void CSchemaMember::SetValueTo(CXMLElement* pBase, LPCTSTR pszValue)
00156 {
00157 if ( CXMLElement* pElement = pBase->GetElementByName( m_sName ) )
00158 {
00159 if ( m_bElement && pszValue != NULL && _tcslen( pszValue ) > 0 )
00160 pElement->SetValue( pszValue );
00161 else
00162 pElement->Delete();
00163 }
00164 else if ( m_bElement && pszValue != NULL && _tcslen( pszValue ) > 0 )
00165 {
00166 CXMLElement* pElement = pBase->AddElement( m_sName );
00167 pElement->SetValue( pszValue );
00168 }
00169
00170 if ( CXMLAttribute* pAttribute = pBase->GetAttribute( m_sName ) )
00171 {
00172 if ( ! m_bElement && pszValue != NULL && _tcslen( pszValue ) > 0 )
00173 pAttribute->SetValue( pszValue );
00174 else
00175 pAttribute->Delete();
00176 }
00177 else if ( ! m_bElement && pszValue != NULL && _tcslen( pszValue ) > 0 )
00178 {
00179 pBase->AddAttribute( m_sName, pszValue );
00180 }
00181 }
00182
00184
00185
00186 BOOL CSchemaMember::LoadSchema(CXMLElement* pRoot, CXMLElement* pElement)
00187 {
00188 m_bElement = pElement->GetName().CompareNoCase( _T("element") ) == 0;
00189
00190 m_sName = pElement->GetAttributeValue( _T("name"), _T("") );
00191 if ( m_sName.IsEmpty() ) return FALSE;
00192
00193 m_sTitle = m_sName;
00194 m_sTitle.SetAt( 0, toupper( m_sTitle.GetAt( 0 ) ) );
00195
00196 m_sType = pElement->GetAttributeValue( _T("type"), _T("") );
00197 CharLower( m_sType.GetBuffer() );
00198 m_sType.ReleaseBuffer();
00199
00200 m_bNumeric = ( m_sType == _T("short") || m_sType == _T("int") || m_sType == _T("decimal") );
00201
00202 CString strValue = pElement->GetAttributeValue( _T("minOccurs"), _T("0") );
00203 _stscanf( strValue, _T("%i"), &m_nMinOccurs );
00204 strValue = pElement->GetAttributeValue( _T("maxOccurs"), _T("65536") );
00205 _stscanf( strValue, _T("%i"), &m_nMaxOccurs );
00206
00207 if ( pElement->GetElementCount() )
00208 {
00209 return LoadType( pElement->GetFirstElement() );
00210 }
00211 else if ( m_sType.GetLength() )
00212 {
00213 CXMLElement* pType = m_pSchema->GetType( pRoot, m_sType );
00214 return pType ? LoadType( pType ) : TRUE;
00215 }
00216 else
00217 {
00218 return FALSE;
00219 }
00220 }
00221
00222 BOOL CSchemaMember::LoadType(CXMLElement* pType)
00223 {
00224 CString strName = pType->GetName();
00225
00226 if ( strName.CompareNoCase( _T("simpleType") ) &&
00227 strName.CompareNoCase( _T("complexType") ) ) return FALSE;
00228
00229 m_sType = pType->GetAttributeValue( _T("base"), _T("") );
00230 CharLower( m_sType.GetBuffer() );
00231 m_sType.ReleaseBuffer();
00232 m_bNumeric = ( m_sType == _T("short") || m_sType == _T("int") || m_sType == _T("decimal") );
00233
00234 for ( POSITION pos = pType->GetElementIterator() ; pos ; )
00235 {
00236 CXMLElement* pElement = pType->GetNextElement( pos );
00237 CString strElement = pElement->GetName();
00238
00239 if ( strElement.CompareNoCase( _T("enumeration") ) == 0 )
00240 {
00241 CString strValue = pElement->GetAttributeValue( _T("value"), _T("") );
00242 if ( strValue.GetLength() ) m_pItems.AddTail( strValue );
00243 }
00244 else if ( strElement.CompareNoCase( _T("maxInclusive") ) == 0 )
00245 {
00246 CString strValue = pElement->GetAttributeValue( _T("value"), _T("0") );
00247 _stscanf( strValue, _T("%i"), &m_nMaxLength );
00248 }
00249 }
00250
00251 return TRUE;
00252 }
00253
00255
00256
00257 BOOL CSchemaMember::LoadDescriptor(CXMLElement* pXML)
00258 {
00259 CString strSearch = pXML->GetAttributeValue( _T("search") );
00260
00261 if ( strSearch.CompareNoCase( _T("generic") ) == 0 )
00262 {
00263 m_bIndexed = TRUE;
00264 m_bSearched = TRUE;
00265 }
00266 else if ( strSearch.CompareNoCase( _T("indexed") ) == 0 )
00267 {
00268 m_bIndexed = TRUE;
00269 }
00270
00271 CString strTitle = m_sTitle;
00272 m_sTitle.Empty();
00273
00274 for ( POSITION pos = pXML->GetElementIterator() ; pos ; )
00275 {
00276 CXMLElement* pElement = pXML->GetNextElement( pos );
00277
00278 if ( pElement->IsNamed( _T("display") ) )
00279 {
00280 LoadDisplay( pElement );
00281 }
00282 else if ( pElement->IsNamed( _T("title") ) )
00283 {
00284 if ( pElement->GetAttributeValue( _T("language") ).
00285 CompareNoCase( Settings.General.Language ) == 0 )
00286 {
00287 m_sTitle = pElement->GetValue();
00288 }
00289 else if ( m_sTitle.IsEmpty() )
00290 {
00291 m_sTitle = pElement->GetValue();
00292 }
00293 }
00294 else if ( pElement->IsNamed( _T("link") ) )
00295 {
00296 m_sLinkURI = pElement->GetAttributeValue( _T("location") );
00297 m_sLinkName = pElement->GetAttributeValue( _T("remote") );
00298 }
00299 }
00300
00301 if ( m_sTitle.IsEmpty() ) m_sTitle = strTitle;
00302
00303 return TRUE;
00304 }
00305
00306 BOOL CSchemaMember::LoadDisplay(CXMLElement* pDisplay)
00307 {
00308 CString strFormat = pDisplay->GetAttributeValue( _T("format") );
00309 CString strWidth = pDisplay->GetAttributeValue( _T("columnWidth") );
00310 CString strAlign = pDisplay->GetAttributeValue( _T("columnAlign") );
00311 CString strColumn = pDisplay->GetAttributeValue( _T("defaultColumn") );
00312 CString strSearch = pDisplay->GetAttributeValue( _T("prompt") );
00313
00314 if ( strFormat.CompareNoCase( _T("timeMMSS") ) == 0 )
00315 m_nFormat = smfTimeMMSS;
00316 else if ( strFormat.CompareNoCase( _T("timeHHMMSSdec") ) == 0 )
00317 m_nFormat = smfTimeHHMMSSdec;
00318 else if ( strFormat.CompareNoCase( _T("bitrate") ) == 0 )
00319 m_nFormat = smfBitrate;
00320 else if ( strFormat.CompareNoCase( _T("frequency") ) == 0 )
00321 m_nFormat = smfFrequency;
00322
00323 _stscanf( strWidth, _T("%lu"), &m_nColumnWidth );
00324
00325 if ( strAlign.CompareNoCase( _T("left") ) == 0 )
00326 m_nColumnAlign = LVCFMT_LEFT;
00327 else if ( strAlign.CompareNoCase( _T("center") ) == 0 )
00328 m_nColumnAlign = LVCFMT_CENTER;
00329 else if ( strAlign.CompareNoCase( _T("right") ) == 0 )
00330 m_nColumnAlign = LVCFMT_RIGHT;
00331
00332 if ( strColumn.CompareNoCase( _T("true") ) == 0 )
00333 {
00334 m_pSchema->m_sDefaultColumns += '|';
00335 m_pSchema->m_sDefaultColumns += m_sName;
00336 m_pSchema->m_sDefaultColumns += '|';
00337 }
00338
00339 if ( strSearch.CompareNoCase( _T("true") ) == 0 )
00340 {
00341 m_bPrompt = TRUE;
00342 }
00343
00344 return TRUE;
00345 }