⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webhistory.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "WebKitDLL.h"#include "WebHistory.h"#include "CFDictionaryPropertyBag.h"#include "WebKit.h"#include "MarshallingHelpers.h"#include "WebHistoryItem.h"#include "WebKit.h"#include "WebNotificationCenter.h"#include "WebPreferences.h"#include <CoreFoundation/CoreFoundation.h>#pragma warning( push, 0 )#include <wtf/Vector.h>#include <WebCore/KURL.h>#include <WebCore/PageGroup.h>#include <WebCore/HistoryItem.h>#pragma warning( pop )#include <wtf/StdLibExtras.h>using namespace WebCore;CFStringRef DatesArrayKey = CFSTR("WebHistoryDates");CFStringRef FileVersionKey = CFSTR("WebHistoryFileVersion");#define currentFileVersion 1static bool areEqualOrClose(double d1, double d2){    double diff = d1-d2;    return (diff < .000001 && diff > -.000001);}static CFDictionaryPropertyBag* createUserInfoFromArray(BSTR notificationStr, CFArrayRef arrayItem){    RetainPtr<CFMutableDictionaryRef> dictionary(AdoptCF,         CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));    RetainPtr<CFStringRef> key(AdoptCF, MarshallingHelpers::BSTRToCFStringRef(notificationStr));    CFDictionaryAddValue(dictionary.get(), key.get(), arrayItem);    CFDictionaryPropertyBag* result = CFDictionaryPropertyBag::createInstance();    result->setDictionary(dictionary.get());    return result;}static CFDictionaryPropertyBag* createUserInfoFromHistoryItem(BSTR notificationStr, IWebHistoryItem* item){    // reference counting of item added to the array is managed by the CFArray value callbacks    RetainPtr<CFArrayRef> itemList(AdoptCF, CFArrayCreate(0, (const void**) &item, 1, &MarshallingHelpers::kIUnknownArrayCallBacks));    CFDictionaryPropertyBag* info = createUserInfoFromArray(notificationStr, itemList.get());    return info;}static void releaseUserInfo(CFDictionaryPropertyBag* userInfo){    // free the dictionary    userInfo->setDictionary(0);    int result = userInfo->Release();    (void)result;    ASSERT(result == 0);   // make sure no one else holds a reference to the userInfo.}// WebHistory -----------------------------------------------------------------WebHistory::WebHistory(): m_refCount(0), m_preferences(0){    gClassCount++;    gClassNameCount.add("WebHistory");    m_entriesByURL.adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &MarshallingHelpers::kIUnknownDictionaryValueCallBacks));    m_datesWithEntries.adoptCF(CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));    m_entriesByDate.adoptCF(CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));    m_preferences = WebPreferences::sharedStandardPreferences();}WebHistory::~WebHistory(){    gClassCount--;    gClassNameCount.remove("WebHistory");}WebHistory* WebHistory::createInstance(){    WebHistory* instance = new WebHistory();    instance->AddRef();    return instance;}HRESULT WebHistory::postNotification(NotificationType notifyType, IPropertyBag* userInfo /*=0*/){    IWebNotificationCenter* nc = WebNotificationCenter::defaultCenterInternal();    HRESULT hr = nc->postNotificationName(getNotificationString(notifyType), static_cast<IWebHistory*>(this), userInfo);    if (FAILED(hr))        return hr;    return S_OK;}BSTR WebHistory::getNotificationString(NotificationType notifyType){    static BSTR keys[6] = {0};    if (!keys[0]) {        keys[0] = SysAllocString(WebHistoryItemsAddedNotification);        keys[1] = SysAllocString(WebHistoryItemsRemovedNotification);        keys[2] = SysAllocString(WebHistoryAllItemsRemovedNotification);        keys[3] = SysAllocString(WebHistoryLoadedNotification);        keys[4] = SysAllocString(WebHistoryItemsDiscardedWhileLoadingNotification);        keys[5] = SysAllocString(WebHistorySavedNotification);    }    return keys[notifyType];}// IUnknown -------------------------------------------------------------------HRESULT STDMETHODCALLTYPE WebHistory::QueryInterface(REFIID riid, void** ppvObject){    *ppvObject = 0;    if (IsEqualGUID(riid, CLSID_WebHistory))        *ppvObject = this;    else if (IsEqualGUID(riid, IID_IUnknown))        *ppvObject = static_cast<IWebHistory*>(this);    else if (IsEqualGUID(riid, IID_IWebHistory))        *ppvObject = static_cast<IWebHistory*>(this);    else if (IsEqualGUID(riid, IID_IWebHistoryPrivate))        *ppvObject = static_cast<IWebHistoryPrivate*>(this);    else        return E_NOINTERFACE;    AddRef();    return S_OK;}ULONG STDMETHODCALLTYPE WebHistory::AddRef(void){    return ++m_refCount;}ULONG STDMETHODCALLTYPE WebHistory::Release(void){    ULONG newRef = --m_refCount;    if (!newRef)        delete(this);    return newRef;}// IWebHistory ----------------------------------------------------------------static inline COMPtr<WebHistory>& sharedHistoryStorage(){    DEFINE_STATIC_LOCAL(COMPtr<WebHistory>, sharedHistory, ());    return sharedHistory;}WebHistory* WebHistory::sharedHistory(){    return sharedHistoryStorage().get();}HRESULT STDMETHODCALLTYPE WebHistory::optionalSharedHistory(     /* [retval][out] */ IWebHistory** history){    *history = sharedHistory();    if (*history)        (*history)->AddRef();    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::setOptionalSharedHistory(     /* [in] */ IWebHistory* history){    if (sharedHistoryStorage() == history)        return S_OK;    sharedHistoryStorage().query(history);    PageGroup::setShouldTrackVisitedLinks(sharedHistoryStorage());    PageGroup::removeAllVisitedLinks();    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::loadFromURL(     /* [in] */ BSTR url,    /* [out] */ IWebError** error,    /* [retval][out] */ BOOL* succeeded){    HRESULT hr = S_OK;    RetainPtr<CFMutableArrayRef> discardedItems(AdoptCF,         CFArrayCreateMutable(0, 0, &MarshallingHelpers::kIUnknownArrayCallBacks));    RetainPtr<CFURLRef> urlRef(AdoptCF, MarshallingHelpers::BSTRToCFURLRef(url));    hr = loadHistoryGutsFromURL(urlRef.get(), discardedItems.get(), error);    if (FAILED(hr))        goto exit;    hr = postNotification(kWebHistoryLoadedNotification);    if (FAILED(hr))        goto exit;    if (CFArrayGetCount(discardedItems.get()) > 0) {        CFDictionaryPropertyBag* userInfo = createUserInfoFromArray(getNotificationString(kWebHistoryItemsDiscardedWhileLoadingNotification), discardedItems.get());        hr = postNotification(kWebHistoryItemsDiscardedWhileLoadingNotification, userInfo);        releaseUserInfo(userInfo);        if (FAILED(hr))            goto exit;    }exit:    if (succeeded)        *succeeded = SUCCEEDED(hr);    return hr;}static CFDictionaryRef createHistoryListFromStream(CFReadStreamRef stream, CFPropertyListFormat format){    return (CFDictionaryRef)CFPropertyListCreateFromStream(0, stream, 0, kCFPropertyListImmutable, &format, 0);}HRESULT WebHistory::loadHistoryGutsFromURL(CFURLRef url, CFMutableArrayRef discardedItems, IWebError** /*error*/) //FIXME{    CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0 | kCFPropertyListXMLFormat_v1_0;    HRESULT hr = S_OK;    int numberOfItemsLoaded = 0;    RetainPtr<CFReadStreamRef> stream(AdoptCF, CFReadStreamCreateWithFile(0, url));    if (!stream)         return E_FAIL;    if (!CFReadStreamOpen(stream.get()))         return E_FAIL;    RetainPtr<CFDictionaryRef> historyList(AdoptCF, createHistoryListFromStream(stream.get(), format));    CFReadStreamClose(stream.get());    if (!historyList)         return E_FAIL;    CFNumberRef fileVersionObject = (CFNumberRef)CFDictionaryGetValue(historyList.get(), FileVersionKey);    int fileVersion;    if (!CFNumberGetValue(fileVersionObject, kCFNumberIntType, &fileVersion))         return E_FAIL;    if (fileVersion > currentFileVersion)         return E_FAIL;        CFArrayRef datesArray = (CFArrayRef)CFDictionaryGetValue(historyList.get(), DatesArrayKey);    int itemCountLimit;    hr = historyItemLimit(&itemCountLimit);    if (FAILED(hr))        return hr;    CFAbsoluteTime limitDate;    hr = ageLimitDate(&limitDate);    if (FAILED(hr))        return hr;    bool ageLimitPassed = false;    bool itemLimitPassed = false;    CFIndex itemCount = CFArrayGetCount(datesArray);    for (CFIndex i = 0; i < itemCount; ++i) {        CFDictionaryRef itemAsDictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(datesArray, i);        COMPtr<WebHistoryItem> item(AdoptCOM, WebHistoryItem::createInstance());        hr = item->initFromDictionaryRepresentation((void*)itemAsDictionary);        if (FAILED(hr))            return hr;        // item without URL is useless; data on disk must have been bad; ignore        BOOL hasURL;        hr = item->hasURLString(&hasURL);        if (FAILED(hr))            return hr;                if (hasURL) {            // Test against date limit. Since the items are ordered newest to oldest, we can stop comparing            // once we've found the first item that's too old.            if (!ageLimitPassed) {                DATE lastVisitedTime;                hr = item->lastVisitedTimeInterval(&lastVisitedTime);                if (FAILED(hr))                    return hr;                if (timeToDate(MarshallingHelpers::DATEToCFAbsoluteTime(lastVisitedTime)) <= limitDate)                    ageLimitPassed = true;            }            if (ageLimitPassed || itemLimitPassed)                CFArrayAppendValue(discardedItems, item.get());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -