1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/glue_serialize.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/pickle.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebHTTPBody.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebSerializedScriptValue.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebData; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebHistoryItem; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebHTTPBody; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebPoint; 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebSerializedScriptValue; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebString; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebUChar; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebVector; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace webkit_glue { 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct SerializeObject { 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SerializeObject() : iter(NULL) {} 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SerializeObject(const char* data, int len) : pickle(data, len), iter(NULL) {} 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string GetAsString() { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(static_cast<const char*>(pickle.data()), pickle.size()); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Pickle pickle; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable void* iter; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mutable int version; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(mpcomplete): obsolete versions 1 and 2 after 1/1/2008. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Version ID used in reading/writing history items. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 1: Initial revision. 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 2: Added case for NULL string versus "". Version 2 code can read Version 1 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// data, but not vice versa. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 3: Version 2 was broken, it stored number of WebUChars, not number of bytes. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This version checks and reads v1 and v2 correctly. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 4: Adds support for storing FormData::identifier(). 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 5: Adds support for empty FormData 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 6: Adds support for documentSequenceNumbers 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 7: Adds support for stateObject 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 8: Adds support for file range and modification time 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 9: Adds support for itemSequenceNumbers 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// 10: Adds support for blob 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Should be const, but unit tests may modify it. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NOTE: If the version is -1, then the pickle contains only a URL string. 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See CreateHistoryStateForURL. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint kVersion = 10; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A bunch of convenience functions to read/write to SerializeObjects. 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The serializers assume the input data is in the correct format and so does 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// no error checking. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteData(const void* data, int length, SerializeObject* obj) { 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteData(static_cast<const char*>(data), length); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void ReadData(const SerializeObject* obj, const void** data, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* length) { 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* tmp = NULL; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.ReadData(&obj->iter, &tmp, length); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *data = tmp; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline bool ReadBytes(const SerializeObject* obj, const void** data, 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int length) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char *tmp; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!obj->pickle.ReadBytes(&obj->iter, &tmp, length)) 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *data = tmp; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteInteger(int data, SerializeObject* obj) { 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(data); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline int ReadInteger(const SerializeObject* obj) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int tmp = 0; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.ReadInt(&obj->iter, &tmp); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return tmp; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteInteger64(int64 data, SerializeObject* obj) { 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt64(data); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline int64 ReadInteger64(const SerializeObject* obj) { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 tmp = 0; 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.ReadInt64(&obj->iter, &tmp); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return tmp; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteReal(double data, SerializeObject* obj) { 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteData(&data, sizeof(double), obj); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline double ReadReal(const SerializeObject* obj) { 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const void* tmp = NULL; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int length = 0; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReadData(obj, &tmp, &length); 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (tmp && length > 0 && length >= static_cast<int>(sizeof(0.0))) 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *static_cast<const double*>(tmp); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0.0; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteBoolean(bool data, SerializeObject* obj) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(data ? 1 : 0); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline bool ReadBoolean(const SerializeObject* obj) { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool tmp = false; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.ReadBool(&obj->iter, &tmp); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return tmp; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteGURL(const GURL& url, SerializeObject* obj) { 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteString(url.possibly_invalid_spec()); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline GURL ReadGURL(const SerializeObject* obj) { 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string spec; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.ReadString(&obj->iter, &spec); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(spec); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Read/WriteString pickle the WebString as <int length><WebUChar* data>. 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// If length == -1, then the WebString itself is NULL (WebString()). 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Otherwise the length is the number of WebUChars (not bytes) in the WebString. 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline void WriteString(const WebString& str, SerializeObject* obj) { 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (kVersion) { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case 1: 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Version 1 writes <length in bytes><string data>. 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It saves WebString() and "" as "". 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(str.length() * sizeof(WebUChar)); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteBytes(str.data(), str.length() * sizeof(WebUChar)); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case 2: 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Version 2 writes <length in WebUChar><string data>. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It uses -1 in the length field to mean WebString(). 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (str.isNull()) { 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(-1); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(str.length()); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteBytes(str.data(), 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch str.length() * sizeof(WebUChar)); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Version 3+ writes <length in bytes><string data>. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It uses -1 in the length field to mean WebString(). 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (str.isNull()) { 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(-1); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteInt(str.length() * sizeof(WebUChar)); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->pickle.WriteBytes(str.data(), 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch str.length() * sizeof(WebUChar)); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This reads a serialized WebString from obj. If a string can't be read, 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebString() is returned. 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochinline WebString ReadString(const SerializeObject* obj) { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int length; 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Versions 1, 2, and 3 all start with an integer. 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!obj->pickle.ReadInt(&obj->iter, &length)) 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebString(); 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Starting with version 2, -1 means WebString(). 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (length == -1) 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebString(); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In version 2, the length field was the length in WebUChars. 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In version 1 and 3 it is the length in bytes. 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int bytes = length; 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (obj->version == 2) 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bytes *= sizeof(WebUChar); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const void* data; 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ReadBytes(obj, &data, bytes)) 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebString(); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebString(static_cast<const WebUChar*>(data), 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bytes / sizeof(WebUChar)); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Writes a Vector of Strings into a SerializeObject for serialization. 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void WriteStringVector( 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebVector<WebString>& data, SerializeObject* obj) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(static_cast<int>(data.size()), obj); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0, c = data.size(); i < c; ++i) { 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned ui = static_cast<unsigned>(i); // sigh 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(data[ui], obj); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic WebVector<WebString> ReadStringVector(const SerializeObject* obj) { 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_elements = ReadInteger(obj); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebVector<WebString> result(static_cast<size_t>(num_elements)); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < num_elements; ++i) 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result[i] = ReadString(obj); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Writes a FormData object into a SerializeObject for serialization. 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void WriteFormData(const WebHTTPBody& http_body, SerializeObject* obj) { 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteBoolean(!http_body.isNull(), obj); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (http_body.isNull()) 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(static_cast<int>(http_body.elementCount()), obj); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebHTTPBody::Element element; 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; http_body.elementAt(i, element); ++i) { 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(element.type, obj); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (element.type == WebHTTPBody::Element::TypeData) { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteData(element.data.data(), static_cast<int>(element.data.size()), 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj); 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (element.type == WebHTTPBody::Element::TypeFile) { 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(element.filePath, obj); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger64(element.fileStart, obj); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger64(element.fileLength, obj); 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WriteReal(element.modificationTime, obj); 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WriteGURL(element.blobURL, obj); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger64(http_body.identifier(), obj); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic WebHTTPBody ReadFormData(const SerializeObject* obj) { 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In newer versions, an initial boolean indicates if we have form data. 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version >= 5 && !ReadBoolean(obj)) 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebHTTPBody(); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In older versions, 0 elements implied no form data. 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_elements = ReadInteger(obj); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (num_elements == 0 && obj->version < 5) 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebHTTPBody(); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebHTTPBody http_body; 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch http_body.initialize(); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < num_elements; ++i) { 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int type = ReadInteger(obj); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == WebHTTPBody::Element::TypeData) { 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const void* data; 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int length = -1; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReadData(obj, &data, &length); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (length >= 0) 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch http_body.appendData(WebData(static_cast<const char*>(data), length)); 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (type == WebHTTPBody::Element::TypeFile) { 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebString file_path = ReadString(obj); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch long long file_start = 0; 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch long long file_length = -1; 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick double modification_time = 0.0; 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version >= 8) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_start = ReadInteger64(obj); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_length = ReadInteger64(obj); 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick modification_time = ReadReal(obj); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick http_body.appendFileRange(file_path, file_start, file_length, 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick modification_time); 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (obj->version >= 10) { 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL blob_url = ReadGURL(obj); 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick http_body.appendBlob(blob_url); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version >= 4) 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch http_body.setIdentifier(ReadInteger64(obj)); 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return http_body; 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Writes the HistoryItem data into the SerializeObject object for 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// serialization. 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void WriteHistoryItem( 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebHistoryItem& item, SerializeObject* obj) { 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WARNING: This data may be persisted for later use. As such, care must be 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // taken when changing the serialized format. If a new field needs to be 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // written, only adding at the end will make it easier to deal with loading 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // older versions. Similarly, this should NOT save fields with sensitive 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // data, such as password fields. 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(kVersion, obj); 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.urlString(), obj); 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.originalURLString(), obj); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.target(), obj); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.parent(), obj); 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.title(), obj); 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.alternateTitle(), obj); 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteReal(item.lastVisitedTime(), obj); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(item.scrollOffset().x, obj); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(item.scrollOffset().y, obj); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteBoolean(item.isTargetItem(), obj); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(item.visitCount(), obj); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.referrer(), obj); 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteStringVector(item.documentState(), obj); 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (kVersion >= 9) 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger64(item.itemSequenceNumber(), obj); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (kVersion >= 6) 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger64(item.documentSequenceNumber(), obj); 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (kVersion >= 7) { 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_state_object = !item.stateObject().isNull(); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteBoolean(has_state_object, obj); 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_state_object) 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.stateObject().toString(), obj); 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Yes, the referrer is written twice. This is for backwards 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // compatibility with the format. 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteFormData(item.httpBody(), obj); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.httpContentType(), obj); 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteString(item.referrer(), obj); 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Subitems 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebVector<WebHistoryItem>& children = item.children(); 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(static_cast<int>(children.size()), obj); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0, c = children.size(); i < c; ++i) 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteHistoryItem(children[i], obj); 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a new HistoryItem tree based on the serialized string. 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Assumes the data is in the format returned by WriteHistoryItem. 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic WebHistoryItem ReadHistoryItem( 34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const SerializeObject* obj, 34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool include_form_data, 34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool include_scroll_offset) { 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See note in WriteHistoryItem. on this. 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch obj->version = ReadInteger(obj); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version == -1) { 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url = ReadGURL(obj); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebHistoryItem item; 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.initialize(); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setURLString(WebString::fromUTF8(url.possibly_invalid_spec())); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return item; 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version > kVersion || obj->version < 1) 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebHistoryItem(); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebHistoryItem item; 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.initialize(); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setURLString(ReadString(obj)); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setOriginalURLString(ReadString(obj)); 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setTarget(ReadString(obj)); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setParent(ReadString(obj)); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setTitle(ReadString(obj)); 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setAlternateTitle(ReadString(obj)); 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setLastVisitedTime(ReadReal(obj)); 37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int x = ReadInteger(obj); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int y = ReadInteger(obj); 37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (include_scroll_offset) 37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen item.setScrollOffset(WebPoint(x, y)); 37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setIsTargetItem(ReadBoolean(obj)); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setVisitCount(ReadInteger(obj)); 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setReferrer(ReadString(obj)); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setDocumentState(ReadStringVector(obj)); 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version >= 9) 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setItemSequenceNumber(ReadInteger64(obj)); 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version >= 6) 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setDocumentSequenceNumber(ReadInteger64(obj)); 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (obj->version >= 7) { 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_state_object = ReadBoolean(obj); 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_state_object) { 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setStateObject( 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebSerializedScriptValue::fromString(ReadString(obj))); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The extra referrer string is read for backwards compat. 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebHTTPBody& http_body = ReadFormData(obj); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebString& http_content_type = ReadString(obj); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_UNUSED const WebString& unused_referrer = ReadString(obj); 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (include_form_data) { 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setHTTPBody(http_body); 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch item.setHTTPContentType(http_content_type); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Subitems 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int num_children = ReadInteger(obj); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < num_children; ++i) 40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen item.appendToChildren(ReadHistoryItem(obj, 41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen include_form_data, 41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen include_scroll_offset)); 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return item; 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Serialize a HistoryItem to a string, using our JSON Value serializer. 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string HistoryItemToString(const WebHistoryItem& item) { 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (item.isNull()) 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(); 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SerializeObject obj; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteHistoryItem(item, &obj); 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return obj.GetAsString(); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Reconstruct a HistoryItem from a string, using our JSON Value deserializer. 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This assumes that the given serialized string has all the required key,value 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pairs, and does minimal error checking. If |include_form_data| is true, 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the form data from a post is restored, otherwise the form data is empty. 43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// If |include_scroll_offset| is true, the scroll offset is restored. 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic WebHistoryItem HistoryItemFromString( 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& serialized_item, 43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool include_form_data, 43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool include_scroll_offset) { 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (serialized_item.empty()) 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WebHistoryItem(); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SerializeObject obj(serialized_item.data(), 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(serialized_item.length())); 44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ReadHistoryItem(&obj, include_form_data, include_scroll_offset); 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebHistoryItem HistoryItemFromString( 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& serialized_item) { 44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return HistoryItemFromString(serialized_item, true, true); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For testing purposes only. 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryItemToVersionedString(const WebHistoryItem& item, int version, 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* serialized_item) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (item.isNull()) { 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch serialized_item->clear(); 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Temporarily change the version. 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int real_version = kVersion; 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kVersion = version; 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SerializeObject obj; 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteHistoryItem(item, &obj); 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *serialized_item = obj.GetAsString(); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kVersion = real_version; 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string CreateHistoryStateForURL(const GURL& url) { 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We avoid using the WebKit API here, so that we do not need to have WebKit 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // initialized before calling this method. Instead, we write a simple 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // serialization of the given URL with a dummy version number of -1. This 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will be interpreted by ReadHistoryItem as a request to create a default 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WebHistoryItem. 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SerializeObject obj; 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteInteger(-1, &obj); 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteGURL(url, &obj); 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return obj.GetAsString(); 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string RemoveFormDataFromHistoryState(const std::string& content_state) { 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(darin): We should avoid using the WebKit API here, so that we do not 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // need to have WebKit initialized before calling this method. 48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const WebHistoryItem& item = 48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HistoryItemFromString(content_state, false, true); 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (item.isNull()) { 48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Couldn't parse the string, return an empty string. 48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return std::string(); 48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 48821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 48921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return HistoryItemToString(item); 49021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 49121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 49221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstd::string RemoveScrollOffsetFromHistoryState( 49321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const std::string& content_state) { 49421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(darin): We should avoid using the WebKit API here, so that we do not 49521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // need to have WebKit initialized before calling this method. 49621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const WebHistoryItem& item = 49721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen HistoryItemFromString(content_state, true, false); 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (item.isNull()) { 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Couldn't parse the string, return an empty string. 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return HistoryItemToString(item); 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace webkit_glue 507