1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "mojo/public/bindings/lib/bindings_serialization.h" 6 7 #include <assert.h> 8 9 namespace mojo { 10 namespace internal { 11 12 size_t Align(size_t size) { 13 const size_t kAlignment = 8; 14 return size + (kAlignment - (size % kAlignment)) % kAlignment; 15 } 16 17 void EncodePointer(const void* ptr, uint64_t* offset) { 18 if (!ptr) { 19 *offset = 0; 20 return; 21 } 22 23 const char* p_obj = reinterpret_cast<const char*>(ptr); 24 const char* p_slot = reinterpret_cast<const char*>(offset); 25 assert(p_obj > p_slot); 26 27 *offset = static_cast<uint64_t>(p_obj - p_slot); 28 } 29 30 const void* DecodePointerRaw(const uint64_t* offset) { 31 if (!*offset) 32 return NULL; 33 return reinterpret_cast<const char*>(offset) + *offset; 34 } 35 36 bool ValidatePointer(const void* ptr, const Message& message) { 37 const uint8_t* data = static_cast<const uint8_t*>(ptr); 38 if (reinterpret_cast<ptrdiff_t>(data) % 8 != 0) 39 return false; 40 41 const uint8_t* data_start = reinterpret_cast<const uint8_t*>(message.data); 42 const uint8_t* data_end = data_start + message.data->header.num_bytes; 43 44 return data >= data_start && data < data_end; 45 } 46 47 void EncodeHandle(Handle* handle, std::vector<Handle>* handles) { 48 if (handle->is_valid()) { 49 handles->push_back(*handle); 50 handle->set_value(static_cast<MojoHandle>(handles->size() - 1)); 51 } else { 52 // Encode -1 to mean the invalid handle. 53 handle->set_value(static_cast<MojoHandle>(-1)); 54 } 55 } 56 57 bool DecodeHandle(Handle* handle, std::vector<Handle>* handles) { 58 // Decode -1 to mean the invalid handle. 59 if (handle->value() == static_cast<MojoHandle>(-1)) { 60 *handle = Handle(); 61 return true; 62 } 63 if (handle->value() >= handles->size()) 64 return false; 65 // Just leave holes in the vector so we don't screw up other indices. 66 *handle = FetchAndReset(&handles->at(handle->value())); 67 return true; 68 } 69 70 // static 71 void ArrayHelper<Handle>::EncodePointersAndHandles( 72 const ArrayHeader* header, 73 ElementType* elements, 74 std::vector<Handle>* handles) { 75 for (uint32_t i = 0; i < header->num_elements; ++i) 76 EncodeHandle(&elements[i], handles); 77 } 78 79 // static 80 bool ArrayHelper<Handle>::DecodePointersAndHandles( 81 const ArrayHeader* header, 82 ElementType* elements, 83 Message* message) { 84 for (uint32_t i = 0; i < header->num_elements; ++i) { 85 if (!DecodeHandle(&elements[i], &message->handles)) 86 return false; 87 } 88 return true; 89 } 90 91 } // namespace internal 92 } // namespace mojo 93