Home | History | Annotate | Download | only in lib
      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