📄 webhistory.cpp
字号:
else { bool added; addItem(item.get(), true, &added); // ref is added inside addItem if (added) ++numberOfItemsLoaded; if (numberOfItemsLoaded == itemCountLimit) itemLimitPassed = true; } } } return hr;}HRESULT STDMETHODCALLTYPE WebHistory::saveToURL( /* [in] */ BSTR url, /* [out] */ IWebError** error, /* [retval][out] */ BOOL* succeeded){ HRESULT hr = S_OK; RetainPtr<CFURLRef> urlRef(AdoptCF, MarshallingHelpers::BSTRToCFURLRef(url)); hr = saveHistoryGuts(urlRef.get(), error); if (succeeded) *succeeded = SUCCEEDED(hr); if (SUCCEEDED(hr)) hr = postNotification(kWebHistorySavedNotification); return hr;}HRESULT WebHistory::saveHistoryGuts(CFURLRef url, IWebError** error){ HRESULT hr = S_OK; // FIXME: Correctly report error when new API is ready. if (error) *error = 0; RetainPtr<CFWriteStreamRef> stream(AdoptCF, CFWriteStreamCreateWithFile(kCFAllocatorDefault, url)); if (!stream) return E_FAIL; CFMutableArrayRef rawEntries; hr = datesArray(&rawEntries); if (FAILED(hr)) return hr; RetainPtr<CFMutableArrayRef> entries(AdoptCF, rawEntries); // create the outer dictionary CFTypeRef keys[2]; CFTypeRef values[2]; keys[0] = DatesArrayKey; values[0] = entries.get(); keys[1] = FileVersionKey; int version = currentFileVersion; RetainPtr<CFNumberRef> versionCF(AdoptCF, CFNumberCreate(0, kCFNumberIntType, &version)); values[1] = versionCF.get(); RetainPtr<CFDictionaryRef> dictionary(AdoptCF, CFDictionaryCreate(0, keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); if (!CFWriteStreamOpen(stream.get())) return E_FAIL; if (!CFPropertyListWriteToStream(dictionary.get(), stream.get(), kCFPropertyListXMLFormat_v1_0, 0)) hr = E_FAIL; CFWriteStreamClose(stream.get()); return hr;}HRESULT WebHistory::datesArray(CFMutableArrayRef* datesArray){ HRESULT hr = S_OK; RetainPtr<CFMutableArrayRef> result(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); // for each date with entries int dateCount = CFArrayGetCount(m_entriesByDate.get()); for (int i = 0; i < dateCount; ++i) { // get the entries for that date CFArrayRef entries = (CFArrayRef)CFArrayGetValueAtIndex(m_entriesByDate.get(), i); int entriesCount = CFArrayGetCount(entries); for (int j = entriesCount - 1; j >= 0; --j) { IWebHistoryItem* item = (IWebHistoryItem*) CFArrayGetValueAtIndex(entries, j); IWebHistoryItemPrivate* webHistoryItem; hr = item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&webHistoryItem); if (FAILED(hr)) return E_FAIL; CFDictionaryRef itemDict; hr = webHistoryItem->dictionaryRepresentation((void**)&itemDict); webHistoryItem->Release(); if (FAILED(hr)) return E_FAIL; CFArrayAppendValue(result.get(), itemDict); CFRelease(itemDict); } } if (SUCCEEDED(hr)) *datesArray = result.releaseRef(); return hr;}HRESULT STDMETHODCALLTYPE WebHistory::addItems( /* [in] */ int itemCount, /* [in] */ IWebHistoryItem** items){ // There is no guarantee that the incoming entries are in any particular // order, but if this is called with a set of entries that were created by // iterating through the results of orderedLastVisitedDays and orderedItemsLastVisitedOnDay // then they will be ordered chronologically from newest to oldest. We can make adding them // faster (fewer compares) by inserting them from oldest to newest. HRESULT hr; for (int i = itemCount - 1; i >= 0; --i) { hr = addItem(items[i], false, 0); if (FAILED(hr)) return hr; } return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::removeItems( /* [in] */ int itemCount, /* [in] */ IWebHistoryItem** items){ HRESULT hr; for (int i = 0; i < itemCount; ++i) { hr = removeItem(items[i]); if (FAILED(hr)) return hr; } return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::removeAllItems( void){ CFArrayRemoveAllValues(m_entriesByDate.get()); CFArrayRemoveAllValues(m_datesWithEntries.get()); CFIndex itemCount = CFDictionaryGetCount(m_entriesByURL.get()); Vector<IWebHistoryItem*> itemsVector(itemCount); CFDictionaryGetKeysAndValues(m_entriesByURL.get(), 0, (const void**)itemsVector.data()); RetainPtr<CFArrayRef> allItems(AdoptCF, CFArrayCreate(kCFAllocatorDefault, (const void**)itemsVector.data(), itemCount, &MarshallingHelpers::kIUnknownArrayCallBacks)); CFDictionaryRemoveAllValues(m_entriesByURL.get()); PageGroup::removeAllVisitedLinks(); CFDictionaryPropertyBag* userInfo = createUserInfoFromArray(getNotificationString(kWebHistoryAllItemsRemovedNotification), allItems.get()); return postNotification(kWebHistoryAllItemsRemovedNotification, userInfo);}HRESULT STDMETHODCALLTYPE WebHistory::orderedLastVisitedDays( /* [out][in] */ int* count, /* [in] */ DATE* calendarDates){ int dateCount = CFArrayGetCount(m_datesWithEntries.get()); if (!calendarDates) { *count = dateCount; return S_OK; } if (*count < dateCount) { *count = dateCount; return E_FAIL; } *count = dateCount; for (int i = 0; i < dateCount; i++) { CFNumberRef absoluteTimeNumberRef = (CFNumberRef)CFArrayGetValueAtIndex(m_datesWithEntries.get(), i); CFAbsoluteTime absoluteTime; if (!CFNumberGetValue(absoluteTimeNumberRef, kCFNumberDoubleType, &absoluteTime)) return E_FAIL; calendarDates[i] = MarshallingHelpers::CFAbsoluteTimeToDATE(absoluteTime); } return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::orderedItemsLastVisitedOnDay( /* [out][in] */ int* count, /* [in] */ IWebHistoryItem** items, /* [in] */ DATE calendarDate){ int index; if (!findIndex(&index, MarshallingHelpers::DATEToCFAbsoluteTime(calendarDate))) { *count = 0; return 0; } CFArrayRef entries = (CFArrayRef)CFArrayGetValueAtIndex(m_entriesByDate.get(), index); if (!entries) { *count = 0; return 0; } int newCount = CFArrayGetCount(entries); if (!items) { *count = newCount; return S_OK; } if (*count < newCount) { *count = newCount; return E_FAIL; } *count = newCount; for (int i = 0; i < newCount; i++) { IWebHistoryItem* item = (IWebHistoryItem*)CFArrayGetValueAtIndex(entries, i); item->AddRef(); items[newCount - i - 1] = item; // reverse when inserting to get the list sorted oldest to newest } return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::allItems( /* [out][in] */ int* count, /* [out][retval] */ IWebHistoryItem** items){ int entriesByURLCount = CFDictionaryGetCount(m_entriesByURL.get()); if (!items) { *count = entriesByURLCount; return S_OK; } if (*count < entriesByURLCount) { *count = entriesByURLCount; return E_FAIL; } *count = entriesByURLCount; CFDictionaryGetKeysAndValues(m_entriesByURL.get(), 0, (const void**)items); for (int i = 0; i < entriesByURLCount; i++) items[i]->AddRef(); return S_OK;}HRESULT STDMETHODCALLTYPE WebHistory::setHistoryItemLimit( /* [in] */ int limit){ if (!m_preferences) return E_FAIL; return m_preferences->setHistoryItemLimit(limit);}HRESULT STDMETHODCALLTYPE WebHistory::historyItemLimit( /* [retval][out] */ int* limit){ if (!m_preferences) return E_FAIL; return m_preferences->historyItemLimit(limit);}HRESULT STDMETHODCALLTYPE WebHistory::setHistoryAgeInDaysLimit( /* [in] */ int limit){ if (!m_preferences) return E_FAIL; return m_preferences->setHistoryAgeInDaysLimit(limit);}HRESULT STDMETHODCALLTYPE WebHistory::historyAgeInDaysLimit( /* [retval][out] */ int* limit){ if (!m_preferences) return E_FAIL; return m_preferences->historyAgeInDaysLimit(limit);}HRESULT WebHistory::removeItem(IWebHistoryItem* entry){ HRESULT hr = S_OK; BSTR urlBStr = 0; hr = entry->URLString(&urlBStr); if (FAILED(hr)) return hr; RetainPtr<CFStringRef> urlString(AdoptCF, MarshallingHelpers::BSTRToCFStringRef(urlBStr)); SysFreeString(urlBStr); // If this exact object isn't stored, then make no change. // FIXME: Is this the right behavior if this entry isn't present, but another entry for the same URL is? // Maybe need to change the API to make something like removeEntryForURLString public instead. IWebHistoryItem *matchingEntry = (IWebHistoryItem*)CFDictionaryGetValue(m_entriesByURL.get(), urlString.get()); if (matchingEntry != entry) return E_FAIL; hr = removeItemForURLString(urlString.get()); if (FAILED(hr)) return hr; CFDictionaryPropertyBag* userInfo = createUserInfoFromHistoryItem( getNotificationString(kWebHistoryItemsRemovedNotification), entry); hr = postNotification(kWebHistoryItemsRemovedNotification, userInfo); releaseUserInfo(userInfo); return hr;}HRESULT WebHistory::addItem(IWebHistoryItem* entry, bool discardDuplicate, bool* added)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -