16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/embedder/simple_platform_shared_buffer.h"
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/logging.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/embedder/platform_handle_utils.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace mojo {
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace embedder {
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SimplePlatformSharedBuffer* SimplePlatformSharedBuffer::Create(
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t num_bytes) {
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK_GT(num_bytes, 0u);
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SimplePlatformSharedBuffer* rv = new SimplePlatformSharedBuffer(num_bytes);
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!rv->Init()) {
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // We can't just delete it directly, due to the "in destructor" (debug)
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // check.
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<SimplePlatformSharedBuffer> deleter(rv);
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return nullptr;
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return rv;
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// static
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SimplePlatformSharedBuffer*
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SimplePlatformSharedBuffer::CreateFromPlatformHandle(
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t num_bytes,
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ScopedPlatformHandle platform_handle) {
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK_GT(num_bytes, 0u);
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SimplePlatformSharedBuffer* rv = new SimplePlatformSharedBuffer(num_bytes);
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!rv->InitFromPlatformHandle(platform_handle.Pass())) {
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // We can't just delete it directly, due to the "in destructor" (debug)
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // check.
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_refptr<SimplePlatformSharedBuffer> deleter(rv);
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return nullptr;
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return rv;
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)size_t SimplePlatformSharedBuffer::GetNumBytes() const {
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return num_bytes_;
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::Map(
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t offset,
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t length) {
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!IsValidMap(offset, length))
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return scoped_ptr<PlatformSharedBufferMapping>();
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return MapNoCheck(offset, length);
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool SimplePlatformSharedBuffer::IsValidMap(size_t offset, size_t length) {
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (offset > num_bytes_ || length == 0)
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return false;
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Note: This is an overflow-safe check of |offset + length > num_bytes_|
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // (that |num_bytes >= offset| is verified above).
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (length > num_bytes_ - offset)
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return false;
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return true;
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_ptr<PlatformSharedBufferMapping> SimplePlatformSharedBuffer::MapNoCheck(
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t offset,
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    size_t length) {
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(IsValidMap(offset, length));
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return MapImpl(offset, length);
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ScopedPlatformHandle SimplePlatformSharedBuffer::DuplicatePlatformHandle() {
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return mojo::embedder::DuplicatePlatformHandle(handle_.get());
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ScopedPlatformHandle SimplePlatformSharedBuffer::PassPlatformHandle() {
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(HasOneRef());
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return handle_.Pass();
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SimplePlatformSharedBuffer::SimplePlatformSharedBuffer(size_t num_bytes)
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : num_bytes_(num_bytes) {
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SimplePlatformSharedBuffer::~SimplePlatformSharedBuffer() {
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SimplePlatformSharedBufferMapping::~SimplePlatformSharedBufferMapping() {
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Unmap();
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void* SimplePlatformSharedBufferMapping::GetBase() const {
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return base_;
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)size_t SimplePlatformSharedBufferMapping::GetLength() const {
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return length_;
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace embedder
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace mojo
109