18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKitDLL.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebHistory.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CFDictionaryPropertyBag.h" 310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "MemoryStream.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKit.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MarshallingHelpers.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebHistoryItem.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKit.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebNotificationCenter.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebPreferences.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <CoreFoundation/CoreFoundation.h> 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <WebCore/HistoryItem.h> 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <WebCore/HistoryPropertyList.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/KURL.h> 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/PageGroup.h> 430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <WebCore/SharedBuffer.h> 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <functional> 45563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <wtf/StdLibExtras.h> 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Vector.h> 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WebCore; 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochusing namespace std; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFStringRef DatesArrayKey = CFSTR("WebHistoryDates"); 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFStringRef FileVersionKey = CFSTR("WebHistoryFileVersion"); 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define currentFileVersion 1 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass WebHistoryWriter : public HistoryPropertyListWriter { 570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochpublic: 580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch WebHistoryWriter(const WebHistory::DateToEntriesMap&); 590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochprivate: 610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch virtual void writeHistoryItems(BinaryPropertyListObjectStream&); 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const WebHistory::DateToEntriesMap& m_entriesByDate; 640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Vector<WebHistory::DateKey> m_dateKeys; 650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochWebHistoryWriter::WebHistoryWriter(const WebHistory::DateToEntriesMap& entriesByDate) 680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch : m_entriesByDate(entriesByDate) 690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch copyKeysToVector(m_entriesByDate, m_dateKeys); 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch sort(m_dateKeys.begin(), m_dateKeys.end()); 720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid WebHistoryWriter::writeHistoryItems(BinaryPropertyListObjectStream& stream) 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (int dateIndex = m_dateKeys.size() - 1; dateIndex >= 0; --dateIndex) { 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // get the entries for that date 780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFArrayRef entries = m_entriesByDate.get(m_dateKeys[dateIndex]).get(); 790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFIndex entriesCount = CFArrayGetCount(entries); 800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (CFIndex j = entriesCount - 1; j >= 0; --j) { 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IWebHistoryItem* item = (IWebHistoryItem*) CFArrayGetValueAtIndex(entries, j); 820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch COMPtr<WebHistoryItem> webItem(Query, item); 830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!webItem) 840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch continue; 850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch writeHistoryItem(stream, webItem->historyItem()); 870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool areEqualOrClose(double d1, double d2) 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double diff = d1-d2; 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (diff < .000001 && diff > -.000001); 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 97643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic COMPtr<CFDictionaryPropertyBag> createUserInfoFromArray(BSTR notificationStr, CFArrayRef arrayItem) 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFMutableDictionaryRef> dictionary(AdoptCF, 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFStringRef> key(AdoptCF, MarshallingHelpers::BSTRToCFStringRef(notificationStr)); 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionaryAddValue(dictionary.get(), key.get(), arrayItem); 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> result = CFDictionaryPropertyBag::createInstance(); 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result->setDictionary(dictionary.get()); 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 110643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic COMPtr<CFDictionaryPropertyBag> createUserInfoFromHistoryItem(BSTR notificationStr, IWebHistoryItem* item) 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // reference counting of item added to the array is managed by the CFArray value callbacks 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFArrayRef> itemList(AdoptCF, CFArrayCreate(0, (const void**) &item, 1, &MarshallingHelpers::kIUnknownArrayCallBacks)); 114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> info = createUserInfoFromArray(notificationStr, itemList.get()); 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return info; 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// WebHistory ----------------------------------------------------------------- 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebHistory::WebHistory() 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project: m_refCount(0) 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project, m_preferences(0) 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClassCount++; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClassNameCount.add("WebHistory"); 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_entriesByURL.adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &MarshallingHelpers::kIUnknownDictionaryValueCallBacks)); 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_preferences = WebPreferences::sharedStandardPreferences(); 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebHistory::~WebHistory() 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClassCount--; 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClassNameCount.remove("WebHistory"); 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebHistory* WebHistory::createInstance() 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WebHistory* instance = new WebHistory(); 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instance->AddRef(); 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return instance; 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::postNotification(NotificationType notifyType, IPropertyBag* userInfo /*=0*/) 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IWebNotificationCenter* nc = WebNotificationCenter::defaultCenterInternal(); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = nc->postNotificationName(getNotificationString(notifyType), static_cast<IWebHistory*>(this), userInfo); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectBSTR WebHistory::getNotificationString(NotificationType notifyType) 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static BSTR keys[6] = {0}; 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!keys[0]) { 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project keys[0] = SysAllocString(WebHistoryItemsAddedNotification); 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project keys[1] = SysAllocString(WebHistoryItemsRemovedNotification); 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project keys[2] = SysAllocString(WebHistoryAllItemsRemovedNotification); 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project keys[3] = SysAllocString(WebHistoryLoadedNotification); 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project keys[4] = SysAllocString(WebHistoryItemsDiscardedWhileLoadingNotification); 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project keys[5] = SysAllocString(WebHistorySavedNotification); 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return keys[notifyType]; 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// IUnknown ------------------------------------------------------------------- 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::QueryInterface(REFIID riid, void** ppvObject) 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *ppvObject = 0; 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (IsEqualGUID(riid, CLSID_WebHistory)) 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *ppvObject = this; 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (IsEqualGUID(riid, IID_IUnknown)) 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *ppvObject = static_cast<IWebHistory*>(this); 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (IsEqualGUID(riid, IID_IWebHistory)) 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *ppvObject = static_cast<IWebHistory*>(this); 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else if (IsEqualGUID(riid, IID_IWebHistoryPrivate)) 181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *ppvObject = static_cast<IWebHistoryPrivate*>(this); 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_NOINTERFACE; 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project AddRef(); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectULONG STDMETHODCALLTYPE WebHistory::AddRef(void) 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ++m_refCount; 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectULONG STDMETHODCALLTYPE WebHistory::Release(void) 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ULONG newRef = --m_refCount; 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!newRef) 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete(this); 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return newRef; 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// IWebHistory ---------------------------------------------------------------- 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline COMPtr<WebHistory>& sharedHistoryStorage() 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 207563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark DEFINE_STATIC_LOCAL(COMPtr<WebHistory>, sharedHistory, ()); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return sharedHistory; 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectWebHistory* WebHistory::sharedHistory() 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return sharedHistoryStorage().get(); 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::optionalSharedHistory( 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [retval][out] */ IWebHistory** history) 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *history = sharedHistory(); 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*history) 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (*history)->AddRef(); 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::setOptionalSharedHistory( 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ IWebHistory* history) 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (sharedHistoryStorage() == history) 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sharedHistoryStorage().query(history); 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PageGroup::setShouldTrackVisitedLinks(sharedHistoryStorage()); 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PageGroup::removeAllVisitedLinks(); 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::loadFromURL( 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ BSTR url, 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [out] */ IWebError** error, 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [retval][out] */ BOOL* succeeded) 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFMutableArrayRef> discardedItems(AdoptCF, 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFArrayCreateMutable(0, 0, &MarshallingHelpers::kIUnknownArrayCallBacks)); 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFURLRef> urlRef(AdoptCF, MarshallingHelpers::BSTRToCFURLRef(url)); 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = loadHistoryGutsFromURL(urlRef.get(), discardedItems.get(), error); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto exit; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = postNotification(kWebHistoryLoadedNotification); 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto exit; 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (CFArrayGetCount(discardedItems.get()) > 0) { 256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> userInfo = createUserInfoFromArray(getNotificationString(kWebHistoryItemsDiscardedWhileLoadingNotification), discardedItems.get()); 257643ca7872b450ea4efacab6188849e5aac2ba161Steve Block hr = postNotification(kWebHistoryItemsDiscardedWhileLoadingNotification, userInfo.get()); 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto exit; 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectexit: 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (succeeded) 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *succeeded = SUCCEEDED(hr); 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic CFDictionaryRef createHistoryListFromStream(CFReadStreamRef stream, CFPropertyListFormat format) 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (CFDictionaryRef)CFPropertyListCreateFromStream(0, stream, 0, kCFPropertyListImmutable, &format, 0); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::loadHistoryGutsFromURL(CFURLRef url, CFMutableArrayRef discardedItems, IWebError** /*error*/) //FIXME 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0 | kCFPropertyListXMLFormat_v1_0; 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int numberOfItemsLoaded = 0; 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFReadStreamRef> stream(AdoptCF, CFReadStreamCreateWithFile(0, url)); 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stream) 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!CFReadStreamOpen(stream.get())) 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFDictionaryRef> historyList(AdoptCF, createHistoryListFromStream(stream.get(), format)); 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFReadStreamClose(stream.get()); 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!historyList) 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFNumberRef fileVersionObject = (CFNumberRef)CFDictionaryGetValue(historyList.get(), FileVersionKey); 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int fileVersion; 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!CFNumberGetValue(fileVersionObject, kCFNumberIntType, &fileVersion)) 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fileVersion > currentFileVersion) 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFArrayRef datesArray = (CFArrayRef)CFDictionaryGetValue(historyList.get(), DatesArrayKey); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int itemCountLimit; 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = historyItemLimit(&itemCountLimit); 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFAbsoluteTime limitDate; 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = ageLimitDate(&limitDate); 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ageLimitPassed = false; 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool itemLimitPassed = false; 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFIndex itemCount = CFArrayGetCount(datesArray); 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (CFIndex i = 0; i < itemCount; ++i) { 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionaryRef itemAsDictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(datesArray, i); 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<WebHistoryItem> item(AdoptCOM, WebHistoryItem::createInstance()); 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = item->initFromDictionaryRepresentation((void*)itemAsDictionary); 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // item without URL is useless; data on disk must have been bad; ignore 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BOOL hasURL; 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = item->hasURLString(&hasURL); 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (hasURL) { 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Test against date limit. Since the items are ordered newest to oldest, we can stop comparing 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // once we've found the first item that's too old. 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!ageLimitPassed) { 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DATE lastVisitedTime; 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = item->lastVisitedTimeInterval(&lastVisitedTime); 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (timeToDate(MarshallingHelpers::DATEToCFAbsoluteTime(lastVisitedTime)) <= limitDate) 3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ageLimitPassed = true; 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ageLimitPassed || itemLimitPassed) 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFArrayAppendValue(discardedItems, item.get()); 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool added; 344635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project addItem(item.get(), true, &added); // ref is added inside addItem 345635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (added) 346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ++numberOfItemsLoaded; 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (numberOfItemsLoaded == itemCountLimit) 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project itemLimitPassed = true; 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::saveToURL( 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ BSTR url, 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [out] */ IWebError** error, 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [retval][out] */ BOOL* succeeded) 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFURLRef> urlRef(AdoptCF, MarshallingHelpers::BSTRToCFURLRef(url)); 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = saveHistoryGuts(urlRef.get(), error); 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (succeeded) 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *succeeded = SUCCEEDED(hr); 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(hr)) 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = postNotification(kWebHistorySavedNotification); 3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::saveHistoryGuts(CFURLRef url, IWebError** error) 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // FIXME: Correctly report error when new API is ready. 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (error) 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *error = 0; 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RetainPtr<CFDataRef> data = this->data(); 3820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFWriteStreamRef> stream(AdoptCF, CFWriteStreamCreateWithFile(kCFAllocatorDefault, url)); 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!stream) 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!CFWriteStreamOpen(stream.get())) 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const UInt8* dataPtr = CFDataGetBytePtr(data.get()); 3910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFIndex length = CFDataGetLength(data.get()); 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while (length) { 3940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFIndex bytesWritten = CFWriteStreamWrite(stream.get(), dataPtr, length); 3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (bytesWritten <= 0) { 3960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hr = E_FAIL; 3970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch break; 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch dataPtr += bytesWritten; 4000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch length -= bytesWritten; 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFWriteStreamClose(stream.get()); 4040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::addItems( 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ int itemCount, 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ IWebHistoryItem** items) 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // There is no guarantee that the incoming entries are in any particular 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // order, but if this is called with a set of entries that were created by 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // iterating through the results of orderedLastVisitedDays and orderedItemsLastVisitedOnDay 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // then they will be ordered chronologically from newest to oldest. We can make adding them 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // faster (fewer compares) by inserting them from oldest to newest. 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr; 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = itemCount - 1; i >= 0; --i) { 420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project hr = addItem(items[i], false, 0); 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::removeItems( 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ int itemCount, 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ IWebHistoryItem** items) 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr; 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < itemCount; ++i) { 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = removeItem(items[i]); 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::removeAllItems( void) 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_entriesByDate.clear(); 4450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_orderedLastVisitedDays.clear(); 446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 447635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFIndex itemCount = CFDictionaryGetCount(m_entriesByURL.get()); 448635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Vector<IWebHistoryItem*> itemsVector(itemCount); 449635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFDictionaryGetKeysAndValues(m_entriesByURL.get(), 0, (const void**)itemsVector.data()); 450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<CFArrayRef> allItems(AdoptCF, CFArrayCreate(kCFAllocatorDefault, (const void**)itemsVector.data(), itemCount, &MarshallingHelpers::kIUnknownArrayCallBacks)); 451635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionaryRemoveAllValues(m_entriesByURL.get()); 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PageGroup::removeAllVisitedLinks(); 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> userInfo = createUserInfoFromArray(getNotificationString(kWebHistoryAllItemsRemovedNotification), allItems.get()); 457643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return postNotification(kWebHistoryAllItemsRemovedNotification, userInfo.get()); 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::orderedLastVisitedDays( 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [out][in] */ int* count, 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ DATE* calendarDates) 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int dateCount = m_entriesByDate.size(); 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!calendarDates) { 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = dateCount; 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*count < dateCount) { 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = dateCount; 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = dateCount; 4760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!m_orderedLastVisitedDays) { 4772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_orderedLastVisitedDays = adoptArrayPtr(new DATE[dateCount]); 4780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DateToEntriesMap::const_iterator::Keys end = m_entriesByDate.end().keys(); 4790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int i = 0; 4800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (DateToEntriesMap::const_iterator::Keys it = m_entriesByDate.begin().keys(); it != end; ++it, ++i) 4810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_orderedLastVisitedDays[i] = MarshallingHelpers::CFAbsoluteTimeToDATE(*it); 4820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Use std::greater to sort the days in descending order (i.e., most-recent first). 4830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch sort(m_orderedLastVisitedDays.get(), m_orderedLastVisitedDays.get() + dateCount, greater<DATE>()); 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch memcpy(calendarDates, m_orderedLastVisitedDays.get(), dateCount * sizeof(DATE)); 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::orderedItemsLastVisitedOnDay( 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [out][in] */ int* count, 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ IWebHistoryItem** items, 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ DATE calendarDate) 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DateKey dateKey; 4960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!findKey(&dateKey, MarshallingHelpers::DATEToCFAbsoluteTime(calendarDate))) { 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = 0; 4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFArrayRef entries = m_entriesByDate.get(dateKey).get(); 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!entries) { 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = 0; 5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int newCount = CFArrayGetCount(entries); 5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!items) { 5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = newCount; 5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*count < newCount) { 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = newCount; 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *count = newCount; 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < newCount; i++) { 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IWebHistoryItem* item = (IWebHistoryItem*)CFArrayGetValueAtIndex(entries, i); 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project item->AddRef(); 5230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch items[i] = item; 5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::allItems( 530635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [out][in] */ int* count, 531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* [out][retval] */ IWebHistoryItem** items) 532635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int entriesByURLCount = CFDictionaryGetCount(m_entriesByURL.get()); 534635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!items) { 536635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *count = entriesByURLCount; 537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 538635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 539635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 540635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (*count < entriesByURLCount) { 541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *count = entriesByURLCount; 542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return E_FAIL; 543635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 544635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 545635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *count = entriesByURLCount; 546635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFDictionaryGetKeysAndValues(m_entriesByURL.get(), 0, (const void**)items); 547635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (int i = 0; i < entriesByURLCount; i++) 548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project items[i]->AddRef(); 549635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 552635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 5530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHRESULT WebHistory::data(IStream** stream) 5540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 5550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!stream) 5560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return E_POINTER; 5570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *stream = 0; 5590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RetainPtr<CFDataRef> historyData = data(); 5610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!historyData) 5620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return S_OK; 5630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch COMPtr<MemoryStream> result = MemoryStream::createInstance(SharedBuffer::wrapCFData(historyData.get())); 5650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return result.copyRefTo(stream); 5660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 5670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 568cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockHRESULT WebHistory::setVisitedLinkTrackingEnabled(BOOL visitedLinkTrackingEnabled) 569cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 570cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block PageGroup::setShouldTrackVisitedLinks(visitedLinkTrackingEnabled); 571cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return S_OK; 572cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 573cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 574cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockHRESULT WebHistory::removeAllVisitedLinks() 575cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 576cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block PageGroup::removeAllVisitedLinks(); 577cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return S_OK; 578cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 579cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::setHistoryItemLimit( 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ int limit) 5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_preferences) 5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_preferences->setHistoryItemLimit(limit); 5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::historyItemLimit( 5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [retval][out] */ int* limit) 5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_preferences) 5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_preferences->historyItemLimit(limit); 5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::setHistoryAgeInDaysLimit( 5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ int limit) 5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_preferences) 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_preferences->setHistoryAgeInDaysLimit(limit); 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::historyAgeInDaysLimit( 6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [retval][out] */ int* limit) 6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_preferences) 6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_preferences->historyAgeInDaysLimit(limit); 6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::removeItem(IWebHistoryItem* entry) 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BSTR urlBStr = 0; 6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = entry->URLString(&urlBStr); 6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFStringRef> urlString(AdoptCF, MarshallingHelpers::BSTRToCFStringRef(urlBStr)); 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SysFreeString(urlBStr); 6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If this exact object isn't stored, then make no change. 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Is this the right behavior if this entry isn't present, but another entry for the same URL is? 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Maybe need to change the API to make something like removeEntryForURLString public instead. 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IWebHistoryItem *matchingEntry = (IWebHistoryItem*)CFDictionaryGetValue(m_entriesByURL.get(), urlString.get()); 6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (matchingEntry != entry) 6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = removeItemForURLString(urlString.get()); 6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> userInfo = createUserInfoFromHistoryItem( 6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getNotificationString(kWebHistoryItemsRemovedNotification), entry); 637643ca7872b450ea4efacab6188849e5aac2ba161Steve Block hr = postNotification(kWebHistoryItemsRemovedNotification, userInfo.get()); 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 642635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHRESULT WebHistory::addItem(IWebHistoryItem* entry, bool discardDuplicate, bool* added) 6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!entry) 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BSTR urlBStr = 0; 6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = entry->URLString(&urlBStr); 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFStringRef> urlString(AdoptCF, MarshallingHelpers::BSTRToCFStringRef(urlBStr)); 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SysFreeString(urlBStr); 6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project COMPtr<IWebHistoryItem> oldEntry((IWebHistoryItem*) CFDictionaryGetValue( 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_entriesByURL.get(), urlString.get())); 6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (oldEntry) { 661635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (discardDuplicate) { 662635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (added) 663635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *added = false; 664635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return S_OK; 665635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 666635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project removeItemForURLString(urlString.get()); 6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we already have an item with this URL, we need to merge info that drives the 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // URL autocomplete heuristics from that item into the new one. 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IWebHistoryItemPrivate* entryPriv; 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = entry->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&entryPriv); 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (SUCCEEDED(hr)) { 6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project entryPriv->mergeAutoCompleteHints(oldEntry.get()); 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project entryPriv->Release(); 6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project hr = addItemToDateCaches(entry); 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionarySetValue(m_entriesByURL.get(), urlString.get(), entry); 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 685643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> userInfo = createUserInfoFromHistoryItem( 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project getNotificationString(kWebHistoryItemsAddedNotification), entry); 687643ca7872b450ea4efacab6188849e5aac2ba161Steve Block hr = postNotification(kWebHistoryItemsAddedNotification, userInfo.get()); 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 689635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (added) 690635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *added = true; 691635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid WebHistory::visitedURL(const KURL& url, const String& title, const String& httpMethod, bool wasFailure, bool increaseVisitCount) 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 697635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<CFStringRef> urlString(AdoptCF, url.string().createCFString()); 6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 699635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project IWebHistoryItem* entry = (IWebHistoryItem*) CFDictionaryGetValue(m_entriesByURL.get(), urlString.get()); 700635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (entry) { 701635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<IWebHistoryItemPrivate> entryPrivate(Query, entry); 702635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!entryPrivate) 703635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 704635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 705635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Remove the item from date caches before changing its last visited date. Otherwise we might get duplicate entries 706635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // as seen in <rdar://problem/6570573>. 707635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project removeItemFromDateCaches(entry); 7080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch entryPrivate->visitedWithTitle(BString(title), increaseVisitCount); 709635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { 710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<WebHistoryItem> item(AdoptCOM, WebHistoryItem::createInstance()); 711635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!item) 712635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 713635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 714635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project entry = item.get(); 715635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 716635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project SYSTEMTIME currentTime; 717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project GetSystemTime(¤tTime); 718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DATE lastVisited; 719635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!SystemTimeToVariantTime(¤tTime, &lastVisited)) 720635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 722635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (FAILED(entry->initWithURLString(BString(url.string()), BString(title), lastVisited))) 723635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 724635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 725635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project item->recordInitialVisit(); 726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CFDictionarySetValue(m_entriesByURL.get(), urlString.get(), entry); 728635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 729635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 730635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project addItemToDateCaches(entry); 731635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 732635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project COMPtr<IWebHistoryItemPrivate> entryPrivate(Query, entry); 733635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!entryPrivate) 7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 736635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project entryPrivate->setLastVisitWasFailure(wasFailure); 737635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!httpMethod.isEmpty()) 7380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch entryPrivate->setLastVisitWasHTTPNonGet(!equalIgnoringCase(httpMethod, "GET") && url.protocolInHTTPFamily()); 739635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 740563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark COMPtr<WebHistoryItem> item(Query, entry); 7410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch item->historyItem()->setRedirectURLs(0); 742635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 743643ca7872b450ea4efacab6188849e5aac2ba161Steve Block COMPtr<CFDictionaryPropertyBag> userInfo = createUserInfoFromHistoryItem( 744635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project getNotificationString(kWebHistoryItemsAddedNotification), entry); 745643ca7872b450ea4efacab6188849e5aac2ba161Steve Block postNotification(kWebHistoryItemsAddedNotification, userInfo.get()); 746635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 747635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::itemForURLString( 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ CFStringRef urlString, 750563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark /* [retval][out] */ IWebHistoryItem** item) const 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!item) 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *item = 0; 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IWebHistoryItem* foundItem = (IWebHistoryItem*) CFDictionaryGetValue(m_entriesByURL.get(), urlString); 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!foundItem) 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project foundItem->AddRef(); 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *item = foundItem; 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT STDMETHODCALLTYPE WebHistory::itemForURL( 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [in] */ BSTR url, 7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* [retval][out] */ IWebHistoryItem** item) 7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFStringRef> urlString(AdoptCF, MarshallingHelpers::BSTRToCFStringRef(url)); 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return itemForURLString(urlString.get(), item); 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::removeItemForURLString(CFStringRef urlString) 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IWebHistoryItem* entry = (IWebHistoryItem*) CFDictionaryGetValue(m_entriesByURL.get(), urlString); 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!entry) 7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = removeItemFromDateCaches(entry); 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionaryRemoveValue(m_entriesByURL.get(), urlString); 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!CFDictionaryGetCount(m_entriesByURL.get())) 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PageGroup::removeAllVisitedLinks(); 7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 788563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkCOMPtr<IWebHistoryItem> WebHistory::itemForURLString(const String& urlString) const 789563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{ 790563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark RetainPtr<CFStringRef> urlCFString(AdoptCF, urlString.createCFString()); 791563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (!urlCFString) 792563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return 0; 793563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark COMPtr<IWebHistoryItem> item; 794563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark if (FAILED(itemForURLString(urlCFString.get(), &item))) 795563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return 0; 796563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark return item; 797563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark} 798563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark 7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::addItemToDateCaches(IWebHistoryItem* entry) 8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DATE lastVisitedCOMTime; 8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project entry->lastVisitedTimeInterval(&lastVisitedCOMTime); 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DateKey dateKey; 8070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (findKey(&dateKey, MarshallingHelpers::DATEToCFAbsoluteTime(lastVisitedCOMTime))) { 8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // other entries already exist for this date 8090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch hr = insertItem(entry, dateKey); 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 8110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!m_entriesByDate.contains(dateKey)); 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // no other entries exist for this date 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<CFMutableArrayRef> entryArray(AdoptCF, 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFArrayCreateMutable(0, 0, &MarshallingHelpers::kIUnknownArrayCallBacks)); 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFArrayAppendValue(entryArray.get(), entry); 8160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_entriesByDate.set(dateKey, entryArray); 8170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Clear m_orderedLastVisitedDays so it will be regenerated when next requested. 8180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_orderedLastVisitedDays.clear(); 8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::removeItemFromDateCaches(IWebHistoryItem* entry) 8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DATE lastVisitedCOMTime; 8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project entry->lastVisitedTimeInterval(&lastVisitedCOMTime); 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DateKey dateKey; 8320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!findKey(&dateKey, MarshallingHelpers::DATEToCFAbsoluteTime(lastVisitedCOMTime))) 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DateToEntriesMap::iterator found = m_entriesByDate.find(dateKey); 8360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(found != m_entriesByDate.end()); 8370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFMutableArrayRef entriesForDate = found->second.get(); 8380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFIndex count = CFArrayGetCount(entriesForDate); 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = count - 1; i >= 0; --i) { 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((IWebHistoryItem*)CFArrayGetValueAtIndex(entriesForDate, i) == entry) 8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFArrayRemoveValueAtIndex(entriesForDate, i); 8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // remove this date entirely if there are no other entries on it 8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (CFArrayGetCount(entriesForDate) == 0) { 8470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_entriesByDate.remove(found); 8480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Clear m_orderedLastVisitedDays so it will be regenerated when next requested. 8490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_orderedLastVisitedDays.clear(); 8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 855231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void getDayBoundaries(CFAbsoluteTime day, CFAbsoluteTime& beginningOfDay, CFAbsoluteTime& beginningOfNextDay) 8560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 8570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RetainPtr<CFTimeZoneRef> timeZone(AdoptCF, CFTimeZoneCopyDefault()); 8580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(day, timeZone.get()); 8590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch date.hour = 0; 8600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch date.minute = 0; 8610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch date.second = 0; 862231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block beginningOfDay = CFGregorianDateGetAbsoluteTime(date, timeZone.get()); 863231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block date.day += 1; 864231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block beginningOfNextDay = CFGregorianDateGetAbsoluteTime(date, timeZone.get()); 865231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 8660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 867231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic inline CFAbsoluteTime beginningOfDay(CFAbsoluteTime date) 868231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 869231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static CFAbsoluteTime cachedBeginningOfDay = numeric_limits<CFAbsoluteTime>::quiet_NaN(); 870231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static CFAbsoluteTime cachedBeginningOfNextDay; 871231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!(date >= cachedBeginningOfDay && date < cachedBeginningOfNextDay)) 872231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block getDayBoundaries(date, cachedBeginningOfDay, cachedBeginningOfNextDay); 873231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return cachedBeginningOfDay; 874231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 875231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 876231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic inline WebHistory::DateKey dateKey(CFAbsoluteTime date) 877231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 878231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Converting from double (CFAbsoluteTime) to int64_t (WebHistoryDateKey) is 879231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // safe here because all sensible dates are in the range -2**48 .. 2**47 which 880231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // safely fits in an int64_t. 881231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return beginningOfDay(date); 8820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 8830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Returns whether the day is already in the list of days, 8850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// and fills in *key with the found or proposed key. 8860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool WebHistory::findKey(DateKey* key, CFAbsoluteTime forDay) 8870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 8880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT_ARG(key, key); 8890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 890231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *key = dateKey(forDay); 8910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return m_entriesByDate.contains(*key); 8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHRESULT WebHistory::insertItem(IWebHistoryItem* entry, DateKey dateKey) 8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT_ARG(entry, entry); 8970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT_ARG(dateKey, m_entriesByDate.contains(dateKey)); 8980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = S_OK; 9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!entry) 9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return E_FAIL; 9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DATE entryTime; 9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project entry->lastVisitedTimeInterval(&entryTime); 9060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFMutableArrayRef entriesForDate = m_entriesByDate.get(dateKey).get(); 9070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned count = CFArrayGetCount(entriesForDate); 9080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // The entries for each day are stored in a sorted array with the most recent entry first 9100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Check for the common cases of the entry being newer than all existing entries or the first entry of the day 9110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool isNewerThanAllEntries = false; 9120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (count) { 9130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IWebHistoryItem* item = const_cast<IWebHistoryItem*>(static_cast<const IWebHistoryItem*>(CFArrayGetValueAtIndex(entriesForDate, 0))); 9140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DATE itemTime; 9150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch isNewerThanAllEntries = SUCCEEDED(item->lastVisitedTimeInterval(&itemTime)) && itemTime < entryTime; 9160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!count || isNewerThanAllEntries) { 9180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFArrayInsertValueAtIndex(entriesForDate, 0, entry); 9190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return S_OK; 9200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // .. or older than all existing entries 9230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool isOlderThanAllEntries = false; 9240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (count > 0) { 9250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IWebHistoryItem* item = const_cast<IWebHistoryItem*>(static_cast<const IWebHistoryItem*>(CFArrayGetValueAtIndex(entriesForDate, count - 1))); 9260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DATE itemTime; 9270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch isOlderThanAllEntries = SUCCEEDED(item->lastVisitedTimeInterval(&itemTime)) && itemTime >= entryTime; 9280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isOlderThanAllEntries) { 9300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFArrayInsertValueAtIndex(entriesForDate, count, entry); 9310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return S_OK; 9320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned low = 0; 9350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned high = count; 9360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch while (low < high) { 9370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned mid = low + (high - low) / 2; 9380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch IWebHistoryItem* item = const_cast<IWebHistoryItem*>(static_cast<const IWebHistoryItem*>(CFArrayGetValueAtIndex(entriesForDate, mid))); 9390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DATE itemTime; 9400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (FAILED(item->lastVisitedTimeInterval(&itemTime))) 9410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return E_FAIL; 9420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (itemTime >= entryTime) 9440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch low = mid + 1; 9450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else 9460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch high = mid; 9470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 9480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 9490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // low is now the index of the first entry that is older than entryDate 9500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CFArrayInsertValueAtIndex(entriesForDate, low, entry); 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCFAbsoluteTime WebHistory::timeToDate(CFAbsoluteTime time) 9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // can't just divide/round since the day boundaries depend on our current time zone 9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const double secondsPerDay = 60 * 60 * 24; 9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); 9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(time, timeZone); 9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project date.hour = date.minute = 0; 9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project date.second = 0.0; 9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFAbsoluteTime timeInDays = CFGregorianDateGetAbsoluteTime(date, timeZone); 9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (areEqualOrClose(time - timeInDays, secondsPerDay)) 9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project timeInDays += secondsPerDay; 9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return timeInDays; 9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Return a date that marks the age limit for history entries saved to or 9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// loaded from disk. Any entry older than this item should be rejected. 9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHRESULT WebHistory::ageLimitDate(CFAbsoluteTime* time) 9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // get the current date as a CFAbsoluteTime 9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFAbsoluteTime currentDate = timeToDate(CFAbsoluteTimeGetCurrent()); 9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFGregorianUnits ageLimit = {0}; 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int historyLimitDays; 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HRESULT hr = historyAgeInDaysLimit(&historyLimitDays); 9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FAILED(hr)) 9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return hr; 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ageLimit.days = -historyLimitDays; 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *time = CFAbsoluteTimeAddGregorianUnits(currentDate, CFTimeZoneCopySystem(), ageLimit); 9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return S_OK; 9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void addVisitedLinkToPageGroup(const void* key, const void*, void* context) 9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFStringRef url = static_cast<CFStringRef>(key); 9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PageGroup* group = static_cast<PageGroup*>(context); 9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFIndex length = CFStringGetLength(url); 9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* characters = reinterpret_cast<const UChar*>(CFStringGetCharactersPtr(url)); 9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (characters) 9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project group->addVisitedLink(characters, length); 9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<UChar, 512> buffer(length); 9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFStringGetCharacters(url, CFRangeMake(0, length), reinterpret_cast<UniChar*>(buffer.data())); 9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project group->addVisitedLink(buffer.data(), length); 9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebHistory::addVisitedLinksToPageGroup(PageGroup& group) 10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CFDictionaryApplyFunction(m_entriesByURL.get(), addVisitedLinkToPageGroup, &group); 10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 10060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRetainPtr<CFDataRef> WebHistory::data() const 10070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 10080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (m_entriesByDate.isEmpty()) 10090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 10100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 10110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch WebHistoryWriter writer(m_entriesByDate); 10120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch writer.writePropertyList(); 10130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return writer.releaseData(); 10140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1015