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