gdSnarfCont.cpp

Go to the documentation of this file.
00001 #include "gdSnarfCont.h"  // Snarf-contents
00002 #include "gHtmlCtrl.h"
00003 #include "gstringext.h"
00004 ////////////////////////////////////////////////////////////
00005 gdHCouple::gdHCouple (unsigned lineNr)
00006     : gHtmlCouple( lineNr, nil )
00007 {
00008 }
00009 
00010 gdHCouple::gdHCouple (unsigned lineNr, char* sText)
00011     : gHtmlCouple( lineNr, sText )
00012 {
00013 }
00014 
00015 gdHCouple::gdHCouple (unsigned lineNr, char* strTag, char* sAttrLst)
00016     : gHtmlCouple( lineNr, strTag==nil ? nil : strTag+(strTag[0]=='/'), sAttrLst )
00017 {
00018  // strTag not nil, asserted by: gHtmlCouple::AddTag
00019  thisInitTag( strTag[0]=='/' );
00020 }
00021 
00022 gdHCouple::~gdHCouple ()
00023 {
00024 }
00025 
00026 bool gdHCouple::IsOk ()
00027 {
00028  if ( attrs.IsOk()==false ) return false;
00029  return gHtmlCouple::IsOk();
00030 }
00031 
00032 char* gdHCouple::GetStr ()
00033 {
00034  // Redefinition of gHtmlCouple
00035  ;
00036  unsigned iAttr, nAttrs;
00037  char* strL;
00038  char* strR;
00039 
00040  sWholeTag.SetEmpty();
00041  if ( IsText() ) {
00042      if ( pHStr==nil ) return Str(1);
00043      return pHStr->Str();
00044  }
00045  sWholeTag.Add( '<' );
00046  if ( IsTagEnd() ) sWholeTag.Add( '/' );
00047  sWholeTag.AddString( sTag );
00048  ;
00049  for (iAttr=1, nAttrs=attrs.N(); iAttr<=nAttrs; iAttr++) {
00050      strL = attrs.GetAttrValue( iAttr ).Str();
00051      strR = attrs.GetAttr( iAttr ).GetStr();
00052      //printf("ATTRLIST=%u:",nAttrs);attrs.Show(true);printf(".{%s=%s}\n",attrs.GetAttrValue(1).Str(),attrs.GetAttr(1).GetStr());printf("DBG:LST-end!\n");
00053      sWholeTag.Add( ' ' );
00054      sWholeTag.Add( strL );
00055      if ( strR!=nil && strR[0]!=0 ) {
00056          sWholeTag.Add( '=' );
00057          sWholeTag.Add( '"' );
00058          sWholeTag.Add( strR );
00059          sWholeTag.Add( '"' );
00060      }
00061  }
00062  sWholeTag.Add( '>' );
00063  return sWholeTag.Str();
00064 }
00065 
00066 sHtmlElement* gdHCouple::GetTagElement (t_int16 idxTag)
00067 {
00068  sHtmlElement* ptrElem;
00069 
00070  ptrElem = gHtmlCtrl::Self().ParserPtr()->GetTagElement( idxTag );
00071  // Only difference to gHtmlParser: the assertion below
00072  ASSERTION(ptrElem!=nil,"ptrElem!=nil");
00073  return ptrElem;
00074 }
00075 
00076 char* gdHCouple::TagStr (bool forceEnd)
00077 {
00078  // Note: 'sTagStr' from gHtmlCouple is allocated: this return is valid
00079  return TagString( forceEnd ).Str();
00080 }
00081 
00082 int gdHCouple::FindTagIdx (char* strTag, t_int16& idxTag)
00083 {
00084  return gHtmlCtrl::Self().ParserPtr()->FindTagIdx( strTag, idxTag );
00085 }
00086 
00087 char* gdHCouple::GetHRef ()
00088 {
00089  if ( idTag!=XH_IDTAG_ANCHOR ) return nil;
00090  gHAType* pValue = attrs.GetAttrPtr( 1 );
00091  if ( pValue==nil ) return nil;
00092  if ( pValue->GetType()!=e_HATp_URI ) return nil;
00093  return pValue->GetStr();
00094 }
00095 
00096 int gdHCouple::CopyNormalizeAttr (char* strTag, t_int16 idxTag, gHAttrList& copyL)
00097 {
00098  // Return 0 if no attribute has a basic error
00099  ;
00100  short i, iOk, n=copyL.NAttr();
00101  short k, kN;
00102  char* str;
00103  char* strL, *strR;
00104  gString* sLVal, *sRVal;
00105  gList lLVal, lRVal;
00106  FILE* fErr = gHtmlCtrl::Self().hLog.fRepErr;
00107  gHtmlParser* pParser = gHtmlCtrl::Self().ParserPtr();
00108 
00109  t_int16 idx, uniqIdx;
00110  sAttrRefer* lstAttrRef = pParser->GetAttrRef();
00111  sAttrDef* dAttr;
00112 
00113  ASSERTION(idxTag>=0,"AttrNorm(0)");
00114 
00115  // Copy is only allowed if current list is empty
00116  ASSERTION(attrs.N()==0,"AttrNorm(1)");
00117 
00118  sLVal = new gString[ n+1 ];
00119  sRVal = new gString[ n+1 ];
00120  ASSERTION(sLVal!=nil && sRVal!=nil,"AttrNorm(2)");
00121 
00122  for (i=1, iOk=0; i<=n; i++) {
00123      strL = copyL.GetAttrLValue( i );
00124      strR = copyL.GetAttrRValue( i );
00125      ASSERTION(strL!=nil,"strL!=nil");
00126      // Check if attr 'strL' (LValue of assignment, e.g. HREF=uri, strL="HREF")
00127      // is o.k. for the tag
00128      idx = lstAttrRef->FindAttr( strL, strTag, uniqIdx );
00129      // If the attribute exists, but not suited for that tag, then uniqIdx>=0.
00130      if ( uniqIdx<0 ) {
00131          if ( gStrControl::Self().Match(strL,"/") )
00132              HTML_LOG( fErr, LOG_NOTICE, "Line %u: attribute not DTD: '%s'\n", iLine, strL );
00133          else
00134              HTML_LOG( fErr, LOG_ERROR, "Line %u: invalid attribute: '%s'\n", iLine, strL );
00135          continue;
00136      }
00137      else {
00138          if ( idx<0 ) {
00139              HTML_LOG( fErr, LOG_ERROR, "Line %u: attribute '%s' not valid for tag: %s\n", iLine, strL, strTag );
00140              //fprintf(stderr,"DBG: sOutHelper=[@(All-tags-but):%s,...]\n",lstAttrRef->sOutHelper.Str());
00141              continue;
00142          }
00143      }
00144      ASSERTION(idx>=0,"idx>=0");
00145      dAttr = pParser->GetAttrDef( idx );
00146      // ...or if
00147      // is to be skipped
00148      if ( dAttr->ctrl==XH_SKIP_ATTR ) {
00149          HTML_LOG( fErr, LOG_NOTICE, "Line %u: attribute '%s' skipped (tag: %s)\n", iLine, strL, strTag );
00150          continue;
00151      }
00152      iOk++;
00153      sLVal[ iOk ].Set( strL );
00154      sRVal[ iOk ].Set( strR );
00155  }
00156 
00157  //printf("DBG: LOG_ERROR:\n");log.lLog[LOG_ERROR].Show(true);printf("DBG: LOG_ERROR-END.\n");
00158  //printf("DBG: LOG_NOTICE:\n");log.lLog[LOG_NOTICE].Show(true);printf("DBG: LOG_NOTICE-END.\n");
00159 
00160  // Copy attributes from the order specified in gHOutOpt::lAttrsNorm (struct sAttrsTagNorm)
00161  gSmartList* lstNorms = pParser->htmlOpt.outOpt.lAttrsNorm.lstNorms;
00162  gSmartList* pList = nil;
00163 
00164  ASSERTION(lstNorms!=nil,"AttrNorm(4):temporary");
00165  if ( lstNorms!=nil ) {
00166      pList = &lstNorms[ idxTag ];
00167  }
00168 
00169  if ( pList!=nil ) {
00170      for (k=1, kN=pList->N(); k<=kN; k++) {
00171          str = pList->Str( k );
00172          for (i=1; i<=iOk; i++) {
00173              if ( sLVal[ i ].Match( str ) ) {
00174                  strR = sRVal[ i ].Str();
00175                  lLVal.Add( str );
00176                  lRVal.Add( strR );
00177                  sLVal[ i ].SetEmpty();
00178              }
00179          }
00180      }
00181  }
00182 
00183  // We have copied by order, the norm'ed attrs, now copy remaining
00184  for (i=1; i<=iOk; i++) {
00185      if ( sLVal[ i ].IsEmpty() ) continue;
00186      lLVal.Add( sLVal[ i ] );
00187      lRVal.Add( sRVal[ i ] );
00188  }
00189 
00190  delete[] sLVal;
00191  delete[] sRVal;
00192 
00193  gControl logValues;
00194  attrs.BuildFromLRLists( strTag, lLVal, lRVal, false, iLine );
00195 
00196  return 0;
00197 }
00198 
00199 void gdHCouple::Show (bool doShowAll)
00200 {
00201  DBGPRINT_WEBA1("DBG: gdHCouple::Show%s (N=%u)\n",doShowAll?":ALL":"\0",N());
00202  if ( doShowAll ) {
00203      printf("gdHCouple:START:\n");
00204  }
00205  gHtmlCouple::Show( doShowAll );
00206  if ( doShowAll ) {
00207      attrs.Show( true );
00208      printf("gdHCouple:END.\n");
00209  }
00210 }
00211 
00212 int gdHCouple::thisInitTag (bool isEndTag)
00213 {
00214  char* strTag = sTag.Str();
00215  idEndTag = isEndTag ? XH_ENDTAG : 0;
00216  if ( FindTagIdx( strTag, idTag )<0 ) return -1;
00217  pElem = GetTagElement( idTag );
00218  // From here, pElem points correctly
00219  ASSERTION(pElem!=nil,"pElem!=nil");
00220  return 0;
00221 }
00222 ////////////////////////////////////////////////////////////
00223 gdSnarfCont::gdSnarfCont (gHtmlOpt* pHtmlOpt)
00224 {
00225  if ( pHtmlOpt==nil ) pHtmlOpt = new gHtmlOpt;
00226  ASSERTION(pHtmlOpt!=nil,"pHtmlOpt!=nil");
00227  pHtmlOpt->outOpt.aTidy.doTidyAll = true;  // Tidy all tags&attrs by default
00228  SetHtmlOpt( pHtmlOpt );
00229 }
00230 
00231 gdSnarfCont::~gdSnarfCont ()
00232 {
00233  delete theHtmlOpt;
00234  theHtmlOpt = nil;
00235 }
00236 
00237 gdHCouple* gdSnarfCont::GetOCouple (unsigned idx)
00238 {
00239  gHtmlCouple* pObjC = GetCouple( idx );
00240  gdHCouple* pHObjC;
00241  if ( pObjC==nil ) return nil;
00242  pHObjC = (gdHCouple*)pObjC->oCouple;
00243  return pHObjC;
00244 }
00245 
00246 char* gdSnarfCont::Str (unsigned idx)
00247 {
00248  // Redefinition of gHtmlContent
00249  gHtmlCouple* pObjC = GetCouple( idx );
00250  gdHCouple* pHObjC;
00251  if ( pObjC==nil ) return nil;
00252  pHObjC = (gdHCouple*)pObjC->oCouple;
00253  if ( pHObjC==nil ) return pObjC->GetStr();
00254  return pHObjC->GetStr();
00255 }
00256 
00257 unsigned gdSnarfCont::Add (char* s)
00258 {
00259  // Returns 0 on error, or the actual number of lines.
00260  // This method allows to:
00261  //   add a complete tag line (e.g. "<A HREF=abc>")
00262  ;
00263  // It is very similar to its parent, but also sets the
00264  // couple idTag and 'pElem' correctly.
00265  ;
00266  unsigned uResult;
00267  gHtmlCouple* pCouple;
00268  gdHCouple* pNewCouple;
00269  char* strTag;
00270  t_int16 idxTag=XH_NOTAG;
00271 
00272  uResult = gHtmlContent::Add( s );
00273  if ( uResult==0 ) return 0;
00274 
00275  pCouple = (gHtmlCouple*)GetLastObjectPtr();
00276  ASSERTION(pCouple!=nil,"pCouple!=nil");
00277 
00278  if ( pCouple->IsText() ) return uResult;
00279 
00280  strTag = pCouple->sTag.Str();
00281 
00282  // If pCouple contains two entries, the second entry contains all attributes
00283  // pNewCouple = new gdHCouple( uResult, strTag, pCouple->N()<=1 ? nil : pCouple->Str(2) );
00284 
00285  pNewCouple = new gdHCouple( uResult, strTag, nil );  // No attributes (nil)
00286  ASSERTION(pNewCouple!=nil,"pNewCouple!=nil");
00287  if ( pNewCouple->FindTagIdx( strTag, idxTag )<0 ) {
00288      pCouple->synError = -1;
00289      delete pNewCouple;
00290      return 0;
00291  }
00292 
00293  ASSERTION(idxTag>=0,"idxTag>=0");
00294 
00295  pCouple->idTag = idxTag;
00296  pCouple->pElem = pNewCouple->GetTagElement( idxTag );
00297 
00298  ASSERTION(pCouple->oCouple==nil,"pCouple->oCouple==nil");
00299  if ( pCouple->IsTagEnd() ) {
00300      // Check if there are no attributes.
00301      // If no check was made, then these attrs would be silently discarded...
00302      delete pNewCouple;
00303      if ( pCouple->attrL.N()>0 ) {
00304          HTML_LOG( nil, LOG_WARNING, "Line %u: tag-end (%s) with %u attribute(s)\n",
00305                    uResult, strTag, pCouple->attrL.N() );
00306      }
00307  }
00308  else {
00309      // Syntax o.k. (and it's a starting tag)
00310      pNewCouple->CopyNormalizeAttr( strTag, idxTag, pCouple->attrL );
00311      pCouple->oCouple = pNewCouple;
00312  }
00313 
00314  return uResult;
00315 }
00316 
00317 int gdSnarfCont::AddFromStr (char* s)
00318 {
00319  // Returns 0 on success
00320  return Add( s )==0;
00321 }
00322 
00323 int gdSnarfCont::AddFromString (gString& aS)
00324 {
00325  return AddFromStr( aS.Str() );
00326 }
00327 
00328 int gdSnarfCont::AddFromList (gList& aL)
00329 {
00330  unsigned i, n;
00331 
00332  for (i=1, n=aL.N(); i<=n; i++) {
00333      gString s( aL.Str( i ) );
00334      AddFromString( s );
00335  }
00336  return 0;
00337 }
00338 ////////////////////////////////////////////////////////////
00339 

Generated on Sat Aug 18 02:40:52 2007 for xpfweb_v2x lib by  doxygen 1.4.2