| // Copyright 2015 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. | 
 |  | 
 | #include "files/c/lib/fd_table.h" | 
 |  | 
 | #include <errno.h> | 
 |  | 
 | #include <limits> | 
 | #include <utility> | 
 |  | 
 | #include "files/c/lib/errno_impl.h" | 
 | #include "mojo/public/cpp/environment/logging.h" | 
 |  | 
 | namespace mojio { | 
 |  | 
 | FDTable::FDTable(ErrnoImpl* errno_impl, size_t max_num_fds) | 
 |     : errno_impl_(errno_impl), table_(max_num_fds) { | 
 |   MOJO_DCHECK(max_num_fds > 0); | 
 |   // The index of the last FD has to fit into an |int|. | 
 |   MOJO_DCHECK(max_num_fds - 1 <= | 
 |               static_cast<size_t>(std::numeric_limits<int>::max())); | 
 | } | 
 |  | 
 | FDTable::~FDTable() { | 
 |   // TODO(vtl): Warn if there are still non-null entries? | 
 | } | 
 |  | 
 | int FDTable::Add(std::unique_ptr<FDImpl> fd_impl) { | 
 |   ErrnoImpl::Setter errno_setter(errno_impl_); | 
 |   MOJO_DCHECK(fd_impl); | 
 |  | 
 |   for (size_t i = 0; i < table_.size(); i++) { | 
 |     if (!table_[i]) { | 
 |       table_[i] = std::move(fd_impl); | 
 |       return static_cast<int>(i); | 
 |     } | 
 |   } | 
 |   errno_setter.Set(EMFILE); | 
 |   return -1; | 
 | } | 
 |  | 
 | FDImpl* FDTable::Get(int fd) const { | 
 |   ErrnoImpl::Setter errno_setter(errno_impl_); | 
 |   if (fd < 0 || static_cast<size_t>(fd) >= table_.size() || !table_[fd]) { | 
 |     errno_setter.Set(EBADF); | 
 |     return nullptr; | 
 |   } | 
 |   return table_[fd].get(); | 
 | } | 
 |  | 
 | std::unique_ptr<FDImpl> FDTable::Remove(int fd) { | 
 |   ErrnoImpl::Setter errno_setter(errno_impl_); | 
 |   if (fd < 0 || static_cast<size_t>(fd) >= table_.size() || !table_[fd]) { | 
 |     errno_setter.Set(EBADF); | 
 |     return nullptr; | 
 |   } | 
 |   return std::move(table_[fd]); | 
 | } | 
 |  | 
 | }  // namespace mojio |