1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/common/page_state_serialization.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <algorithm>
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <limits>
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/pickle.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_number_conversions.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_util.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/utf_string_conversions.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/gfx/screen.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content {
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochfloat g_device_scale_factor_for_testing = 0.0;
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//-----------------------------------------------------------------------------
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppendDataToHttpBody(ExplodedHttpBody* http_body, const char* data,
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          int data_length) {
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExplodedHttpBodyElement element;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  element.type = blink::WebHTTPBody::Element::TypeData;
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.data.assign(data, data_length);
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  http_body->elements.push_back(element);
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppendFileRangeToHttpBody(ExplodedHttpBody* http_body,
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               const base::NullableString16& file_path,
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               int file_start,
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               int file_length,
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               double file_modification_time) {
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExplodedHttpBodyElement element;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  element.type = blink::WebHTTPBody::Element::TypeFile;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_path = file_path;
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_start = file_start;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_length = file_length;
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_modification_time = file_modification_time;
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  http_body->elements.push_back(element);
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppendURLRangeToHttpBody(ExplodedHttpBody* http_body,
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              const GURL& url,
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              int file_start,
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              int file_length,
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              double file_modification_time) {
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ExplodedHttpBodyElement element;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  element.type = blink::WebHTTPBody::Element::TypeFileSystemURL;
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  element.filesystem_url = url;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_start = file_start;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_length = file_length;
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  element.file_modification_time = file_modification_time;
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  http_body->elements.push_back(element);
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AppendBlobToHttpBody(ExplodedHttpBody* http_body,
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                          const std::string& uuid) {
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ExplodedHttpBodyElement element;
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  element.type = blink::WebHTTPBody::Element::TypeBlob;
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  element.blob_uuid = uuid;
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  http_body->elements.push_back(element);
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//----------------------------------------------------------------------------
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppendReferencedFilesFromHttpBody(
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::vector<ExplodedHttpBodyElement>& elements,
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<base::NullableString16>* referenced_files) {
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < elements.size(); ++i) {
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (elements[i].type == blink::WebHTTPBody::Element::TypeFile)
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      referenced_files->push_back(elements[i].file_path);
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool AppendReferencedFilesFromDocumentState(
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::vector<base::NullableString16>& document_state,
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<base::NullableString16>* referenced_files) {
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (document_state.empty())
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This algorithm is adapted from Blink's core/html/FormController.cpp code.
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We only care about how that code worked when this code snapshot was taken
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // as this code is only needed for backwards compat.
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // For reference, see FormController::formStatesFromStateVector at:
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://src.chromium.org/viewvc/blink/trunk/Source/core/html/FormController.cpp?pathrev=152274
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t index = 0;
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (document_state.size() < 3)
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  index++;  // Skip over magic signature.
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  index++;  // Skip over form key.
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t item_count;
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!base::StringToSizeT(document_state[index++].string(), &item_count))
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  while (item_count--) {
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (index + 1 >= document_state.size())
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return false;
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    index++;  // Skip over name.
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::NullableString16& type = document_state[index++];
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (index >= document_state.size())
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return false;
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    size_t value_size;
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!base::StringToSizeT(document_state[index++].string(), &value_size))
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return false;
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (index + value_size > document_state.size() ||
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        index + value_size < index)  // Check for overflow.
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return false;
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (EqualsASCII(type.string(), "file")) {
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (value_size != 2)
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return false;
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      referenced_files->push_back(document_state[index++]);
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      index++;  // Skip over display name.
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      index += value_size;
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return true;
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool RecursivelyAppendReferencedFiles(
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const ExplodedFrameState& frame_state,
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<base::NullableString16>* referenced_files) {
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!frame_state.http_body.is_null) {
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    AppendReferencedFilesFromHttpBody(frame_state.http_body.elements,
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      referenced_files);
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!AppendReferencedFilesFromDocumentState(frame_state.document_state,
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                              referenced_files))
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < frame_state.children.size(); ++i) {
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!RecursivelyAppendReferencedFiles(frame_state.children[i],
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                          referenced_files))
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return false;
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return true;
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//----------------------------------------------------------------------------
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct SerializeObject {
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SerializeObject()
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : version(0),
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        parse_error(false) {
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SerializeObject(const char* data, int len)
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : pickle(data, len),
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        version(0),
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        parse_error(false) {
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    iter = PickleIterator(pickle);
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string GetAsString() {
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return std::string(static_cast<const char*>(pickle.data()), pickle.size());
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Pickle pickle;
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PickleIterator iter;
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int version;
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool parse_error;
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Version ID of serialized format.
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 11: Min version
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 12: Adds support for contains_passwords in HTTP body
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 13: Adds support for URL (FileSystem URL)
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 14: Adds list of referenced files, version written only for first item.
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// 15: Removes a bunch of values we defined but never used.
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// 16: Switched from blob urls to blob uuids.
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// 17: Add a target frame id number.
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 18: Add referrer policy.
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// 19: Remove target frame id, which was a bad idea, and original url string,
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//         which is no longer used.
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 20: Add pinch viewport scroll offset, the offset of the pinched zoomed
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//     viewport within the unzoomed main frame.
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 21: Add frame sequence number
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// NOTE: If the version is -1, then the pickle contains only a URL string.
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// See ReadPageState.
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kMinVersion = 11;
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kCurrentVersion = 21;
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A bunch of convenience functions to read/write to SerializeObjects.  The
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// de-serializers assume the input data will be in the correct format and fall
206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// back to returning safe defaults when not.
207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteData(const void* data, int length, SerializeObject* obj) {
209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->pickle.WriteData(static_cast<const char*>(data), length);
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ReadData(SerializeObject* obj, const void** data, int* length) {
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char* tmp;
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->pickle.ReadData(&obj->iter, &tmp, length)) {
215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    *data = tmp;
216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    *data = NULL;
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    *length = 0;
220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteInteger(int data, SerializeObject* obj) {
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->pickle.WriteInt(data);
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint ReadInteger(SerializeObject* obj) {
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int tmp;
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->pickle.ReadInt(&obj->iter, &tmp))
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return tmp;
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->parse_error = true;
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return 0;
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ConsumeInteger(SerializeObject* obj) {
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int unused ALLOW_UNUSED = ReadInteger(obj);
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteInteger64(int64 data, SerializeObject* obj) {
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->pickle.WriteInt64(data);
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint64 ReadInteger64(SerializeObject* obj) {
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int64 tmp = 0;
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->pickle.ReadInt64(&obj->iter, &tmp))
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return tmp;
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->parse_error = true;
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return 0;
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ConsumeInteger64(SerializeObject* obj) {
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int64 unused ALLOW_UNUSED = ReadInteger64(obj);
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteReal(double data, SerializeObject* obj) {
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteData(&data, sizeof(double), obj);
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochdouble ReadReal(SerializeObject* obj) {
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const void* tmp = NULL;
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int length = 0;
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  double value = 0.0;
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ReadData(obj, &tmp, &length);
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (length == static_cast<int>(sizeof(double))) {
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Use memcpy, as tmp may not be correctly aligned.
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    memcpy(&value, tmp, sizeof(double));
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return value;
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ConsumeReal(SerializeObject* obj) {
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  double unused ALLOW_UNUSED = ReadReal(obj);
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteBoolean(bool data, SerializeObject* obj) {
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->pickle.WriteInt(data ? 1 : 0);
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ReadBoolean(SerializeObject* obj) {
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool tmp;
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->pickle.ReadBool(&obj->iter, &tmp))
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return tmp;
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->parse_error = true;
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return false;
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ConsumeBoolean(SerializeObject* obj) {
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool unused ALLOW_UNUSED = ReadBoolean(obj);
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteGURL(const GURL& url, SerializeObject* obj) {
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->pickle.WriteString(url.possibly_invalid_spec());
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGURL ReadGURL(SerializeObject* obj) {
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string spec;
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->pickle.ReadString(&obj->iter, &spec))
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return GURL(spec);
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->parse_error = true;
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return GURL();
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void WriteStdString(const std::string& s, SerializeObject* obj) {
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  obj->pickle.WriteString(s);
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
30968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string ReadStdString(SerializeObject* obj) {
31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string s;
31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (obj->pickle.ReadString(&obj->iter, &s))
31268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return s;
31368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  obj->parse_error = true;
31468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return std::string();
31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
31668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// WriteString pickles the NullableString16 as <int length><char16* data>.
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// If length == -1, then the NullableString16 itself is null.  Otherwise the
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// length is the number of char16 (not bytes) in the NullableString16.
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteString(const base::NullableString16& str, SerializeObject* obj) {
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (str.is_null()) {
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->pickle.WriteInt(-1);
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else {
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::char16* data = str.string().data();
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t length_in_bytes = str.string().length() * sizeof(base::char16);
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CHECK_LT(length_in_bytes,
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             static_cast<size_t>(std::numeric_limits<int>::max()));
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->pickle.WriteInt(length_in_bytes);
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->pickle.WriteBytes(data, length_in_bytes);
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This reads a serialized NullableString16 from obj. If a string can't be
335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// read, NULL is returned.
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const base::char16* ReadStringNoCopy(SerializeObject* obj, int* num_chars) {
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int length_in_bytes;
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!obj->pickle.ReadInt(&obj->iter, &length_in_bytes)) {
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return NULL;
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (length_in_bytes < 0)
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return NULL;
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char* data;
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!obj->pickle.ReadBytes(&obj->iter, &data, length_in_bytes)) {
348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return NULL;
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (num_chars)
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *num_chars = length_in_bytes / sizeof(base::char16);
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return reinterpret_cast<const base::char16*>(data);
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::NullableString16 ReadString(SerializeObject* obj) {
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int num_chars;
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::char16* chars = ReadStringNoCopy(obj, &num_chars);
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return chars ?
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::NullableString16(base::string16(chars, num_chars), false) :
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::NullableString16();
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ConsumeString(SerializeObject* obj) {
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::char16* unused ALLOW_UNUSED = ReadStringNoCopy(obj, NULL);
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtemplate <typename T>
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteAndValidateVectorSize(const std::vector<T>& v, SerializeObject* obj) {
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CHECK_LT(v.size(), std::numeric_limits<int>::max() / sizeof(T));
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger(static_cast<int>(v.size()), obj);
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochsize_t ReadAndValidateVectorSize(SerializeObject* obj, size_t element_size) {
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t num_elements = static_cast<size_t>(ReadInteger(obj));
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Ensure that resizing a vector to size num_elements makes sense.
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (std::numeric_limits<int>::max() / element_size <= num_elements) {
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return 0;
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Ensure that it is plausible for the pickle to contain num_elements worth
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // of data.
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->pickle.payload_size() <= num_elements) {
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return 0;
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return num_elements;
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Writes a Vector of strings into a SerializeObject for serialization.
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteStringVector(
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::vector<base::NullableString16>& data, SerializeObject* obj) {
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteAndValidateVectorSize(data, obj);
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < data.size(); ++i) {
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    WriteString(data[i], obj);
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ReadStringVector(SerializeObject* obj,
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                      std::vector<base::NullableString16>* result) {
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t num_elements =
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ReadAndValidateVectorSize(obj, sizeof(base::NullableString16));
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  result->resize(num_elements);
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < num_elements; ++i)
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    (*result)[i] = ReadString(obj);
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Writes an ExplodedHttpBody object into a SerializeObject for serialization.
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteHttpBody(const ExplodedHttpBody& http_body, SerializeObject* obj) {
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteBoolean(!http_body.is_null, obj);
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (http_body.is_null)
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteAndValidateVectorSize(http_body.elements, obj);
421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < http_body.elements.size(); ++i) {
422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const ExplodedHttpBodyElement& element = http_body.elements[i];
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    WriteInteger(element.type, obj);
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (element.type == blink::WebHTTPBody::Element::TypeData) {
425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteData(element.data.data(), static_cast<int>(element.data.size()),
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                obj);
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (element.type == blink::WebHTTPBody::Element::TypeFile) {
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteString(element.file_path, obj);
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteInteger64(element.file_start, obj);
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteInteger64(element.file_length, obj);
431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteReal(element.file_modification_time, obj);
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    } else if (element.type ==
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               blink::WebHTTPBody::Element::TypeFileSystemURL) {
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      WriteGURL(element.filesystem_url, obj);
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteInteger64(element.file_start, obj);
436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteInteger64(element.file_length, obj);
437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteReal(element.file_modification_time, obj);
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(element.type == blink::WebHTTPBody::Element::TypeBlob);
44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      WriteStdString(element.blob_uuid, obj);
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger64(http_body.identifier, obj);
444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteBoolean(http_body.contains_passwords, obj);
445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ReadHttpBody(SerializeObject* obj, ExplodedHttpBody* http_body) {
448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // An initial boolean indicates if we have an HTTP body.
449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!ReadBoolean(obj))
450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  http_body->is_null = false;
452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int num_elements = ReadInteger(obj);
454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (int i = 0; i < num_elements; ++i) {
456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int type = ReadInteger(obj);
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (type == blink::WebHTTPBody::Element::TypeData) {
458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const void* data;
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int length = -1;
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ReadData(obj, &data, &length);
461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (length >= 0) {
462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AppendDataToHttpBody(http_body, static_cast<const char*>(data),
463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             length);
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (type == blink::WebHTTPBody::Element::TypeFile) {
466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::NullableString16 file_path = ReadString(obj);
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int64 file_start = ReadInteger64(obj);
468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int64 file_length = ReadInteger64(obj);
469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      double file_modification_time = ReadReal(obj);
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AppendFileRangeToHttpBody(http_body, file_path, file_start, file_length,
471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                file_modification_time);
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (type == blink::WebHTTPBody::Element::TypeFileSystemURL) {
473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GURL url = ReadGURL(obj);
474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int64 file_start = ReadInteger64(obj);
475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      int64 file_length = ReadInteger64(obj);
476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      double file_modification_time = ReadReal(obj);
477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AppendURLRangeToHttpBody(http_body, url, file_start, file_length,
478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                               file_modification_time);
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (type == blink::WebHTTPBody::Element::TypeBlob) {
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (obj->version >= 16) {
48168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        std::string blob_uuid = ReadStdString(obj);
48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        AppendBlobToHttpBody(http_body, blob_uuid);
48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      } else {
48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        ReadGURL(obj); // Skip the obsolete blob url value.
48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  http_body->identifier = ReadInteger64(obj);
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version >= 12)
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    http_body->contains_passwords = ReadBoolean(obj);
492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Writes the ExplodedFrameState data into the SerializeObject object for
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// serialization.
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WriteFrameState(
497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const ExplodedFrameState& state, SerializeObject* obj, bool is_top) {
498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // WARNING: This data may be persisted for later use. As such, care must be
499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // taken when changing the serialized format. If a new field needs to be
500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // written, only adding at the end will make it easier to deal with loading
501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // older versions. Similarly, this should NOT save fields with sensitive
502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // data, such as password fields.
503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteString(state.url_string, obj);
505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteString(state.target, obj);
506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger(state.scroll_offset.x(), obj);
507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger(state.scroll_offset.y(), obj);
508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteString(state.referrer, obj);
509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteStringVector(state.document_state, obj);
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteReal(state.page_scale_factor, obj);
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger64(state.item_sequence_number, obj);
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger64(state.document_sequence_number, obj);
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WriteInteger64(state.frame_sequence_number, obj);
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WriteInteger(state.referrer_policy, obj);
517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WriteReal(state.pinch_viewport_scroll_offset.x(), obj);
518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WriteReal(state.pinch_viewport_scroll_offset.y(), obj);
519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool has_state_object = !state.state_object.is_null();
521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteBoolean(has_state_object, obj);
522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (has_state_object)
523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    WriteString(state.state_object, obj);
524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteHttpBody(state.http_body, obj);
526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // NOTE: It is a quirk of the format that we still have to write the
528eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http_content_type field when the HTTP body is null.  That's why this code
529eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // is here instead of inside WriteHttpBody.
530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteString(state.http_body.http_content_type, obj);
531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Subitems
533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const std::vector<ExplodedFrameState>& children = state.children;
534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteAndValidateVectorSize(children, obj);
535eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < children.size(); ++i)
536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    WriteFrameState(children[i], obj, false);
537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ReadFrameState(SerializeObject* obj, bool is_top,
540eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                    ExplodedFrameState* state) {
541eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version < 14 && !is_top)
542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ConsumeInteger(obj);  // Skip over redundant version field.
543eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
544eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->url_string = ReadString(obj);
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (obj->version < 19)
547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ConsumeString(obj);  // Skip obsolete original url string field.
548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->target = ReadString(obj);
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (obj->version < 15) {
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ConsumeString(obj);  // Skip obsolete parent field.
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ConsumeString(obj);  // Skip obsolete title field.
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ConsumeString(obj);  // Skip obsolete alternate title field.
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ConsumeReal(obj);    // Skip obsolete visited time field.
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int x = ReadInteger(obj);
558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int y = ReadInteger(obj);
559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->scroll_offset = gfx::Point(x, y);
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (obj->version < 15) {
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ConsumeBoolean(obj);  // Skip obsolete target item flag.
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ConsumeInteger(obj);  // Skip obsolete visit count field.
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->referrer = ReadString(obj);
566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
567eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ReadStringVector(obj, &state->document_state);
568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
569eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->page_scale_factor = ReadReal(obj);
570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->item_sequence_number = ReadInteger64(obj);
571eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->document_sequence_number = ReadInteger64(obj);
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (obj->version >= 21)
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    state->frame_sequence_number = ReadInteger64(obj);
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (obj->version >= 17 && obj->version < 19)
576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ConsumeInteger64(obj); // Skip obsolete target frame id number.
577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (obj->version >= 18) {
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state->referrer_policy =
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<blink::WebReferrerPolicy>(ReadInteger(obj));
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (obj->version >= 20) {
584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double x = ReadReal(obj);
585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double y = ReadReal(obj);
586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    state->pinch_viewport_scroll_offset = gfx::PointF(x, y);
587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    state->pinch_viewport_scroll_offset = gfx::PointF(-1, -1);
589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool has_state_object = ReadBoolean(obj);
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (has_state_object)
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    state->state_object = ReadString(obj);
594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ReadHttpBody(obj, &state->http_body);
596eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
597eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // NOTE: It is a quirk of the format that we still have to read the
598eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http_content_type field when the HTTP body is null.  That's why this code
599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // is here instead of inside ReadHttpBody.
600eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->http_body.http_content_type = ReadString(obj);
601eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version < 14)
603eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ConsumeString(obj);  // Skip unused referrer string.
604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version == 11) {
607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Now-unused values that shipped in this version of Chrome for Android when
608eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // it was on a private branch.
609eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ReadReal(obj);
610eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ReadBoolean(obj);
611eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
612eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // In this version, page_scale_factor included device_scale_factor and
613eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // scroll offsets were premultiplied by pageScaleFactor.
614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (state->page_scale_factor) {
615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      float device_scale_factor = g_device_scale_factor_for_testing;
616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!device_scale_factor) {
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        device_scale_factor =
618eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().
619eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                device_scale_factor();
620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      state->scroll_offset =
622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          gfx::Point(state->scroll_offset.x() / state->page_scale_factor,
623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     state->scroll_offset.y() / state->page_scale_factor);
624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      state->page_scale_factor /= device_scale_factor;
625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
629eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Subitems
630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  size_t num_children =
631eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ReadAndValidateVectorSize(obj, sizeof(ExplodedFrameState));
632eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->children.resize(num_children);
633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < num_children; ++i)
634eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ReadFrameState(obj, false, &state->children[i]);
635eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
636eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid WritePageState(const ExplodedPageState& state, SerializeObject* obj) {
638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteInteger(obj->version, obj);
639eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteStringVector(state.referenced_files, obj);
640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WriteFrameState(state.top, obj, true);
641eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ReadPageState(SerializeObject* obj, ExplodedPageState* state) {
644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj->version = ReadInteger(obj);
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version == -1) {
647eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    GURL url = ReadGURL(obj);
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // NOTE: GURL::possibly_invalid_spec() always returns valid UTF-8.
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state->top.url_string =
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::NullableString16(
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::UTF8ToUTF16(url.possibly_invalid_spec()), false);
652eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
653eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
654eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
655eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version > kCurrentVersion || obj->version < kMinVersion) {
656eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    obj->parse_error = true;
657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
658eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
659eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
660eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version >= 14)
661eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ReadStringVector(obj, &state->referenced_files);
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ReadFrameState(obj, true, &state->top);
664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (obj->version < 14)
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    RecursivelyAppendReferencedFiles(state->top, &state->referenced_files);
667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // De-dupe
669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  state->referenced_files.erase(
670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      std::unique(state->referenced_files.begin(),
671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  state->referenced_files.end()),
672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      state->referenced_files.end());
673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedHttpBodyElement::ExplodedHttpBodyElement()
678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : type(blink::WebHTTPBody::Element::TypeData),
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_start(0),
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_length(-1),
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      file_modification_time(std::numeric_limits<double>::quiet_NaN()) {
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedHttpBodyElement::~ExplodedHttpBodyElement() {
685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedHttpBody::ExplodedHttpBody()
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : identifier(0),
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      contains_passwords(false),
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_null(true) {
691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedHttpBody::~ExplodedHttpBody() {
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedFrameState::ExplodedFrameState()
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : item_sequence_number(0),
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      document_sequence_number(0),
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame_sequence_number(0),
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      page_scale_factor(0.0),
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      referrer_policy(blink::WebReferrerPolicyDefault) {
702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ExplodedFrameState::ExplodedFrameState(const ExplodedFrameState& other) {
7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  assign(other);
7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedFrameState::~ExplodedFrameState() {
709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ExplodedFrameState::operator=(const ExplodedFrameState& other) {
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (&other != this)
7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    assign(other);
7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ExplodedFrameState::assign(const ExplodedFrameState& other) {
7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  url_string = other.url_string;
7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  referrer = other.referrer;
7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  target = other.target;
7205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  state_object = other.state_object;
7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  document_state = other.document_state;
7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pinch_viewport_scroll_offset = other.pinch_viewport_scroll_offset;
7235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scroll_offset = other.scroll_offset;
7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  item_sequence_number = other.item_sequence_number;
7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  document_sequence_number = other.document_sequence_number;
7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  frame_sequence_number = other.frame_sequence_number;
7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  page_scale_factor = other.page_scale_factor;
7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  referrer_policy = other.referrer_policy;
7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  http_body = other.http_body;
7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  children = other.children;
7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedPageState::ExplodedPageState() {
734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExplodedPageState::~ExplodedPageState() {
737eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool DecodePageState(const std::string& encoded, ExplodedPageState* exploded) {
740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *exploded = ExplodedPageState();
741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (encoded.empty())
743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return true;
744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SerializeObject obj(encoded.data(), static_cast<int>(encoded.size()));
746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ReadPageState(&obj, exploded);
747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return !obj.parse_error;
748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool EncodePageState(const ExplodedPageState& exploded, std::string* encoded) {
751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SerializeObject obj;
752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  obj.version = kCurrentVersion;
753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  WritePageState(exploded, &obj);
754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  *encoded = obj.GetAsString();
755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return true;
756eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool DecodePageStateWithDeviceScaleFactorForTesting(
760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& encoded,
761eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    float device_scale_factor,
762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ExplodedPageState* exploded) {
763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  g_device_scale_factor_for_testing = device_scale_factor;
764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool rv = DecodePageState(encoded, exploded);
765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  g_device_scale_factor_for_testing = 0.0;
766eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return rv;
767eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
768eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace content
771