00001 #include "gHtmlAttr.h"
00002 #include "gstringext.h"
00003
00004 gHAttrList::gHAttrList ()
00005 : nAttr( 0 ),
00006 originalLst( nil ),
00007 pAttrAssign( nil )
00008 {
00009 }
00010
00011 gHAttrList::~gHAttrList ()
00012 {
00013 Reset();
00014 }
00015
00016 char* gHAttrList::Str ()
00017 {
00018 sAttr.SetEmpty();
00019 for (short idx=1; idx<=nAttr; idx++) {
00020 gParam* pAssign = pAttrAssign[idx];
00021 ASSERTION(pAssign!=nil,"pAssign!=nil");
00022 unsigned n = pAssign->N();
00023 if ( n==0 ) continue;
00024 if ( idx>1 ) sAttr.Add( ' ' );
00025 sAttr.Add( pAssign->Str(1) );
00026 if ( n>1 ) {
00027 sAttr.Add( '=' );
00028 sAttr.Add( pAssign->Str(2) );
00029 }
00030 }
00031 return sAttr.Str();
00032 }
00033
00034 unsigned gHAttrList::N ()
00035 {
00036 ASSERTION(nAttr>=0,"nAttr>=0");
00037 return (unsigned)nAttr;
00038 }
00039
00040 gParam* gHAttrList::GetAttrParam (short iAttr)
00041 {
00042 ASSERTION(iAttr>=1 && iAttr<=nAttr,"iAttr>=1");
00043 gParam* pAssign = pAttrAssign[iAttr];
00044 ASSERTION(pAssign!=nil,"pAssign!=nil");
00045 return pAssign;
00046 }
00047
00048 char* gHAttrList::GetAttr (short iAttr)
00049 {
00050 unsigned iter, n;
00051 ASSERTION(iAttr>=1,"iAttr>=1");
00052 if ( iAttr>nAttr ) return nil;
00053 sOAttr.SetEmpty();
00054 gParam* pAssign = pAttrAssign[iAttr];
00055 for (iter=1, n=pAssign->N(); iter<=n; iter++) {
00056 sOAttr.Add( pAssign->Str(iter) );
00057 if ( iter<n ) sOAttr.Add( ' ' );
00058 }
00059 return sOAttr.Str();
00060 }
00061
00062 char* gHAttrList::GetAttrValue (short iAttr)
00063 {
00064 unsigned len;
00065
00066 // Same as GetAttr, except:
00067 // If the attribute contains quotes, then this result is merely the attribute.
00068 // Examples:
00069 // <A HREF="abc" Attr2=Val2>
00070 // There are two attributes: HREF="abc" and Attr2=Val2, i.e. nAttr=2.
00071 // The result from GetAttr and GetAttrValue is the same.
00072 // Now the statement <!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
00073 // contains 6 attributes. But typically this is encoded with quotes, like:
00074 // <!DOCTYPE HTML PUBLIC "-
00075
00076
00077
00078 if ( GetAttr(iAttr)==nil ) return nil;
00079 len = sOAttr.Length();
00080 if ( sOAttr[1]=='"' && sOAttr[len]=='"' ) {
00081 gString sTemp;
00082 sTemp.CopyFromTo( sOAttr, 2, len-1 );
00083 sOAttr = sTemp;
00084 }
00085 return sOAttr.Str();
00086 }
00087
00088 char* gHAttrList::GetAttrLValue (short iAttr)
00089 {
00090 gParam* pAssign = GetAttrParam( iAttr );
00091 return pAssign->Str( 1 );
00092 }
00093
00094 char* gHAttrList::GetAttrRValue (short iAttr)
00095 {
00096 gParam* pAssign = GetAttrParam( iAttr );
00097 return pAssign->Str( 2 );
00098 }
00099
00100 int gHAttrList::ValidateValue (char* s)
00101 {
00102
00103 ASSERTION(s!=nil,"s!=nil");
00104 gString aStr( s );
00105 return thisValidateValue( aStr );
00106 }
00107
00108 void gHAttrList::Reset ()
00109 {
00110 gControl::Reset();
00111 delete originalLst;
00112 for (short idx=1; pAttrAssign!=nil && idx<=nAttr; idx++) delete pAttrAssign[idx];
00113 delete[] pAttrAssign;
00114 nAttr = 0;
00115 }
00116
00117 void gHAttrList::Set (char* s)
00118 {
00119 lastOpError = 0;
00120 if ( s==nil ) {
00121 Reset();
00122 return;
00123 }
00124 DBGPRINT_MIN("DBG:.\nDBG: ATTR is: %s\n",s);
00125 ASSERTION(originalLst==nil,"Set(1)");
00126 originalLst = new gParam( s, " ", gParam::e_NormalQuoted );
00127 ASSERTION(originalLst!=nil,"Set(2)");
00128 nAttr = originalLst->N();
00129 ASSERTION(nAttr>=1,"Set(3): nAttr>=1");
00130
00131 pAttrAssign = new gParam*[ nAttr+1 ];
00132 pAttrAssign[ 0 ] = nil;
00133 for (short idx=1; idx<=nAttr; idx++) {
00134 gParam* pAssign;
00135 char* str = originalLst->Str(idx);
00136 char* str2 = nil;
00137 pAssign = new gParam( str, "=", gParam::e_StopSplitOnFirst );
00138 ASSERTION(pAssign!=nil,"Set(4): pAssign!=nil");
00139 pAttrAssign[idx] = pAssign;
00140 unsigned n = pAssign->N();
00141 ASSERTION(n==1 || n==2,"Set(5): n==1 || n==2");
00142 if ( n==2 ) {
00143 lastOpError += ValidateValue( str2 = pAssign->Str(2) )!=0;
00144 }
00145 else {
00146 lastOpError += ValidateValue( str )!=0;
00147 }
00148 DBGPRINT_MIN("DBG: ATTR: [%s] n=%u (IDX=%u/%u) AttrVal:[%s|%s], nerrors=%d\n",str,pAssign->N(),idx,nAttr,pAssign->Str(1),str2,lastOpError);
00149 }
00150
00151 DBGPRINT_MIN("DBG: ATTR [[end]]\n");
00152 }
00153
00154 void gHAttrList::CopyAttr (gHAttrList& copy)
00155 {
00156 if ( copy.IsEmpty() ) return;
00157 DBGPRINT_MIN("DBG:.\nDBG: ATTR [[copy]]");
00158 Set( copy.Str() );
00159 }
00160
00161 char* gHAttrList::Find (char* strAttr, bool doUnquote, gList& otherL)
00162 {
00163 short iAttr;
00164 gParam* pAttr;
00165 gString s;
00166 unsigned len;
00167
00168 for (iAttr=1; iAttr<=nAttr; iAttr++) {
00169 pAttr = pAttrAssign[ iAttr ];
00170 ASSERTION(pAttr!=nil,"pAttr!=nil");
00171 if ( gStrControl::Self().Match( strAttr, pAttr->Str(1), true ) ) {
00172 s.Set( pAttr->Str(2) );
00173 len = s.Length();
00174 sThisVal = s;
00175 if ( len<=2 ) return sThisVal.Str();
00176 if ( doUnquote ) {
00177 if ( (s[1]=='"' && s[len]=='"') ||
00178 s[1]=='\'' && s[len]=='\'' ) {
00179 sThisVal.CopyFromTo( s, 2, len-1 );
00180 }
00181 }
00182 return sThisVal.Str();
00183 }
00184 }
00185 return nil;
00186 }
00187
00188 int gHAttrList::thisValidateValue (gString& s)
00189 {
00190 unsigned len=s.Length();
00191 if ( s[1]=='=' || s[len]=='=' ) return 32;
00192
00193 return 0;
00194 }
00195
00196