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 "base/pickle.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h>
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <algorithm>  // for max()
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <limits>
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int Pickle::kPayloadUnit = 64;
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We mark a read only pickle with a special capacity_.
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const size_t kCapacityReadOnly = std::numeric_limits<size_t>::max();
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Payload is uint32 aligned.
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottPickle::Pickle()
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : header_(NULL),
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      header_size_(sizeof(Header)),
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      capacity_(0),
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      variable_buffer_offset_(0) {
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Resize(kPayloadUnit);
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  header_->payload_size = 0;
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottPickle::Pickle(int header_size)
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : header_(NULL),
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      header_size_(AlignInt(header_size, sizeof(uint32))),
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      capacity_(0),
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      variable_buffer_offset_(0) {
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header));
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(header_size <= kPayloadUnit);
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Resize(kPayloadUnit);
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  header_->payload_size = 0;
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottPickle::Pickle(const char* data, int data_len)
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : header_(reinterpret_cast<Header*>(const_cast<char*>(data))),
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      header_size_(0),
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      capacity_(kCapacityReadOnly),
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      variable_buffer_offset_(0) {
474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (data_len >= static_cast<int>(sizeof(Header)))
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    header_size_ = data_len - header_->payload_size;
494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (header_size_ > static_cast<unsigned int>(data_len))
514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    header_size_ = 0;
524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (header_size_ != AlignInt(header_size_, sizeof(uint32)))
544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    header_size_ = 0;
554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // If there is anything wrong with the data, we're not going to use it.
574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!header_size_)
584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    header_ = NULL;
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottPickle::Pickle(const Pickle& other)
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : header_(NULL),
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      header_size_(other.header_size_),
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      capacity_(0),
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      variable_buffer_offset_(other.variable_buffer_offset_) {
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t payload_size = header_size_ + other.header_->payload_size;
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool resized = Resize(payload_size);
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK(resized);  // Realloc failed.
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(header_, other.header_, payload_size);
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottPickle::~Pickle() {
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (capacity_ != kCapacityReadOnly)
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    free(header_);
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottPickle& Pickle::operator=(const Pickle& other) {
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (this == &other) {
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTREACHED();
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return *this;
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (capacity_ == kCapacityReadOnly) {
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    header_ = NULL;
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    capacity_ = 0;
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (header_size_ != other.header_size_) {
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    free(header_);
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    header_ = NULL;
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    header_size_ = other.header_size_;
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool resized = Resize(other.header_size_ + other.header_->payload_size);
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK(resized);  // Realloc failed.
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(header_, other.header_,
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         other.header_size_ + other.header_->payload_size);
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  variable_buffer_offset_ = other.variable_buffer_offset_;
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return *this;
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadBool(void** iter, bool* result) const {
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int tmp;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!ReadInt(iter, &tmp))
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(0 == tmp || 1 == tmp);
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *result = tmp ? true : false;
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadInt(void** iter, int* result) const {
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!*iter)
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = const_cast<char*>(payload());
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(jar): http://crbug.com/13108 Pickle should be cleaned up, and not
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // dependent on alignment.
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Next line is otherwise the same as: memcpy(result, *iter, sizeof(*result));
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *result = *reinterpret_cast<int*>(*iter);
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, sizeof(*result));
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadLong(void** iter, long* result) const {
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!*iter)
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = const_cast<char*>(payload());
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(jar): http://crbug.com/13108 Pickle should be cleaned up, and not
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // dependent on alignment.
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(result, *iter, sizeof(*result));
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, sizeof(*result));
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadSize(void** iter, size_t* result) const {
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!*iter)
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = const_cast<char*>(payload());
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // TODO(jar): http://crbug.com/13108 Pickle should be cleaned up, and not
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // dependent on alignment.
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Next line is otherwise the same as: memcpy(result, *iter, sizeof(*result));
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *result = *reinterpret_cast<size_t*>(*iter);
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, sizeof(*result));
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool Pickle::ReadUInt16(void** iter, uint16* result) const {
161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(iter);
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!*iter)
163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    *iter = const_cast<char*>(payload());
164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return false;
167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  memcpy(result, *iter, sizeof(*result));
169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  UpdateIter(iter, sizeof(*result));
171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return true;
172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadUInt32(void** iter, uint32* result) const {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!*iter)
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = const_cast<char*>(payload());
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(result, *iter, sizeof(*result));
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, sizeof(*result));
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadInt64(void** iter, int64* result) const {
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!*iter)
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = const_cast<char*>(payload());
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(result, *iter, sizeof(*result));
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, sizeof(*result));
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadUInt64(void** iter, uint64* result) const {
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!*iter)
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = const_cast<char*>(payload());
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, sizeof(*result)))
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(result, *iter, sizeof(*result));
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, sizeof(*result));
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadString(void** iter, std::string* result) const {
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int len;
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!ReadLength(iter, &len))
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, len))
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* chars = reinterpret_cast<char*>(*iter);
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result->assign(chars, len);
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, len);
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadWString(void** iter, std::wstring* result) const {
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int len;
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!ReadLength(iter, &len))
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Avoid integer overflow.
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (len > INT_MAX / static_cast<int>(sizeof(wchar_t)))
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, len * sizeof(wchar_t)))
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  wchar_t* chars = reinterpret_cast<wchar_t*>(*iter);
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result->assign(chars, len);
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, len * sizeof(wchar_t));
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadString16(void** iter, string16* result) const {
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int len;
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!ReadLength(iter, &len))
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!IteratorHasRoomFor(*iter, len * sizeof(char16)))
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char16* chars = reinterpret_cast<char16*>(*iter);
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  result->assign(chars, len);
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  UpdateIter(iter, len * sizeof(char16));
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::ReadData(void** iter, const char** data, int* length) const {
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(iter);
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(data);
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(length);
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *length = 0;
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *data = 0;
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!ReadLength(iter, length))
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return ReadBytes(iter, data, *length);
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool Pickle::ReadBytes(void** iter, const char** data, int length) const {
2813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(iter);
2823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(data);
2833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  *data = 0;
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!*iter)
2853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    *iter = const_cast<char*>(payload());
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!IteratorHasRoomFor(*iter, length))
2883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return false;
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  *data = reinterpret_cast<const char*>(*iter);
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  UpdateIter(iter, length);
2933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return true;
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
2963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool Pickle::ReadLength(void** iter, int* result) const {
2973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!ReadInt(iter, result))
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
2993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return ((*result) >= 0);
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::WriteString(const std::string& value) {
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!WriteInt(static_cast<int>(value.size())))
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return WriteBytes(value.data(), static_cast<int>(value.size()));
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::WriteWString(const std::wstring& value) {
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!WriteInt(static_cast<int>(value.size())))
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return WriteBytes(value.data(),
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    static_cast<int>(value.size() * sizeof(wchar_t)));
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::WriteString16(const string16& value) {
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!WriteInt(static_cast<int>(value.size())))
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return WriteBytes(value.data(),
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    static_cast<int>(value.size()) * sizeof(char16));
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::WriteData(const char* data, int length) {
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return length >= 0 && WriteInt(length) && WriteBytes(data, length);
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool Pickle::WriteBytes(const void* data, int data_len) {
3303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(capacity_ != kCapacityReadOnly) << "oops: pickle is readonly";
3313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  char* dest = BeginWrite(data_len);
3333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!dest)
3343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return false;
3353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  memcpy(dest, data, data_len);
3373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EndWrite(dest, data_len);
3393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return true;
3403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
3413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottchar* Pickle::BeginWriteData(int length) {
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK_EQ(variable_buffer_offset_, 0U) <<
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    "There can only be one variable buffer in a Pickle";
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (length < 0 || !WriteInt(length))
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char *data_ptr = BeginWrite(length);
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!data_ptr)
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  variable_buffer_offset_ =
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      data_ptr - reinterpret_cast<char*>(header_) - sizeof(int);
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // EndWrite doesn't necessarily have to be called after the write operation,
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // so we call it here to pad out what the caller will eventually write.
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EndWrite(data_ptr, length);
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return data_ptr;
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Pickle::TrimWriteData(int new_length) {
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK_NE(variable_buffer_offset_, 0U);
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fetch the the variable buffer size
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int* cur_length = reinterpret_cast<int*>(
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      reinterpret_cast<char*>(header_) + variable_buffer_offset_);
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (new_length < 0 || new_length > *cur_length) {
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    NOTREACHED() << "Invalid length in TrimWriteData.";
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Update the payload size and variable buffer size
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  header_->payload_size -= (*cur_length - new_length);
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *cur_length = new_length;
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
3793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenchar* Pickle::BeginWrite(size_t length) {
3803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // write at a uint32-aligned offset from the beginning of the header
3813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  size_t offset = AlignInt(header_->payload_size, sizeof(uint32));
3823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  size_t new_size = offset + length;
3843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  size_t needed_size = header_size_ + new_size;
3853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (needed_size > capacity_ && !Resize(std::max(capacity_ * 2, needed_size)))
3863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return NULL;
3873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#ifdef ARCH_CPU_64_BITS
3893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK_LE(length, std::numeric_limits<uint32>::max());
3903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#endif
3913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  header_->payload_size = static_cast<uint32>(new_size);
3933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return payload() + offset;
3943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
3953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid Pickle::EndWrite(char* dest, int length) {
3973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Zero-pad to keep tools like purify from complaining about uninitialized
3983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // memory.
3993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (length % sizeof(uint32))
4003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    memset(dest + length, 0, sizeof(uint32) - (length % sizeof(uint32)));
4013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
4023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Pickle::Resize(size_t new_capacity) {
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  new_capacity = AlignInt(new_capacity, kPayloadUnit);
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK_NE(capacity_, kCapacityReadOnly);
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void* p = realloc(header_, new_capacity);
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!p)
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  header_ = reinterpret_cast<Header*>(p);
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  capacity_ = new_capacity;
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char* Pickle::FindNext(size_t header_size,
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             const char* start,
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                             const char* end) {
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(header_size == AlignInt(header_size, sizeof(uint32)));
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(header_size <= static_cast<size_t>(kPayloadUnit));
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (static_cast<size_t>(end - start) < sizeof(Header))
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return NULL;
42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const Header* hdr = reinterpret_cast<const Header*>(start);
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* payload_base = start + header_size;
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* payload_end = payload_base + hdr->payload_size;
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (payload_end < payload_base)
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (payload_end > end) ? NULL : payload_end;
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
434