/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
// This class provides facilities for basic binary value packing and unpacking. // // The Pickle class supports appending primitive values (ints, strings, etc.) // to a pickle instance. The Pickle instance grows its internal memory buffer // dynamically to hold the sequence of primitive values. The internal memory // buffer is exposed as the "data" of the Pickle. This "data" can be passed // to a Pickle object to initialize it for reading. // // When reading from a Pickle object, it is important for the consumer to know // what value types to read and in what order to read them as the Pickle does // not keep track of the type of data written to it. // // The Pickle's data has a header which contains the size of the Pickle's // payload. It can optionally support additional space in the header. That // space is controlled by the header_size parameter passed to the Pickle // constructor. // class Pickle { public:
~Pickle();
Pickle() = delete;
// Initialize a Pickle object with the specified header size in bytes, which // must be greater-than-or-equal-to sizeof(Pickle::Header). The header size // will be rounded up to ensure that the header size is 32bit-aligned. explicit Pickle(uint32_t header_size, size_t segment_capacity = 0);
// Methods for reading the payload of the Pickle. To read from the start of // the Pickle, initialize *iter to NULL. If successful, these methods return // true. Otherwise, false is returned to indicate that the result could not // be extracted.
[[nodiscard]] bool ReadBool(PickleIterator* iter, bool* result) const;
[[nodiscard]] bool ReadInt16(PickleIterator* iter, int16_t* result) const;
[[nodiscard]] bool ReadUInt16(PickleIterator* iter, uint16_t* result) const;
[[nodiscard]] bool ReadShort(PickleIterator* iter, short* result) const;
[[nodiscard]] bool ReadInt(PickleIterator* iter, int* result) const;
[[nodiscard]] bool ReadLong(PickleIterator* iter, long* result) const;
[[nodiscard]] bool ReadULong(PickleIterator* iter, unsignedlong* result) const;
[[nodiscard]] bool ReadInt32(PickleIterator* iter, int32_t* result) const;
[[nodiscard]] bool ReadUInt32(PickleIterator* iter, uint32_t* result) const;
[[nodiscard]] bool ReadInt64(PickleIterator* iter, int64_t* result) const;
[[nodiscard]] bool ReadUInt64(PickleIterator* iter, uint64_t* result) const;
[[nodiscard]] bool ReadDouble(PickleIterator* iter, double* result) const;
[[nodiscard]] bool ReadIntPtr(PickleIterator* iter, intptr_t* result) const;
[[nodiscard]] bool ReadUnsignedChar(PickleIterator* iter, unsignedchar* result) const;
[[nodiscard]] bool ReadString(PickleIterator* iter,
std::string* result) const;
[[nodiscard]] bool ReadWString(PickleIterator* iter,
std::wstring* result) const;
[[nodiscard]] bool ReadBytesInto(PickleIterator* iter, void* data,
uint32_t length) const;
// Safer version of ReadInt() checks for the result not being negative. // Use it for reading the object sizes.
[[nodiscard]] bool ReadLength(PickleIterator* iter, int* result) const;
// NOTE: The message type optional parameter should _only_ be called from // generated IPDL code, as it is used to trigger the IPC_READ_LATENCY_MS // telemetry probe. void EndRead(PickleIterator& iter, uint32_t ipcMessageType = 0) const;
// Returns true if the given iterator has at least |len| bytes remaining it, // across all segments. If there is not that much data available, returns // false. Generally used when reading a (len, data) pair from the message, // before allocating |len| bytes of space, to ensure that reading |len| bytes // will succeed. bool HasBytesAvailable(const PickleIterator* iter, uint32_t len) const;
// Truncate the message at the current point, discarding any data after this // point in the message. void Truncate(PickleIterator* iter);
// Methods for adding to the payload of the Pickle. These values are // appended to the end of the Pickle's payload. When reading values from a // Pickle, it is important to read them in the order in which they were added // to the Pickle. bool WriteBytes(constvoid* data, uint32_t data_len);
// Payload follows after allocation of Header (header size is customizable). struct Header {
uint32_t payload_size; // Specifies the size of the payload.
};
// Returns the header, cast to a user-specified type T. The type T must be a // subclass of Header and its size must correspond to the header_size passed // to the Pickle constructor. template <class T>
T* headerT() {
DCHECK(sizeof(T) == header_size_); returnstatic_cast<T*>(header_);
} template <class T> const T* headerT() const {
DCHECK(sizeof(T) == header_size_); returnstatic_cast<const T*>(header_);
}
// Resizes the buffer for use when writing the specified amount of data. Call // EndWrite with the given length to pad out for the next write. void BeginWrite(uint32_t length);
// Completes the write operation by padding the data with poison bytes. Should // be paired with BeginWrite, but it does not necessarily have to be called // after the data is written. void EndWrite(uint32_t length);
// Round 'bytes' up to the next multiple of 'alignment'. 'alignment' must be // a power of 2. template <uint32_t alignment> struct ConstantAligner { static uint32_t align(int bytes) {
static_assert((alignment & (alignment - 1)) == 0, "alignment must be a power of two"); return (bytes + (alignment - 1)) & ~static_cast<uint32_t>(alignment - 1);
}
};
// Returns true if the given iterator could point to data with the given // length. If there is no room for the given data before the end of the // payload, returns false. bool IteratorHasRoomFor(const PickleIterator& iter, uint32_t len) const;
// Moves the iterator by the given number of bytes, making sure it is aligned. // Pointer (iterator) is NOT aligned, but the change in the pointer // is guaranteed to be a multiple of sizeof(memberAlignmentType). void UpdateIter(PickleIterator* iter, uint32_t bytes) const;
// Figure out how big the message starting at range_start is. Returns 0 if // there's no enough data to determine (i.e., if [range_start, range_end) does // not contain enough of the message header to know the size). static uint32_t MessageSize(uint32_t header_size, constchar* range_start, constchar* range_end);
// Segments capacities are aligned to 8 bytes to ensure that all reads/writes // at 8-byte aligned offsets will be on 8-byte aligned pointers. staticconst uint32_t kSegmentAlignment = 8;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.