Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / buffer.hpp @ 2486

History | View | Annotate | Download (69.2 kB)

1
//
2
// buffer.hpp
3
// ~~~~~~~~~~
4
//
5
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6
//
7
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
//
10

    
11
#ifndef BOOST_ASIO_BUFFER_HPP
12
#define BOOST_ASIO_BUFFER_HPP
13

    
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15
# pragma once
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17

    
18
#include <boost/asio/detail/config.hpp>
19
#include <cstddef>
20
#include <cstring>
21
#include <string>
22
#include <vector>
23
#include <boost/asio/detail/array_fwd.hpp>
24

    
25
#if defined(BOOST_ASIO_MSVC)
26
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
27
#  if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
28
#   define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
29
#  endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
30
# endif // defined(_HAS_ITERATOR_DEBUGGING)
31
#endif // defined(BOOST_ASIO_MSVC)
32

    
33
#if defined(__GNUC__)
34
# if defined(_GLIBCXX_DEBUG)
35
#  if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
36
#   define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
37
#  endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
38
# endif // defined(_GLIBCXX_DEBUG)
39
#endif // defined(__GNUC__)
40

    
41
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
42
# include <boost/asio/detail/function.hpp>
43
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
44

    
45
#if defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
46
# include <boost/detail/workaround.hpp>
47
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
48
    || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
49
#  define BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND
50
# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
51
        // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
52
#endif // defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
53

    
54
#if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
55
# include <boost/asio/detail/type_traits.hpp>
56
#endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
57

    
58
#include <boost/asio/detail/push_options.hpp>
59

    
60
namespace boost {
61
namespace asio {
62

    
63
class mutable_buffer;
64
class const_buffer;
65

    
66
namespace detail {
67
void* buffer_cast_helper(const mutable_buffer&);
68
const void* buffer_cast_helper(const const_buffer&);
69
std::size_t buffer_size_helper(const mutable_buffer&);
70
std::size_t buffer_size_helper(const const_buffer&);
71
} // namespace detail
72

    
73
/// Holds a buffer that can be modified.
74
/**
75
 * The mutable_buffer class provides a safe representation of a buffer that can
76
 * be modified. It does not own the underlying data, and so is cheap to copy or
77
 * assign.
78
 *
79
 * @par Accessing Buffer Contents
80
 *
81
 * The contents of a buffer may be accessed using the @ref buffer_size
82
 * and @ref buffer_cast functions:
83
 *
84
 * @code boost::asio::mutable_buffer b1 = ...;
85
 * std::size_t s1 = boost::asio::buffer_size(b1);
86
 * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
87
 * @endcode
88
 *
89
 * The boost::asio::buffer_cast function permits violations of type safety, so
90
 * uses of it in application code should be carefully considered.
91
 */
92
class mutable_buffer
93
{
94
public:
95
  /// Construct an empty buffer.
96
  mutable_buffer()
97
    : data_(0),
98
      size_(0)
99
  {
100
  }
101

    
102
  /// Construct a buffer to represent a given memory range.
103
  mutable_buffer(void* data, std::size_t size)
104
    : data_(data),
105
      size_(size)
106
  {
107
  }
108

    
109
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
110
  mutable_buffer(void* data, std::size_t size,
111
      boost::asio::detail::function<void()> debug_check)
112
    : data_(data),
113
      size_(size),
114
      debug_check_(debug_check)
115
  {
116
  }
117

    
118
  const boost::asio::detail::function<void()>& get_debug_check() const
119
  {
120
    return debug_check_;
121
  }
122
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
123

    
124
private:
125
  friend void* boost::asio::detail::buffer_cast_helper(
126
      const mutable_buffer& b);
127
  friend std::size_t boost::asio::detail::buffer_size_helper(
128
      const mutable_buffer& b);
129

    
130
  void* data_;
131
  std::size_t size_;
132

    
133
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
134
  boost::asio::detail::function<void()> debug_check_;
135
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
136
};
137

    
138
namespace detail {
139

    
140
inline void* buffer_cast_helper(const mutable_buffer& b)
141
{
142
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
143
  if (b.size_ && b.debug_check_)
144
    b.debug_check_();
145
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
146
  return b.data_;
147
}
148

    
149
inline std::size_t buffer_size_helper(const mutable_buffer& b)
150
{
151
  return b.size_;
152
}
153

    
154
} // namespace detail
155

    
156
/// Adapts a single modifiable buffer so that it meets the requirements of the
157
/// MutableBufferSequence concept.
158
class mutable_buffers_1
159
  : public mutable_buffer
160
{
161
public:
162
  /// The type for each element in the list of buffers.
163
  typedef mutable_buffer value_type;
164

    
165
  /// A random-access iterator type that may be used to read elements.
166
  typedef const mutable_buffer* const_iterator;
167

    
168
  /// Construct to represent a given memory range.
169
  mutable_buffers_1(void* data, std::size_t size)
170
    : mutable_buffer(data, size)
171
  {
172
  }
173

    
174
  /// Construct to represent a single modifiable buffer.
175
  explicit mutable_buffers_1(const mutable_buffer& b)
176
    : mutable_buffer(b)
177
  {
178
  }
179

    
180
  /// Get a random-access iterator to the first element.
181
  const_iterator begin() const
182
  {
183
    return this;
184
  }
185

    
186
  /// Get a random-access iterator for one past the last element.
187
  const_iterator end() const
188
  {
189
    return begin() + 1;
190
  }
191
};
192

    
193
/// Holds a buffer that cannot be modified.
194
/**
195
 * The const_buffer class provides a safe representation of a buffer that cannot
196
 * be modified. It does not own the underlying data, and so is cheap to copy or
197
 * assign.
198
 *
199
 * @par Accessing Buffer Contents
200
 *
201
 * The contents of a buffer may be accessed using the @ref buffer_size
202
 * and @ref buffer_cast functions:
203
 *
204
 * @code boost::asio::const_buffer b1 = ...;
205
 * std::size_t s1 = boost::asio::buffer_size(b1);
206
 * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
207
 * @endcode
208
 *
209
 * The boost::asio::buffer_cast function permits violations of type safety, so
210
 * uses of it in application code should be carefully considered.
211
 */
212
class const_buffer
213
{
214
public:
215
  /// Construct an empty buffer.
216
  const_buffer()
217
    : data_(0),
218
      size_(0)
219
  {
220
  }
221

    
222
  /// Construct a buffer to represent a given memory range.
223
  const_buffer(const void* data, std::size_t size)
224
    : data_(data),
225
      size_(size)
226
  {
227
  }
228

    
229
  /// Construct a non-modifiable buffer from a modifiable one.
230
  const_buffer(const mutable_buffer& b)
231
    : data_(boost::asio::detail::buffer_cast_helper(b)),
232
      size_(boost::asio::detail::buffer_size_helper(b))
233
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
234
      , debug_check_(b.get_debug_check())
235
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
236
  {
237
  }
238

    
239
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
240
  const_buffer(const void* data, std::size_t size,
241
      boost::asio::detail::function<void()> debug_check)
242
    : data_(data),
243
      size_(size),
244
      debug_check_(debug_check)
245
  {
246
  }
247

    
248
  const boost::asio::detail::function<void()>& get_debug_check() const
249
  {
250
    return debug_check_;
251
  }
252
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
253

    
254
private:
255
  friend const void* boost::asio::detail::buffer_cast_helper(
256
      const const_buffer& b);
257
  friend std::size_t boost::asio::detail::buffer_size_helper(
258
      const const_buffer& b);
259

    
260
  const void* data_;
261
  std::size_t size_;
262

    
263
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
264
  boost::asio::detail::function<void()> debug_check_;
265
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
266
};
267

    
268
namespace detail {
269

    
270
inline const void* buffer_cast_helper(const const_buffer& b)
271
{
272
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
273
  if (b.size_ && b.debug_check_)
274
    b.debug_check_();
275
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
276
  return b.data_;
277
}
278

    
279
inline std::size_t buffer_size_helper(const const_buffer& b)
280
{
281
  return b.size_;
282
}
283

    
284
} // namespace detail
285

    
286
/// Adapts a single non-modifiable buffer so that it meets the requirements of
287
/// the ConstBufferSequence concept.
288
class const_buffers_1
289
  : public const_buffer
290
{
291
public:
292
  /// The type for each element in the list of buffers.
293
  typedef const_buffer value_type;
294

    
295
  /// A random-access iterator type that may be used to read elements.
296
  typedef const const_buffer* const_iterator;
297

    
298
  /// Construct to represent a given memory range.
299
  const_buffers_1(const void* data, std::size_t size)
300
    : const_buffer(data, size)
301
  {
302
  }
303

    
304
  /// Construct to represent a single non-modifiable buffer.
305
  explicit const_buffers_1(const const_buffer& b)
306
    : const_buffer(b)
307
  {
308
  }
309

    
310
  /// Get a random-access iterator to the first element.
311
  const_iterator begin() const
312
  {
313
    return this;
314
  }
315

    
316
  /// Get a random-access iterator for one past the last element.
317
  const_iterator end() const
318
  {
319
    return begin() + 1;
320
  }
321
};
322

    
323
/// An implementation of both the ConstBufferSequence and MutableBufferSequence
324
/// concepts to represent a null buffer sequence.
325
class null_buffers
326
{
327
public:
328
  /// The type for each element in the list of buffers.
329
  typedef mutable_buffer value_type;
330

    
331
  /// A random-access iterator type that may be used to read elements.
332
  typedef const mutable_buffer* const_iterator;
333

    
334
  /// Get a random-access iterator to the first element.
335
  const_iterator begin() const
336
  {
337
    return &buf_;
338
  }
339

    
340
  /// Get a random-access iterator for one past the last element.
341
  const_iterator end() const
342
  {
343
    return &buf_;
344
  }
345

    
346
private:
347
  mutable_buffer buf_;
348
};
349

    
350
/** @defgroup buffer_size boost::asio::buffer_size
351
 *
352
 * @brief The boost::asio::buffer_size function determines the total number of
353
 * bytes in a buffer or buffer sequence.
354
 */
355
/*@{*/
356

    
357
/// Get the number of bytes in a modifiable buffer.
358
inline std::size_t buffer_size(const mutable_buffer& b)
359
{
360
  return detail::buffer_size_helper(b);
361
}
362

    
363
/// Get the number of bytes in a modifiable buffer.
364
inline std::size_t buffer_size(const mutable_buffers_1& b)
365
{
366
  return detail::buffer_size_helper(b);
367
}
368

    
369
/// Get the number of bytes in a non-modifiable buffer.
370
inline std::size_t buffer_size(const const_buffer& b)
371
{
372
  return detail::buffer_size_helper(b);
373
}
374

    
375
/// Get the number of bytes in a non-modifiable buffer.
376
inline std::size_t buffer_size(const const_buffers_1& b)
377
{
378
  return detail::buffer_size_helper(b);
379
}
380

    
381
/// Get the total number of bytes in a buffer sequence.
382
/** 
383
 * The @c BufferSequence template parameter may meet either of the @c
384
 * ConstBufferSequence or @c MutableBufferSequence type requirements.
385
 */
386
template <typename BufferSequence>
387
inline std::size_t buffer_size(const BufferSequence& b)
388
{
389
  std::size_t total_buffer_size = 0;
390

    
391
  typename BufferSequence::const_iterator iter = b.begin();
392
  typename BufferSequence::const_iterator end = b.end();
393
  for (; iter != end; ++iter)
394
    total_buffer_size += detail::buffer_size_helper(*iter);
395

    
396
  return total_buffer_size;
397
}
398

    
399
/*@}*/
400

    
401
/** @defgroup buffer_cast boost::asio::buffer_cast
402
 *
403
 * @brief The boost::asio::buffer_cast function is used to obtain a pointer to
404
 * the underlying memory region associated with a buffer.
405
 *
406
 * @par Examples:
407
 *
408
 * To access the memory of a non-modifiable buffer, use:
409
 * @code boost::asio::const_buffer b1 = ...;
410
 * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
411
 * @endcode
412
 *
413
 * To access the memory of a modifiable buffer, use:
414
 * @code boost::asio::mutable_buffer b2 = ...;
415
 * unsigned char* p2 = boost::asio::buffer_cast<unsigned char*>(b2);
416
 * @endcode
417
 *
418
 * The boost::asio::buffer_cast function permits violations of type safety, so
419
 * uses of it in application code should be carefully considered.
420
 */
421
/*@{*/
422

    
423
/// Cast a non-modifiable buffer to a specified pointer to POD type.
424
template <typename PointerToPodType>
425
inline PointerToPodType buffer_cast(const mutable_buffer& b)
426
{
427
  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
428
}
429

    
430
/// Cast a non-modifiable buffer to a specified pointer to POD type.
431
template <typename PointerToPodType>
432
inline PointerToPodType buffer_cast(const const_buffer& b)
433
{
434
  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
435
}
436

    
437
/*@}*/
438

    
439
/// Create a new modifiable buffer that is offset from the start of another.
440
/**
441
 * @relates mutable_buffer
442
 */
443
inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
444
{
445
  if (start > buffer_size(b))
446
    return mutable_buffer();
447
  char* new_data = buffer_cast<char*>(b) + start;
448
  std::size_t new_size = buffer_size(b) - start;
449
  return mutable_buffer(new_data, new_size
450
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
451
      , b.get_debug_check()
452
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
453
      );
454
}
455

    
456
/// Create a new modifiable buffer that is offset from the start of another.
457
/**
458
 * @relates mutable_buffer
459
 */
460
inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
461
{
462
  if (start > buffer_size(b))
463
    return mutable_buffer();
464
  char* new_data = buffer_cast<char*>(b) + start;
465
  std::size_t new_size = buffer_size(b) - start;
466
  return mutable_buffer(new_data, new_size
467
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
468
      , b.get_debug_check()
469
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
470
      );
471
}
472

    
473
/// Create a new non-modifiable buffer that is offset from the start of another.
474
/**
475
 * @relates const_buffer
476
 */
477
inline const_buffer operator+(const const_buffer& b, std::size_t start)
478
{
479
  if (start > buffer_size(b))
480
    return const_buffer();
481
  const char* new_data = buffer_cast<const char*>(b) + start;
482
  std::size_t new_size = buffer_size(b) - start;
483
  return const_buffer(new_data, new_size
484
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
485
      , b.get_debug_check()
486
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
487
      );
488
}
489

    
490
/// Create a new non-modifiable buffer that is offset from the start of another.
491
/**
492
 * @relates const_buffer
493
 */
494
inline const_buffer operator+(std::size_t start, const const_buffer& b)
495
{
496
  if (start > buffer_size(b))
497
    return const_buffer();
498
  const char* new_data = buffer_cast<const char*>(b) + start;
499
  std::size_t new_size = buffer_size(b) - start;
500
  return const_buffer(new_data, new_size
501
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
502
      , b.get_debug_check()
503
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
504
      );
505
}
506

    
507
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
508
namespace detail {
509

    
510
template <typename Iterator>
511
class buffer_debug_check
512
{
513
public:
514
  buffer_debug_check(Iterator iter)
515
    : iter_(iter)
516
  {
517
  }
518

    
519
  ~buffer_debug_check()
520
  {
521
#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
522
    // MSVC 8's string iterator checking may crash in a std::string::iterator
523
    // object's destructor when the iterator points to an already-destroyed
524
    // std::string object, unless the iterator is cleared first.
525
    iter_ = Iterator();
526
#endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
527
  }
528

    
529
  void operator()()
530
  {
531
    *iter_;
532
  }
533

    
534
private:
535
  Iterator iter_;
536
};
537

    
538
} // namespace detail
539
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
540

    
541
/** @defgroup buffer boost::asio::buffer
542
 *
543
 * @brief The boost::asio::buffer function is used to create a buffer object to
544
 * represent raw memory, an array of POD elements, a vector of POD elements,
545
 * or a std::string.
546
 *
547
 * A buffer object represents a contiguous region of memory as a 2-tuple
548
 * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,
549
 * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a
550
 * tuple of the form <tt>{const void*, size_t}</tt> specifies a const
551
 * (non-modifiable) region of memory. These two forms correspond to the classes
552
 * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion
553
 * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the
554
 * opposite conversion is not permitted.
555
 *
556
 * The simplest use case involves reading or writing a single buffer of a
557
 * specified size:
558
 *
559
 * @code sock.send(boost::asio::buffer(data, size)); @endcode
560
 *
561
 * In the above example, the return value of boost::asio::buffer meets the
562
 * requirements of the ConstBufferSequence concept so that it may be directly
563
 * passed to the socket's write function. A buffer created for modifiable
564
 * memory also meets the requirements of the MutableBufferSequence concept.
565
 *
566
 * An individual buffer may be created from a builtin array, std::vector,
567
 * std::array or boost::array of POD elements. This helps prevent buffer
568
 * overruns by automatically determining the size of the buffer:
569
 *
570
 * @code char d1[128];
571
 * size_t bytes_transferred = sock.receive(boost::asio::buffer(d1));
572
 *
573
 * std::vector<char> d2(128);
574
 * bytes_transferred = sock.receive(boost::asio::buffer(d2));
575
 *
576
 * std::array<char, 128> d3;
577
 * bytes_transferred = sock.receive(boost::asio::buffer(d3));
578
 *
579
 * boost::array<char, 128> d4;
580
 * bytes_transferred = sock.receive(boost::asio::buffer(d4)); @endcode
581
 *
582
 * In all three cases above, the buffers created are exactly 128 bytes long.
583
 * Note that a vector is @e never automatically resized when creating or using
584
 * a buffer. The buffer size is determined using the vector's <tt>size()</tt>
585
 * member function, and not its capacity.
586
 *
587
 * @par Accessing Buffer Contents
588
 *
589
 * The contents of a buffer may be accessed using the @ref buffer_size and
590
 * @ref buffer_cast functions:
591
 *
592
 * @code boost::asio::mutable_buffer b1 = ...;
593
 * std::size_t s1 = boost::asio::buffer_size(b1);
594
 * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
595
 *
596
 * boost::asio::const_buffer b2 = ...;
597
 * std::size_t s2 = boost::asio::buffer_size(b2);
598
 * const void* p2 = boost::asio::buffer_cast<const void*>(b2); @endcode
599
 *
600
 * The boost::asio::buffer_cast function permits violations of type safety, so
601
 * uses of it in application code should be carefully considered.
602
 *
603
 * For convenience, the @ref buffer_size function also works on buffer
604
 * sequences (that is, types meeting the ConstBufferSequence or
605
 * MutableBufferSequence type requirements). In this case, the function returns
606
 * the total size of all buffers in the sequence.
607
 *
608
 * @par Buffer Copying
609
 *
610
 * The @ref buffer_copy function may be used to copy raw bytes between
611
 * individual buffers and buffer sequences.
612
 *
613
 * In particular, when used with the @ref buffer_size, the @ref buffer_copy
614
 * function can be used to linearise a sequence of buffers. For example:
615
 *
616
 * @code vector<const_buffer> buffers = ...;
617
 *
618
 * vector<unsigned char> data(boost::asio::buffer_size(buffers));
619
 * boost::asio::buffer_copy(boost::asio::buffer(data), buffers); @endcode
620
 *
621
 * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
622
 * consequently it cannot be used to copy between overlapping memory regions.
623
 *
624
 * @par Buffer Invalidation
625
 *
626
 * A buffer object does not have any ownership of the memory it refers to. It
627
 * is the responsibility of the application to ensure the memory region remains
628
 * valid until it is no longer required for an I/O operation. When the memory
629
 * is no longer available, the buffer is said to have been invalidated.
630
 *
631
 * For the boost::asio::buffer overloads that accept an argument of type
632
 * std::vector, the buffer objects returned are invalidated by any vector
633
 * operation that also invalidates all references, pointers and iterators
634
 * referring to the elements in the sequence (C++ Std, 23.2.4)
635
 *
636
 * For the boost::asio::buffer overloads that accept an argument of type
637
 * std::basic_string, the buffer objects returned are invalidated according to
638
 * the rules defined for invalidation of references, pointers and iterators
639
 * referring to elements of the sequence (C++ Std, 21.3).
640
 *
641
 * @par Buffer Arithmetic
642
 *
643
 * Buffer objects may be manipulated using simple arithmetic in a safe way
644
 * which helps prevent buffer overruns. Consider an array initialised as
645
 * follows:
646
 *
647
 * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode
648
 *
649
 * A buffer object @c b1 created using:
650
 *
651
 * @code b1 = boost::asio::buffer(a); @endcode
652
 *
653
 * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An
654
 * optional second argument to the boost::asio::buffer function may be used to
655
 * limit the size, in bytes, of the buffer:
656
 *
657
 * @code b2 = boost::asio::buffer(a, 3); @endcode
658
 *
659
 * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the
660
 * size argument exceeds the actual size of the array, the size of the buffer
661
 * object created will be limited to the array size.
662
 *
663
 * An offset may be applied to an existing buffer to create a new one:
664
 *
665
 * @code b3 = b1 + 2; @endcode
666
 *
667
 * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset
668
 * exceeds the size of the existing buffer, the newly created buffer will be
669
 * empty.
670
 *
671
 * Both an offset and size may be specified to create a buffer that corresponds
672
 * to a specific range of bytes within an existing buffer:
673
 *
674
 * @code b4 = boost::asio::buffer(b1 + 1, 3); @endcode
675
 *
676
 * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.
677
 *
678
 * @par Buffers and Scatter-Gather I/O
679
 *
680
 * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
681
 * buffer objects may be assigned into a container that supports the
682
 * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
683
 *
684
 * @code
685
 * char d1[128];
686
 * std::vector<char> d2(128);
687
 * boost::array<char, 128> d3;
688
 *
689
 * boost::array<mutable_buffer, 3> bufs1 = {
690
 *   boost::asio::buffer(d1),
691
 *   boost::asio::buffer(d2),
692
 *   boost::asio::buffer(d3) };
693
 * bytes_transferred = sock.receive(bufs1);
694
 *
695
 * std::vector<const_buffer> bufs2;
696
 * bufs2.push_back(boost::asio::buffer(d1));
697
 * bufs2.push_back(boost::asio::buffer(d2));
698
 * bufs2.push_back(boost::asio::buffer(d3));
699
 * bytes_transferred = sock.send(bufs2); @endcode
700
 */
701
/*@{*/
702

    
703
/// Create a new modifiable buffer from an existing buffer.
704
/**
705
 * @returns <tt>mutable_buffers_1(b)</tt>.
706
 */
707
inline mutable_buffers_1 buffer(const mutable_buffer& b)
708
{
709
  return mutable_buffers_1(b);
710
}
711

    
712
/// Create a new modifiable buffer from an existing buffer.
713
/**
714
 * @returns A mutable_buffers_1 value equivalent to:
715
 * @code mutable_buffers_1(
716
 *     buffer_cast<void*>(b),
717
 *     min(buffer_size(b), max_size_in_bytes)); @endcode
718
 */
719
inline mutable_buffers_1 buffer(const mutable_buffer& b,
720
    std::size_t max_size_in_bytes)
721
{
722
  return mutable_buffers_1(
723
      mutable_buffer(buffer_cast<void*>(b),
724
        buffer_size(b) < max_size_in_bytes
725
        ? buffer_size(b) : max_size_in_bytes
726
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
727
        , b.get_debug_check()
728
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
729
        ));
730
}
731

    
732
/// Create a new non-modifiable buffer from an existing buffer.
733
/**
734
 * @returns <tt>const_buffers_1(b)</tt>.
735
 */
736
inline const_buffers_1 buffer(const const_buffer& b)
737
{
738
  return const_buffers_1(b);
739
}
740

    
741
/// Create a new non-modifiable buffer from an existing buffer.
742
/**
743
 * @returns A const_buffers_1 value equivalent to:
744
 * @code const_buffers_1(
745
 *     buffer_cast<const void*>(b),
746
 *     min(buffer_size(b), max_size_in_bytes)); @endcode
747
 */
748
inline const_buffers_1 buffer(const const_buffer& b,
749
    std::size_t max_size_in_bytes)
750
{
751
  return const_buffers_1(
752
      const_buffer(buffer_cast<const void*>(b),
753
        buffer_size(b) < max_size_in_bytes
754
        ? buffer_size(b) : max_size_in_bytes
755
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
756
        , b.get_debug_check()
757
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
758
        ));
759
}
760

    
761
/// Create a new modifiable buffer that represents the given memory range.
762
/**
763
 * @returns <tt>mutable_buffers_1(data, size_in_bytes)</tt>.
764
 */
765
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
766
{
767
  return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
768
}
769

    
770
/// Create a new non-modifiable buffer that represents the given memory range.
771
/**
772
 * @returns <tt>const_buffers_1(data, size_in_bytes)</tt>.
773
 */
774
inline const_buffers_1 buffer(const void* data,
775
    std::size_t size_in_bytes)
776
{
777
  return const_buffers_1(const_buffer(data, size_in_bytes));
778
}
779

    
780
/// Create a new modifiable buffer that represents the given POD array.
781
/**
782
 * @returns A mutable_buffers_1 value equivalent to:
783
 * @code mutable_buffers_1(
784
 *     static_cast<void*>(data),
785
 *     N * sizeof(PodType)); @endcode
786
 */
787
template <typename PodType, std::size_t N>
788
inline mutable_buffers_1 buffer(PodType (&data)[N])
789
{
790
  return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
791
}
792
 
793
/// Create a new modifiable buffer that represents the given POD array.
794
/**
795
 * @returns A mutable_buffers_1 value equivalent to:
796
 * @code mutable_buffers_1(
797
 *     static_cast<void*>(data),
798
 *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode
799
 */
800
template <typename PodType, std::size_t N>
801
inline mutable_buffers_1 buffer(PodType (&data)[N],
802
    std::size_t max_size_in_bytes)
803
{
804
  return mutable_buffers_1(
805
      mutable_buffer(data,
806
        N * sizeof(PodType) < max_size_in_bytes
807
        ? N * sizeof(PodType) : max_size_in_bytes));
808
}
809
 
810
/// Create a new non-modifiable buffer that represents the given POD array.
811
/**
812
 * @returns A const_buffers_1 value equivalent to:
813
 * @code const_buffers_1(
814
 *     static_cast<const void*>(data),
815
 *     N * sizeof(PodType)); @endcode
816
 */
817
template <typename PodType, std::size_t N>
818
inline const_buffers_1 buffer(const PodType (&data)[N])
819
{
820
  return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
821
}
822

    
823
/// Create a new non-modifiable buffer that represents the given POD array.
824
/**
825
 * @returns A const_buffers_1 value equivalent to:
826
 * @code const_buffers_1(
827
 *     static_cast<const void*>(data),
828
 *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode
829
 */
830
template <typename PodType, std::size_t N>
831
inline const_buffers_1 buffer(const PodType (&data)[N],
832
    std::size_t max_size_in_bytes)
833
{
834
  return const_buffers_1(
835
      const_buffer(data,
836
        N * sizeof(PodType) < max_size_in_bytes
837
        ? N * sizeof(PodType) : max_size_in_bytes));
838
}
839

    
840
#if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
841

    
842
// Borland C++ and Sun Studio think the overloads:
843
//
844
//   unspecified buffer(boost::array<PodType, N>& array ...);
845
//
846
// and
847
//
848
//   unspecified buffer(boost::array<const PodType, N>& array ...);
849
//
850
// are ambiguous. This will be worked around by using a buffer_types traits
851
// class that contains typedefs for the appropriate buffer and container
852
// classes, based on whether PodType is const or non-const.
853

    
854
namespace detail {
855

    
856
template <bool IsConst>
857
struct buffer_types_base;
858

    
859
template <>
860
struct buffer_types_base<false>
861
{
862
  typedef mutable_buffer buffer_type;
863
  typedef mutable_buffers_1 container_type;
864
};
865

    
866
template <>
867
struct buffer_types_base<true>
868
{
869
  typedef const_buffer buffer_type;
870
  typedef const_buffers_1 container_type;
871
};
872

    
873
template <typename PodType>
874
struct buffer_types
875
  : public buffer_types_base<is_const<PodType>::value>
876
{
877
};
878

    
879
} // namespace detail
880

    
881
template <typename PodType, std::size_t N>
882
inline typename detail::buffer_types<PodType>::container_type
883
buffer(boost::array<PodType, N>& data)
884
{
885
  typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
886
    buffer_type;
887
  typedef typename boost::asio::detail::buffer_types<PodType>::container_type
888
    container_type;
889
  return container_type(
890
      buffer_type(data.c_array(), data.size() * sizeof(PodType)));
891
}
892

    
893
template <typename PodType, std::size_t N>
894
inline typename detail::buffer_types<PodType>::container_type
895
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
896
{
897
  typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
898
    buffer_type;
899
  typedef typename boost::asio::detail::buffer_types<PodType>::container_type
900
    container_type;
901
  return container_type(
902
      buffer_type(data.c_array(),
903
        data.size() * sizeof(PodType) < max_size_in_bytes
904
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
905
}
906

    
907
#else // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
908

    
909
/// Create a new modifiable buffer that represents the given POD array.
910
/**
911
 * @returns A mutable_buffers_1 value equivalent to:
912
 * @code mutable_buffers_1(
913
 *     data.data(),
914
 *     data.size() * sizeof(PodType)); @endcode
915
 */
916
template <typename PodType, std::size_t N>
917
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
918
{
919
  return mutable_buffers_1(
920
      mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
921
}
922

    
923
/// Create a new modifiable buffer that represents the given POD array.
924
/**
925
 * @returns A mutable_buffers_1 value equivalent to:
926
 * @code mutable_buffers_1(
927
 *     data.data(),
928
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
929
 */
930
template <typename PodType, std::size_t N>
931
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
932
    std::size_t max_size_in_bytes)
933
{
934
  return mutable_buffers_1(
935
      mutable_buffer(data.c_array(),
936
        data.size() * sizeof(PodType) < max_size_in_bytes
937
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
938
}
939

    
940
/// Create a new non-modifiable buffer that represents the given POD array.
941
/**
942
 * @returns A const_buffers_1 value equivalent to:
943
 * @code const_buffers_1(
944
 *     data.data(),
945
 *     data.size() * sizeof(PodType)); @endcode
946
 */
947
template <typename PodType, std::size_t N>
948
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
949
{
950
  return const_buffers_1(
951
      const_buffer(data.data(), data.size() * sizeof(PodType)));
952
}
953

    
954
/// Create a new non-modifiable buffer that represents the given POD array.
955
/**
956
 * @returns A const_buffers_1 value equivalent to:
957
 * @code const_buffers_1(
958
 *     data.data(),
959
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
960
 */
961
template <typename PodType, std::size_t N>
962
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
963
    std::size_t max_size_in_bytes)
964
{
965
  return const_buffers_1(
966
      const_buffer(data.data(),
967
        data.size() * sizeof(PodType) < max_size_in_bytes
968
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
969
}
970

    
971
#endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
972

    
973
/// Create a new non-modifiable buffer that represents the given POD array.
974
/**
975
 * @returns A const_buffers_1 value equivalent to:
976
 * @code const_buffers_1(
977
 *     data.data(),
978
 *     data.size() * sizeof(PodType)); @endcode
979
 */
980
template <typename PodType, std::size_t N>
981
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
982
{
983
  return const_buffers_1(
984
      const_buffer(data.data(), data.size() * sizeof(PodType)));
985
}
986

    
987
/// Create a new non-modifiable buffer that represents the given POD array.
988
/**
989
 * @returns A const_buffers_1 value equivalent to:
990
 * @code const_buffers_1(
991
 *     data.data(),
992
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
993
 */
994
template <typename PodType, std::size_t N>
995
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
996
    std::size_t max_size_in_bytes)
997
{
998
  return const_buffers_1(
999
      const_buffer(data.data(),
1000
        data.size() * sizeof(PodType) < max_size_in_bytes
1001
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
1002
}
1003

    
1004
#if defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
1005

    
1006
/// Create a new modifiable buffer that represents the given POD array.
1007
/**
1008
 * @returns A mutable_buffers_1 value equivalent to:
1009
 * @code mutable_buffers_1(
1010
 *     data.data(),
1011
 *     data.size() * sizeof(PodType)); @endcode
1012
 */
1013
template <typename PodType, std::size_t N>
1014
inline mutable_buffers_1 buffer(std::array<PodType, N>& data)
1015
{
1016
  return mutable_buffers_1(
1017
      mutable_buffer(data.data(), data.size() * sizeof(PodType)));
1018
}
1019

    
1020
/// Create a new modifiable buffer that represents the given POD array.
1021
/**
1022
 * @returns A mutable_buffers_1 value equivalent to:
1023
 * @code mutable_buffers_1(
1024
 *     data.data(),
1025
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
1026
 */
1027
template <typename PodType, std::size_t N>
1028
inline mutable_buffers_1 buffer(std::array<PodType, N>& data,
1029
    std::size_t max_size_in_bytes)
1030
{
1031
  return mutable_buffers_1(
1032
      mutable_buffer(data.data(),
1033
        data.size() * sizeof(PodType) < max_size_in_bytes
1034
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
1035
}
1036

    
1037
/// Create a new non-modifiable buffer that represents the given POD array.
1038
/**
1039
 * @returns A const_buffers_1 value equivalent to:
1040
 * @code const_buffers_1(
1041
 *     data.data(),
1042
 *     data.size() * sizeof(PodType)); @endcode
1043
 */
1044
template <typename PodType, std::size_t N>
1045
inline const_buffers_1 buffer(std::array<const PodType, N>& data)
1046
{
1047
  return const_buffers_1(
1048
      const_buffer(data.data(), data.size() * sizeof(PodType)));
1049
}
1050

    
1051
/// Create a new non-modifiable buffer that represents the given POD array.
1052
/**
1053
 * @returns A const_buffers_1 value equivalent to:
1054
 * @code const_buffers_1(
1055
 *     data.data(),
1056
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
1057
 */
1058
template <typename PodType, std::size_t N>
1059
inline const_buffers_1 buffer(std::array<const PodType, N>& data,
1060
    std::size_t max_size_in_bytes)
1061
{
1062
  return const_buffers_1(
1063
      const_buffer(data.data(),
1064
        data.size() * sizeof(PodType) < max_size_in_bytes
1065
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
1066
}
1067

    
1068
/// Create a new non-modifiable buffer that represents the given POD array.
1069
/**
1070
 * @returns A const_buffers_1 value equivalent to:
1071
 * @code const_buffers_1(
1072
 *     data.data(),
1073
 *     data.size() * sizeof(PodType)); @endcode
1074
 */
1075
template <typename PodType, std::size_t N>
1076
inline const_buffers_1 buffer(const std::array<PodType, N>& data)
1077
{
1078
  return const_buffers_1(
1079
      const_buffer(data.data(), data.size() * sizeof(PodType)));
1080
}
1081

    
1082
/// Create a new non-modifiable buffer that represents the given POD array.
1083
/**
1084
 * @returns A const_buffers_1 value equivalent to:
1085
 * @code const_buffers_1(
1086
 *     data.data(),
1087
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
1088
 */
1089
template <typename PodType, std::size_t N>
1090
inline const_buffers_1 buffer(const std::array<PodType, N>& data,
1091
    std::size_t max_size_in_bytes)
1092
{
1093
  return const_buffers_1(
1094
      const_buffer(data.data(),
1095
        data.size() * sizeof(PodType) < max_size_in_bytes
1096
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
1097
}
1098

    
1099
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
1100

    
1101
/// Create a new modifiable buffer that represents the given POD vector.
1102
/**
1103
 * @returns A mutable_buffers_1 value equivalent to:
1104
 * @code mutable_buffers_1(
1105
 *     data.size() ? &data[0] : 0,
1106
 *     data.size() * sizeof(PodType)); @endcode
1107
 *
1108
 * @note The buffer is invalidated by any vector operation that would also
1109
 * invalidate iterators.
1110
 */
1111
template <typename PodType, typename Allocator>
1112
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
1113
{
1114
  return mutable_buffers_1(
1115
      mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
1116
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1117
        , detail::buffer_debug_check<
1118
            typename std::vector<PodType, Allocator>::iterator
1119
          >(data.begin())
1120
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
1121
        ));
1122
}
1123

    
1124
/// Create a new modifiable buffer that represents the given POD vector.
1125
/**
1126
 * @returns A mutable_buffers_1 value equivalent to:
1127
 * @code mutable_buffers_1(
1128
 *     data.size() ? &data[0] : 0,
1129
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
1130
 *
1131
 * @note The buffer is invalidated by any vector operation that would also
1132
 * invalidate iterators.
1133
 */
1134
template <typename PodType, typename Allocator>
1135
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
1136
    std::size_t max_size_in_bytes)
1137
{
1138
  return mutable_buffers_1(
1139
      mutable_buffer(data.size() ? &data[0] : 0,
1140
        data.size() * sizeof(PodType) < max_size_in_bytes
1141
        ? data.size() * sizeof(PodType) : max_size_in_bytes
1142
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1143
        , detail::buffer_debug_check<
1144
            typename std::vector<PodType, Allocator>::iterator
1145
          >(data.begin())
1146
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
1147
        ));
1148
}
1149

    
1150
/// Create a new non-modifiable buffer that represents the given POD vector.
1151
/**
1152
 * @returns A const_buffers_1 value equivalent to:
1153
 * @code const_buffers_1(
1154
 *     data.size() ? &data[0] : 0,
1155
 *     data.size() * sizeof(PodType)); @endcode
1156
 *
1157
 * @note The buffer is invalidated by any vector operation that would also
1158
 * invalidate iterators.
1159
 */
1160
template <typename PodType, typename Allocator>
1161
inline const_buffers_1 buffer(
1162
    const std::vector<PodType, Allocator>& data)
1163
{
1164
  return const_buffers_1(
1165
      const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
1166
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1167
        , detail::buffer_debug_check<
1168
            typename std::vector<PodType, Allocator>::const_iterator
1169
          >(data.begin())
1170
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
1171
        ));
1172
}
1173

    
1174
/// Create a new non-modifiable buffer that represents the given POD vector.
1175
/**
1176
 * @returns A const_buffers_1 value equivalent to:
1177
 * @code const_buffers_1(
1178
 *     data.size() ? &data[0] : 0,
1179
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
1180
 *
1181
 * @note The buffer is invalidated by any vector operation that would also
1182
 * invalidate iterators.
1183
 */
1184
template <typename PodType, typename Allocator>
1185
inline const_buffers_1 buffer(
1186
    const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
1187
{
1188
  return const_buffers_1(
1189
      const_buffer(data.size() ? &data[0] : 0,
1190
        data.size() * sizeof(PodType) < max_size_in_bytes
1191
        ? data.size() * sizeof(PodType) : max_size_in_bytes
1192
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1193
        , detail::buffer_debug_check<
1194
            typename std::vector<PodType, Allocator>::const_iterator
1195
          >(data.begin())
1196
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
1197
        ));
1198
}
1199

    
1200
/// Create a new non-modifiable buffer that represents the given string.
1201
/**
1202
 * @returns <tt>const_buffers_1(data.data(), data.size() * sizeof(Elem))</tt>.
1203
 *
1204
 * @note The buffer is invalidated by any non-const operation called on the
1205
 * given string object.
1206
 */
1207
template <typename Elem, typename Traits, typename Allocator>
1208
inline const_buffers_1 buffer(
1209
    const std::basic_string<Elem, Traits, Allocator>& data)
1210
{
1211
  return const_buffers_1(const_buffer(data.data(), data.size() * sizeof(Elem)
1212
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1213
        , detail::buffer_debug_check<
1214
            typename std::basic_string<Elem, Traits, Allocator>::const_iterator
1215
          >(data.begin())
1216
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
1217
        ));
1218
}
1219

    
1220
/// Create a new non-modifiable buffer that represents the given string.
1221
/**
1222
 * @returns A const_buffers_1 value equivalent to:
1223
 * @code const_buffers_1(
1224
 *     data.data(),
1225
 *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
1226
 *
1227
 * @note The buffer is invalidated by any non-const operation called on the
1228
 * given string object.
1229
 */
1230
template <typename Elem, typename Traits, typename Allocator>
1231
inline const_buffers_1 buffer(
1232
    const std::basic_string<Elem, Traits, Allocator>& data,
1233
    std::size_t max_size_in_bytes)
1234
{
1235
  return const_buffers_1(
1236
      const_buffer(data.data(),
1237
        data.size() * sizeof(Elem) < max_size_in_bytes
1238
        ? data.size() * sizeof(Elem) : max_size_in_bytes
1239
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1240
        , detail::buffer_debug_check<
1241
            typename std::basic_string<Elem, Traits, Allocator>::const_iterator
1242
          >(data.begin())
1243
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
1244
        ));
1245
}
1246

    
1247
/*@}*/
1248

    
1249
/** @defgroup buffer_copy boost::asio::buffer_copy
1250
 *
1251
 * @brief The boost::asio::buffer_copy function is used to copy bytes from a
1252
 * source buffer (or buffer sequence) to a target buffer (or buffer sequence).
1253
 *
1254
 * The @c buffer_copy function is available in two forms:
1255
 *
1256
 * @li A 2-argument form: @c buffer_copy(target, source)
1257
 *
1258
 * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy)
1259

1260
 * Both forms return the number of bytes actually copied. The number of bytes
1261
 * copied is the lesser of:
1262
 *
1263
 * @li @c buffer_size(target)
1264
 *
1265
 * @li @c buffer_size(source)
1266
 *
1267
 * @li @c If specified, @c max_bytes_to_copy.
1268
 *
1269
 * This prevents buffer overflow, regardless of the buffer sizes used in the
1270
 * copy operation.
1271
 *
1272
 * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
1273
 * consequently it cannot be used to copy between overlapping memory regions.
1274
 */
1275
/*@{*/
1276

    
1277
/// Copies bytes from a source buffer to a target buffer.
1278
/**
1279
 * @param target A modifiable buffer representing the memory region to which
1280
 * the bytes will be copied.
1281
 *
1282
 * @param source A non-modifiable buffer representing the memory region from
1283
 * which the bytes will be copied.
1284
 *
1285
 * @returns The number of bytes copied.
1286
 *
1287
 * @note The number of bytes copied is the lesser of:
1288
 *
1289
 * @li @c buffer_size(target)
1290
 *
1291
 * @li @c buffer_size(source)
1292
 *
1293
 * This function is implemented in terms of @c memcpy, and consequently it
1294
 * cannot be used to copy between overlapping memory regions.
1295
 */
1296
inline std::size_t buffer_copy(const mutable_buffer& target,
1297
    const const_buffer& source)
1298
{
1299
  using namespace std; // For memcpy.
1300
  std::size_t target_size = buffer_size(target);
1301
  std::size_t source_size = buffer_size(source);
1302
  std::size_t n = target_size < source_size ? target_size : source_size;
1303
  memcpy(buffer_cast<void*>(target), buffer_cast<const void*>(source), n);
1304
  return n;
1305
}
1306

    
1307
/// Copies bytes from a source buffer to a target buffer.
1308
/**
1309
 * @param target A modifiable buffer representing the memory region to which
1310
 * the bytes will be copied.
1311
 *
1312
 * @param source A non-modifiable buffer representing the memory region from
1313
 * which the bytes will be copied.
1314
 *
1315
 * @returns The number of bytes copied.
1316
 *
1317
 * @note The number of bytes copied is the lesser of:
1318
 *
1319
 * @li @c buffer_size(target)
1320
 *
1321
 * @li @c buffer_size(source)
1322
 *
1323
 * This function is implemented in terms of @c memcpy, and consequently it
1324
 * cannot be used to copy between overlapping memory regions.
1325
 */
1326
inline std::size_t buffer_copy(const mutable_buffer& target,
1327
    const const_buffers_1& source)
1328
{
1329
  return buffer_copy(target, static_cast<const const_buffer&>(source));
1330
}
1331

    
1332
/// Copies bytes from a source buffer to a target buffer.
1333
/**
1334
 * @param target A modifiable buffer representing the memory region to which
1335
 * the bytes will be copied.
1336
 *
1337
 * @param source A modifiable buffer representing the memory region from which
1338
 * the bytes will be copied. The contents of the source buffer will not be
1339
 * modified.
1340
 *
1341
 * @returns The number of bytes copied.
1342
 *
1343
 * @note The number of bytes copied is the lesser of:
1344
 *
1345
 * @li @c buffer_size(target)
1346
 *
1347
 * @li @c buffer_size(source)
1348
 *
1349
 * This function is implemented in terms of @c memcpy, and consequently it
1350
 * cannot be used to copy between overlapping memory regions.
1351
 */
1352
inline std::size_t buffer_copy(const mutable_buffer& target,
1353
    const mutable_buffer& source)
1354
{
1355
  return buffer_copy(target, const_buffer(source));
1356
}
1357

    
1358
/// Copies bytes from a source buffer to a target buffer.
1359
/**
1360
 * @param target A modifiable buffer representing the memory region to which
1361
 * the bytes will be copied.
1362
 *
1363
 * @param source A modifiable buffer representing the memory region from which
1364
 * the bytes will be copied. The contents of the source buffer will not be
1365
 * modified.
1366
 *
1367
 * @returns The number of bytes copied.
1368
 *
1369
 * @note The number of bytes copied is the lesser of:
1370
 *
1371
 * @li @c buffer_size(target)
1372
 *
1373
 * @li @c buffer_size(source)
1374
 *
1375
 * This function is implemented in terms of @c memcpy, and consequently it
1376
 * cannot be used to copy between overlapping memory regions.
1377
 */
1378
inline std::size_t buffer_copy(const mutable_buffer& target,
1379
    const mutable_buffers_1& source)
1380
{
1381
  return buffer_copy(target, const_buffer(source));
1382
}
1383

    
1384
/// Copies bytes from a source buffer sequence to a target buffer.
1385
/**
1386
 * @param target A modifiable buffer representing the memory region to which
1387
 * the bytes will be copied.
1388
 *
1389
 * @param source A non-modifiable buffer sequence representing the memory
1390
 * regions from which the bytes will be copied.
1391
 *
1392
 * @returns The number of bytes copied.
1393
 *
1394
 * @note The number of bytes copied is the lesser of:
1395
 *
1396
 * @li @c buffer_size(target)
1397
 *
1398
 * @li @c buffer_size(source)
1399
 *
1400
 * This function is implemented in terms of @c memcpy, and consequently it
1401
 * cannot be used to copy between overlapping memory regions.
1402
 */
1403
template <typename ConstBufferSequence>
1404
std::size_t buffer_copy(const mutable_buffer& target,
1405
    const ConstBufferSequence& source)
1406
{
1407
  std::size_t total_bytes_copied = 0;
1408

    
1409
  typename ConstBufferSequence::const_iterator source_iter = source.begin();
1410
  typename ConstBufferSequence::const_iterator source_end = source.end();
1411

    
1412
  for (mutable_buffer target_buffer(target);
1413
      buffer_size(target_buffer) && source_iter != source_end; ++source_iter)
1414
  {
1415
    const_buffer source_buffer(*source_iter);
1416
    std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
1417
    total_bytes_copied += bytes_copied;
1418
    target_buffer = target_buffer + bytes_copied;
1419
  }
1420

    
1421
  return total_bytes_copied;
1422
}
1423

    
1424
/// Copies bytes from a source buffer to a target buffer.
1425
/**
1426
 * @param target A modifiable buffer representing the memory region to which
1427
 * the bytes will be copied.
1428
 *
1429
 * @param source A non-modifiable buffer representing the memory region from
1430
 * which the bytes will be copied.
1431
 *
1432
 * @returns The number of bytes copied.
1433
 *
1434
 * @note The number of bytes copied is the lesser of:
1435
 *
1436
 * @li @c buffer_size(target)
1437
 *
1438
 * @li @c buffer_size(source)
1439
 *
1440
 * This function is implemented in terms of @c memcpy, and consequently it
1441
 * cannot be used to copy between overlapping memory regions.
1442
 */
1443
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1444
    const const_buffer& source)
1445
{
1446
  return buffer_copy(static_cast<const mutable_buffer&>(target), source);
1447
}
1448

    
1449
/// Copies bytes from a source buffer to a target buffer.
1450
/**
1451
 * @param target A modifiable buffer representing the memory region to which
1452
 * the bytes will be copied.
1453
 *
1454
 * @param source A non-modifiable buffer representing the memory region from
1455
 * which the bytes will be copied.
1456
 *
1457
 * @returns The number of bytes copied.
1458
 *
1459
 * @note The number of bytes copied is the lesser of:
1460
 *
1461
 * @li @c buffer_size(target)
1462
 *
1463
 * @li @c buffer_size(source)
1464
 *
1465
 * This function is implemented in terms of @c memcpy, and consequently it
1466
 * cannot be used to copy between overlapping memory regions.
1467
 */
1468
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1469
    const const_buffers_1& source)
1470
{
1471
  return buffer_copy(static_cast<const mutable_buffer&>(target),
1472
      static_cast<const const_buffer&>(source));
1473
}
1474

    
1475
/// Copies bytes from a source buffer to a target buffer.
1476
/**
1477
 * @param target A modifiable buffer representing the memory region to which
1478
 * the bytes will be copied.
1479
 *
1480
 * @param source A modifiable buffer representing the memory region from which
1481
 * the bytes will be copied. The contents of the source buffer will not be
1482
 * modified.
1483
 *
1484
 * @returns The number of bytes copied.
1485
 *
1486
 * @note The number of bytes copied is the lesser of:
1487
 *
1488
 * @li @c buffer_size(target)
1489
 *
1490
 * @li @c buffer_size(source)
1491
 *
1492
 * This function is implemented in terms of @c memcpy, and consequently it
1493
 * cannot be used to copy between overlapping memory regions.
1494
 */
1495
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1496
    const mutable_buffer& source)
1497
{
1498
  return buffer_copy(static_cast<const mutable_buffer&>(target),
1499
      const_buffer(source));
1500
}
1501

    
1502
/// Copies bytes from a source buffer to a target buffer.
1503
/**
1504
 * @param target A modifiable buffer representing the memory region to which
1505
 * the bytes will be copied.
1506
 *
1507
 * @param source A modifiable buffer representing the memory region from which
1508
 * the bytes will be copied. The contents of the source buffer will not be
1509
 * modified.
1510
 *
1511
 * @returns The number of bytes copied.
1512
 *
1513
 * @note The number of bytes copied is the lesser of:
1514
 *
1515
 * @li @c buffer_size(target)
1516
 *
1517
 * @li @c buffer_size(source)
1518
 *
1519
 * This function is implemented in terms of @c memcpy, and consequently it
1520
 * cannot be used to copy between overlapping memory regions.
1521
 */
1522
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1523
    const mutable_buffers_1& source)
1524
{
1525
  return buffer_copy(static_cast<const mutable_buffer&>(target),
1526
      const_buffer(source));
1527
}
1528

    
1529
/// Copies bytes from a source buffer sequence to a target buffer.
1530
/**
1531
 * @param target A modifiable buffer representing the memory region to which
1532
 * the bytes will be copied.
1533
 *
1534
 * @param source A non-modifiable buffer sequence representing the memory
1535
 * regions from which the bytes will be copied.
1536
 *
1537
 * @returns The number of bytes copied.
1538
 *
1539
 * @note The number of bytes copied is the lesser of:
1540
 *
1541
 * @li @c buffer_size(target)
1542
 *
1543
 * @li @c buffer_size(source)
1544
 *
1545
 * This function is implemented in terms of @c memcpy, and consequently it
1546
 * cannot be used to copy between overlapping memory regions.
1547
 */
1548
template <typename ConstBufferSequence>
1549
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1550
    const ConstBufferSequence& source)
1551
{
1552
  return buffer_copy(static_cast<const mutable_buffer&>(target), source);
1553
}
1554

    
1555
/// Copies bytes from a source buffer to a target buffer sequence.
1556
/**
1557
 * @param target A modifiable buffer sequence representing the memory regions to
1558
 * which the bytes will be copied.
1559
 *
1560
 * @param source A non-modifiable buffer representing the memory region from
1561
 * which the bytes will be copied.
1562
 *
1563
 * @returns The number of bytes copied.
1564
 *
1565
 * @note The number of bytes copied is the lesser of:
1566
 *
1567
 * @li @c buffer_size(target)
1568
 *
1569
 * @li @c buffer_size(source)
1570
 *
1571
 * This function is implemented in terms of @c memcpy, and consequently it
1572
 * cannot be used to copy between overlapping memory regions.
1573
 */
1574
template <typename MutableBufferSequence>
1575
std::size_t buffer_copy(const MutableBufferSequence& target,
1576
    const const_buffer& source)
1577
{
1578
  std::size_t total_bytes_copied = 0;
1579

    
1580
  typename MutableBufferSequence::const_iterator target_iter = target.begin();
1581
  typename MutableBufferSequence::const_iterator target_end = target.end();
1582

    
1583
  for (const_buffer source_buffer(source);
1584
      buffer_size(source_buffer) && target_iter != target_end; ++target_iter)
1585
  {
1586
    mutable_buffer target_buffer(*target_iter);
1587
    std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
1588
    total_bytes_copied += bytes_copied;
1589
    source_buffer = source_buffer + bytes_copied;
1590
  }
1591

    
1592
  return total_bytes_copied;
1593
}
1594

    
1595
/// Copies bytes from a source buffer to a target buffer sequence.
1596
/**
1597
 * @param target A modifiable buffer sequence representing the memory regions to
1598
 * which the bytes will be copied.
1599
 *
1600
 * @param source A non-modifiable buffer representing the memory region from
1601
 * which the bytes will be copied.
1602
 *
1603
 * @returns The number of bytes copied.
1604
 *
1605
 * @note The number of bytes copied is the lesser of:
1606
 *
1607
 * @li @c buffer_size(target)
1608
 *
1609
 * @li @c buffer_size(source)
1610
 *
1611
 * This function is implemented in terms of @c memcpy, and consequently it
1612
 * cannot be used to copy between overlapping memory regions.
1613
 */
1614
template <typename MutableBufferSequence>
1615
inline std::size_t buffer_copy(const MutableBufferSequence& target,
1616
    const const_buffers_1& source)
1617
{
1618
  return buffer_copy(target, static_cast<const const_buffer&>(source));
1619
}
1620

    
1621
/// Copies bytes from a source buffer to a target buffer sequence.
1622
/**
1623
 * @param target A modifiable buffer sequence representing the memory regions to
1624
 * which the bytes will be copied.
1625
 *
1626
 * @param source A modifiable buffer representing the memory region from which
1627
 * the bytes will be copied. The contents of the source buffer will not be
1628
 * modified.
1629
 *
1630
 * @returns The number of bytes copied.
1631
 *
1632
 * @note The number of bytes copied is the lesser of:
1633
 *
1634
 * @li @c buffer_size(target)
1635
 *
1636
 * @li @c buffer_size(source)
1637
 *
1638
 * This function is implemented in terms of @c memcpy, and consequently it
1639
 * cannot be used to copy between overlapping memory regions.
1640
 */
1641
template <typename MutableBufferSequence>
1642
inline std::size_t buffer_copy(const MutableBufferSequence& target,
1643
    const mutable_buffer& source)
1644
{
1645
  return buffer_copy(target, const_buffer(source));
1646
}
1647

    
1648
/// Copies bytes from a source buffer to a target buffer sequence.
1649
/**
1650
 * @param target A modifiable buffer sequence representing the memory regions to
1651
 * which the bytes will be copied.
1652
 *
1653
 * @param source A modifiable buffer representing the memory region from which
1654
 * the bytes will be copied. The contents of the source buffer will not be
1655
 * modified.
1656
 *
1657
 * @returns The number of bytes copied.
1658
 *
1659
 * @note The number of bytes copied is the lesser of:
1660
 *
1661
 * @li @c buffer_size(target)
1662
 *
1663
 * @li @c buffer_size(source)
1664
 *
1665
 * This function is implemented in terms of @c memcpy, and consequently it
1666
 * cannot be used to copy between overlapping memory regions.
1667
 */
1668
template <typename MutableBufferSequence>
1669
inline std::size_t buffer_copy(const MutableBufferSequence& target,
1670
    const mutable_buffers_1& source)
1671
{
1672
  return buffer_copy(target, const_buffer(source));
1673
}
1674

    
1675
/// Copies bytes from a source buffer sequence to a target buffer sequence.
1676
/**
1677
 * @param target A modifiable buffer sequence representing the memory regions to
1678
 * which the bytes will be copied.
1679
 *
1680
 * @param source A non-modifiable buffer sequence representing the memory
1681
 * regions from which the bytes will be copied.
1682
 *
1683
 * @returns The number of bytes copied.
1684
 *
1685
 * @note The number of bytes copied is the lesser of:
1686
 *
1687
 * @li @c buffer_size(target)
1688
 *
1689
 * @li @c buffer_size(source)
1690
 *
1691
 * This function is implemented in terms of @c memcpy, and consequently it
1692
 * cannot be used to copy between overlapping memory regions.
1693
 */
1694
template <typename MutableBufferSequence, typename ConstBufferSequence>
1695
std::size_t buffer_copy(const MutableBufferSequence& target,
1696
    const ConstBufferSequence& source)
1697
{
1698
  std::size_t total_bytes_copied = 0;
1699

    
1700
  typename MutableBufferSequence::const_iterator target_iter = target.begin();
1701
  typename MutableBufferSequence::const_iterator target_end = target.end();
1702
  std::size_t target_buffer_offset = 0;
1703

    
1704
  typename ConstBufferSequence::const_iterator source_iter = source.begin();
1705
  typename ConstBufferSequence::const_iterator source_end = source.end();
1706
  std::size_t source_buffer_offset = 0;
1707

    
1708
  while (target_iter != target_end && source_iter != source_end)
1709
  {
1710
    mutable_buffer target_buffer =
1711
      mutable_buffer(*target_iter) + target_buffer_offset;
1712

    
1713
    const_buffer source_buffer =
1714
      const_buffer(*source_iter) + source_buffer_offset;
1715

    
1716
    std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
1717
    total_bytes_copied += bytes_copied;
1718

    
1719
    if (bytes_copied == buffer_size(target_buffer))
1720
    {
1721
      ++target_iter;
1722
      target_buffer_offset = 0;
1723
    }
1724
    else
1725
      target_buffer_offset += bytes_copied;
1726

    
1727
    if (bytes_copied == buffer_size(source_buffer))
1728
    {
1729
      ++source_iter;
1730
      source_buffer_offset = 0;
1731
    }
1732
    else
1733
      source_buffer_offset += bytes_copied;
1734
  }
1735

    
1736
  return total_bytes_copied;
1737
}
1738

    
1739
/// Copies a limited number of bytes from a source buffer to a target buffer.
1740
/**
1741
 * @param target A modifiable buffer representing the memory region to which
1742
 * the bytes will be copied.
1743
 *
1744
 * @param source A non-modifiable buffer representing the memory region from
1745
 * which the bytes will be copied.
1746
 *
1747
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1748
 *
1749
 * @returns The number of bytes copied.
1750
 *
1751
 * @note The number of bytes copied is the lesser of:
1752
 *
1753
 * @li @c buffer_size(target)
1754
 *
1755
 * @li @c buffer_size(source)
1756
 *
1757
 * @li @c max_bytes_to_copy
1758
 *
1759
 * This function is implemented in terms of @c memcpy, and consequently it
1760
 * cannot be used to copy between overlapping memory regions.
1761
 */
1762
inline std::size_t buffer_copy(const mutable_buffer& target,
1763
    const const_buffer& source, std::size_t max_bytes_to_copy)
1764
{
1765
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1766
}
1767

    
1768
/// Copies a limited number of bytes from a source buffer to a target buffer.
1769
/**
1770
 * @param target A modifiable buffer representing the memory region to which
1771
 * the bytes will be copied.
1772
 *
1773
 * @param source A non-modifiable buffer representing the memory region from
1774
 * which the bytes will be copied.
1775
 *
1776
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1777
 *
1778
 * @returns The number of bytes copied.
1779
 *
1780
 * @note The number of bytes copied is the lesser of:
1781
 *
1782
 * @li @c buffer_size(target)
1783
 *
1784
 * @li @c buffer_size(source)
1785
 *
1786
 * @li @c max_bytes_to_copy
1787
 *
1788
 * This function is implemented in terms of @c memcpy, and consequently it
1789
 * cannot be used to copy between overlapping memory regions.
1790
 */
1791
inline std::size_t buffer_copy(const mutable_buffer& target,
1792
    const const_buffers_1& source, std::size_t max_bytes_to_copy)
1793
{
1794
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1795
}
1796

    
1797
/// Copies a limited number of bytes from a source buffer to a target buffer.
1798
/**
1799
 * @param target A modifiable buffer representing the memory region to which
1800
 * the bytes will be copied.
1801
 *
1802
 * @param source A modifiable buffer representing the memory region from which
1803
 * the bytes will be copied. The contents of the source buffer will not be
1804
 * modified.
1805
 *
1806
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1807
 *
1808
 * @returns The number of bytes copied.
1809
 *
1810
 * @note The number of bytes copied is the lesser of:
1811
 *
1812
 * @li @c buffer_size(target)
1813
 *
1814
 * @li @c buffer_size(source)
1815
 *
1816
 * @li @c max_bytes_to_copy
1817
 *
1818
 * This function is implemented in terms of @c memcpy, and consequently it
1819
 * cannot be used to copy between overlapping memory regions.
1820
 */
1821
inline std::size_t buffer_copy(const mutable_buffer& target,
1822
    const mutable_buffer& source, std::size_t max_bytes_to_copy)
1823
{
1824
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1825
}
1826

    
1827
/// Copies a limited number of bytes from a source buffer to a target buffer.
1828
/**
1829
 * @param target A modifiable buffer representing the memory region to which
1830
 * the bytes will be copied.
1831
 *
1832
 * @param source A modifiable buffer representing the memory region from which
1833
 * the bytes will be copied. The contents of the source buffer will not be
1834
 * modified.
1835
 *
1836
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1837
 *
1838
 * @returns The number of bytes copied.
1839
 *
1840
 * @note The number of bytes copied is the lesser of:
1841
 *
1842
 * @li @c buffer_size(target)
1843
 *
1844
 * @li @c buffer_size(source)
1845
 *
1846
 * @li @c max_bytes_to_copy
1847
 *
1848
 * This function is implemented in terms of @c memcpy, and consequently it
1849
 * cannot be used to copy between overlapping memory regions.
1850
 */
1851
inline std::size_t buffer_copy(const mutable_buffer& target,
1852
    const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
1853
{
1854
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1855
}
1856

    
1857
/// Copies a limited number of bytes from a source buffer sequence to a target
1858
/// buffer.
1859
/**
1860
 * @param target A modifiable buffer representing the memory region to which
1861
 * the bytes will be copied.
1862
 *
1863
 * @param source A non-modifiable buffer sequence representing the memory
1864
 * regions from which the bytes will be copied.
1865
 *
1866
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1867
 *
1868
 * @returns The number of bytes copied.
1869
 *
1870
 * @note The number of bytes copied is the lesser of:
1871
 *
1872
 * @li @c buffer_size(target)
1873
 *
1874
 * @li @c buffer_size(source)
1875
 *
1876
 * @li @c max_bytes_to_copy
1877
 *
1878
 * This function is implemented in terms of @c memcpy, and consequently it
1879
 * cannot be used to copy between overlapping memory regions.
1880
 */
1881
template <typename ConstBufferSequence>
1882
inline std::size_t buffer_copy(const mutable_buffer& target,
1883
    const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
1884
{
1885
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1886
}
1887

    
1888
/// Copies a limited number of bytes from a source buffer to a target buffer.
1889
/**
1890
 * @param target A modifiable buffer representing the memory region to which
1891
 * the bytes will be copied.
1892
 *
1893
 * @param source A non-modifiable buffer representing the memory region from
1894
 * which the bytes will be copied.
1895
 *
1896
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1897
 *
1898
 * @returns The number of bytes copied.
1899
 *
1900
 * @note The number of bytes copied is the lesser of:
1901
 *
1902
 * @li @c buffer_size(target)
1903
 *
1904
 * @li @c buffer_size(source)
1905
 *
1906
 * @li @c max_bytes_to_copy
1907
 *
1908
 * This function is implemented in terms of @c memcpy, and consequently it
1909
 * cannot be used to copy between overlapping memory regions.
1910
 */
1911
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1912
    const const_buffer& source, std::size_t max_bytes_to_copy)
1913
{
1914
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1915
}
1916

    
1917
/// Copies a limited number of bytes from a source buffer to a target buffer.
1918
/**
1919
 * @param target A modifiable buffer representing the memory region to which
1920
 * the bytes will be copied.
1921
 *
1922
 * @param source A non-modifiable buffer representing the memory region from
1923
 * which the bytes will be copied.
1924
 *
1925
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1926
 *
1927
 * @returns The number of bytes copied.
1928
 *
1929
 * @note The number of bytes copied is the lesser of:
1930
 *
1931
 * @li @c buffer_size(target)
1932
 *
1933
 * @li @c buffer_size(source)
1934
 *
1935
 * @li @c max_bytes_to_copy
1936
 *
1937
 * This function is implemented in terms of @c memcpy, and consequently it
1938
 * cannot be used to copy between overlapping memory regions.
1939
 */
1940
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1941
    const const_buffers_1& source, std::size_t max_bytes_to_copy)
1942
{
1943
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1944
}
1945

    
1946
/// Copies a limited number of bytes from a source buffer to a target buffer.
1947
/**
1948
 * @param target A modifiable buffer representing the memory region to which
1949
 * the bytes will be copied.
1950
 *
1951
 * @param source A modifiable buffer representing the memory region from which
1952
 * the bytes will be copied. The contents of the source buffer will not be
1953
 * modified.
1954
 *
1955
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1956
 *
1957
 * @returns The number of bytes copied.
1958
 *
1959
 * @note The number of bytes copied is the lesser of:
1960
 *
1961
 * @li @c buffer_size(target)
1962
 *
1963
 * @li @c buffer_size(source)
1964
 *
1965
 * @li @c max_bytes_to_copy
1966
 *
1967
 * This function is implemented in terms of @c memcpy, and consequently it
1968
 * cannot be used to copy between overlapping memory regions.
1969
 */
1970
inline std::size_t buffer_copy(const mutable_buffers_1& target,
1971
    const mutable_buffer& source, std::size_t max_bytes_to_copy)
1972
{
1973
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1974
}
1975

    
1976
/// Copies a limited number of bytes from a source buffer to a target buffer.
1977
/**
1978
 * @param target A modifiable buffer representing the memory region to which
1979
 * the bytes will be copied.
1980
 *
1981
 * @param source A modifiable buffer representing the memory region from which
1982
 * the bytes will be copied. The contents of the source buffer will not be
1983
 * modified.
1984
 *
1985
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
1986
 *
1987
 * @returns The number of bytes copied.
1988
 *
1989
 * @note The number of bytes copied is the lesser of:
1990
 *
1991
 * @li @c buffer_size(target)
1992
 *
1993
 * @li @c buffer_size(source)
1994
 *
1995
 * @li @c max_bytes_to_copy
1996
 *
1997
 * This function is implemented in terms of @c memcpy, and consequently it
1998
 * cannot be used to copy between overlapping memory regions.
1999
 */
2000
inline std::size_t buffer_copy(const mutable_buffers_1& target,
2001
    const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
2002
{
2003
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
2004
}
2005

    
2006
/// Copies a limited number of bytes from a source buffer sequence to a target
2007
/// buffer.
2008
/**
2009
 * @param target A modifiable buffer representing the memory region to which
2010
 * the bytes will be copied.
2011
 *
2012
 * @param source A non-modifiable buffer sequence representing the memory
2013
 * regions from which the bytes will be copied.
2014
 *
2015
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
2016
 *
2017
 * @returns The number of bytes copied.
2018
 *
2019
 * @note The number of bytes copied is the lesser of:
2020
 *
2021
 * @li @c buffer_size(target)
2022
 *
2023
 * @li @c buffer_size(source)
2024
 *
2025
 * @li @c max_bytes_to_copy
2026
 *
2027
 * This function is implemented in terms of @c memcpy, and consequently it
2028
 * cannot be used to copy between overlapping memory regions.
2029
 */
2030
template <typename ConstBufferSequence>
2031
inline std::size_t buffer_copy(const mutable_buffers_1& target,
2032
    const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
2033
{
2034
  return buffer_copy(buffer(target, max_bytes_to_copy), source);
2035
}
2036

    
2037
/// Copies a limited number of bytes from a source buffer to a target buffer
2038
/// sequence.
2039
/**
2040
 * @param target A modifiable buffer sequence representing the memory regions to
2041
 * which the bytes will be copied.
2042
 *
2043
 * @param source A non-modifiable buffer representing the memory region from
2044
 * which the bytes will be copied.
2045
 *
2046
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
2047
 *
2048
 * @returns The number of bytes copied.
2049
 *
2050
 * @note The number of bytes copied is the lesser of:
2051
 *
2052
 * @li @c buffer_size(target)
2053
 *
2054
 * @li @c buffer_size(source)
2055
 *
2056
 * @li @c max_bytes_to_copy
2057
 *
2058
 * This function is implemented in terms of @c memcpy, and consequently it
2059
 * cannot be used to copy between overlapping memory regions.
2060
 */
2061
template <typename MutableBufferSequence>
2062
inline std::size_t buffer_copy(const MutableBufferSequence& target,
2063
    const const_buffer& source, std::size_t max_bytes_to_copy)
2064
{
2065
  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2066
}
2067

    
2068
/// Copies a limited number of bytes from a source buffer to a target buffer
2069
/// sequence.
2070
/**
2071
 * @param target A modifiable buffer sequence representing the memory regions to
2072
 * which the bytes will be copied.
2073
 *
2074
 * @param source A non-modifiable buffer representing the memory region from
2075
 * which the bytes will be copied.
2076
 *
2077
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
2078
 *
2079
 * @returns The number of bytes copied.
2080
 *
2081
 * @note The number of bytes copied is the lesser of:
2082
 *
2083
 * @li @c buffer_size(target)
2084
 *
2085
 * @li @c buffer_size(source)
2086
 *
2087
 * @li @c max_bytes_to_copy
2088
 *
2089
 * This function is implemented in terms of @c memcpy, and consequently it
2090
 * cannot be used to copy between overlapping memory regions.
2091
 */
2092
template <typename MutableBufferSequence>
2093
inline std::size_t buffer_copy(const MutableBufferSequence& target,
2094
    const const_buffers_1& source, std::size_t max_bytes_to_copy)
2095
{
2096
  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2097
}
2098

    
2099
/// Copies a limited number of bytes from a source buffer to a target buffer
2100
/// sequence.
2101
/**
2102
 * @param target A modifiable buffer sequence representing the memory regions to
2103
 * which the bytes will be copied.
2104
 *
2105
 * @param source A modifiable buffer representing the memory region from which
2106
 * the bytes will be copied. The contents of the source buffer will not be
2107
 * modified.
2108
 *
2109
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
2110
 *
2111
 * @returns The number of bytes copied.
2112
 *
2113
 * @note The number of bytes copied is the lesser of:
2114
 *
2115
 * @li @c buffer_size(target)
2116
 *
2117
 * @li @c buffer_size(source)
2118
 *
2119
 * @li @c max_bytes_to_copy
2120
 *
2121
 * This function is implemented in terms of @c memcpy, and consequently it
2122
 * cannot be used to copy between overlapping memory regions.
2123
 */
2124
template <typename MutableBufferSequence>
2125
inline std::size_t buffer_copy(const MutableBufferSequence& target,
2126
    const mutable_buffer& source, std::size_t max_bytes_to_copy)
2127
{
2128
  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2129
}
2130

    
2131
/// Copies a limited number of bytes from a source buffer to a target buffer
2132
/// sequence.
2133
/**
2134
 * @param target A modifiable buffer sequence representing the memory regions to
2135
 * which the bytes will be copied.
2136
 *
2137
 * @param source A modifiable buffer representing the memory region from which
2138
 * the bytes will be copied. The contents of the source buffer will not be
2139
 * modified.
2140
 *
2141
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
2142
 *
2143
 * @returns The number of bytes copied.
2144
 *
2145
 * @note The number of bytes copied is the lesser of:
2146
 *
2147
 * @li @c buffer_size(target)
2148
 *
2149
 * @li @c buffer_size(source)
2150
 *
2151
 * @li @c max_bytes_to_copy
2152
 *
2153
 * This function is implemented in terms of @c memcpy, and consequently it
2154
 * cannot be used to copy between overlapping memory regions.
2155
 */
2156
template <typename MutableBufferSequence>
2157
inline std::size_t buffer_copy(const MutableBufferSequence& target,
2158
    const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
2159
{
2160
  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2161
}
2162

    
2163
/// Copies a limited number of bytes from a source buffer sequence to a target
2164
/// buffer sequence.
2165
/**
2166
 * @param target A modifiable buffer sequence representing the memory regions to
2167
 * which the bytes will be copied.
2168
 *
2169
 * @param source A non-modifiable buffer sequence representing the memory
2170
 * regions from which the bytes will be copied.
2171
 *
2172
 * @param max_bytes_to_copy The maximum number of bytes to be copied.
2173
 *
2174
 * @returns The number of bytes copied.
2175
 *
2176
 * @note The number of bytes copied is the lesser of:
2177
 *
2178
 * @li @c buffer_size(target)
2179
 *
2180
 * @li @c buffer_size(source)
2181
 *
2182
 * @li @c max_bytes_to_copy
2183
 *
2184
 * This function is implemented in terms of @c memcpy, and consequently it
2185
 * cannot be used to copy between overlapping memory regions.
2186
 */
2187
template <typename MutableBufferSequence, typename ConstBufferSequence>
2188
std::size_t buffer_copy(const MutableBufferSequence& target,
2189
    const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
2190
{
2191
  std::size_t total_bytes_copied = 0;
2192

    
2193
  typename MutableBufferSequence::const_iterator target_iter = target.begin();
2194
  typename MutableBufferSequence::const_iterator target_end = target.end();
2195
  std::size_t target_buffer_offset = 0;
2196

    
2197
  typename ConstBufferSequence::const_iterator source_iter = source.begin();
2198
  typename ConstBufferSequence::const_iterator source_end = source.end();
2199
  std::size_t source_buffer_offset = 0;
2200

    
2201
  while (total_bytes_copied != max_bytes_to_copy
2202
      && target_iter != target_end && source_iter != source_end)
2203
  {
2204
    mutable_buffer target_buffer =
2205
      mutable_buffer(*target_iter) + target_buffer_offset;
2206

    
2207
    const_buffer source_buffer =
2208
      const_buffer(*source_iter) + source_buffer_offset;
2209

    
2210
    std::size_t bytes_copied = buffer_copy(target_buffer,
2211
        source_buffer, max_bytes_to_copy - total_bytes_copied);
2212
    total_bytes_copied += bytes_copied;
2213

    
2214
    if (bytes_copied == buffer_size(target_buffer))
2215
    {
2216
      ++target_iter;
2217
      target_buffer_offset = 0;
2218
    }
2219
    else
2220
      target_buffer_offset += bytes_copied;
2221

    
2222
    if (bytes_copied == buffer_size(source_buffer))
2223
    {
2224
      ++source_iter;
2225
      source_buffer_offset = 0;
2226
    }
2227
    else
2228
      source_buffer_offset += bytes_copied;
2229
  }
2230

    
2231
  return total_bytes_copied;
2232
}
2233

    
2234
/*@}*/
2235

    
2236
} // namespace asio
2237
} // namespace boost
2238

    
2239
#include <boost/asio/detail/pop_options.hpp>
2240

    
2241
#endif // BOOST_ASIO_BUFFER_HPP