$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: chris_at_[hidden]
Date: 2008-06-11 07:17:54
Author: chris_kohlhoff
Date: 2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
New Revision: 46319
URL: http://svn.boost.org/trac/boost/changeset/46319
Log:
Add random-access handles for use on Windows.
Added:
   trunk/boost/asio/impl/read_at.ipp   (contents, props changed)
   trunk/boost/asio/impl/write_at.ipp   (contents, props changed)
   trunk/boost/asio/read_at.hpp   (contents, props changed)
   trunk/boost/asio/windows/basic_random_access_handle.hpp   (contents, props changed)
   trunk/boost/asio/windows/random_access_handle.hpp   (contents, props changed)
   trunk/boost/asio/windows/random_access_handle_service.hpp   (contents, props changed)
   trunk/boost/asio/write_at.hpp   (contents, props changed)
   trunk/libs/asio/test/windows/basic_random_access_handle.cpp   (contents, props changed)
   trunk/libs/asio/test/windows/random_access_handle.cpp   (contents, props changed)
   trunk/libs/asio/test/windows/random_access_handle_service.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/asio.hpp                                |     5 +++                                     
   trunk/boost/asio/detail/win_iocp_handle_service.hpp |    66 +++++++++++++++++++++++++++++++++++++-- 
   trunk/boost/asio/write.hpp                          |     6 +-                                      
   trunk/libs/asio/test/Jamfile                        |     3 +                                       
   trunk/libs/asio/test/Jamfile.v2                     |     6 +++                                     
   5 files changed, 79 insertions(+), 7 deletions(-)
Modified: trunk/boost/asio.hpp
==============================================================================
--- trunk/boost/asio.hpp	(original)
+++ trunk/boost/asio.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -73,6 +73,7 @@
 #include <boost/asio/posix/stream_descriptor_service.hpp>
 #include <boost/asio/raw_socket_service.hpp>
 #include <boost/asio/read.hpp>
+#include <boost/asio/read_at.hpp>
 #include <boost/asio/read_until.hpp>
 #include <boost/asio/serial_port.hpp>
 #include <boost/asio/serial_port_base.hpp>
@@ -85,9 +86,13 @@
 #include <boost/asio/time_traits.hpp>
 #include <boost/asio/version.hpp>
 #include <boost/asio/windows/basic_handle.hpp>
+#include <boost/asio/windows/basic_random_access_handle.hpp>
 #include <boost/asio/windows/basic_stream_handle.hpp>
+#include <boost/asio/windows/random_access_handle.hpp>
+#include <boost/asio/windows/random_access_handle_service.hpp>
 #include <boost/asio/windows/stream_handle.hpp>
 #include <boost/asio/windows/stream_handle_service.hpp>
 #include <boost/asio/write.hpp>
+#include <boost/asio/write_at.hpp>
 
 #endif // BOOST_ASIO_HPP
Modified: trunk/boost/asio/detail/win_iocp_handle_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_handle_service.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_handle_service.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -22,6 +22,10 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
@@ -283,11 +287,20 @@
     }
   };
 
-  // Write the given data. Returns the number of bytes sent.
+  // Write the given data. Returns the number of bytes written.
   template <typename ConstBufferSequence>
   size_t write_some(implementation_type& impl,
       const ConstBufferSequence& buffers, boost::system::error_code& ec)
   {
+    return write_some_at(impl, 0, buffers, ec);
+  }
+
+  // Write the given data at the specified offset. Returns the number of bytes
+  // written.
+  template <typename ConstBufferSequence>
+  size_t write_some_at(implementation_type& impl, boost::uint64_t offset,
+      const ConstBufferSequence& buffers, boost::system::error_code& ec)
+  {
     if (!is_open(impl))
     {
       ec = boost::asio::error::bad_descriptor;
@@ -305,7 +318,7 @@
         break;
     }
 
-    // A request to write 0 bytes on a stream handle is a no-op.
+    // A request to write 0 bytes on a handle is a no-op.
     if (boost::asio::buffer_size(buffer) == 0)
     {
       ec = boost::system::error_code();
@@ -319,6 +332,8 @@
     }
 
     // Write the data. 
+    overlapped.Offset = offset & 0xFFFFFFFF;
+    overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
     BOOL ok = ::WriteFile(impl.handle_,
         boost::asio::buffer_cast<LPCVOID>(buffer),
         static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
@@ -432,6 +447,15 @@
   void async_write_some(implementation_type& impl,
       const ConstBufferSequence& buffers, Handler handler)
   {
+    async_write_some_at(impl, 0, buffers, handler);
+  }
+
+  // Start an asynchronous write at a specified offset. The data being written
+  // must be valid for the lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename Handler>
+  void async_write_some_at(implementation_type& impl, boost::uint64_t offset,
+      const ConstBufferSequence& buffers, Handler handler)
+  {
     if (!is_open(impl))
     {
       this->get_io_service().post(bind_handler(handler,
@@ -462,7 +486,7 @@
         break;
     }
 
-    // A request to write 0 bytes on a stream handle is a no-op.
+    // A request to write 0 bytes on a handle is a no-op.
     if (boost::asio::buffer_size(buffer) == 0)
     {
       boost::asio::io_service::work work(this->get_io_service());
@@ -474,6 +498,8 @@
 
     // Write the data.
     DWORD bytes_transferred = 0;
+    ptr.get()->Offset = offset & 0xFFFFFFFF;
+    ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
     BOOL ok = ::WriteFile(impl.handle_,
         boost::asio::buffer_cast<LPCVOID>(buffer),
         static_cast<DWORD>(boost::asio::buffer_size(buffer)),
@@ -500,6 +526,14 @@
   size_t read_some(implementation_type& impl,
       const MutableBufferSequence& buffers, boost::system::error_code& ec)
   {
+    return read_some_at(impl, 0, buffers, ec);
+  }
+
+  // Read some data at a specified offset. Returns the number of bytes received.
+  template <typename MutableBufferSequence>
+  size_t read_some_at(implementation_type& impl, boost::uint64_t offset,
+      const MutableBufferSequence& buffers, boost::system::error_code& ec)
+  {
     if (!is_open(impl))
     {
       ec = boost::asio::error::bad_descriptor;
@@ -530,7 +564,9 @@
       return 0;
     }
 
-    // Write the data. 
+    // Read some data.
+    overlapped.Offset = offset & 0xFFFFFFFF;
+    overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
     BOOL ok = ::ReadFile(impl.handle_,
         boost::asio::buffer_cast<LPVOID>(buffer),
         static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
@@ -668,6 +704,16 @@
   void async_read_some(implementation_type& impl,
       const MutableBufferSequence& buffers, Handler handler)
   {
+    async_read_some_at(impl, 0, buffers, handler);
+  }
+
+  // Start an asynchronous read at a specified offset. The buffer for the data
+  // being received must be valid for the lifetime of the asynchronous
+  // operation.
+  template <typename MutableBufferSequence, typename Handler>
+  void async_read_some_at(implementation_type& impl, boost::uint64_t offset,
+      const MutableBufferSequence& buffers, Handler handler)
+  {
     if (!is_open(impl))
     {
       this->get_io_service().post(bind_handler(handler,
@@ -710,6 +756,8 @@
 
     // Read some data.
     DWORD bytes_transferred = 0;
+    ptr.get()->Offset = offset & 0xFFFFFFFF;
+    ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
     BOOL ok = ::ReadFile(impl.handle_,
         boost::asio::buffer_cast<LPVOID>(buffer),
         static_cast<DWORD>(boost::asio::buffer_size(buffer)),
@@ -733,14 +781,24 @@
   // Prevent the use of the null_buffers type with this service.
   size_t write_some(implementation_type& impl,
       const null_buffers& buffers, boost::system::error_code& ec);
+  size_t write_some_at(implementation_type& impl, boost::uint64_t offset,
+      const null_buffers& buffers, boost::system::error_code& ec);
   template <typename Handler>
   void async_write_some(implementation_type& impl,
       const null_buffers& buffers, Handler handler);
+  template <typename Handler>
+  void async_write_some_at(implementation_type& impl, boost::uint64_t offset,
+      const null_buffers& buffers, Handler handler);
   size_t read_some(implementation_type& impl,
       const null_buffers& buffers, boost::system::error_code& ec);
+  size_t read_some_at(implementation_type& impl, boost::uint64_t offset,
+      const null_buffers& buffers, boost::system::error_code& ec);
   template <typename Handler>
   void async_read_some(implementation_type& impl,
       const null_buffers& buffers, Handler handler);
+  template <typename Handler>
+  void async_read_some_at(implementation_type& impl, boost::uint64_t offset,
+      const null_buffers& buffers, Handler handler);
 
   // Helper function to close a handle when the associated object is being
   // destroyed.
Added: trunk/boost/asio/impl/read_at.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/read_at.ipp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,339 @@
+//
+// read_at.ipp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_READ_AT_IPP
+#define BOOST_ASIO_READ_AT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <algorithm>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/completion_condition.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/consuming_buffers.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+  boost::asio::detail::consuming_buffers<
+    mutable_buffer, MutableBufferSequence> tmp(buffers);
+  std::size_t total_transferred = 0;
+  while (tmp.begin() != tmp.end())
+  {
+    std::size_t bytes_transferred = d.read_some_at(
+        offset + total_transferred, tmp, ec);
+    tmp.consume(bytes_transferred);
+    total_transferred += bytes_transferred;
+    if (completion_condition(ec, total_transferred))
+      return total_transferred;
+  }
+  ec = boost::system::error_code();
+  return total_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = read_at(
+      d, offset, buffers, transfer_all(), ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename CompletionCondition>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    CompletionCondition completion_condition)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = read_at(
+      d, offset, buffers, completion_condition, ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename Allocator,
+    typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+  std::size_t total_transferred = 0;
+  for (;;)
+  {
+    std::size_t bytes_available =
+      std::min<std::size_t>(512, b.max_size() - b.size());
+    std::size_t bytes_transferred = d.read_some_at(
+        offset + total_transferred, b.prepare(bytes_available), ec);
+    b.commit(bytes_transferred);
+    total_transferred += bytes_transferred;
+    if (b.size() == b.max_size()
+        || completion_condition(ec, total_transferred))
+      return total_transferred;
+  }
+}
+
+template <typename SyncRandomAccessReadDevice, typename Allocator>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = read_at(
+      d, offset, b, transfer_all(), ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename Allocator,
+    typename CompletionCondition>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = read_at(
+      d, offset, b, completion_condition, ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+namespace detail
+{
+  template <typename AsyncRandomAccessReadDevice,
+      typename MutableBufferSequence, typename CompletionCondition,
+      typename ReadHandler>
+  class read_at_handler
+  {
+  public:
+    typedef boost::asio::detail::consuming_buffers<
+      mutable_buffer, MutableBufferSequence> buffers_type;
+
+    read_at_handler(AsyncRandomAccessReadDevice& stream,
+        boost::uint64_t offset, const buffers_type& buffers,
+        CompletionCondition completion_condition, ReadHandler handler)
+      : stream_(stream),
+        offset_(offset),
+        buffers_(buffers),
+        total_transferred_(0),
+        completion_condition_(completion_condition),
+        handler_(handler)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      total_transferred_ += bytes_transferred;
+      buffers_.consume(bytes_transferred);
+      if (completion_condition_(ec, total_transferred_)
+          || buffers_.begin() == buffers_.end())
+      {
+        handler_(ec, total_transferred_);
+      }
+      else
+      {
+        stream_.async_read_some_at(
+            offset_ + total_transferred_, buffers_, *this);
+      }
+    }
+
+  //private:
+    AsyncRandomAccessReadDevice& stream_;
+    boost::uint64_t offset_;
+    buffers_type buffers_;
+    std::size_t total_transferred_;
+    CompletionCondition completion_condition_;
+    ReadHandler handler_;
+  };
+
+  template <typename AsyncRandomAccessReadDevice,
+      typename MutableBufferSequence, typename CompletionCondition,
+      typename ReadHandler>
+  inline void* asio_handler_allocate(std::size_t size,
+      read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    return boost_asio_handler_alloc_helpers::allocate(
+        size, &this_handler->handler_);
+  }
+
+  template <typename AsyncRandomAccessReadDevice,
+      typename MutableBufferSequence, typename CompletionCondition,
+      typename ReadHandler>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(
+        pointer, size, &this_handler->handler_);
+  }
+
+  template <typename Function, typename AsyncRandomAccessReadDevice,
+      typename MutableBufferSequence, typename CompletionCondition,
+      typename ReadHandler>
+  inline void asio_handler_invoke(const Function& function,
+      read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, &this_handler->handler_);
+  }
+} // namespace detail
+
+template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename CompletionCondition, typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    CompletionCondition completion_condition, ReadHandler handler)
+{
+  boost::asio::detail::consuming_buffers<
+    mutable_buffer, MutableBufferSequence> tmp(buffers);
+  d.async_read_some_at(offset, tmp,
+      detail::read_at_handler<AsyncRandomAccessReadDevice,
+        MutableBufferSequence, CompletionCondition, ReadHandler>(
+          d, offset, tmp, completion_condition, handler));
+}
+
+template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    ReadHandler handler)
+{
+  async_read_at(d, offset, buffers, transfer_all(), handler);
+}
+
+namespace detail
+{
+  template <typename AsyncRandomAccessReadDevice, typename Allocator,
+      typename CompletionCondition, typename ReadHandler>
+  class read_at_streambuf_handler
+  {
+  public:
+    read_at_streambuf_handler(AsyncRandomAccessReadDevice& stream,
+        boost::uint64_t offset, basic_streambuf<Allocator>& streambuf,
+        CompletionCondition completion_condition, ReadHandler handler)
+      : stream_(stream),
+        offset_(offset),
+        streambuf_(streambuf),
+        total_transferred_(0),
+        completion_condition_(completion_condition),
+        handler_(handler)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      total_transferred_ += bytes_transferred;
+      streambuf_.commit(bytes_transferred);
+      if (streambuf_.size() == streambuf_.max_size()
+          || completion_condition_(ec, total_transferred_))
+      {
+        handler_(ec, total_transferred_);
+      }
+      else
+      {
+        std::size_t bytes_available =
+          std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size());
+        stream_.async_read_some_at(offset_ + total_transferred_,
+            streambuf_.prepare(bytes_available), *this);
+      }
+    }
+
+  //private:
+    AsyncRandomAccessReadDevice& stream_;
+    boost::uint64_t offset_;
+    boost::asio::basic_streambuf<Allocator>& streambuf_;
+    std::size_t total_transferred_;
+    CompletionCondition completion_condition_;
+    ReadHandler handler_;
+  };
+
+  template <typename AsyncRandomAccessReadDevice, typename Allocator,
+      typename CompletionCondition, typename ReadHandler>
+  inline void* asio_handler_allocate(std::size_t size,
+      read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    return boost_asio_handler_alloc_helpers::allocate(
+        size, &this_handler->handler_);
+  }
+
+  template <typename AsyncRandomAccessReadDevice, typename Allocator,
+      typename CompletionCondition, typename ReadHandler>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(
+        pointer, size, &this_handler->handler_);
+  }
+
+  template <typename Function, typename AsyncRandomAccessReadDevice,
+      typename Allocator, typename CompletionCondition, typename ReadHandler>
+  inline void asio_handler_invoke(const Function& function,
+      read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
+        CompletionCondition, ReadHandler>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, &this_handler->handler_);
+  }
+} // namespace detail
+
+template <typename AsyncRandomAccessReadDevice, typename Allocator,
+    typename CompletionCondition, typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition, ReadHandler handler)
+{
+  std::size_t bytes_available =
+    std::min<std::size_t>(512, b.max_size() - b.size());
+  d.async_read_some_at(offset, b.prepare(bytes_available),
+      detail::read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
+        CompletionCondition, ReadHandler>(
+          d, offset, b, completion_condition, handler));
+}
+
+template <typename AsyncRandomAccessReadDevice, typename Allocator,
+    typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    ReadHandler handler)
+{
+  async_read_at(d, offset, b, transfer_all(), handler);
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_READ_AT_IPP
Added: trunk/boost/asio/impl/write_at.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/write_at.ipp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,298 @@
+//
+// write_at.ipp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_WRITE_AT_IPP
+#define BOOST_ASIO_WRITE_AT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/completion_condition.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/consuming_buffers.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+  boost::asio::detail::consuming_buffers<
+    const_buffer, ConstBufferSequence> tmp(buffers);
+  std::size_t total_transferred = 0;
+  while (tmp.begin() != tmp.end())
+  {
+    std::size_t bytes_transferred = d.write_some_at(
+        offset + total_transferred, tmp, ec);
+    tmp.consume(bytes_transferred);
+    total_transferred += bytes_transferred;
+    if (completion_condition(ec, total_transferred))
+      return total_transferred;
+  }
+  ec = boost::system::error_code();
+  return total_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = write_at(
+      d, offset, buffers, transfer_all(), ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename CompletionCondition>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    CompletionCondition completion_condition)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = write_at(
+      d, offset, buffers, completion_condition, ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename Allocator,
+    typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+  std::size_t bytes_transferred = write_at(
+      d, offset, b.data(), completion_condition, ec);
+  b.consume(bytes_transferred);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename Allocator>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename Allocator,
+    typename CompletionCondition>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition)
+{
+  boost::system::error_code ec;
+  std::size_t bytes_transferred = write_at(
+      d, offset, b, completion_condition, ec);
+  boost::asio::detail::throw_error(ec);
+  return bytes_transferred;
+}
+
+namespace detail
+{
+  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+      typename CompletionCondition, typename WriteHandler>
+  class write_at_handler
+  {
+  public:
+    typedef boost::asio::detail::consuming_buffers<
+      const_buffer, ConstBufferSequence> buffers_type;
+
+    write_at_handler(AsyncRandomAccessWriteDevice& stream,
+        boost::uint64_t offset, const buffers_type& buffers,
+        CompletionCondition completion_condition, WriteHandler handler)
+      : stream_(stream),
+        buffers_(buffers),
+        offset_(offset),
+        total_transferred_(0),
+        completion_condition_(completion_condition),
+        handler_(handler)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      total_transferred_ += bytes_transferred;
+      buffers_.consume(bytes_transferred);
+      if (completion_condition_(ec, total_transferred_)
+          || buffers_.begin() == buffers_.end())
+      {
+        handler_(ec, total_transferred_);
+      }
+      else
+      {
+        stream_.async_write_some_at(
+            offset_ + total_transferred_, buffers_, *this);
+      }
+    }
+
+  //private:
+    AsyncRandomAccessWriteDevice& stream_;
+    buffers_type buffers_;
+    boost::uint64_t offset_;
+    std::size_t total_transferred_;
+    CompletionCondition completion_condition_;
+    WriteHandler handler_;
+  };
+
+  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+      typename CompletionCondition, typename WriteHandler>
+  inline void* asio_handler_allocate(std::size_t size,
+      write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
+        CompletionCondition, WriteHandler>* this_handler)
+  {
+    return boost_asio_handler_alloc_helpers::allocate(
+        size, &this_handler->handler_);
+  }
+
+  template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+      typename CompletionCondition, typename WriteHandler>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
+        CompletionCondition, WriteHandler>* this_handler)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(
+        pointer, size, &this_handler->handler_);
+  }
+
+  template <typename Function, typename AsyncRandomAccessWriteDevice,
+      typename ConstBufferSequence, typename CompletionCondition,
+      typename WriteHandler>
+  inline void asio_handler_invoke(const Function& function,
+      write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
+        CompletionCondition, WriteHandler>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, &this_handler->handler_);
+  }
+} // namespace detail
+
+template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename CompletionCondition, typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    CompletionCondition completion_condition, WriteHandler handler)
+{
+  boost::asio::detail::consuming_buffers<
+    const_buffer, ConstBufferSequence> tmp(buffers);
+  d.async_write_some_at(offset, tmp,
+      detail::write_at_handler<AsyncRandomAccessWriteDevice,
+      ConstBufferSequence, CompletionCondition, WriteHandler>(
+          d, offset, tmp, completion_condition, handler));
+}
+
+template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    WriteHandler handler)
+{
+  async_write_at(d, offset, buffers, transfer_all(), handler);
+}
+
+namespace detail
+{
+  template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+      typename WriteHandler>
+  class write_at_streambuf_handler
+  {
+  public:
+    write_at_streambuf_handler(
+        boost::asio::basic_streambuf<Allocator>& streambuf,
+        WriteHandler handler)
+      : streambuf_(streambuf),
+        handler_(handler)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      streambuf_.consume(bytes_transferred);
+      handler_(ec, bytes_transferred);
+    }
+
+  //private:
+    boost::asio::basic_streambuf<Allocator>& streambuf_;
+    WriteHandler handler_;
+  };
+
+  template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+      typename WriteHandler>
+  inline void* asio_handler_allocate(std::size_t size,
+      write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
+        Allocator, WriteHandler>* this_handler)
+  {
+    return boost_asio_handler_alloc_helpers::allocate(
+        size, &this_handler->handler_);
+  }
+
+  template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+      typename WriteHandler>
+  inline void asio_handler_deallocate(void* pointer, std::size_t size,
+      write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
+        Allocator, WriteHandler>* this_handler)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(
+        pointer, size, &this_handler->handler_);
+  }
+
+  template <typename Function, typename AsyncRandomAccessWriteDevice,
+      typename Allocator, typename WriteHandler>
+  inline void asio_handler_invoke(const Function& function,
+      write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
+        Allocator, WriteHandler>* this_handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(
+        function, &this_handler->handler_);
+  }
+} // namespace detail
+
+template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+    typename CompletionCondition, typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition, WriteHandler handler)
+{
+  async_write_at(d, offset, b.data(), completion_condition,
+      detail::write_at_streambuf_handler<
+        AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler));
+}
+
+template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+    typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+    WriteHandler handler)
+{
+  async_write_at(d, offset, b, transfer_all(), handler);
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_WRITE_AT_IPP
Added: trunk/boost/asio/read_at.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/read_at.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,564 @@
+//
+// read_at.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_READ_AT_HPP
+#define BOOST_ASIO_READ_AT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/error.hpp>
+
+namespace boost {
+namespace asio {
+
+/**
+ * @defgroup read_at boost::asio::read_at
+ */
+/*@{*/
+
+/// Attempt to read a certain amount of data at the specified offset before
+/// returning.
+/**
+ * This function is used to read a certain number of bytes of data from a
+ * random access device at the specified offset. The call will block until one
+ * of the following conditions is true:
+ *
+ * @li The supplied buffers are full. That is, the bytes transferred is equal to
+ * the sum of the buffer sizes.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the SyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param buffers One or more buffers into which the data will be read. The sum
+ * of the buffer sizes indicates the maximum number of bytes to read from the
+ * device.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * To read into a single data buffer use the @ref buffer function as follows:
+ * @code boost::asio::read_at(d, 42, boost::asio::buffer(data, size)); @endcode
+ * See the @ref buffer documentation for information on reading into multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::read_at(
+ *     d, 42, buffers,
+ *     boost::asio::transfer_all()); @endcode
+ */
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers);
+
+/// Attempt to read a certain amount of data at the specified offset before
+/// returning.
+/**
+ * This function is used to read a certain number of bytes of data from a
+ * random access device at the specified offset. The call will block until one
+ * of the following conditions is true:
+ *
+ * @li The supplied buffers are full. That is, the bytes transferred is equal to
+ * the sum of the buffer sizes.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the SyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param buffers One or more buffers into which the data will be read. The sum
+ * of the buffer sizes indicates the maximum number of bytes to read from the
+ * device.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest read_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the read operation is complete. False
+ * indicates that further calls to the device's read_some_at function are
+ * required.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * To read into a single data buffer use the @ref buffer function as follows:
+ * @code boost::asio::read_at(d, 42, boost::asio::buffer(data, size),
+ *     boost::asio::transfer_at_least(32)); @endcode
+ * See the @ref buffer documentation for information on reading into multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    CompletionCondition completion_condition);
+
+/// Attempt to read a certain amount of data at the specified offset before
+/// returning.
+/**
+ * This function is used to read a certain number of bytes of data from a
+ * random access device at the specified offset. The call will block until one
+ * of the following conditions is true:
+ *
+ * @li The supplied buffers are full. That is, the bytes transferred is equal to
+ * the sum of the buffer sizes.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the SyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param buffers One or more buffers into which the data will be read. The sum
+ * of the buffer sizes indicates the maximum number of bytes to read from the
+ * device.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   const boost::system::error_code& error, // Result of latest read_some_at
+ *                                           // operation.
+ *
+ *   std::size_t bytes_transferred           // Number of bytes transferred
+ *                                           // so far.
+ * ); @endcode
+ * A return value of true indicates that the read operation is complete. False
+ * indicates that further calls to the device's read_some_at function are
+ * required.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes read. If an error occurs, returns the total
+ * number of bytes successfully transferred prior to the error.
+ */
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    CompletionCondition completion_condition, boost::system::error_code& ec);
+
+/// Attempt to read a certain amount of data at the specified offset before
+/// returning.
+/**
+ * This function is used to read a certain number of bytes of data from a
+ * random access device at the specified offset. The call will block until one
+ * of the following conditions is true:
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the SyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param b The basic_streambuf object into which the data will be read.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::read_at(
+ *     d, 42, b,
+ *     boost::asio::transfer_all()); @endcode
+ */
+template <typename SyncRandomAccessReadDevice, typename Allocator>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, basic_streambuf<Allocator>& b);
+
+/// Attempt to read a certain amount of data at the specified offset before
+/// returning.
+/**
+ * This function is used to read a certain number of bytes of data from a
+ * random access device at the specified offset. The call will block until one
+ * of the following conditions is true:
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the SyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param b The basic_streambuf object into which the data will be read.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest read_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the read operation is complete. False
+ * indicates that further calls to the device's read_some_at function are
+ * required.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+template <typename SyncRandomAccessReadDevice, typename Allocator,
+    typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition);
+
+/// Attempt to read a certain amount of data at the specified offset before
+/// returning.
+/**
+ * This function is used to read a certain number of bytes of data from a
+ * random access device at the specified offset. The call will block until one
+ * of the following conditions is true:
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the SyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param b The basic_streambuf object into which the data will be read.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest read_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the read operation is complete. False
+ * indicates that further calls to the device's read_some_at function are
+ * required.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes read. If an error occurs, returns the total
+ * number of bytes successfully transferred prior to the error.
+ */
+template <typename SyncRandomAccessReadDevice, typename Allocator,
+    typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition, boost::system::error_code& ec);
+
+/*@}*/
+/**
+ * @defgroup async_read_at boost::asio::async_read_at
+ */
+/*@{*/
+
+/// Start an asynchronous operation to read a certain amount of data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously read a certain number of bytes of
+ * data from a random access device at the specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li The supplied buffers are full. That is, the bytes transferred is equal to
+ * the sum of the buffer sizes.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the AsyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param buffers One or more buffers into which the data will be read. The sum
+ * of the buffer sizes indicates the maximum number of bytes to read from the
+ * device. Although the buffers object may be copied as necessary, ownership of
+ * the underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes copied into the buffers. If an error
+ *   // occurred, this will be the number of bytes successfully
+ *   // transferred prior to the error.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ *
+ * @par Example
+ * To read into a single data buffer use the @ref buffer function as follows:
+ * @code
+ * boost::asio::async_read_at(d, 42, boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on reading into multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::async_read_at(
+ *     d, 42, buffers,
+ *     boost::asio::transfer_all(),
+ *     handler); @endcode
+ */
+template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename ReadHandler>
+void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset,
+    const MutableBufferSequence& buffers, ReadHandler handler);
+
+/// Start an asynchronous operation to read a certain amount of data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously read a certain number of bytes of
+ * data from a random access device at the specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li The supplied buffers are full. That is, the bytes transferred is equal to
+ * the sum of the buffer sizes.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the AsyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param buffers One or more buffers into which the data will be read. The sum
+ * of the buffer sizes indicates the maximum number of bytes to read from the
+ * device. Although the buffers object may be copied as necessary, ownership of
+ * the underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest read_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the read operation is complete. False
+ * indicates that further calls to the device's async_read_some_at function are
+ * required.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes copied into the buffers. If an error
+ *   // occurred, this will be the number of bytes successfully
+ *   // transferred prior to the error.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ *
+ * @par Example
+ * To read into a single data buffer use the @ref buffer function as follows:
+ * @code boost::asio::async_read_at(d, 42,
+ *     boost::asio::buffer(data, size),
+ *     boost::asio::transfer_at_least(32),
+ *     handler); @endcode
+ * See the @ref buffer documentation for information on reading into multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
+    typename CompletionCondition, typename ReadHandler>
+void async_read_at(AsyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, const MutableBufferSequence& buffers,
+    CompletionCondition completion_condition, ReadHandler handler);
+
+/// Start an asynchronous operation to read a certain amount of data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously read a certain number of bytes of
+ * data from a random access device at the specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the AsyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param b A basic_streambuf object into which the data will be read. Ownership
+ * of the streambuf is retained by the caller, which must guarantee that it
+ * remains valid until the handler is called.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes copied into the buffers. If an error
+ *   // occurred, this will be the number of bytes successfully
+ *   // transferred prior to the error.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::async_read_at(
+ *     d, 42, b,
+ *     boost::asio::transfer_all(),
+ *     handler); @endcode
+ */
+template <typename AsyncRandomAccessReadDevice, typename Allocator,
+    typename ReadHandler>
+void async_read_at(AsyncRandomAccessReadDevice& d, boost::uint64_t offset,
+    basic_streambuf<Allocator>& b, ReadHandler handler);
+
+/// Start an asynchronous operation to read a certain amount of data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously read a certain number of bytes of
+ * data from a random access device at the specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_read_some_at function.
+ *
+ * @param d The device from which the data is to be read. The type must support
+ * the AsyncRandomAccessReadDevice concept.
+ *
+ * @param offset The offset at which the data will be read.
+ *
+ * @param b A basic_streambuf object into which the data will be read. Ownership
+ * of the streambuf is retained by the caller, which must guarantee that it
+ * remains valid until the handler is called.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest read_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the read operation is complete. False
+ * indicates that further calls to the device's async_read_some_at function are
+ * required.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes copied into the buffers. If an error
+ *   // occurred, this will be the number of bytes successfully
+ *   // transferred prior to the error.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ */
+template <typename AsyncRandomAccessReadDevice, typename Allocator,
+    typename CompletionCondition, typename ReadHandler>
+void async_read_at(AsyncRandomAccessReadDevice& d,
+    boost::uint64_t offset, basic_streambuf<Allocator>& b,
+    CompletionCondition completion_condition, ReadHandler handler);
+
+/*@}*/
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/impl/read_at.ipp>
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_READ_AT_HPP
Added: trunk/boost/asio/windows/basic_random_access_handle.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/windows/basic_random_access_handle.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,322 @@
+//
+// basic_random_access_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP
+#define BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/windows/basic_handle.hpp>
+#include <boost/asio/windows/random_access_handle_service.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace boost {
+namespace asio {
+namespace windows {
+
+/// Provides random-access handle functionality.
+/**
+ * The windows::basic_random_access_handle class template provides asynchronous
+ * and blocking random-access handle functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe._at_n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename RandomAccessHandleService = random_access_handle_service>
+class basic_random_access_handle
+  : public basic_handle<RandomAccessHandleService>
+{
+public:
+  /// The native representation of a handle.
+  typedef typename RandomAccessHandleService::native_type native_type;
+
+  /// Construct a basic_random_access_handle without opening it.
+  /**
+   * This constructor creates a random-access handle without opening it. The
+   * handle needs to be opened before data can be written to or or read from it.
+   *
+   * @param io_service The io_service object that the random-access handle will
+   * use to dispatch handlers for any asynchronous operations performed on the
+   * handle.
+   */
+  explicit basic_random_access_handle(boost::asio::io_service& io_service)
+    : basic_handle<RandomAccessHandleService>(io_service)
+  {
+  }
+
+  /// Construct a basic_random_access_handle on an existing native handle.
+  /**
+   * This constructor creates a random-access handle object to hold an existing
+   * native handle.
+   *
+   * @param io_service The io_service object that the random-access handle will
+   * use to dispatch handlers for any asynchronous operations performed on the
+   * handle.
+   *
+   * @param native_handle The new underlying handle implementation.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_random_access_handle(boost::asio::io_service& io_service,
+      const native_type& native_handle)
+    : basic_handle<RandomAccessHandleService>(io_service, native_handle)
+  {
+  }
+
+  /// Write some data to the handle at the specified offset.
+  /**
+   * This function is used to write data to the random-access handle. The
+   * function call will block until one or more bytes of the data has been
+   * written successfully, or until an error occurs.
+   *
+   * @param offset The offset at which the data will be written.
+   *
+   * @param buffers One or more data buffers to be written to the handle.
+   *
+   * @returns The number of bytes written.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The write_some_at operation may not write all of the data. Consider
+   * using the @ref write_at function if you need to ensure that all data is
+   * written before the blocking operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * handle.write_some_at(42, boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some_at(boost::uint64_t offset,
+      const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->service.write_some_at(
+        this->implementation, offset, buffers, ec);
+    boost::asio::detail::throw_error(ec);
+    return s;
+  }
+
+  /// Write some data to the handle at the specified offset.
+  /**
+   * This function is used to write data to the random-access handle. The
+   * function call will block until one or more bytes of the data has been
+   * written successfully, or until an error occurs.
+   *
+   * @param offset The offset at which the data will be written.
+   *
+   * @param buffers One or more data buffers to be written to the handle.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes written. Returns 0 if an error occurred.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write_at function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some_at(boost::uint64_t offset,
+      const ConstBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return this->service.write_some_at(
+        this->implementation, offset, buffers, ec);
+  }
+
+  /// Start an asynchronous write at the specified offset.
+  /**
+   * This function is used to asynchronously write data to the random-access
+   * handle. The function call always returns immediately.
+   *
+   * @param offset The offset at which the data will be written.
+   *
+   * @param buffers One or more data buffers to be written to the handle.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the write operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes written.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_service::post().
+   *
+   * @note The write operation may not transmit all of the data to the peer.
+   * Consider using the @ref async_write_at function if you need to ensure that
+   * all data is written before the asynchronous operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * handle.async_write_some_at(42, boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  void async_write_some_at(boost::uint64_t offset,
+      const ConstBufferSequence& buffers, WriteHandler handler)
+  {
+    this->service.async_write_some_at(
+        this->implementation, offset, buffers, handler);
+  }
+
+  /// Read some data from the handle at the specified offset.
+  /**
+   * This function is used to read data from the random-access handle. The
+   * function call will block until one or more bytes of data has been read
+   * successfully, or until an error occurs.
+   *
+   * @param offset The offset at which the data will be read.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @returns The number of bytes read.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read_at function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * handle.read_some_at(42, boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some_at(boost::uint64_t offset,
+      const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->service.read_some_at(
+        this->implementation, offset, buffers, ec);
+    boost::asio::detail::throw_error(ec);
+    return s;
+  }
+
+  /// Read some data from the handle at the specified offset.
+  /**
+   * This function is used to read data from the random-access handle. The
+   * function call will block until one or more bytes of data has been read
+   * successfully, or until an error occurs.
+   *
+   * @param offset The offset at which the data will be read.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes read. Returns 0 if an error occurred.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read_at function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some_at(boost::uint64_t offset,
+      const MutableBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return this->service.read_some_at(
+        this->implementation, offset, buffers, ec);
+  }
+
+  /// Start an asynchronous read at the specified offset.
+  /**
+   * This function is used to asynchronously read data from the random-access
+   * handle. The function call always returns immediately.
+   *
+   * @param offset The offset at which the data will be read.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the read operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes read.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_service::post().
+   *
+   * @note The read operation may not read all of the requested number of bytes.
+   * Consider using the @ref async_read_at function if you need to ensure that
+   * the requested amount of data is read before the asynchronous operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * handle.async_read_some_at(42, boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  void async_read_some_at(boost::uint64_t offset,
+      const MutableBufferSequence& buffers, ReadHandler handler)
+  {
+    this->service.async_read_some_at(
+        this->implementation, offset, buffers, handler);
+  }
+};
+
+} // namespace windows
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP
Added: trunk/boost/asio/windows/random_access_handle.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/windows/random_access_handle.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,41 @@
+//
+// random_access_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP
+#define BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/windows/basic_random_access_handle.hpp>
+
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace boost {
+namespace asio {
+namespace windows {
+
+/// Typedef for the typical usage of a random-access handle.
+typedef basic_random_access_handle<> random_access_handle;
+
+} // namespace windows
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP
Added: trunk/boost/asio/windows/random_access_handle_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/windows/random_access_handle_service.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,181 @@
+//
+// random_access_handle_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP
+#define BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/service_base.hpp>
+#include <boost/asio/detail/win_iocp_handle_service.hpp>
+
+#if !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
+# if defined(BOOST_ASIO_HAS_IOCP)
+#  define BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1
+# endif // defined(BOOST_ASIO_HAS_IOCP)
+#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
+
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace boost {
+namespace asio {
+namespace windows {
+
+/// Default service implementation for a random-access handle.
+class random_access_handle_service
+#if defined(GENERATING_DOCUMENTATION)
+  : public boost::asio::io_service::service
+#else
+  : public boost::asio::detail::service_base<random_access_handle_service>
+#endif
+{
+public:
+#if defined(GENERATING_DOCUMENTATION)
+  /// The unique service identifier.
+  static boost::asio::io_service::id id;
+#endif
+
+private:
+  // The type of the platform-specific implementation.
+  typedef detail::win_iocp_handle_service service_impl_type;
+
+public:
+  /// The type of a random-access handle implementation.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined implementation_type;
+#else
+  typedef service_impl_type::implementation_type implementation_type;
+#endif
+
+  /// The native handle type.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_type;
+#else
+  typedef service_impl_type::native_type native_type;
+#endif
+
+  /// Construct a new random-access handle service for the specified io_service.
+  explicit random_access_handle_service(boost::asio::io_service& io_service)
+    : boost::asio::detail::service_base<
+        random_access_handle_service>(io_service),
+      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+  {
+  }
+
+  /// Destroy all user-defined handler objects owned by the service.
+  void shutdown_service()
+  {
+  }
+
+  /// Construct a new random-access handle implementation.
+  void construct(implementation_type& impl)
+  {
+    service_impl_.construct(impl);
+  }
+
+  /// Destroy a random-access handle implementation.
+  void destroy(implementation_type& impl)
+  {
+    service_impl_.destroy(impl);
+  }
+
+  /// Assign an existing native handle to a random-access handle.
+  boost::system::error_code assign(implementation_type& impl,
+      const native_type& native_handle, boost::system::error_code& ec)
+  {
+    return service_impl_.assign(impl, native_handle, ec);
+  }
+
+  /// Determine whether the handle is open.
+  bool is_open(const implementation_type& impl) const
+  {
+    return service_impl_.is_open(impl);
+  }
+
+  /// Close a random-access handle implementation.
+  boost::system::error_code close(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.close(impl, ec);
+  }
+
+  /// Get the native handle implementation.
+  native_type native(implementation_type& impl)
+  {
+    return service_impl_.native(impl);
+  }
+
+  /// Cancel all asynchronous operations associated with the handle.
+  boost::system::error_code cancel(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.cancel(impl, ec);
+  }
+
+  /// Write the given data at the specified offset.
+  template <typename ConstBufferSequence>
+  std::size_t write_some_at(implementation_type& impl, boost::uint64_t offset,
+      const ConstBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return service_impl_.write_some_at(impl, offset, buffers, ec);
+  }
+
+  /// Start an asynchronous write at the specified offset.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  void async_write_some_at(implementation_type& impl, boost::uint64_t offset,
+      const ConstBufferSequence& buffers, WriteHandler handler)
+  {
+    service_impl_.async_write_some_at(impl, offset, buffers, handler);
+  }
+
+  /// Read some data from the specified offset.
+  template <typename MutableBufferSequence>
+  std::size_t read_some_at(implementation_type& impl, boost::uint64_t offset,
+      const MutableBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return service_impl_.read_some_at(impl, offset, buffers, ec);
+  }
+
+  /// Start an asynchronous read at the specified offset.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  void async_read_some_at(implementation_type& impl, boost::uint64_t offset,
+      const MutableBufferSequence& buffers, ReadHandler handler)
+  {
+    service_impl_.async_read_some_at(impl, offset, buffers, handler);
+  }
+
+private:
+  // The service that provides the platform-specific implementation.
+  service_impl_type& service_impl_;
+};
+
+} // namespace windows
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP
Modified: trunk/boost/asio/write.hpp
==============================================================================
--- trunk/boost/asio/write.hpp	(original)
+++ trunk/boost/asio/write.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -167,7 +167,7 @@
 std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
     CompletionCondition completion_condition, boost::system::error_code& ec);
 
-/// Write a certain amount of data to a stream before returning.
+/// Write all of the supplied data to a stream before returning.
 /**
  * This function is used to write a certain number of bytes of data to a stream.
  * The call will block until one of the following conditions is true:
@@ -283,7 +283,7 @@
  */
 /*@{*/
 
-/// Start an asynchronous operation to write of all of the supplied data to a
+/// Start an asynchronous operation to write all of the supplied data to a
 /// stream.
 /**
  * This function is used to asynchronously write a certain number of bytes of
@@ -406,7 +406,7 @@
 void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
     CompletionCondition completion_condition, WriteHandler handler);
 
-/// Start an asynchronous operation to write a certain amount of data to a
+/// Start an asynchronous operation to write all of the supplied data to a
 /// stream.
 /**
  * This function is used to asynchronously write a certain number of bytes of
Added: trunk/boost/asio/write_at.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/write_at.hpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,546 @@
+//
+// write_at.hpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_WRITE_AT_HPP
+#define BOOST_ASIO_WRITE_AT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/error.hpp>
+
+namespace boost {
+namespace asio {
+
+/**
+ * @defgroup write_at boost::asio::write_at
+ */
+/*@{*/
+
+/// Write all of the supplied data at the specified offset before returning.
+/**
+ * This function is used to write a certain number of bytes of data to a random
+ * access device at a specified offset. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li All of the data in the supplied buffers has been written. That is, the
+ * bytes transferred is equal to the sum of the buffer sizes.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the SyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param buffers One or more buffers containing the data to be written. The sum
+ * of the buffer sizes indicates the maximum number of bytes to write to the
+ * device.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * To write a single data buffer use the @ref buffer function as follows:
+ * @code boost::asio::write_at(d, 42, boost::asio::buffer(data, size)); @endcode
+ * See the @ref buffer documentation for information on writing multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::write_at(
+ *     d, offset, buffers,
+ *     boost::asio::transfer_all()); @endcode
+ */
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers);
+
+/// Write a certain amount of data at a specified offset before returning.
+/**
+ * This function is used to write a certain number of bytes of data to a random
+ * access device at a specified offset. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li All of the data in the supplied buffers has been written. That is, the
+ * bytes transferred is equal to the sum of the buffer sizes.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the SyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param buffers One or more buffers containing the data to be written. The sum
+ * of the buffer sizes indicates the maximum number of bytes to write to the
+ * device.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest write_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the write operation is complete. False
+ * indicates that further calls to the device's write_some_at function are
+ * required.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * To write a single data buffer use the @ref buffer function as follows:
+ * @code boost::asio::write_at(d, 42, boost::asio::buffer(data, size),
+ *     boost::asio::transfer_at_least(32)); @endcode
+ * See the @ref buffer documentation for information on writing multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    CompletionCondition completion_condition);
+
+/// Write a certain amount of data at a specified offset before returning.
+/**
+ * This function is used to write a certain number of bytes of data to a random
+ * access device at a specified offset. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li All of the data in the supplied buffers has been written. That is, the
+ * bytes transferred is equal to the sum of the buffer sizes.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the SyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param buffers One or more buffers containing the data to be written. The sum
+ * of the buffer sizes indicates the maximum number of bytes to write to the
+ * device.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest write_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the write operation is complete. False
+ * indicates that further calls to the device's write_some_at function are
+ * required.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes written. If an error occurs, returns the total
+ * number of bytes successfully transferred prior to the error.
+ */
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename CompletionCondition>
+std::size_t write(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    CompletionCondition completion_condition, boost::system::error_code& ec);
+
+/// Write all of the supplied data at the specified offset before returning.
+/**
+ * This function is used to write a certain number of bytes of data to a random
+ * access device at a specified offset. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li All of the data in the supplied basic_streambuf has been written.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the SyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param b The basic_streambuf object from which data will be written.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::write_at(
+ *     d, 42, b,
+ *     boost::asio::transfer_all()); @endcode
+ */
+template <typename SyncRandomAccessWriteDevice, typename Allocator>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, basic_streambuf<Allocator>& b);
+
+/// Write a certain amount of data at a specified offset before returning.
+/**
+ * This function is used to write a certain number of bytes of data to a random
+ * access device at a specified offset. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li All of the data in the supplied basic_streambuf has been written.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the SyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param b The basic_streambuf object from which data will be written.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest write_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the write operation is complete. False
+ * indicates that further calls to the device's write_some_at function are
+ * required.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+template <typename SyncRandomAccessWriteDevice, typename Allocator,
+    typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::uint64_t offset,
+    basic_streambuf<Allocator>& b, CompletionCondition completion_condition);
+
+/// Write a certain amount of data at a specified offset before returning.
+/**
+ * This function is used to write a certain number of bytes of data to a random
+ * access device at a specified offset. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li All of the data in the supplied basic_streambuf has been written.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the SyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param b The basic_streambuf object from which data will be written.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest write_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the write operation is complete. False
+ * indicates that further calls to the device's write_some_at function are
+ * required.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes written. If an error occurs, returns the total
+ * number of bytes successfully transferred prior to the error.
+ */
+template <typename SyncRandomAccessWriteDevice, typename Allocator,
+    typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d, boost::uint64_t offset,
+    basic_streambuf<Allocator>& b, CompletionCondition completion_condition,
+    boost::system::error_code& ec);
+
+/*@}*/
+/**
+ * @defgroup async_write_at boost::asio::async_write_at
+ */
+/*@{*/
+
+/// Start an asynchronous operation to write all of the supplied data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously write a certain number of bytes of
+ * data to a random access device at a specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li All of the data in the supplied buffers has been written. That is, the
+ * bytes transferred is equal to the sum of the buffer sizes.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the AsyncRandomAccessWriteDevice concept.
+ *
+ * @param offset The offset at which the data will be written.
+ *
+ * @param buffers One or more buffers containing the data to be written.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of
+ * the handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes written from the buffers. If an error
+ *   // occurred, this will be less than the sum of the buffer sizes.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ *
+ * @par Example
+ * To write a single data buffer use the @ref buffer function as follows:
+ * @code
+ * boost::asio::async_write_at(d, 42, boost::asio::buffer(data, size), handler);
+ * @endcode
+ * See the @ref buffer documentation for information on writing multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename WriteHandler>
+void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset,
+    const ConstBufferSequence& buffers, WriteHandler handler);
+
+/// Start an asynchronous operation to write a certain amount of data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously write a certain number of bytes of
+ * data to a random access device at a specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li All of the data in the supplied buffers has been written. That is, the
+ * bytes transferred is equal to the sum of the buffer sizes.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the AsyncRandomAccessWriteDevice concept.
+ *
+ * @param buffers One or more buffers containing the data to be written.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest write_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the write operation is complete. False
+ * indicates that further calls to the device's async_write_some_at function are
+ * required.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes written from the buffers. If an error
+ *   // occurred, this will be less than the sum of the buffer sizes.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ *
+ * @par Example
+ * To write a single data buffer use the @ref buffer function as follows:
+ * @code boost::asio::async_write_at(d, 42,
+ *     boost::asio::buffer(data, size),
+ *     boost::asio::transfer_at_least(32),
+ *     handler); @endcode
+ * See the @ref buffer documentation for information on writing multiple
+ * buffers in one go, and how to use it with arrays, boost::array or
+ * std::vector.
+ */
+template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+    typename CompletionCondition, typename WriteHandler>
+void async_write_at(AsyncRandomAccessWriteDevice& d,
+    boost::uint64_t offset, const ConstBufferSequence& buffers,
+    CompletionCondition completion_condition, WriteHandler handler);
+
+/// Start an asynchronous operation to write all of the supplied data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously write a certain number of bytes of
+ * data to a random access device at a specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li All of the data in the supplied basic_streambuf has been written.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the AsyncRandomAccessWriteDevice concept.
+ *
+ * @param b A basic_streambuf object from which data will be written. Ownership
+ * of the streambuf is retained by the caller, which must guarantee that it
+ * remains valid until the handler is called.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes written from the buffers. If an error
+ *   // occurred, this will be less than the sum of the buffer sizes.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ */
+template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+    typename WriteHandler>
+void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset,
+    basic_streambuf<Allocator>& b, WriteHandler handler);
+
+/// Start an asynchronous operation to write a certain amount of data at the
+/// specified offset.
+/**
+ * This function is used to asynchronously write a certain number of bytes of
+ * data to a random access device at a specified offset. The function call
+ * always returns immediately. The asynchronous operation will continue until
+ * one of the following conditions is true:
+ *
+ * @li All of the data in the supplied basic_streambuf has been written.
+ *
+ * @li The completion_condition function object returns true.
+ *
+ * This operation is implemented in terms of one or more calls to the device's
+ * async_write_some_at function.
+ *
+ * @param d The device to which the data is to be written. The type must support
+ * the AsyncRandomAccessWriteDevice concept.
+ *
+ * @param b A basic_streambuf object from which data will be written. Ownership
+ * of the streambuf is retained by the caller, which must guarantee that it
+ * remains valid until the handler is called.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code bool completion_condition(
+ *   // Result of latest async_write_some_at operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes transferred so far.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of true indicates that the write operation is complete. False
+ * indicates that further calls to the device's async_write_some_at function are
+ * required.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ *   // Result of operation.
+ *   const boost::system::error_code& error,
+ *
+ *   // Number of bytes written from the buffers. If an error
+ *   // occurred, this will be less than the sum of the buffer sizes.
+ *   std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation of
+ * the handler will be performed in a manner equivalent to using
+ * boost::asio::io_service::post().
+ */
+template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+    typename CompletionCondition, typename WriteHandler>
+void async_write_at(AsyncRandomAccessWriteDevice& d, boost::uint64_t offset,
+    basic_streambuf<Allocator>& b, CompletionCondition completion_condition,
+    WriteHandler handler);
+
+/*@}*/
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/impl/write_at.ipp>
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_WRITE_AT_HPP
Modified: trunk/libs/asio/test/Jamfile
==============================================================================
--- trunk/libs/asio/test/Jamfile	(original)
+++ trunk/libs/asio/test/Jamfile	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -87,7 +87,10 @@
   [ run stream_socket_service.cpp <template>asio_unit_test ]
   [ run time_traits.cpp <template>asio_unit_test ]
   [ run windows/basic_handle.cpp <template>asio_unit_test ]
+  [ run windows/basic_random_access_handle.cpp <template>asio_unit_test ]
   [ run windows/basic_stream_handle.cpp <template>asio_unit_test ]
+  [ run windows/random_access_handle.cpp <template>asio_unit_test ]
+  [ run windows/random_access_handle_service.cpp <template>asio_unit_test ]
   [ run windows/stream_handle.cpp <template>asio_unit_test ]
   [ run windows/stream_handle_service.cpp <template>asio_unit_test ]
   [ run write.cpp <template>asio_unit_test ]
Modified: trunk/libs/asio/test/Jamfile.v2
==============================================================================
--- trunk/libs/asio/test/Jamfile.v2	(original)
+++ trunk/libs/asio/test/Jamfile.v2	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -152,8 +152,14 @@
   [ link time_traits.cpp : $(USE_SELECT) : time_traits_select ]
   [ link windows/basic_handle.cpp : : windows_basic_handle ]
   [ link windows/basic_handle.cpp : $(USE_SELECT) : windows_basic_handle_select ]
+  [ link windows/basic_random_access_handle.cpp : : windows_basic_random_access_handle ]
+  [ link windows/basic_random_access_handle.cpp : $(USE_SELECT) : windows_basic_random_access_handle_select ]
   [ link windows/basic_stream_handle.cpp : : windows_basic_stream_handle ]
   [ link windows/basic_stream_handle.cpp : $(USE_SELECT) : windows_basic_stream_handle_select ]
+  [ link windows/random_access_handle.cpp : : windows_random_access_handle ]
+  [ link windows/random_access_handle.cpp : $(USE_SELECT) : windows_random_access_handle_select ]
+  [ link windows/random_access_handle_service.cpp : : windows_random_access_handle_service ]
+  [ link windows/random_access_handle_service.cpp : $(USE_SELECT) : windows_random_access_handle_service_select ]
   [ link windows/stream_handle.cpp : : windows_stream_handle ]
   [ link windows/stream_handle.cpp : $(USE_SELECT) : windows_stream_handle_select ]
   [ link windows/stream_handle_service.cpp : : windows_stream_handle_service ]
Added: trunk/libs/asio/test/windows/basic_random_access_handle.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/windows/basic_random_access_handle.cpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,27 @@
+//
+// basic_random_access_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/windows/basic_random_access_handle.hpp>
+
+#include <boost/asio.hpp>
+#include "../unit_test.hpp"
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("windows/basic_random_access_handle");
+  test->add(BOOST_TEST_CASE(&null_test));
+  return test;
+}
Added: trunk/libs/asio/test/windows/random_access_handle.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/windows/random_access_handle.cpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,118 @@
+//
+// random_access_handle.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/windows/random_access_handle.hpp>
+
+#include <boost/asio.hpp>
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// windows_random_access_handle_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// windows::random_access_handle compile and link correctly. Runtime failures
+// are ignored.
+
+namespace windows_random_access_handle_compile {
+
+void write_some_handler(const boost::system::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const boost::system::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+  using namespace boost::asio;
+  namespace win = boost::asio::windows;
+
+  try
+  {
+    io_service ios;
+    char mutable_char_buffer[128] = "";
+    const char const_char_buffer[128] = "";
+    boost::uint64_t offset = 0;
+    boost::system::error_code ec;
+
+    // basic_random_access_handle constructors.
+
+    win::random_access_handle handle1(ios);
+    HANDLE native_handle1 = INVALID_HANDLE_VALUE;
+    win::random_access_handle handle2(ios, native_handle1);
+
+    // basic_io_object functions.
+
+    io_service& ios_ref = handle1.io_service();
+    (void)ios_ref;
+
+    // basic_handle functions.
+
+    win::random_access_handle::lowest_layer_type& lowest_layer
+      = handle1.lowest_layer();
+    (void)lowest_layer;
+
+    HANDLE native_handle2 = INVALID_HANDLE_VALUE;
+    handle1.assign(native_handle2);
+
+    bool is_open = handle1.is_open();
+    (void)is_open;
+
+    handle1.close();
+    handle1.close(ec);
+
+    win::random_access_handle::native_type native_handle3 = handle1.native();
+    (void)native_handle3;
+
+    handle1.cancel();
+    handle1.cancel(ec);
+
+    // basic_random_access_handle functions.
+
+    handle1.write_some_at(offset, buffer(mutable_char_buffer));
+    handle1.write_some_at(offset, buffer(const_char_buffer));
+    handle1.write_some_at(offset, buffer(mutable_char_buffer), ec);
+    handle1.write_some_at(offset, buffer(const_char_buffer), ec);
+
+    handle1.async_write_some_at(offset,
+        buffer(mutable_char_buffer), write_some_handler);
+    handle1.async_write_some_at(offset,
+        buffer(const_char_buffer), write_some_handler);
+
+    handle1.read_some_at(offset, buffer(mutable_char_buffer));
+    handle1.read_some_at(offset, buffer(mutable_char_buffer), ec);
+
+    handle1.async_read_some_at(offset,
+        buffer(mutable_char_buffer), read_some_handler);
+  }
+  catch (std::exception&)
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+}
+
+} // namespace windows_random_access_handle_compile
+
+//------------------------------------------------------------------------------
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("windows/random_access_handle");
+  test->add(BOOST_TEST_CASE(&windows_random_access_handle_compile::test));
+  return test;
+}
Added: trunk/libs/asio/test/windows/random_access_handle_service.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/windows/random_access_handle_service.cpp	2008-06-11 07:17:53 EDT (Wed, 11 Jun 2008)
@@ -0,0 +1,27 @@
+//
+// random_access_handle_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/windows/random_access_handle_service.hpp>
+
+#include <boost/asio.hpp>
+#include "../unit_test.hpp"
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("windows/random_access_handle_service");
+  test->add(BOOST_TEST_CASE(&null_test));
+  return test;
+}