1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/pickle.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string16.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int testint = 2093847192;
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst std::string teststr("Hello world");  // note non-aligned string length
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst std::wstring testwstr(L"Hello, world");
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char testdata[] = "AAA\0BBB\0";
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int testdatalen = arraysize(testdata) - 1;
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst bool testbool1 = false;
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst bool testbool2 = true;
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst uint16 testuint16 = 32123;
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// checks that the result
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid VerifyResult(const Pickle& pickle) {
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int outint;
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadInt(&iter, &outint));
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(testint, outint);
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string outstr;
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(teststr, outstr);
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::wstring outwstr;
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadWString(&iter, &outwstr));
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(testwstr, outwstr);
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool outbool;
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(testbool1, outbool);
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(testbool2, outbool);
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  uint16 outuint16;
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(pickle.ReadUInt16(&iter, &outuint16));
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(testuint16, outuint16);
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* outdata;
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int outdatalen;
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(testdatalen, outdatalen);
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(testdatalen, outdatalen);
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // reads past the end should fail
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(pickle.ReadInt(&iter, &outint));
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, EncodeDecode) {
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteInt(testint));
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteString(teststr));
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteWString(testwstr));
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteBool(testbool1));
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteBool(testbool2));
74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(pickle.WriteUInt16(testuint16));
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteData(testdata, testdatalen));
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Over allocate BeginWriteData so we can test TrimWriteData.
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* dest = pickle.BeginWriteData(testdatalen + 100);
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(dest);
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(dest, testdata, testdatalen);
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle.TrimWriteData(testdatalen);
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VerifyResult(pickle);
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // test copy constructor
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle2(pickle);
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VerifyResult(pickle2);
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // test operator=
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle3;
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle3 = pickle;
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  VerifyResult(pickle3);
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Tests that we can handle really small buffers.
974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST(PickleTest, SmallBuffer) {
984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  scoped_array<char> buffer(new char[1]);
994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // We should not touch the buffer.
1014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  Pickle pickle(buffer.get(), 1);
1024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void* iter = NULL;
1044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int data;
1054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  EXPECT_FALSE(pickle.ReadInt(&iter, &data));
1064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
1074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Tests that we can handle improper headers.
1094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST(PickleTest, BigSize) {
1104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int buffer[] = { 0x56035200, 25, 40, 50 };
1114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
1134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void* iter = NULL;
1154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int data;
1164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  EXPECT_FALSE(pickle.ReadInt(&iter, &data));
1174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
1184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST(PickleTest, UnalignedSize) {
1204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int buffer[] = { 10, 25, 40, 50 };
1214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
1234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  void* iter = NULL;
1254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int data;
1264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  EXPECT_FALSE(pickle.ReadInt(&iter, &data));
1274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
1284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, ZeroLenStr) {
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteString(""));
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string outstr;
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("", outstr);
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, ZeroLenWStr) {
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteWString(L""));
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string outstr;
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ("", outstr);
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, BadLenStr) {
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteInt(-2));
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string outstr;
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(pickle.ReadString(&iter, &outstr));
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, BadLenWStr) {
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteInt(-1));
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::wstring woutstr;
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr));
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, FindNext) {
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteInt(1));
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteString("Domo"));
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* start = reinterpret_cast<const char*>(pickle.data());
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* end = start + pickle.size();
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end));
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1));
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1));
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST(PickleTest, FindNextWithIncompleteHeader) {
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  size_t header_size = sizeof(Pickle::Header);
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_array<char> buffer(new char[header_size - 1]);
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  memset(buffer.get(), 0x1, header_size - 1);
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const char* start = buffer.get();
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const char* end = start + header_size - 1;
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end));
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, IteratorHasRoom) {
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteInt(1));
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteInt(2));
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const void* iter = 0;
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, 1));
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  iter = pickle.payload();
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 0));
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 1));
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, -1));
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, sizeof(int) * 2));
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, (sizeof(int) * 2) + 1));
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, Resize) {
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t unit = Pickle::kPayloadUnit;
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  scoped_array<char> data(new char[unit]);
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* data_ptr = data.get();
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (size_t i = 0; i < unit; i++)
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    data_ptr[i] = 'G';
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // construct a message that will be exactly the size of one payload unit,
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // note that any data will have a 4-byte header indicating the size
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const size_t payload_size_after_header = unit - sizeof(uint32);
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle.WriteData(data_ptr,
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      static_cast<int>(payload_size_after_header - sizeof(uint32)));
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t cur_payload = payload_size_after_header;
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // note: we assume 'unit' is a power of 2
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(unit, pickle.capacity());
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // fill out a full page (noting data header)
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32)));
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cur_payload += unit;
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(unit * 2, pickle.capacity());
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(cur_payload, pickle.payload_size());
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // one more byte should double the capacity
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle.WriteData(data_ptr, 1);
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cur_payload += 5;
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(unit * 4, pickle.capacity());
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(cur_payload, pickle.payload_size());
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct CustomHeader : Pickle::Header {
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int blah;
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, HeaderPadding) {
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const uint32 kMagic = 0x12345678;
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle(sizeof(CustomHeader));
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle.WriteInt(kMagic);
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // this should not overwrite the 'int' payload
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  pickle.headerT<CustomHeader>()->blah = 10;
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int result;
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(pickle.ReadInt(&iter, &result));
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(static_cast<uint32>(result), kMagic);
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, EqualsOperator) {
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle source;
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  source.WriteInt(1);
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 source.size());
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle copy;
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  copy = copy_refs_source_buffer;
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_EQ(source.size(), copy.size());
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, EvilLengths) {
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle source;
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string str(100000, 'A');
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  source.WriteData(str.c_str(), 100000);
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ReadString16 used to have its read buffer length calculation wrong leading
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to out-of-bounds reading.
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  string16 str16;
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(source.ReadString16(&iter, &str16));
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // And check we didn't break ReadString16.
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  str16 = (wchar_t) 'A';
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle str16_pickle;
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  str16_pickle.WriteString16(str16);
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  iter = NULL;
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16));
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(1U, str16.length());
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Check we don't fail in a length check with large WStrings.
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle big_len;
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  big_len.WriteInt(1 << 30);
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  iter = NULL;
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::wstring wstr;
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_FALSE(big_len.ReadWString(&iter, &wstr));
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Check we can write zero bytes of data and 'data' can be NULL.
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(PickleTest, ZeroLength) {
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle pickle;
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.WriteData(NULL, 0));
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* iter = NULL;
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* outdata;
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int outdatalen;
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(0, outdatalen);
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We can't assert that outdata is NULL.
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Check that ReadBytes works properly with an iterator initialized to NULL.
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(PickleTest, ReadBytes) {
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Pickle pickle;
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int data = 0x7abcd;
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data)));
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void* iter = NULL;
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* outdata_char;
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data)));
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int outdata;
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  memcpy(&outdata, outdata_char, sizeof(outdata));
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(data, outdata);
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
326