LibreOffice Module svl (master) 1
inethist.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <svl/inethist.hxx>
21
22#include <algorithm>
23#include <string.h>
24
25#include <rtl/crc.h>
26#include <tools/debug.hxx>
27#include <tools/urlobj.hxx>
28
29/*
30 * INetURLHistory internals.
31 */
32#define INETHIST_DEF_FTP_PORT 21
33#define INETHIST_DEF_HTTP_PORT 80
34#define INETHIST_DEF_HTTPS_PORT 443
35
36#define INETHIST_SIZE_LIMIT 1024
37#define INETHIST_MAGIC_HEAD 0x484D4849UL
38
40{
42 {
45 sal_uInt32 m_nMagic;
46 sal_uInt16 m_nNext;
47
51 {
53 m_nNext = 0;
54 }
55 };
56
58 {
61 sal_uInt32 m_nHash;
62 sal_uInt16 m_nLru;
63
66 void initialize (sal_uInt16 nLru)
67 {
68 m_nHash = 0;
69 m_nLru = nLru;
70 }
71
74 bool operator== (sal_uInt32 nHash) const
75 {
76 return (m_nHash == nHash);
77 }
78 bool operator< (sal_uInt32 nHash) const
79 {
80 return (m_nHash < nHash);
81 }
82 };
83
84 struct lru_entry
85 {
88 sal_uInt32 m_nHash;
89 sal_uInt16 m_nNext;
90 sal_uInt16 m_nPrev;
91
94 void initialize (sal_uInt16 nThis)
95 {
96 m_nHash = 0;
97 m_nNext = nThis;
98 m_nPrev = nThis;
99 }
100 };
101
107
110 void initialize();
111
112 static sal_uInt16 capacity()
113 {
114 return sal_uInt16(INETHIST_SIZE_LIMIT);
115 }
116
117 static sal_uInt32 crc32 (OUString const & rData)
118 {
119 return rtl_crc32 (0, rData.getStr(), rData.getLength() * sizeof(sal_Unicode));
120 }
121
122 sal_uInt16 find (sal_uInt32 nHash) const;
123
124 void move (sal_uInt16 nSI, sal_uInt16 nDI);
125
126 void backlink (sal_uInt16 nThis, sal_uInt16 nTail)
127 {
128 lru_entry &rThis = m_pList[nThis];
129 lru_entry &rTail = m_pList[nTail];
130
131 rTail.m_nNext = nThis;
132 rTail.m_nPrev = rThis.m_nPrev;
133 rThis.m_nPrev = nTail;
134 m_pList[rTail.m_nPrev].m_nNext = nTail;
135 }
136
137 void unlink (sal_uInt16 nThis)
138 {
139 lru_entry &rThis = m_pList[nThis];
140
141 m_pList[rThis.m_nPrev].m_nNext = rThis.m_nNext;
142 m_pList[rThis.m_nNext].m_nPrev = rThis.m_nPrev;
143 rThis.m_nNext = nThis;
144 rThis.m_nPrev = nThis;
145 }
146
147public:
151
154 void putUrl (const OUString &rUrl);
155 bool queryUrl (const OUString &rUrl) const;
156};
157
159{
160 initialize();
161}
162
164{
166
167 sal_uInt16 i, n = capacity();
168 for (i = 0; i < n; i++)
170 for (i = 0; i < n; i++)
172 for (i = 1; i < n; i++)
174}
175
176sal_uInt16 INetURLHistory_Impl::find (sal_uInt32 nHash) const
177{
178 sal_uInt16 l = 0;
179 sal_uInt16 r = capacity() - 1;
180 sal_uInt16 c = capacity();
181
182 while ((l < r) && (r < c))
183 {
184 sal_uInt16 m = (l + r) / 2;
185 if (m_pHash[m] == nHash)
186 return m;
187
188 if (m_pHash[m] < nHash)
189 l = m + 1;
190 else
191 r = m - 1;
192 }
193 return l;
194}
195
196void INetURLHistory_Impl::move (sal_uInt16 nSI, sal_uInt16 nDI)
197{
198 hash_entry e = m_pHash[nSI];
199 if (nSI < nDI)
200 {
201 // shift left.
202 memmove (
203 &m_pHash[nSI ],
204 &m_pHash[nSI + 1],
205 (nDI - nSI) * sizeof(hash_entry));
206 }
207 if (nSI > nDI)
208 {
209 // shift right.
210 memmove (
211 &m_pHash[nDI + 1],
212 &m_pHash[nDI ],
213 (nSI - nDI) * sizeof(hash_entry));
214 }
215 m_pHash[nDI] = e;
216}
217
218void INetURLHistory_Impl::putUrl (const OUString &rUrl)
219{
220 sal_uInt32 h = crc32 (rUrl);
221 sal_uInt16 k = find (h);
222 if ((k < capacity()) && (m_pHash[k] == h))
223 {
224 // Cache hit.
225 sal_uInt16 nMRU = m_pHash[k].m_nLru;
226 if (nMRU != m_aHead.m_nNext)
227 {
228 // Update LRU chain.
229 unlink (nMRU);
230 backlink (m_aHead.m_nNext, nMRU);
231
232 // Rotate LRU chain.
234 }
235 }
236 else
237 {
238 // Cache miss. Obtain least recently used.
239 sal_uInt16 nLRU = m_pList[m_aHead.m_nNext].m_nPrev;
240
241 sal_uInt16 nSI = find (m_pList[nLRU].m_nHash);
242 if (nLRU != m_pHash[nSI].m_nLru)
243 {
244 // Update LRU chain.
245 nLRU = m_pHash[nSI].m_nLru;
246 unlink (nLRU);
247 backlink (m_aHead.m_nNext, nLRU);
248 }
249
250 // Rotate LRU chain.
252
253 // Check source and destination.
254 sal_uInt16 nDI = std::min (k, sal_uInt16(capacity() - 1));
255 if (nSI < nDI && !(m_pHash[nDI] < h))
256 nDI -= 1;
257 if (nDI < nSI && m_pHash[nDI] < h)
258 nDI += 1;
259
260 // Assign data.
262 move (nSI, nDI);
263 }
264}
265
266bool INetURLHistory_Impl::queryUrl (const OUString &rUrl) const
267{
268 sal_uInt32 h = crc32 (rUrl);
269 sal_uInt16 k = find (h);
270 // true if cache hit
271 return (k < capacity()) && (m_pHash[k] == h);
272}
273
275{
276}
277
279{
280}
281
282/*
283 * GetOrCreate.
284 */
286{
287 static INetURLHistory instance;
288 return &instance;
289}
290
292{
293 switch (rUrl.GetProtocol())
294 {
295 case INetProtocol::File:
297 {
298 OUString aPath (rUrl.GetURLPath(INetURLObject::DecodeMechanism::NONE).toAsciiLowerCase());
300 }
301 break;
302
303 case INetProtocol::Ftp:
304 if (!rUrl.HasPort())
306 break;
307
308 case INetProtocol::Http:
309 if (!rUrl.HasPort())
311 if (!rUrl.HasURLPath())
312 rUrl.SetURLPath(u"/");
313 break;
314
315 case INetProtocol::Https:
316 if (!rUrl.HasPort())
318 if (!rUrl.HasURLPath())
319 rUrl.SetURLPath(u"/");
320 break;
321
322 default:
323 break;
324 }
325}
326
328{
329 DBG_ASSERT (m_pImpl, "PutUrl_Impl(): no Implementation");
330 if (!m_pImpl)
331 return;
332
333 INetURLObject aHistUrl (rUrl);
334 NormalizeUrl_Impl (aHistUrl);
335
338
339 if (aHistUrl.HasMark())
340 {
343
345 Broadcast (INetURLHistoryHint (&aHistUrl));
346 }
347}
348
349bool INetURLHistory::QueryUrl(std::u16string_view rUrl) const
350{
352 if (!QueryProtocol (eProto))
353 return false;
354 return QueryUrl_Impl( INetURLObject(rUrl) );
355}
356
357
359{
360 DBG_ASSERT (m_pImpl, "QueryUrl_Impl(): no Implementation");
361 if (m_pImpl)
362 {
363 NormalizeUrl_Impl (rUrl);
364
366 }
367 return false;
368}
369
370
371/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
lru_entry m_pList[INETHIST_SIZE_LIMIT]
Definition: inethist.cxx:106
void unlink(sal_uInt16 nThis)
Definition: inethist.cxx:137
sal_uInt16 find(sal_uInt32 nHash) const
Definition: inethist.cxx:176
hash_entry m_pHash[INETHIST_SIZE_LIMIT]
Definition: inethist.cxx:105
void move(sal_uInt16 nSI, sal_uInt16 nDI)
Definition: inethist.cxx:196
static sal_uInt16 capacity()
Definition: inethist.cxx:112
static sal_uInt32 crc32(OUString const &rData)
Definition: inethist.cxx:117
INetURLHistory_Impl & operator=(const INetURLHistory_Impl &)=delete
INetURLHistory_Impl(const INetURLHistory_Impl &)=delete
head_entry m_aHead
Representation.
Definition: inethist.cxx:104
void putUrl(const OUString &rUrl)
putUrl/queryUrl.
Definition: inethist.cxx:218
void initialize()
Initialization.
Definition: inethist.cxx:163
void backlink(sal_uInt16 nThis, sal_uInt16 nTail)
Definition: inethist.cxx:126
bool queryUrl(const OUString &rUrl) const
Definition: inethist.cxx:266
static SAL_DLLPRIVATE void NormalizeUrl_Impl(INetURLObject &rUrl)
Implementation.
Definition: inethist.cxx:291
SAL_DLLPRIVATE INetURLHistory()
Construction/Destruction.
Definition: inethist.cxx:274
static INetURLHistory * GetOrCreate()
GetOrCreate.
Definition: inethist.cxx:285
virtual SAL_DLLPRIVATE ~INetURLHistory() override
Definition: inethist.cxx:278
void PutUrl_Impl(const INetURLObject &rUrl)
Definition: inethist.cxx:327
bool QueryProtocol(INetProtocol eProto) const
QueryProtocol.
Definition: inethist.hxx:59
std::unique_ptr< INetURLHistory_Impl > m_pImpl
Representation.
Definition: inethist.hxx:33
bool QueryUrl(const INetURLObject &rUrl) const
QueryUrl.
Definition: inethist.hxx:69
bool QueryUrl_Impl(INetURLObject rUrl) const
Definition: inethist.cxx:358
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool HasURLPath() const
bool SetPort(sal_uInt32 nThePort)
OUString GetURLNoMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool HasPort() const
static INetProtocol CompareProtocolScheme(std::u16string_view aTheAbsURIRef)
bool HasMark() const
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static bool IsCaseSensitive()
bool SetURLPath(std::u16string_view rThePath, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
INetProtocol GetProtocol() const
bool SetURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
void Broadcast(const SfxHint &rHint)
#define DBG_ASSERT(sCon, aError)
float u
#define INETHIST_DEF_FTP_PORT
Definition: inethist.cxx:32
#define INETHIST_DEF_HTTPS_PORT
Definition: inethist.cxx:34
#define INETHIST_SIZE_LIMIT
Definition: inethist.cxx:36
#define INETHIST_MAGIC_HEAD
Definition: inethist.cxx:37
#define INETHIST_DEF_HTTP_PORT
Definition: inethist.cxx:33
sal_Int64 n
int i
m
sal_Int32 h
Definition: inethist.cxx:58
sal_uInt32 m_nHash
Representation.
Definition: inethist.cxx:61
sal_uInt16 m_nLru
Definition: inethist.cxx:62
bool operator<(sal_uInt32 nHash) const
Definition: inethist.cxx:78
bool operator==(sal_uInt32 nHash) const
Comparison.
Definition: inethist.cxx:74
void initialize(sal_uInt16 nLru)
Initialization.
Definition: inethist.cxx:66
Definition: inethist.cxx:42
sal_uInt32 m_nMagic
Representation.
Definition: inethist.cxx:45
sal_uInt16 m_nNext
Definition: inethist.cxx:46
void initialize()
Initialization.
Definition: inethist.cxx:50
Definition: inethist.cxx:85
void initialize(sal_uInt16 nThis)
Initialization.
Definition: inethist.cxx:94
sal_uInt16 m_nPrev
Definition: inethist.cxx:90
sal_uInt16 m_nNext
Definition: inethist.cxx:89
sal_uInt32 m_nHash
Representation.
Definition: inethist.cxx:88
sal_uInt16 sal_Unicode
INetProtocol