///////////////////////////////////////////////// // Url-Lexical-Chars class TUrlLxChDef{ private: TBoolV IsLoAlphaV, IsHiAlphaV, IsAlphaV; TBoolV IsDigitV, IsSafeV, IsExtraV; TBoolV IsNationalV, IsPunctuationV; TBoolV IsReservedV, IsHexV; TBoolV IsUnreservedV, IsUCharV, IsXCharV; TBoolV IsSchemeV, IsHostV, IsHSegmentV; void InclCh(TBoolV& BoolV, const char& Ch); void InclStr(TBoolV& BoolV, const TStr& Str); void InclBoolV(TBoolV& BoolV, const TBoolV& OrBoolV); public: static const char EofCh; static const char EscCh; TUrlLxChDef(); bool IsDigitCh(const char& Ch) const {return (Ch>=0)&&IsDigitV[Ch];} bool IsSchemeCh(const char& Ch) const {return (Ch>=0)&&IsSchemeV[Ch];} bool IsHostCh(const char& Ch) const {return (Ch>=0)&&IsHostV[Ch];} bool IsHSegmentCh(const char& Ch) const { return (Ch<0)||((Ch>=0)&&IsHSegmentV[Ch]);} }; const char TUrlLxChDef::EofCh=0; const char TUrlLxChDef::EscCh='%'; void TUrlLxChDef::InclCh(TBoolV& BoolV, const char& Ch){BoolV[Ch]=true;} void TUrlLxChDef::InclStr(TBoolV& BoolV, const TStr& Str){ for (int CC=0; CC#%\""); InclStr(IsReservedV, ";/?:@&="); InclBoolV(IsHexV, IsDigitV); InclStr(IsHexV, "ABCDEFabcdef"); InclBoolV(IsUnreservedV, IsAlphaV); InclBoolV(IsUnreservedV, IsDigitV); InclBoolV(IsUnreservedV, IsSafeV); InclBoolV(IsUnreservedV, IsExtraV); InclBoolV(IsUCharV, IsUnreservedV); InclStr(IsUCharV, TStr(EscCh)); InclBoolV(IsXCharV, IsUnreservedV); InclBoolV(IsXCharV, IsReservedV); InclStr(IsXCharV, TStr(EscCh)); InclBoolV(IsSchemeV, IsAlphaV); InclBoolV(IsSchemeV, IsDigitV); InclStr(IsSchemeV, "+-."); InclBoolV(IsHostV, IsAlphaV); InclBoolV(IsHostV, IsDigitV); InclStr(IsHostV, "-_"); InclBoolV(IsHSegmentV, IsUCharV); InclStr(IsHSegmentV, ";:@&="); InclBoolV(IsHSegmentV, IsNationalV); InclStr(IsHSegmentV, " "); } ///////////////////////////////////////////////// // Url-Lexical class TUrlLx{ private: static const char EofCh; TChA Bf; int BfC; public: static const TUrlLxChDef ChDef; TUrlLx(const TStr& _Str): Bf(_Str), BfC(0){} bool Eof() const {return BfC==Bf.Len();}; char GetCh(){if (Eof()){return EofCh;} else {return Bf[BfC++];}} char PeekCh() const {if (Eof()){return EofCh;} else {return Bf[BfC];}} char GetCh(const char& Ch){EAssertR(GetCh()==Ch, ""); return Ch;} TStr GetStr(const TStr& Str){ for (int ChN=0; ChNIsOk(), ""); EAssertR(IsAbs(BaseUrlStr), ""); TStr AbsUrlStr=BaseUrlStr; TStr NrRelUrlStr=RelUrlStr; if (NrRelUrlStr.GetLc().IsPrefix(UrlHttpPrefixStr)){ NrRelUrlStr.DelSubStr(0, UrlHttpPrefixStr.Len()-1);} if (NrRelUrlStr.Len()>0){ if (NrRelUrlStr[0]=='/'){ TStr SlashStr; int SlashChN=0; while ((SlashChN=0)&&(AbsUrlStr[ChN]!='/')){ChN--;} AbsUrlStr.DelSubStr(ChN+1, AbsUrlStr.Len()-1); AbsUrlStr+=NrRelUrlStr; } } static const TStr PrevDirStr="/../"; {int ChN; while ((ChN=AbsUrlStr.SearchStr(PrevDirStr))!=-1){ int BChN=ChN; int EChN=ChN+PrevDirStr.Len()-1; while ((BChN-1>=0)&&(AbsUrlStr[BChN-1]!='/')){BChN--;} AbsUrlStr.DelSubStr(BChN, EChN); }} static const TStr CurDirStr="/."; while (AbsUrlStr.DelStr(CurDirStr)){} GetAbs(AbsUrlStr); } TUrl::TUrl(const TStr& _RelUrlStr, const TStr& _BaseUrlStr): Scheme(usUndef), UrlStr(), RelUrlStr(_RelUrlStr), BaseUrlStr(_BaseUrlStr), SchemeNm(), HostNm(), PortStr(), PathStr(), SearchStr(), FragIdStr(), PortN(-1), PathSegV(), IpNum(), FinalUrlStr(), FinalHostNm(), HttpRqStr(){ RelUrlStr.ToTrunc(); RelUrlStr.ChangeStrAll(" ", "%20"); try { if (IsAbs(RelUrlStr)){ GetAbs(RelUrlStr); } else if (IsAbs(BaseUrlStr)){ GetAbsFromBase(RelUrlStr, BaseUrlStr); } else { Scheme=usUndef; } } catch (PExcept&){Scheme=usUndef;} //** old version /* PUrl BaseUrl; if (!BaseUrlStr.Empty()){ // must be outside try-block (CBuilder3.0 bug) BaseUrl=TUrl::New(BaseUrlStr);} try { if (!BaseUrlStr.Empty()){ EAssertR(BaseUrl->IsOk(), "");} if (IsAbs(RelUrlStr)){ GetAbs(RelUrlStr); } else { GetAbsFromBase(RelUrlStr, BaseUrlStr); } } catch (PExcept&){Scheme=usUndef;} */ } TStr TUrl::GetDmNm(const int& MxDmSegs) const { IAssert(IsOk()); TChA DmChA; int DmSegs=0; for (int ChN=HostNm.Len()-1; ChN>=0; ChN--){ if (HostNm[ChN]=='.'){ DmSegs++; if (DmSegs==MxDmSegs){break;} else {DmChA+='.';} } else { DmChA+=HostNm[ChN]; } } DmChA.Reverse(); return DmChA; } void TUrl::DefFinalUrl(const TStr& _FinalHostNm){ IAssert(IsOk(usHttp)); IAssert(!IsDefFinalUrl()); FinalHostNm=_FinalHostNm.GetLc(); if (HostNm==FinalHostNm){ FinalUrlStr=UrlStr; } else { TChA FinalUrlChA; FinalUrlChA+=SchemeNm; FinalUrlChA+="://"; FinalUrlChA+=FinalHostNm; if (!PortStr.Empty()){ FinalUrlChA+=":"; FinalUrlChA+=PortStr;} FinalUrlChA+=PathStr; FinalUrlChA+=SearchStr; FinalUrlStr=FinalUrlChA; } } void TUrl::ToLcPath(){ // test if the conversion is needed if (!PathStr.IsLc()){ // convert path strings to lower-case PathStr.ToLc(); for (int PathSegN=0; PathSegNIsOk(usHttp) && (Url->GetPathStr()=="/") && Url->GetSearchStr().Empty() && Url->GetFragIdStr().Empty(); } PUrl TUrl::GetUrlFromShortcut(const TStr& ShortcutUrlStr, const TStr& DfHostNmPrefix, const TStr& DfHostNmSufix){ // shortcut is already correct url TStr UrlStr=ShortcutUrlStr; PUrl Url=TUrl::New(UrlStr); if (Url->IsOk()){return Url;} // add 'http://' to shortcut (if shortcut is from more segments) if (ShortcutUrlStr.IsChIn('.')){ UrlStr=TUrl::UrlHttpAbsPrefixStr+ShortcutUrlStr; Url=TUrl::New(UrlStr); if (Url->IsOk()){return Url;} } // add 'http://' and '/' to shortcut (if shortcut is from more segments) if (ShortcutUrlStr.IsChIn('.')){ UrlStr=TUrl::UrlHttpAbsPrefixStr+ShortcutUrlStr+"/"; Url=TUrl::New(UrlStr); if (Url->IsOk()){return Url;} } // add 'http://', prefix, postfix and '/' to shortcut UrlStr=UrlHttpAbsPrefixStr+ DfHostNmPrefix+"."+ShortcutUrlStr+"."+DfHostNmSufix+"/"; Url=TUrl::New(UrlStr); return Url; } TStr TUrl::GetUrlSearchStr(const TStr& Str){ TChA InChA=Str; TChA OutChA; for (int ChN=0; ChN3)&&(UcStr!="HTTP")&&(UcStr!="HTML")&&(UcStr!="INDEX")&&(UcStr!="DEFAULT")){ for (int CopyN=0; CopyNIsOk()){ TStr HostNm=Url->GetHostNm().GetLc(); TStrV HostNmSegV; HostNm.SplitOnAllCh('.', HostNmSegV, false); for (int HostNmSegN=0; HostNmSegN0){DocNm+='.';} DocNm+=HostNmSegV[HostNmSegV.Len()-HostNmSegN-1]; } if (!HostOnlyP){ DocNm+=Url->GetPathStr().GetLc(); } } else { DocNm=UrlStr.GetLc(); } if (MxLen!=-1){ DocNm.Trunc(MxLen);} return DocNm; } ///////////////////////////////////////////////// // Url-Search-Environment TStr TUrlEnv::GetFullUrlStr() const { if (GetKeys()==0){return TStr();} TChA SearchChA; SearchChA+=BaseUrlStr; SearchChA+="?"; int KeyVals=0; for (int KeyN=0; KeyN0){SearchChA+="&";} SearchChA+=TUrl::GetUrlSearchStr(KeyNm); SearchChA+='='; SearchChA+=TUrl::GetUrlSearchStr(ValStrV[ValStrN]); KeyVals++; } } return SearchChA; } PUrlEnv TUrlEnv::MkClone(const PUrlEnv& UrlEnv){ PUrlEnv CloneUrlEnv= PUrlEnv(new TUrlEnv(*UrlEnv)); return CloneUrlEnv; }