1*40df464eSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*40df464eSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*40df464eSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*40df464eSAndrew Rist * distributed with this work for additional information 6*40df464eSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*40df464eSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*40df464eSAndrew Rist * "License"); you may not use this file except in compliance 9*40df464eSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*40df464eSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*40df464eSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*40df464eSAndrew Rist * software distributed under the License is distributed on an 15*40df464eSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*40df464eSAndrew Rist * KIND, either express or implied. See the License for the 17*40df464eSAndrew Rist * specific language governing permissions and limitations 18*40df464eSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*40df464eSAndrew Rist *************************************************************/ 21*40df464eSAndrew Rist 22*40df464eSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svl.hxx" 26cdf0e10cSrcweir #include <svl/inethist.hxx> 27cdf0e10cSrcweir 28cdf0e10cSrcweir #ifndef INCLUDED_ALGORITHM 29cdf0e10cSrcweir #include <algorithm> 30cdf0e10cSrcweir #define INCLUDED_ALGORITHM 31cdf0e10cSrcweir #endif 32cdf0e10cSrcweir #include "rtl/instance.hxx" 33cdf0e10cSrcweir #include "rtl/crc.h" 34cdf0e10cSrcweir #include "rtl/memory.h" 35cdf0e10cSrcweir #include <tools/solar.h> 36cdf0e10cSrcweir #include <tools/debug.hxx> 37cdf0e10cSrcweir #include <tools/string.hxx> 38cdf0e10cSrcweir #include <tools/urlobj.hxx> 39cdf0e10cSrcweir 40cdf0e10cSrcweir /*======================================================================== 41cdf0e10cSrcweir * 42cdf0e10cSrcweir * INetURLHistory internals. 43cdf0e10cSrcweir * 44cdf0e10cSrcweir *======================================================================*/ 45cdf0e10cSrcweir #define INETHIST_DEF_FTP_PORT 21 46cdf0e10cSrcweir #define INETHIST_DEF_HTTP_PORT 80 47cdf0e10cSrcweir #define INETHIST_DEF_HTTPS_PORT 443 48cdf0e10cSrcweir 49cdf0e10cSrcweir #define INETHIST_SIZE_LIMIT 1024 50cdf0e10cSrcweir #define INETHIST_MAGIC_HEAD 0x484D4849UL 51cdf0e10cSrcweir 52cdf0e10cSrcweir /* 53cdf0e10cSrcweir * INetURLHistoryHint implementation. 54cdf0e10cSrcweir */ 55cdf0e10cSrcweir IMPL_PTRHINT (INetURLHistoryHint, const INetURLObject); 56cdf0e10cSrcweir 57cdf0e10cSrcweir /*======================================================================== 58cdf0e10cSrcweir * 59cdf0e10cSrcweir * INetURLHistory_Impl interface. 60cdf0e10cSrcweir * 61cdf0e10cSrcweir *======================================================================*/ 62cdf0e10cSrcweir class INetURLHistory_Impl 63cdf0e10cSrcweir { 64cdf0e10cSrcweir /** head_entry. 65cdf0e10cSrcweir */ 66cdf0e10cSrcweir struct head_entry 67cdf0e10cSrcweir { 68cdf0e10cSrcweir /** Representation. 69cdf0e10cSrcweir */ 70cdf0e10cSrcweir sal_uInt32 m_nMagic; 71cdf0e10cSrcweir sal_uInt16 m_nNext; 72cdf0e10cSrcweir sal_uInt16 m_nMBZ; 73cdf0e10cSrcweir 74cdf0e10cSrcweir /** Initialization. 75cdf0e10cSrcweir */ 76cdf0e10cSrcweir void initialize (void) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir m_nMagic = INETHIST_MAGIC_HEAD; 79cdf0e10cSrcweir m_nNext = 0; 80cdf0e10cSrcweir m_nMBZ = 0; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir }; 83cdf0e10cSrcweir 84cdf0e10cSrcweir /** hash_entry. 85cdf0e10cSrcweir */ 86cdf0e10cSrcweir struct hash_entry 87cdf0e10cSrcweir { 88cdf0e10cSrcweir /** Representation. 89cdf0e10cSrcweir */ 90cdf0e10cSrcweir sal_uInt32 m_nHash; 91cdf0e10cSrcweir sal_uInt16 m_nLru; 92cdf0e10cSrcweir sal_uInt16 m_nMBZ; 93cdf0e10cSrcweir 94cdf0e10cSrcweir /** Initialization. 95cdf0e10cSrcweir */ 96cdf0e10cSrcweir void initialize (sal_uInt16 nLru, sal_uInt32 nHash = 0) 97cdf0e10cSrcweir { 98cdf0e10cSrcweir m_nHash = nHash; 99cdf0e10cSrcweir m_nLru = nLru; 100cdf0e10cSrcweir m_nMBZ = 0; 101cdf0e10cSrcweir } 102cdf0e10cSrcweir 103cdf0e10cSrcweir /** Comparison. 104cdf0e10cSrcweir */ 105cdf0e10cSrcweir sal_Bool operator== (const hash_entry &rOther) const 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return (m_nHash == rOther.m_nHash); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir sal_Bool operator< (const hash_entry &rOther) const 110cdf0e10cSrcweir { 111cdf0e10cSrcweir return (m_nHash < rOther.m_nHash); 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir sal_Bool operator== (sal_uInt32 nHash) const 115cdf0e10cSrcweir { 116cdf0e10cSrcweir return (m_nHash == nHash); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir sal_Bool operator< (sal_uInt32 nHash) const 119cdf0e10cSrcweir { 120cdf0e10cSrcweir return (m_nHash < nHash); 121cdf0e10cSrcweir } 122cdf0e10cSrcweir }; 123cdf0e10cSrcweir 124cdf0e10cSrcweir /** lru_entry. 125cdf0e10cSrcweir */ 126cdf0e10cSrcweir struct lru_entry 127cdf0e10cSrcweir { 128cdf0e10cSrcweir /** Representation. 129cdf0e10cSrcweir */ 130cdf0e10cSrcweir sal_uInt32 m_nHash; 131cdf0e10cSrcweir sal_uInt16 m_nNext; 132cdf0e10cSrcweir sal_uInt16 m_nPrev; 133cdf0e10cSrcweir 134cdf0e10cSrcweir /** Initialization. 135cdf0e10cSrcweir */ 136cdf0e10cSrcweir void initialize (sal_uInt16 nThis, sal_uInt32 nHash = 0) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir m_nHash = nHash; 139cdf0e10cSrcweir m_nNext = nThis; 140cdf0e10cSrcweir m_nPrev = nThis; 141cdf0e10cSrcweir } 142cdf0e10cSrcweir }; 143cdf0e10cSrcweir 144cdf0e10cSrcweir /** Representation. 145cdf0e10cSrcweir */ 146cdf0e10cSrcweir head_entry m_aHead; 147cdf0e10cSrcweir hash_entry m_pHash[INETHIST_SIZE_LIMIT]; 148cdf0e10cSrcweir lru_entry m_pList[INETHIST_SIZE_LIMIT]; 149cdf0e10cSrcweir 150cdf0e10cSrcweir /** Initialization. 151cdf0e10cSrcweir */ 152cdf0e10cSrcweir void initialize (void); 153cdf0e10cSrcweir 154cdf0e10cSrcweir void downheap (hash_entry a[], sal_uInt16 n, sal_uInt16 k); 155cdf0e10cSrcweir void heapsort (hash_entry a[], sal_uInt16 n); 156cdf0e10cSrcweir 157cdf0e10cSrcweir /** capacity. 158cdf0e10cSrcweir */ 159cdf0e10cSrcweir sal_uInt16 capacity (void) const 160cdf0e10cSrcweir { 161cdf0e10cSrcweir return (sal_uInt16)(INETHIST_SIZE_LIMIT); 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir /** crc32. 165cdf0e10cSrcweir */ 166cdf0e10cSrcweir sal_uInt32 crc32 (UniString const & rData) const 167cdf0e10cSrcweir { 168cdf0e10cSrcweir return rtl_crc32 (0, rData.GetBuffer(), rData.Len() * sizeof(sal_Unicode)); 169cdf0e10cSrcweir } 170cdf0e10cSrcweir 171cdf0e10cSrcweir /** find. 172cdf0e10cSrcweir */ 173cdf0e10cSrcweir sal_uInt16 find (sal_uInt32 nHash) const; 174cdf0e10cSrcweir 175cdf0e10cSrcweir /** move. 176cdf0e10cSrcweir */ 177cdf0e10cSrcweir void move (sal_uInt16 nSI, sal_uInt16 nDI); 178cdf0e10cSrcweir 179cdf0e10cSrcweir /** backlink. 180cdf0e10cSrcweir */ 181cdf0e10cSrcweir void backlink (sal_uInt16 nThis, sal_uInt16 nTail) 182cdf0e10cSrcweir { 183cdf0e10cSrcweir register lru_entry &rThis = m_pList[nThis]; 184cdf0e10cSrcweir register lru_entry &rTail = m_pList[nTail]; 185cdf0e10cSrcweir 186cdf0e10cSrcweir rTail.m_nNext = nThis; 187cdf0e10cSrcweir rTail.m_nPrev = rThis.m_nPrev; 188cdf0e10cSrcweir rThis.m_nPrev = nTail; 189cdf0e10cSrcweir m_pList[rTail.m_nPrev].m_nNext = nTail; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir /** unlink. 193cdf0e10cSrcweir */ 194cdf0e10cSrcweir void unlink (sal_uInt16 nThis) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir register lru_entry &rThis = m_pList[nThis]; 197cdf0e10cSrcweir 198cdf0e10cSrcweir m_pList[rThis.m_nPrev].m_nNext = rThis.m_nNext; 199cdf0e10cSrcweir m_pList[rThis.m_nNext].m_nPrev = rThis.m_nPrev; 200cdf0e10cSrcweir rThis.m_nNext = nThis; 201cdf0e10cSrcweir rThis.m_nPrev = nThis; 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204cdf0e10cSrcweir /** Not implemented. 205cdf0e10cSrcweir */ 206cdf0e10cSrcweir INetURLHistory_Impl (const INetURLHistory_Impl&); 207cdf0e10cSrcweir INetURLHistory_Impl& operator= (const INetURLHistory_Impl&); 208cdf0e10cSrcweir 209cdf0e10cSrcweir public: 210cdf0e10cSrcweir INetURLHistory_Impl (void); 211cdf0e10cSrcweir ~INetURLHistory_Impl (void); 212cdf0e10cSrcweir 213cdf0e10cSrcweir /** putUrl/queryUrl. 214cdf0e10cSrcweir */ 215cdf0e10cSrcweir void putUrl (const String &rUrl); 216cdf0e10cSrcweir sal_Bool queryUrl (const String &rUrl); 217cdf0e10cSrcweir }; 218cdf0e10cSrcweir 219cdf0e10cSrcweir /*======================================================================== 220cdf0e10cSrcweir * 221cdf0e10cSrcweir * INetURLHistory_Impl implementation. 222cdf0e10cSrcweir * 223cdf0e10cSrcweir *======================================================================*/ 224cdf0e10cSrcweir /* 225cdf0e10cSrcweir * INetURLHistory_Impl. 226cdf0e10cSrcweir */ 227cdf0e10cSrcweir INetURLHistory_Impl::INetURLHistory_Impl (void) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir initialize(); 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir /* 233cdf0e10cSrcweir * ~INetURLHistory_Impl. 234cdf0e10cSrcweir */ 235cdf0e10cSrcweir INetURLHistory_Impl::~INetURLHistory_Impl (void) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir } 238cdf0e10cSrcweir 239cdf0e10cSrcweir /* 240cdf0e10cSrcweir * initialize. 241cdf0e10cSrcweir */ 242cdf0e10cSrcweir void INetURLHistory_Impl::initialize (void) 243cdf0e10cSrcweir { 244cdf0e10cSrcweir m_aHead.initialize(); 245cdf0e10cSrcweir 246cdf0e10cSrcweir sal_uInt16 i, n = capacity(); 247cdf0e10cSrcweir for (i = 0; i < n; i++) 248cdf0e10cSrcweir m_pHash[i].initialize(i); 249cdf0e10cSrcweir for (i = 0; i < n; i++) 250cdf0e10cSrcweir m_pList[i].initialize(i); 251cdf0e10cSrcweir for (i = 1; i < n; i++) 252cdf0e10cSrcweir backlink (m_aHead.m_nNext, i); 253cdf0e10cSrcweir } 254cdf0e10cSrcweir 255cdf0e10cSrcweir /* 256cdf0e10cSrcweir * downheap. 257cdf0e10cSrcweir */ 258cdf0e10cSrcweir void INetURLHistory_Impl::downheap (hash_entry a[], sal_uInt16 n, sal_uInt16 k) 259cdf0e10cSrcweir { 260cdf0e10cSrcweir hash_entry h = a[k]; 261cdf0e10cSrcweir while (k < n / 2) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir sal_uInt16 i = k + k + 1; 264cdf0e10cSrcweir if (((i + 1) < n) && (a[i] < a[i + 1])) i++; 265cdf0e10cSrcweir if (!(h < a[i])) break; 266cdf0e10cSrcweir a[k] = a[i]; 267cdf0e10cSrcweir k = i; 268cdf0e10cSrcweir } 269cdf0e10cSrcweir a[k] = h; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir 272cdf0e10cSrcweir /* 273cdf0e10cSrcweir * heapsort. 274cdf0e10cSrcweir */ 275cdf0e10cSrcweir void INetURLHistory_Impl::heapsort (hash_entry a[], sal_uInt16 n) 276cdf0e10cSrcweir { 277cdf0e10cSrcweir hash_entry h; 278cdf0e10cSrcweir 279cdf0e10cSrcweir for (sal_uInt16 k = (n - 1) / 2 + 1; k > 0; k--) 280cdf0e10cSrcweir downheap (a, n, k - 1); 281cdf0e10cSrcweir 282cdf0e10cSrcweir while (n > 0) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir h = a[0 ]; 285cdf0e10cSrcweir a[0 ] = a[n - 1]; 286cdf0e10cSrcweir a[n - 1] = h; 287cdf0e10cSrcweir downheap (a, --n, 0); 288cdf0e10cSrcweir } 289cdf0e10cSrcweir } 290cdf0e10cSrcweir 291cdf0e10cSrcweir /* 292cdf0e10cSrcweir * find. 293cdf0e10cSrcweir */ 294cdf0e10cSrcweir sal_uInt16 INetURLHistory_Impl::find (sal_uInt32 nHash) const 295cdf0e10cSrcweir { 296cdf0e10cSrcweir sal_uInt16 l = 0; 297cdf0e10cSrcweir sal_uInt16 r = capacity() - 1; 298cdf0e10cSrcweir sal_uInt16 c = capacity(); 299cdf0e10cSrcweir 300cdf0e10cSrcweir while ((l < r) && (r < c)) 301cdf0e10cSrcweir { 302cdf0e10cSrcweir sal_uInt16 m = (l + r) / 2; 303cdf0e10cSrcweir if (m_pHash[m] == nHash) 304cdf0e10cSrcweir return m; 305cdf0e10cSrcweir 306cdf0e10cSrcweir if (m_pHash[m] < nHash) 307cdf0e10cSrcweir l = m + 1; 308cdf0e10cSrcweir else 309cdf0e10cSrcweir r = m - 1; 310cdf0e10cSrcweir } 311cdf0e10cSrcweir return l; 312cdf0e10cSrcweir } 313cdf0e10cSrcweir 314cdf0e10cSrcweir /* 315cdf0e10cSrcweir * move. 316cdf0e10cSrcweir */ 317cdf0e10cSrcweir void INetURLHistory_Impl::move (sal_uInt16 nSI, sal_uInt16 nDI) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir hash_entry e = m_pHash[nSI]; 320cdf0e10cSrcweir if (nSI < nDI) 321cdf0e10cSrcweir { 322cdf0e10cSrcweir // shift left. 323cdf0e10cSrcweir rtl_moveMemory ( 324cdf0e10cSrcweir &m_pHash[nSI ], 325cdf0e10cSrcweir &m_pHash[nSI + 1], 326cdf0e10cSrcweir (nDI - nSI) * sizeof(hash_entry)); 327cdf0e10cSrcweir } 328cdf0e10cSrcweir if (nSI > nDI) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir // shift right. 331cdf0e10cSrcweir rtl_moveMemory ( 332cdf0e10cSrcweir &m_pHash[nDI + 1], 333cdf0e10cSrcweir &m_pHash[nDI ], 334cdf0e10cSrcweir (nSI - nDI) * sizeof(hash_entry)); 335cdf0e10cSrcweir } 336cdf0e10cSrcweir m_pHash[nDI] = e; 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir /* 340cdf0e10cSrcweir * putUrl. 341cdf0e10cSrcweir */ 342cdf0e10cSrcweir void INetURLHistory_Impl::putUrl (const String &rUrl) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir sal_uInt32 h = crc32 (rUrl); 345cdf0e10cSrcweir sal_uInt16 k = find (h); 346cdf0e10cSrcweir if ((k < capacity()) && (m_pHash[k] == h)) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir // Cache hit. 349cdf0e10cSrcweir sal_uInt16 nMRU = m_pHash[k].m_nLru; 350cdf0e10cSrcweir if (nMRU != m_aHead.m_nNext) 351cdf0e10cSrcweir { 352cdf0e10cSrcweir // Update LRU chain. 353cdf0e10cSrcweir unlink (nMRU); 354cdf0e10cSrcweir backlink (m_aHead.m_nNext, nMRU); 355cdf0e10cSrcweir 356cdf0e10cSrcweir // Rotate LRU chain. 357cdf0e10cSrcweir m_aHead.m_nNext = m_pList[m_aHead.m_nNext].m_nPrev; 358cdf0e10cSrcweir } 359cdf0e10cSrcweir } 360cdf0e10cSrcweir else 361cdf0e10cSrcweir { 362cdf0e10cSrcweir // Cache miss. Obtain least recently used. 363cdf0e10cSrcweir sal_uInt16 nLRU = m_pList[m_aHead.m_nNext].m_nPrev; 364cdf0e10cSrcweir 365cdf0e10cSrcweir sal_uInt16 nSI = find (m_pList[nLRU].m_nHash); 366cdf0e10cSrcweir if (!(nLRU == m_pHash[nSI].m_nLru)) 367cdf0e10cSrcweir { 368cdf0e10cSrcweir // Update LRU chain. 369cdf0e10cSrcweir nLRU = m_pHash[nSI].m_nLru; 370cdf0e10cSrcweir unlink (nLRU); 371cdf0e10cSrcweir backlink (m_aHead.m_nNext, nLRU); 372cdf0e10cSrcweir } 373cdf0e10cSrcweir 374cdf0e10cSrcweir // Rotate LRU chain. 375cdf0e10cSrcweir m_aHead.m_nNext = m_pList[m_aHead.m_nNext].m_nPrev; 376cdf0e10cSrcweir 377cdf0e10cSrcweir // Check source and destination. 378cdf0e10cSrcweir sal_uInt16 nDI = std::min (k, sal_uInt16(capacity() - 1)); 379cdf0e10cSrcweir if (nSI < nDI) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir if (!(m_pHash[nDI] < h)) 382cdf0e10cSrcweir nDI -= 1; 383cdf0e10cSrcweir } 384cdf0e10cSrcweir if (nDI < nSI) 385cdf0e10cSrcweir { 386cdf0e10cSrcweir if (m_pHash[nDI] < h) 387cdf0e10cSrcweir nDI += 1; 388cdf0e10cSrcweir } 389cdf0e10cSrcweir 390cdf0e10cSrcweir // Assign data. 391cdf0e10cSrcweir m_pList[m_aHead.m_nNext].m_nHash = m_pHash[nSI].m_nHash = h; 392cdf0e10cSrcweir move (nSI, nDI); 393cdf0e10cSrcweir } 394cdf0e10cSrcweir } 395cdf0e10cSrcweir 396cdf0e10cSrcweir /* 397cdf0e10cSrcweir * queryUrl. 398cdf0e10cSrcweir */ 399cdf0e10cSrcweir sal_Bool INetURLHistory_Impl::queryUrl (const String &rUrl) 400cdf0e10cSrcweir { 401cdf0e10cSrcweir sal_uInt32 h = crc32 (rUrl); 402cdf0e10cSrcweir sal_uInt16 k = find (h); 403cdf0e10cSrcweir if ((k < capacity()) && (m_pHash[k] == h)) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir // Cache hit. 406cdf0e10cSrcweir return sal_True; 407cdf0e10cSrcweir } 408cdf0e10cSrcweir else 409cdf0e10cSrcweir { 410cdf0e10cSrcweir // Cache miss. 411cdf0e10cSrcweir return sal_False; 412cdf0e10cSrcweir } 413cdf0e10cSrcweir } 414cdf0e10cSrcweir 415cdf0e10cSrcweir /*======================================================================== 416cdf0e10cSrcweir * 417cdf0e10cSrcweir * INetURLHistory::StaticInstance implementation. 418cdf0e10cSrcweir * 419cdf0e10cSrcweir *======================================================================*/ 420cdf0e10cSrcweir INetURLHistory * INetURLHistory::StaticInstance::operator ()() 421cdf0e10cSrcweir { 422cdf0e10cSrcweir static INetURLHistory g_aInstance; 423cdf0e10cSrcweir return &g_aInstance; 424cdf0e10cSrcweir } 425cdf0e10cSrcweir 426cdf0e10cSrcweir /*======================================================================== 427cdf0e10cSrcweir * 428cdf0e10cSrcweir * INetURLHistory implementation. 429cdf0e10cSrcweir * 430cdf0e10cSrcweir *======================================================================*/ 431cdf0e10cSrcweir /* 432cdf0e10cSrcweir * INetURLHistory. 433cdf0e10cSrcweir */ 434cdf0e10cSrcweir INetURLHistory::INetURLHistory() : m_pImpl (new INetURLHistory_Impl()) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir } 437cdf0e10cSrcweir 438cdf0e10cSrcweir /* 439cdf0e10cSrcweir * ~INetURLHistory. 440cdf0e10cSrcweir */ 441cdf0e10cSrcweir INetURLHistory::~INetURLHistory() 442cdf0e10cSrcweir { 443cdf0e10cSrcweir DELETEZ (m_pImpl); 444cdf0e10cSrcweir } 445cdf0e10cSrcweir 446cdf0e10cSrcweir /* 447cdf0e10cSrcweir * GetOrCreate. 448cdf0e10cSrcweir */ 449cdf0e10cSrcweir INetURLHistory* INetURLHistory::GetOrCreate() 450cdf0e10cSrcweir { 451cdf0e10cSrcweir return rtl_Instance< 452cdf0e10cSrcweir INetURLHistory, StaticInstance, 453cdf0e10cSrcweir osl::MutexGuard, osl::GetGlobalMutex >::create ( 454cdf0e10cSrcweir StaticInstance(), osl::GetGlobalMutex()); 455cdf0e10cSrcweir } 456cdf0e10cSrcweir 457cdf0e10cSrcweir /* 458cdf0e10cSrcweir * NormalizeUrl_Impl. 459cdf0e10cSrcweir */ 460cdf0e10cSrcweir void INetURLHistory::NormalizeUrl_Impl (INetURLObject &rUrl) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir switch (rUrl.GetProtocol()) 463cdf0e10cSrcweir { 464cdf0e10cSrcweir case INET_PROT_FILE: 465cdf0e10cSrcweir if (!rUrl.IsCaseSensitive()) 466cdf0e10cSrcweir { 467cdf0e10cSrcweir String aPath (rUrl.GetURLPath(INetURLObject::NO_DECODE)); 468cdf0e10cSrcweir aPath.ToLowerAscii(); 469cdf0e10cSrcweir rUrl.SetURLPath (aPath, INetURLObject::NOT_CANONIC); 470cdf0e10cSrcweir } 471cdf0e10cSrcweir break; 472cdf0e10cSrcweir 473cdf0e10cSrcweir case INET_PROT_FTP: 474cdf0e10cSrcweir if (!rUrl.HasPort()) 475cdf0e10cSrcweir rUrl.SetPort (INETHIST_DEF_FTP_PORT); 476cdf0e10cSrcweir break; 477cdf0e10cSrcweir 478cdf0e10cSrcweir case INET_PROT_HTTP: 479cdf0e10cSrcweir if (!rUrl.HasPort()) 480cdf0e10cSrcweir rUrl.SetPort (INETHIST_DEF_HTTP_PORT); 481cdf0e10cSrcweir if (!rUrl.HasURLPath()) 482cdf0e10cSrcweir rUrl.SetURLPath ("/"); 483cdf0e10cSrcweir break; 484cdf0e10cSrcweir 485cdf0e10cSrcweir case INET_PROT_HTTPS: 486cdf0e10cSrcweir if (!rUrl.HasPort()) 487cdf0e10cSrcweir rUrl.SetPort (INETHIST_DEF_HTTPS_PORT); 488cdf0e10cSrcweir if (!rUrl.HasURLPath()) 489cdf0e10cSrcweir rUrl.SetURLPath ("/"); 490cdf0e10cSrcweir break; 491cdf0e10cSrcweir 492cdf0e10cSrcweir default: 493cdf0e10cSrcweir break; 494cdf0e10cSrcweir } 495cdf0e10cSrcweir } 496cdf0e10cSrcweir 497cdf0e10cSrcweir /* 498cdf0e10cSrcweir * PutUrl_Impl. 499cdf0e10cSrcweir */ 500cdf0e10cSrcweir void INetURLHistory::PutUrl_Impl (const INetURLObject &rUrl) 501cdf0e10cSrcweir { 502cdf0e10cSrcweir DBG_ASSERT (m_pImpl, "PutUrl_Impl(): no Implementation"); 503cdf0e10cSrcweir if (m_pImpl) 504cdf0e10cSrcweir { 505cdf0e10cSrcweir INetURLObject aHistUrl (rUrl); 506cdf0e10cSrcweir NormalizeUrl_Impl (aHistUrl); 507cdf0e10cSrcweir 508cdf0e10cSrcweir m_pImpl->putUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); 509cdf0e10cSrcweir Broadcast (INetURLHistoryHint (&rUrl)); 510cdf0e10cSrcweir 511cdf0e10cSrcweir if (aHistUrl.HasMark()) 512cdf0e10cSrcweir { 513cdf0e10cSrcweir aHistUrl.SetURL (aHistUrl.GetURLNoMark(INetURLObject::NO_DECODE), 514cdf0e10cSrcweir INetURLObject::NOT_CANONIC); 515cdf0e10cSrcweir 516cdf0e10cSrcweir m_pImpl->putUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); 517cdf0e10cSrcweir Broadcast (INetURLHistoryHint (&aHistUrl)); 518cdf0e10cSrcweir } 519cdf0e10cSrcweir } 520cdf0e10cSrcweir } 521cdf0e10cSrcweir 522cdf0e10cSrcweir /* 523cdf0e10cSrcweir * QueryUrl_Impl. 524cdf0e10cSrcweir */ 525cdf0e10cSrcweir sal_Bool INetURLHistory::QueryUrl_Impl (const INetURLObject &rUrl) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir DBG_ASSERT (m_pImpl, "QueryUrl_Impl(): no Implementation"); 528cdf0e10cSrcweir if (m_pImpl) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir INetURLObject aHistUrl (rUrl); 531cdf0e10cSrcweir NormalizeUrl_Impl (aHistUrl); 532cdf0e10cSrcweir 533cdf0e10cSrcweir return m_pImpl->queryUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); 534cdf0e10cSrcweir } 535cdf0e10cSrcweir return sal_False; 536cdf0e10cSrcweir } 537cdf0e10cSrcweir 538cdf0e10cSrcweir 539