xref: /trunk/main/svl/source/misc/inethist.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
140df464eSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
340df464eSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
440df464eSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
540df464eSAndrew Rist  * distributed with this work for additional information
640df464eSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
740df464eSAndrew Rist  * to you under the Apache License, Version 2.0 (the
840df464eSAndrew Rist  * "License"); you may not use this file except in compliance
940df464eSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
1140df464eSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
1340df464eSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1440df464eSAndrew Rist  * software distributed under the License is distributed on an
1540df464eSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1640df464eSAndrew Rist  * KIND, either express or implied.  See the License for the
1740df464eSAndrew Rist  * specific language governing permissions and limitations
1840df464eSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
2040df464eSAndrew Rist  *************************************************************/
2140df464eSAndrew Rist 
2240df464eSAndrew 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         */
initializeINetURLHistory_Impl::head_entry76cdf0e10cSrcweir         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         */
initializeINetURLHistory_Impl::hash_entry96cdf0e10cSrcweir         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         */
operator ==INetURLHistory_Impl::hash_entry105cdf0e10cSrcweir         sal_Bool operator== (const hash_entry &rOther) const
106cdf0e10cSrcweir         {
107cdf0e10cSrcweir             return (m_nHash == rOther.m_nHash);
108cdf0e10cSrcweir         }
operator <INetURLHistory_Impl::hash_entry109cdf0e10cSrcweir         sal_Bool operator< (const hash_entry &rOther) const
110cdf0e10cSrcweir         {
111cdf0e10cSrcweir             return (m_nHash < rOther.m_nHash);
112cdf0e10cSrcweir         }
113cdf0e10cSrcweir 
operator ==INetURLHistory_Impl::hash_entry114cdf0e10cSrcweir         sal_Bool operator== (sal_uInt32 nHash) const
115cdf0e10cSrcweir         {
116cdf0e10cSrcweir             return (m_nHash == nHash);
117cdf0e10cSrcweir         }
operator <INetURLHistory_Impl::hash_entry118cdf0e10cSrcweir         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         */
initializeINetURLHistory_Impl::lru_entry136cdf0e10cSrcweir         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     */
capacity(void) const159cdf0e10cSrcweir     sal_uInt16 capacity (void) const
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         return (sal_uInt16)(INETHIST_SIZE_LIMIT);
162cdf0e10cSrcweir     }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir     /** crc32.
165cdf0e10cSrcweir     */
crc32(UniString const & rData) const166cdf0e10cSrcweir     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     */
backlink(sal_uInt16 nThis,sal_uInt16 nTail)181cdf0e10cSrcweir     void backlink (sal_uInt16 nThis, sal_uInt16 nTail)
182cdf0e10cSrcweir     {
183*c1e8cc3aSDon Lewis         lru_entry &rThis = m_pList[nThis];
184*c1e8cc3aSDon Lewis         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     */
unlink(sal_uInt16 nThis)194cdf0e10cSrcweir     void unlink (sal_uInt16 nThis)
195cdf0e10cSrcweir     {
196*c1e8cc3aSDon Lewis         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  */
INetURLHistory_Impl(void)227cdf0e10cSrcweir INetURLHistory_Impl::INetURLHistory_Impl (void)
228cdf0e10cSrcweir {
229cdf0e10cSrcweir     initialize();
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir /*
233cdf0e10cSrcweir  * ~INetURLHistory_Impl.
234cdf0e10cSrcweir  */
~INetURLHistory_Impl(void)235cdf0e10cSrcweir INetURLHistory_Impl::~INetURLHistory_Impl (void)
236cdf0e10cSrcweir {
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir /*
240cdf0e10cSrcweir  * initialize.
241cdf0e10cSrcweir  */
initialize(void)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  */
downheap(hash_entry a[],sal_uInt16 n,sal_uInt16 k)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  */
heapsort(hash_entry a[],sal_uInt16 n)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  */
find(sal_uInt32 nHash) const294cdf0e10cSrcweir 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  */
move(sal_uInt16 nSI,sal_uInt16 nDI)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  */
putUrl(const String & rUrl)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  */
queryUrl(const String & rUrl)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  *======================================================================*/
operator ()()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  */
INetURLHistory()434cdf0e10cSrcweir INetURLHistory::INetURLHistory() : m_pImpl (new INetURLHistory_Impl())
435cdf0e10cSrcweir {
436cdf0e10cSrcweir }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir /*
439cdf0e10cSrcweir  * ~INetURLHistory.
440cdf0e10cSrcweir  */
~INetURLHistory()441cdf0e10cSrcweir INetURLHistory::~INetURLHistory()
442cdf0e10cSrcweir {
443cdf0e10cSrcweir     DELETEZ (m_pImpl);
444cdf0e10cSrcweir }
445cdf0e10cSrcweir 
446cdf0e10cSrcweir /*
447cdf0e10cSrcweir  * GetOrCreate.
448cdf0e10cSrcweir  */
GetOrCreate()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  */
NormalizeUrl_Impl(INetURLObject & rUrl)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  */
PutUrl_Impl(const INetURLObject & rUrl)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  */
QueryUrl_Impl(const INetURLObject & rUrl)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 }
537