2 * Copyright (C) 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "HistoryPropertyList.h"
29 #include "HistoryItem.h"
30 #include <wtf/StringExtras.h>
34 static const int currentFileVersion = 1;
36 HistoryPropertyListWriter::HistoryPropertyListWriter()
37 : m_dailyVisitCountsKey("D")
38 , m_displayTitleKey("displayTitle")
39 , m_lastVisitWasFailureKey("lastVisitWasFailure")
40 , m_lastVisitWasHTTPNonGetKey("lastVisitWasHTTPNonGet")
41 , m_lastVisitedDateKey("lastVisitedDate")
42 , m_redirectURLsKey("redirectURLs")
45 , m_visitCountKey("visitCount")
46 , m_weeklyVisitCountsKey("W")
51 UInt8* HistoryPropertyListWriter::buffer(size_t size)
54 m_buffer = static_cast<UInt8*>(CFAllocatorAllocate(0, size, 0));
59 RetainPtr<CFDataRef> HistoryPropertyListWriter::releaseData()
61 UInt8* buffer = m_buffer;
65 RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, buffer, m_bufferSize, 0));
67 CFAllocatorDeallocate(0, buffer);
73 void HistoryPropertyListWriter::writeObjects(BinaryPropertyListObjectStream& stream)
75 size_t outerDictionaryStart = stream.writeDictionaryStart();
77 stream.writeString("WebHistoryFileVersion");
78 stream.writeString("WebHistoryDates");
80 stream.writeInteger(currentFileVersion);
81 size_t outerDateArrayStart = stream.writeArrayStart();
82 writeHistoryItems(stream);
83 stream.writeArrayEnd(outerDateArrayStart);
85 stream.writeDictionaryEnd(outerDictionaryStart);
88 void HistoryPropertyListWriter::writeHistoryItem(BinaryPropertyListObjectStream& stream, HistoryItem* item)
90 size_t itemDictionaryStart = stream.writeDictionaryStart();
92 const String& title = item->title();
93 const String& displayTitle = item->alternateTitle();
94 double lastVisitedDate = item->lastVisitedTime();
95 int visitCount = item->visitCount();
96 Vector<String>* redirectURLs = item->redirectURLs();
97 const Vector<int>& dailyVisitCounts = item->dailyVisitCounts();
98 const Vector<int>& weeklyVisitCounts = item->weeklyVisitCounts();
101 stream.writeString(m_urlKey);
102 if (!title.isEmpty())
103 stream.writeString(m_titleKey);
104 if (!displayTitle.isEmpty())
105 stream.writeString(m_displayTitleKey);
107 stream.writeString(m_lastVisitedDateKey);
109 stream.writeString(m_visitCountKey);
110 if (item->lastVisitWasFailure())
111 stream.writeString(m_lastVisitWasFailureKey);
112 if (item->lastVisitWasHTTPNonGet())
113 stream.writeString(m_lastVisitWasHTTPNonGetKey);
115 stream.writeString(m_redirectURLsKey);
116 if (!dailyVisitCounts.isEmpty())
117 stream.writeString(m_dailyVisitCountsKey);
118 if (!weeklyVisitCounts.isEmpty())
119 stream.writeString(m_weeklyVisitCountsKey);
122 stream.writeUniqueString(item->urlString());
123 if (!title.isEmpty())
124 stream.writeString(title);
125 if (!displayTitle.isEmpty())
126 stream.writeString(displayTitle);
127 if (lastVisitedDate) {
129 snprintf(buffer, sizeof(buffer), "%.1lf", lastVisitedDate);
130 stream.writeUniqueString(buffer);
133 stream.writeInteger(visitCount);
134 if (item->lastVisitWasFailure())
135 stream.writeBooleanTrue();
136 if (item->lastVisitWasHTTPNonGet()) {
137 ASSERT(item->urlString().startsWith("http:", false) || item->urlString().startsWith("https:", false));
138 stream.writeBooleanTrue();
141 size_t redirectArrayStart = stream.writeArrayStart();
142 size_t size = redirectURLs->size();
144 for (size_t i = 0; i < size; ++i)
145 stream.writeUniqueString(redirectURLs->at(i));
146 stream.writeArrayEnd(redirectArrayStart);
148 if (size_t size = dailyVisitCounts.size())
149 stream.writeIntegerArray(dailyVisitCounts.data(), size);
150 if (size_t size = weeklyVisitCounts.size())
151 stream.writeIntegerArray(weeklyVisitCounts.data(), size);
153 stream.writeDictionaryEnd(itemDictionaryStart);