initial import
[vuplus_webkit] / Source / WebCore / history / cf / HistoryPropertyList.cpp
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #include "config.h"
27 #include "HistoryPropertyList.h"
28
29 #include "HistoryItem.h"
30 #include <wtf/StringExtras.h>
31
32 namespace WebCore {
33
34 static const int currentFileVersion = 1;
35
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")
43     , m_titleKey("title")
44     , m_urlKey("")
45     , m_visitCountKey("visitCount")
46     , m_weeklyVisitCountsKey("W")
47     , m_buffer(0)
48 {
49 }
50
51 UInt8* HistoryPropertyListWriter::buffer(size_t size)
52 {
53     ASSERT(!m_buffer);
54     m_buffer = static_cast<UInt8*>(CFAllocatorAllocate(0, size, 0));
55     m_bufferSize = size;
56     return m_buffer;
57 }
58
59 RetainPtr<CFDataRef> HistoryPropertyListWriter::releaseData()
60 {
61     UInt8* buffer = m_buffer;
62     if (!buffer)
63         return 0;
64     m_buffer = 0;
65     RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(0, buffer, m_bufferSize, 0));
66     if (!data) {
67         CFAllocatorDeallocate(0, buffer);
68         return 0;
69     }
70     return data;
71 }
72
73 void HistoryPropertyListWriter::writeObjects(BinaryPropertyListObjectStream& stream)
74 {
75     size_t outerDictionaryStart = stream.writeDictionaryStart();
76
77     stream.writeString("WebHistoryFileVersion");
78     stream.writeString("WebHistoryDates");
79
80     stream.writeInteger(currentFileVersion);
81     size_t outerDateArrayStart = stream.writeArrayStart();
82     writeHistoryItems(stream);
83     stream.writeArrayEnd(outerDateArrayStart);
84
85     stream.writeDictionaryEnd(outerDictionaryStart);
86 }
87
88 void HistoryPropertyListWriter::writeHistoryItem(BinaryPropertyListObjectStream& stream, HistoryItem* item)
89 {
90     size_t itemDictionaryStart = stream.writeDictionaryStart();
91
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();
99
100     // keys
101     stream.writeString(m_urlKey);
102     if (!title.isEmpty())
103         stream.writeString(m_titleKey);
104     if (!displayTitle.isEmpty())
105         stream.writeString(m_displayTitleKey);
106     if (lastVisitedDate)
107         stream.writeString(m_lastVisitedDateKey);
108     if (visitCount)
109         stream.writeString(m_visitCountKey);
110     if (item->lastVisitWasFailure())
111         stream.writeString(m_lastVisitWasFailureKey);
112     if (item->lastVisitWasHTTPNonGet())
113         stream.writeString(m_lastVisitWasHTTPNonGetKey);
114     if (redirectURLs)
115         stream.writeString(m_redirectURLsKey);
116     if (!dailyVisitCounts.isEmpty())
117         stream.writeString(m_dailyVisitCountsKey);
118     if (!weeklyVisitCounts.isEmpty())
119         stream.writeString(m_weeklyVisitCountsKey);
120
121     // values
122     stream.writeUniqueString(item->urlString());
123     if (!title.isEmpty())
124         stream.writeString(title);
125     if (!displayTitle.isEmpty())
126         stream.writeString(displayTitle);
127     if (lastVisitedDate) {
128         char buffer[32];
129         snprintf(buffer, sizeof(buffer), "%.1lf", lastVisitedDate);
130         stream.writeUniqueString(buffer);
131     }
132     if (visitCount)
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();
139     }
140     if (redirectURLs) {
141         size_t redirectArrayStart = stream.writeArrayStart();
142         size_t size = redirectURLs->size();
143         ASSERT(size);
144         for (size_t i = 0; i < size; ++i)
145             stream.writeUniqueString(redirectURLs->at(i));
146         stream.writeArrayEnd(redirectArrayStart);
147     }
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);
152
153     stream.writeDictionaryEnd(itemDictionaryStart);
154 }
155
156 }