Home | History | Annotate | Download | only in system
      1 // Copyright 2016 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 #ifndef MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_
      6 #define MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_
      7 
      8 #include <limits>
      9 #include <vector>
     10 
     11 #include "base/macros.h"
     12 #include "base/numerics/safe_conversions.h"
     13 #include "base/strings/string_piece.h"
     14 #include "mojo/public/c/system/message_pipe.h"
     15 #include "mojo/public/cpp/system/handle.h"
     16 
     17 namespace mojo {
     18 
     19 const MojoMessageHandle kInvalidMessageHandleValue =
     20     MOJO_MESSAGE_HANDLE_INVALID;
     21 
     22 // Handle wrapper base class for a |MojoMessageHandle|.
     23 class MessageHandle {
     24  public:
     25   MessageHandle() : value_(kInvalidMessageHandleValue) {}
     26   explicit MessageHandle(MojoMessageHandle value) : value_(value) {}
     27   ~MessageHandle() {}
     28 
     29   void swap(MessageHandle& other) {
     30     MojoMessageHandle temp = value_;
     31     value_ = other.value_;
     32     other.value_ = temp;
     33   }
     34 
     35   bool is_valid() const { return value_ != kInvalidMessageHandleValue; }
     36 
     37   const MojoMessageHandle& value() const { return value_; }
     38   MojoMessageHandle* mutable_value() { return &value_; }
     39   void set_value(MojoMessageHandle value) { value_ = value; }
     40 
     41   void Close() {
     42     DCHECK(is_valid());
     43     MojoResult result = MojoDestroyMessage(value_);
     44     ALLOW_UNUSED_LOCAL(result);
     45     DCHECK_EQ(MOJO_RESULT_OK, result);
     46   }
     47 
     48  private:
     49   MojoMessageHandle value_;
     50 };
     51 
     52 using ScopedMessageHandle = ScopedHandleBase<MessageHandle>;
     53 
     54 inline MojoResult CreateMessage(ScopedMessageHandle* handle) {
     55   MojoMessageHandle raw_handle;
     56   MojoResult rv = MojoCreateMessage(nullptr, &raw_handle);
     57   if (rv != MOJO_RESULT_OK)
     58     return rv;
     59 
     60   handle->reset(MessageHandle(raw_handle));
     61   return MOJO_RESULT_OK;
     62 }
     63 
     64 inline MojoResult GetMessageData(MessageHandle message,
     65                                  void** buffer,
     66                                  uint32_t* num_bytes,
     67                                  std::vector<ScopedHandle>* handles,
     68                                  MojoGetMessageDataFlags flags) {
     69   DCHECK(message.is_valid());
     70   DCHECK(num_bytes);
     71   DCHECK(buffer);
     72   uint32_t num_handles = 0;
     73 
     74   MojoGetMessageDataOptions options;
     75   options.struct_size = sizeof(options);
     76   options.flags = flags;
     77   MojoResult rv = MojoGetMessageData(message.value(), &options, buffer,
     78                                      num_bytes, nullptr, &num_handles);
     79   if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) {
     80     if (handles)
     81       handles->clear();
     82     return rv;
     83   }
     84 
     85   handles->resize(num_handles);
     86   return MojoGetMessageData(message.value(), &options, buffer, num_bytes,
     87                             reinterpret_cast<MojoHandle*>(handles->data()),
     88                             &num_handles);
     89 }
     90 
     91 inline MojoResult NotifyBadMessage(MessageHandle message,
     92                                    const base::StringPiece& error) {
     93   DCHECK(message.is_valid());
     94   DCHECK(base::IsValueInRangeForNumericType<uint32_t>(error.size()));
     95   return MojoNotifyBadMessage(message.value(), error.data(),
     96                               static_cast<uint32_t>(error.size()), nullptr);
     97 }
     98 
     99 }  // namespace mojo
    100 
    101 #endif  // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_H_
    102