| Index: mojo/public/bindings/lib/bindings_internal.h
|
| diff --git a/mojo/public/bindings/lib/bindings_internal.h b/mojo/public/bindings/lib/bindings_internal.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cf4f1725a9787fe0a854336b5243d2ba0bd15fd2
|
| --- /dev/null
|
| +++ b/mojo/public/bindings/lib/bindings_internal.h
|
| @@ -0,0 +1,188 @@
|
| +// Copyright 2013 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.
|
| +
|
| +#ifndef MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_INTERNAL_H_
|
| +#define MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_INTERNAL_H_
|
| +
|
| +#include <string.h>
|
| +
|
| +#include <vector>
|
| +
|
| +#include "mojo/public/bindings/lib/bindings.h"
|
| +#include "mojo/public/bindings/lib/message.h"
|
| +
|
| +namespace mojo {
|
| +namespace internal {
|
| +
|
| +// Pointers are encoded as relative offsets. The offsets are relative to the
|
| +// address of where the offset value is stored, such that the pointer may be
|
| +// recovered with the expression:
|
| +//
|
| +// ptr = (offset + *offset)
|
| +//
|
| +// A null pointer is encoded as an offset value of 0.
|
| +//
|
| +void EncodePointer(const void* ptr, uint64_t* offset);
|
| +const void* DecodePointerRaw(const uint64_t* offset);
|
| +
|
| +template <typename T>
|
| +inline void DecodePointer(const uint64_t* offset, T** ptr) {
|
| + *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset)));
|
| +}
|
| +
|
| +// Check that the given pointer references memory contained within the message.
|
| +bool ValidatePointer(const void* ptr, const Message& message);
|
| +
|
| +// Handles are encoded as indices into a vector of handles. These functions
|
| +// manipulate the value of |handle|, mapping it to and from an index.
|
| +void EncodeHandle(Handle* handle, std::vector<Handle>* handles);
|
| +bool DecodeHandle(Handle* handle, const std::vector<Handle>& handles);
|
| +
|
| +// All objects (structs and arrays) can have 3 operations performed on them:
|
| +// - cloning
|
| +// - encoding pointers and handles
|
| +// - decoding pointers and handles
|
| +//
|
| +// The following 3 functions are used to select the proper ObjectTraits<>
|
| +// specialization.
|
| +
|
| +template <typename T>
|
| +inline T* Clone(const T* obj, Buffer* buf) {
|
| + return obj ? ObjectTraits<T>::Clone(obj, buf) : NULL;
|
| +}
|
| +
|
| +template <typename T>
|
| +inline void EncodePointersAndHandles(T* obj,
|
| + std::vector<Handle>* handles) {
|
| + ObjectTraits<T>::EncodePointersAndHandles(obj, handles);
|
| +}
|
| +
|
| +template <typename T>
|
| +inline bool DecodePointersAndHandles(T* obj, const Message& message) {
|
| + return ObjectTraits<T>::DecodePointersAndHandles(obj, message);
|
| +}
|
| +
|
| +// The following 2 functions are used to encode/decode all objects (structs and
|
| +// arrays) in a consistent manner.
|
| +
|
| +template <typename T>
|
| +inline void Encode(T* obj, std::vector<Handle>* handles) {
|
| + if (obj->ptr)
|
| + EncodePointersAndHandles(obj->ptr, handles);
|
| + EncodePointer(obj->ptr, &obj->offset);
|
| +}
|
| +
|
| +template <typename T>
|
| +inline bool Decode(T* obj, const Message& message) {
|
| + DecodePointer(&obj->offset, &obj->ptr);
|
| + if (obj->ptr) {
|
| + if (!ValidatePointer(obj->ptr, message))
|
| + return false;
|
| + if (!DecodePointersAndHandles(obj->ptr, message))
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// What follows is code to support the ObjectTraits<> specialization of
|
| +// Array<T>. There are two interesting cases: arrays of primitives and arrays
|
| +// of objects. Arrays of objects are represented as arrays of pointers to
|
| +// objects.
|
| +
|
| +template <typename T>
|
| +struct ArrayHelper {
|
| + typedef T ElementType;
|
| +
|
| + static void CloneElements(Buffer* buf,
|
| + ArrayHeader* header,
|
| + ElementType* elements) {
|
| + }
|
| +
|
| + static void EncodePointersAndHandles(ArrayHeader* header,
|
| + ElementType* elements,
|
| + std::vector<Handle>* handles) {
|
| + }
|
| + static bool DecodePointersAndHandles(ArrayHeader* header,
|
| + ElementType* elements,
|
| + const Message& message) {
|
| + return true;
|
| + }
|
| +};
|
| +
|
| +template <>
|
| +struct ArrayHelper<Handle> {
|
| + typedef Handle ElementType;
|
| +
|
| + static void CloneElements(Buffer* buf,
|
| + ArrayHeader* header,
|
| + ElementType* elements) {
|
| + }
|
| +
|
| + static void EncodePointersAndHandles(ArrayHeader* header,
|
| + ElementType* elements,
|
| + std::vector<Handle>* handles);
|
| + static bool DecodePointersAndHandles(ArrayHeader* header,
|
| + ElementType* elements,
|
| + const Message& message);
|
| +};
|
| +
|
| +template <typename P>
|
| +struct ArrayHelper<P*> {
|
| + typedef StructPointer<P> ElementType;
|
| +
|
| + static void CloneElements(Buffer* buf,
|
| + ArrayHeader* header,
|
| + ElementType* elements) {
|
| + for (uint32_t i = 0; i < header->num_elements; ++i)
|
| + elements[i].ptr = Clone(elements[i].ptr, buf);
|
| + }
|
| +
|
| + static void EncodePointersAndHandles(ArrayHeader* header,
|
| + ElementType* elements,
|
| + std::vector<Handle>* handles) {
|
| + for (uint32_t i = 0; i < header->num_elements; ++i)
|
| + Encode(&elements[i], handles);
|
| + }
|
| + static bool DecodePointersAndHandles(ArrayHeader* header,
|
| + ElementType* elements,
|
| + const Message& message) {
|
| + for (uint32_t i = 0; i < header->num_elements; ++i) {
|
| + if (!Decode(&elements[i], message))
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +};
|
| +
|
| +template <typename T>
|
| +class ObjectTraits<Array<T> > {
|
| + public:
|
| + static Array<T>* Clone(const Array<T>* array, Buffer* buf) {
|
| + Array<T>* clone = Array<T>::New(buf, array->header_.num_elements);
|
| + memcpy(clone->storage(),
|
| + array->storage(),
|
| + array->header_.num_bytes - sizeof(Array<T>));
|
| +
|
| + ArrayHelper<T>::CloneElements(buf, &clone->header_, clone->storage());
|
| + return clone;
|
| + }
|
| +
|
| + static void EncodePointersAndHandles(Array<T>* array,
|
| + std::vector<Handle>* handles) {
|
| + ArrayHelper<T>::EncodePointersAndHandles(&array->header_, array->storage(),
|
| + handles);
|
| + }
|
| +
|
| + static bool DecodePointersAndHandles(Array<T>* array,
|
| + const Message& message) {
|
| + return ArrayHelper<T>::DecodePointersAndHandles(&array->header_,
|
| + array->storage(),
|
| + message);
|
| + }
|
| +};
|
| +
|
| +} // namespace internal
|
| +} // namespace mojo
|
| +
|
| +#endif // MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_INTERNAL_H_
|
|
|