~cmiller/ubuntu/quantal/deluge/fix-parameter-move-storage

« back to all changes in this revision

Viewing changes to libtorrent/include/asio/buffer.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Cristian Greco
  • Date: 2009-11-13 02:39:45 UTC
  • mfrom: (4.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091113023945-te1bybo2912ejzuc
Tags: 1.2.0~rc3-4
* debian/control: bump build-dep on python-setuptools to (>= 0.6c9).
* debian/patches:
  - 25_r5921_fastresume_files.patch
    new, should fix problems with fresh configs;
  - 30_r5931_ipc_lockfile.patch:
    new, should fix an issue where Deluge will fail to start if there is a
    stale ipc lockfile. (Closes: #555849)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// buffer.hpp
3
 
// ~~~~~~~~~~
4
 
//
5
 
// Copyright (c) 2003-2008 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 ASIO_BUFFER_HPP
12
 
#define 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 "asio/detail/push_options.hpp"
19
 
 
20
 
#include "asio/detail/push_options.hpp"
21
 
#include <cstddef>
22
 
#include <boost/config.hpp>
23
 
#include <boost/array.hpp>
24
 
#include <boost/type_traits/is_const.hpp>
25
 
#include <string>
26
 
#include <vector>
27
 
#include "asio/detail/pop_options.hpp"
28
 
 
29
 
#if defined(BOOST_MSVC)
30
 
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
31
 
#  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
32
 
#   define ASIO_ENABLE_BUFFER_DEBUGGING
33
 
#  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
34
 
# endif // defined(_HAS_ITERATOR_DEBUGGING)
35
 
#endif // defined(BOOST_MSVC)
36
 
 
37
 
#if defined(__GNUC__)
38
 
# if defined(_GLIBCXX_DEBUG)
39
 
#  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
40
 
#   define ASIO_ENABLE_BUFFER_DEBUGGING
41
 
#  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
42
 
# endif // defined(_GLIBCXX_DEBUG)
43
 
#endif // defined(__GNUC__)
44
 
 
45
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
46
 
# include "asio/detail/push_options.hpp"
47
 
# include <boost/function.hpp>
48
 
# include "asio/detail/pop_options.hpp"
49
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
50
 
 
51
 
namespace asio {
52
 
 
53
 
class mutable_buffer;
54
 
class const_buffer;
55
 
 
56
 
namespace detail {
57
 
void* buffer_cast_helper(const mutable_buffer&);
58
 
const void* buffer_cast_helper(const const_buffer&);
59
 
std::size_t buffer_size_helper(const mutable_buffer&);
60
 
std::size_t buffer_size_helper(const const_buffer&);
61
 
} // namespace detail
62
 
 
63
 
/// Holds a buffer that can be modified.
64
 
/**
65
 
 * The mutable_buffer class provides a safe representation of a buffer that can
66
 
 * be modified. It does not own the underlying data, and so is cheap to copy or
67
 
 * assign.
68
 
 */
69
 
class mutable_buffer
70
 
{
71
 
public:
72
 
  /// Construct an empty buffer.
73
 
  mutable_buffer()
74
 
    : data_(0),
75
 
      size_(0)
76
 
  {
77
 
  }
78
 
 
79
 
  /// Construct a buffer to represent a given memory range.
80
 
  mutable_buffer(void* data, std::size_t size)
81
 
    : data_(data),
82
 
      size_(size)
83
 
  {
84
 
  }
85
 
 
86
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
87
 
  mutable_buffer(void* data, std::size_t size,
88
 
      boost::function<void()> debug_check)
89
 
    : data_(data),
90
 
      size_(size),
91
 
      debug_check_(debug_check)
92
 
  {
93
 
  }
94
 
 
95
 
  const boost::function<void()>& get_debug_check() const
96
 
  {
97
 
    return debug_check_;
98
 
  }
99
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
100
 
 
101
 
private:
102
 
  friend void* asio::detail::buffer_cast_helper(
103
 
      const mutable_buffer& b);
104
 
  friend std::size_t asio::detail::buffer_size_helper(
105
 
      const mutable_buffer& b);
106
 
 
107
 
  void* data_;
108
 
  std::size_t size_;
109
 
 
110
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
111
 
  boost::function<void()> debug_check_;
112
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
113
 
};
114
 
 
115
 
namespace detail {
116
 
 
117
 
inline void* buffer_cast_helper(const mutable_buffer& b)
118
 
{
119
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
120
 
  if (b.size_ && b.debug_check_)
121
 
    b.debug_check_();
122
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
123
 
  return b.data_;
124
 
}
125
 
 
126
 
inline std::size_t buffer_size_helper(const mutable_buffer& b)
127
 
{
128
 
  return b.size_;
129
 
}
130
 
 
131
 
} // namespace detail
132
 
 
133
 
/// Cast a non-modifiable buffer to a specified pointer to POD type.
134
 
/**
135
 
 * @relates mutable_buffer
136
 
 */
137
 
template <typename PointerToPodType>
138
 
inline PointerToPodType buffer_cast(const mutable_buffer& b)
139
 
{
140
 
  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
141
 
}
142
 
 
143
 
/// Get the number of bytes in a non-modifiable buffer.
144
 
/**
145
 
 * @relates mutable_buffer
146
 
 */
147
 
inline std::size_t buffer_size(const mutable_buffer& b)
148
 
{
149
 
  return detail::buffer_size_helper(b);
150
 
}
151
 
 
152
 
/// Create a new modifiable buffer that is offset from the start of another.
153
 
/**
154
 
 * @relates mutable_buffer
155
 
 */
156
 
inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
157
 
{
158
 
  if (start > buffer_size(b))
159
 
    return mutable_buffer();
160
 
  char* new_data = buffer_cast<char*>(b) + start;
161
 
  std::size_t new_size = buffer_size(b) - start;
162
 
  return mutable_buffer(new_data, new_size
163
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
164
 
      , b.get_debug_check()
165
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
166
 
      );
167
 
}
168
 
 
169
 
/// Create a new modifiable buffer that is offset from the start of another.
170
 
/**
171
 
 * @relates mutable_buffer
172
 
 */
173
 
inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
174
 
{
175
 
  if (start > buffer_size(b))
176
 
    return mutable_buffer();
177
 
  char* new_data = buffer_cast<char*>(b) + start;
178
 
  std::size_t new_size = buffer_size(b) - start;
179
 
  return mutable_buffer(new_data, new_size
180
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
181
 
      , b.get_debug_check()
182
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
183
 
      );
184
 
}
185
 
 
186
 
/// Adapts a single modifiable buffer so that it meets the requirements of the
187
 
/// MutableBufferSequence concept.
188
 
class mutable_buffers_1
189
 
  : public mutable_buffer
190
 
{
191
 
public:
192
 
  /// The type for each element in the list of buffers.
193
 
  typedef mutable_buffer value_type;
194
 
 
195
 
  /// A random-access iterator type that may be used to read elements.
196
 
  typedef const mutable_buffer* const_iterator;
197
 
 
198
 
  /// Construct to represent a given memory range.
199
 
  mutable_buffers_1(void* data, std::size_t size)
200
 
    : mutable_buffer(data, size)
201
 
  {
202
 
  }
203
 
 
204
 
  /// Construct to represent a single modifiable buffer.
205
 
  explicit mutable_buffers_1(const mutable_buffer& b)
206
 
    : mutable_buffer(b)
207
 
  {
208
 
  }
209
 
 
210
 
  /// Get a random-access iterator to the first element.
211
 
  const_iterator begin() const
212
 
  {
213
 
    return this;
214
 
  }
215
 
 
216
 
  /// Get a random-access iterator for one past the last element.
217
 
  const_iterator end() const
218
 
  {
219
 
    return begin() + 1;
220
 
  }
221
 
};
222
 
 
223
 
/// Holds a buffer that cannot be modified.
224
 
/**
225
 
 * The const_buffer class provides a safe representation of a buffer that cannot
226
 
 * be modified. It does not own the underlying data, and so is cheap to copy or
227
 
 * assign.
228
 
 */
229
 
class const_buffer
230
 
{
231
 
public:
232
 
  /// Construct an empty buffer.
233
 
  const_buffer()
234
 
    : data_(0),
235
 
      size_(0)
236
 
  {
237
 
  }
238
 
 
239
 
  /// Construct a buffer to represent a given memory range.
240
 
  const_buffer(const void* data, std::size_t size)
241
 
    : data_(data),
242
 
      size_(size)
243
 
  {
244
 
  }
245
 
 
246
 
  /// Construct a non-modifiable buffer from a modifiable one.
247
 
  const_buffer(const mutable_buffer& b)
248
 
    : data_(asio::detail::buffer_cast_helper(b)),
249
 
      size_(asio::detail::buffer_size_helper(b))
250
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
251
 
      , debug_check_(b.get_debug_check())
252
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
253
 
  {
254
 
  }
255
 
 
256
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
257
 
  const_buffer(const void* data, std::size_t size,
258
 
      boost::function<void()> debug_check)
259
 
    : data_(data),
260
 
      size_(size),
261
 
      debug_check_(debug_check)
262
 
  {
263
 
  }
264
 
 
265
 
  const boost::function<void()>& get_debug_check() const
266
 
  {
267
 
    return debug_check_;
268
 
  }
269
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
270
 
 
271
 
private:
272
 
  friend const void* asio::detail::buffer_cast_helper(
273
 
      const const_buffer& b);
274
 
  friend std::size_t asio::detail::buffer_size_helper(
275
 
      const const_buffer& b);
276
 
 
277
 
  const void* data_;
278
 
  std::size_t size_;
279
 
 
280
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
281
 
  boost::function<void()> debug_check_;
282
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
283
 
};
284
 
 
285
 
namespace detail {
286
 
 
287
 
inline const void* buffer_cast_helper(const const_buffer& b)
288
 
{
289
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
290
 
  if (b.size_ && b.debug_check_)
291
 
    b.debug_check_();
292
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
293
 
  return b.data_;
294
 
}
295
 
 
296
 
inline std::size_t buffer_size_helper(const const_buffer& b)
297
 
{
298
 
  return b.size_;
299
 
}
300
 
 
301
 
} // namespace detail
302
 
 
303
 
/// Cast a non-modifiable buffer to a specified pointer to POD type.
304
 
/**
305
 
 * @relates const_buffer
306
 
 */
307
 
template <typename PointerToPodType>
308
 
inline PointerToPodType buffer_cast(const const_buffer& b)
309
 
{
310
 
  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
311
 
}
312
 
 
313
 
/// Get the number of bytes in a non-modifiable buffer.
314
 
/**
315
 
 * @relates const_buffer
316
 
 */
317
 
inline std::size_t buffer_size(const const_buffer& b)
318
 
{
319
 
  return detail::buffer_size_helper(b);
320
 
}
321
 
 
322
 
/// Create a new non-modifiable buffer that is offset from the start of another.
323
 
/**
324
 
 * @relates const_buffer
325
 
 */
326
 
inline const_buffer operator+(const const_buffer& b, std::size_t start)
327
 
{
328
 
  if (start > buffer_size(b))
329
 
    return const_buffer();
330
 
  const char* new_data = buffer_cast<const char*>(b) + start;
331
 
  std::size_t new_size = buffer_size(b) - start;
332
 
  return const_buffer(new_data, new_size
333
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
334
 
      , b.get_debug_check()
335
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
336
 
      );
337
 
}
338
 
 
339
 
/// Create a new non-modifiable buffer that is offset from the start of another.
340
 
/**
341
 
 * @relates const_buffer
342
 
 */
343
 
inline const_buffer operator+(std::size_t start, const const_buffer& b)
344
 
{
345
 
  if (start > buffer_size(b))
346
 
    return const_buffer();
347
 
  const char* new_data = buffer_cast<const char*>(b) + start;
348
 
  std::size_t new_size = buffer_size(b) - start;
349
 
  return const_buffer(new_data, new_size
350
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
351
 
      , b.get_debug_check()
352
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
353
 
      );
354
 
}
355
 
 
356
 
/// Adapts a single non-modifiable buffer so that it meets the requirements of
357
 
/// the ConstBufferSequence concept.
358
 
class const_buffers_1
359
 
  : public const_buffer
360
 
{
361
 
public:
362
 
  /// The type for each element in the list of buffers.
363
 
  typedef const_buffer value_type;
364
 
 
365
 
  /// A random-access iterator type that may be used to read elements.
366
 
  typedef const const_buffer* const_iterator;
367
 
 
368
 
  /// Construct to represent a given memory range.
369
 
  const_buffers_1(const void* data, std::size_t size)
370
 
    : const_buffer(data, size)
371
 
  {
372
 
  }
373
 
 
374
 
  /// Construct to represent a single non-modifiable buffer.
375
 
  explicit const_buffers_1(const const_buffer& b)
376
 
    : const_buffer(b)
377
 
  {
378
 
  }
379
 
 
380
 
  /// Get a random-access iterator to the first element.
381
 
  const_iterator begin() const
382
 
  {
383
 
    return this;
384
 
  }
385
 
 
386
 
  /// Get a random-access iterator for one past the last element.
387
 
  const_iterator end() const
388
 
  {
389
 
    return begin() + 1;
390
 
  }
391
 
};
392
 
 
393
 
/// An implementation of both the ConstBufferSequence and MutableBufferSequence
394
 
/// concepts to represent a null buffer sequence.
395
 
class null_buffers
396
 
{
397
 
public:
398
 
  /// The type for each element in the list of buffers.
399
 
  typedef mutable_buffer value_type;
400
 
 
401
 
  /// A random-access iterator type that may be used to read elements.
402
 
  typedef const mutable_buffer* const_iterator;
403
 
 
404
 
  /// Get a random-access iterator to the first element.
405
 
  const_iterator begin() const
406
 
  {
407
 
    return &buf_;
408
 
  }
409
 
 
410
 
  /// Get a random-access iterator for one past the last element.
411
 
  const_iterator end() const
412
 
  {
413
 
    return &buf_;
414
 
  }
415
 
 
416
 
private:
417
 
  mutable_buffer buf_;
418
 
};
419
 
 
420
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
421
 
namespace detail {
422
 
 
423
 
template <typename Iterator>
424
 
class buffer_debug_check
425
 
{
426
 
public:
427
 
  buffer_debug_check(Iterator iter)
428
 
    : iter_(iter)
429
 
  {
430
 
  }
431
 
 
432
 
  ~buffer_debug_check()
433
 
  {
434
 
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
435
 
    // MSVC's string iterator checking may crash in a std::string::iterator
436
 
    // object's destructor when the iterator points to an already-destroyed
437
 
    // std::string object, unless the iterator is cleared first.
438
 
    iter_ = Iterator();
439
 
#endif // BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
440
 
  }
441
 
 
442
 
  void operator()()
443
 
  {
444
 
    *iter_;
445
 
  }
446
 
 
447
 
private:
448
 
  Iterator iter_;
449
 
};
450
 
 
451
 
} // namespace detail
452
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
453
 
 
454
 
/** @defgroup buffer asio::buffer
455
 
 *
456
 
 * @brief The asio::buffer function is used to create a buffer object to
457
 
 * represent raw memory, an array of POD elements, a vector of POD elements,
458
 
 * or a std::string.
459
 
 *
460
 
 * A buffer object represents a contiguous region of memory as a 2-tuple
461
 
 * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,
462
 
 * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a
463
 
 * tuple of the form <tt>{const void*, size_t}</tt> specifies a const
464
 
 * (non-modifiable) region of memory. These two forms correspond to the classes
465
 
 * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion
466
 
 * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the
467
 
 * opposite conversion is not permitted.
468
 
 *
469
 
 * The simplest use case involves reading or writing a single buffer of a
470
 
 * specified size:
471
 
 *
472
 
 * @code sock.send(asio::buffer(data, size)); @endcode
473
 
 *
474
 
 * In the above example, the return value of asio::buffer meets the
475
 
 * requirements of the ConstBufferSequence concept so that it may be directly
476
 
 * passed to the socket's write function. A buffer created for modifiable
477
 
 * memory also meets the requirements of the MutableBufferSequence concept.
478
 
 *
479
 
 * An individual buffer may be created from a builtin array, std::vector or
480
 
 * boost::array of POD elements. This helps prevent buffer overruns by
481
 
 * automatically determining the size of the buffer:
482
 
 *
483
 
 * @code char d1[128];
484
 
 * size_t bytes_transferred = sock.receive(asio::buffer(d1));
485
 
 *
486
 
 * std::vector<char> d2(128);
487
 
 * bytes_transferred = sock.receive(asio::buffer(d2));
488
 
 *
489
 
 * boost::array<char, 128> d3;
490
 
 * bytes_transferred = sock.receive(asio::buffer(d3)); @endcode
491
 
 *
492
 
 * In all three cases above, the buffers created are exactly 128 bytes long.
493
 
 * Note that a vector is @e never automatically resized when creating or using
494
 
 * a buffer. The buffer size is determined using the vector's <tt>size()</tt>
495
 
 * member function, and not its capacity.
496
 
 *
497
 
 * @par Accessing Buffer Contents
498
 
 *
499
 
 * The contents of a buffer may be accessed using the asio::buffer_size
500
 
 * and asio::buffer_cast functions:
501
 
 *
502
 
 * @code asio::mutable_buffer b1 = ...;
503
 
 * std::size_t s1 = asio::buffer_size(b1);
504
 
 * unsigned char* p1 = asio::buffer_cast<unsigned char*>(b1);
505
 
 *
506
 
 * asio::const_buffer b2 = ...;
507
 
 * std::size_t s2 = asio::buffer_size(b2);
508
 
 * const void* p2 = asio::buffer_cast<const void*>(b2); @endcode
509
 
 *
510
 
 * The asio::buffer_cast function permits violations of type safety, so
511
 
 * uses of it in application code should be carefully considered.
512
 
 *
513
 
 * @par Buffer Invalidation
514
 
 *
515
 
 * A buffer object does not have any ownership of the memory it refers to. It
516
 
 * is the responsibility of the application to ensure the memory region remains
517
 
 * valid until it is no longer required for an I/O operation. When the memory
518
 
 * is no longer available, the buffer is said to have been invalidated.
519
 
 *
520
 
 * For the asio::buffer overloads that accept an argument of type
521
 
 * std::vector, the buffer objects returned are invalidated by any vector
522
 
 * operation that also invalidates all references, pointers and iterators
523
 
 * referring to the elements in the sequence (C++ Std, 23.2.4)
524
 
 *
525
 
 * For the asio::buffer overloads that accept an argument of type
526
 
 * std::string, the buffer objects returned are invalidated according to the
527
 
 * rules defined for invalidation of references, pointers and iterators
528
 
 * referring to elements of the sequence (C++ Std, 21.3).
529
 
 *
530
 
 * @par Buffer Arithmetic
531
 
 *
532
 
 * Buffer objects may be manipulated using simple arithmetic in a safe way
533
 
 * which helps prevent buffer overruns. Consider an array initialised as
534
 
 * follows:
535
 
 *
536
 
 * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode
537
 
 *
538
 
 * A buffer object @c b1 created using:
539
 
 *
540
 
 * @code b1 = asio::buffer(a); @endcode
541
 
 *
542
 
 * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An
543
 
 * optional second argument to the asio::buffer function may be used to
544
 
 * limit the size, in bytes, of the buffer:
545
 
 *
546
 
 * @code b2 = asio::buffer(a, 3); @endcode
547
 
 *
548
 
 * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the
549
 
 * size argument exceeds the actual size of the array, the size of the buffer
550
 
 * object created will be limited to the array size.
551
 
 *
552
 
 * An offset may be applied to an existing buffer to create a new one:
553
 
 *
554
 
 * @code b3 = b1 + 2; @endcode
555
 
 *
556
 
 * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset
557
 
 * exceeds the size of the existing buffer, the newly created buffer will be
558
 
 * empty.
559
 
 *
560
 
 * Both an offset and size may be specified to create a buffer that corresponds
561
 
 * to a specific range of bytes within an existing buffer:
562
 
 *
563
 
 * @code b4 = asio::buffer(b1 + 1, 3); @endcode
564
 
 *
565
 
 * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.
566
 
 *
567
 
 * @par Buffers and Scatter-Gather I/O
568
 
 *
569
 
 * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
570
 
 * buffer objects may be assigned into a container that supports the
571
 
 * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
572
 
 *
573
 
 * @code
574
 
 * char d1[128];
575
 
 * std::vector<char> d2(128);
576
 
 * boost::array<char, 128> d3;
577
 
 *
578
 
 * boost::array<mutable_buffer, 3> bufs1 = {
579
 
 *   asio::buffer(d1),
580
 
 *   asio::buffer(d2),
581
 
 *   asio::buffer(d3) };
582
 
 * bytes_transferred = sock.receive(bufs1);
583
 
 *
584
 
 * std::vector<const_buffer> bufs2;
585
 
 * bufs2.push_back(asio::buffer(d1));
586
 
 * bufs2.push_back(asio::buffer(d2));
587
 
 * bufs2.push_back(asio::buffer(d3));
588
 
 * bytes_transferred = sock.send(bufs2); @endcode
589
 
 */
590
 
/*@{*/
591
 
 
592
 
/// Create a new modifiable buffer from an existing buffer.
593
 
/**
594
 
 * @returns <tt>mutable_buffers_1(b)</tt>.
595
 
 */
596
 
inline mutable_buffers_1 buffer(const mutable_buffer& b)
597
 
{
598
 
  return mutable_buffers_1(b);
599
 
}
600
 
 
601
 
/// Create a new modifiable buffer from an existing buffer.
602
 
/**
603
 
 * @returns A mutable_buffers_1 value equivalent to:
604
 
 * @code mutable_buffers_1(
605
 
 *     buffer_cast<void*>(b),
606
 
 *     min(buffer_size(b), max_size_in_bytes)); @endcode
607
 
 */
608
 
inline mutable_buffers_1 buffer(const mutable_buffer& b,
609
 
    std::size_t max_size_in_bytes)
610
 
{
611
 
  return mutable_buffers_1(
612
 
      mutable_buffer(buffer_cast<void*>(b),
613
 
        buffer_size(b) < max_size_in_bytes
614
 
        ? buffer_size(b) : max_size_in_bytes
615
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
616
 
        , b.get_debug_check()
617
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
618
 
        ));
619
 
}
620
 
 
621
 
/// Create a new non-modifiable buffer from an existing buffer.
622
 
/**
623
 
 * @returns <tt>const_buffers_1(b)</tt>.
624
 
 */
625
 
inline const_buffers_1 buffer(const const_buffer& b)
626
 
{
627
 
  return const_buffers_1(b);
628
 
}
629
 
 
630
 
/// Create a new non-modifiable buffer from an existing buffer.
631
 
/**
632
 
 * @returns A const_buffers_1 value equivalent to:
633
 
 * @code const_buffers_1(
634
 
 *     buffer_cast<const void*>(b),
635
 
 *     min(buffer_size(b), max_size_in_bytes)); @endcode
636
 
 */
637
 
inline const_buffers_1 buffer(const const_buffer& b,
638
 
    std::size_t max_size_in_bytes)
639
 
{
640
 
  return const_buffers_1(
641
 
      const_buffer(buffer_cast<const void*>(b),
642
 
        buffer_size(b) < max_size_in_bytes
643
 
        ? buffer_size(b) : max_size_in_bytes
644
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
645
 
        , b.get_debug_check()
646
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
647
 
        ));
648
 
}
649
 
 
650
 
/// Create a new modifiable buffer that represents the given memory range.
651
 
/**
652
 
 * @returns <tt>mutable_buffers_1(data, size_in_bytes)</tt>.
653
 
 */
654
 
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
655
 
{
656
 
  return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
657
 
}
658
 
 
659
 
/// Create a new non-modifiable buffer that represents the given memory range.
660
 
/**
661
 
 * @returns <tt>const_buffers_1(data, size_in_bytes)</tt>.
662
 
 */
663
 
inline const_buffers_1 buffer(const void* data,
664
 
    std::size_t size_in_bytes)
665
 
{
666
 
  return const_buffers_1(const_buffer(data, size_in_bytes));
667
 
}
668
 
 
669
 
/// Create a new modifiable buffer that represents the given POD array.
670
 
/**
671
 
 * @returns A mutable_buffers_1 value equivalent to:
672
 
 * @code mutable_buffers_1(
673
 
 *     static_cast<void*>(data),
674
 
 *     N * sizeof(PodType)); @endcode
675
 
 */
676
 
template <typename PodType, std::size_t N>
677
 
inline mutable_buffers_1 buffer(PodType (&data)[N])
678
 
{
679
 
  return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
680
 
}
681
 
 
682
 
/// Create a new modifiable buffer that represents the given POD array.
683
 
/**
684
 
 * @returns A mutable_buffers_1 value equivalent to:
685
 
 * @code mutable_buffers_1(
686
 
 *     static_cast<void*>(data),
687
 
 *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode
688
 
 */
689
 
template <typename PodType, std::size_t N>
690
 
inline mutable_buffers_1 buffer(PodType (&data)[N],
691
 
    std::size_t max_size_in_bytes)
692
 
{
693
 
  return mutable_buffers_1(
694
 
      mutable_buffer(data,
695
 
        N * sizeof(PodType) < max_size_in_bytes
696
 
        ? N * sizeof(PodType) : max_size_in_bytes));
697
 
}
698
 
 
699
 
/// Create a new non-modifiable buffer that represents the given POD array.
700
 
/**
701
 
 * @returns A const_buffers_1 value equivalent to:
702
 
 * @code const_buffers_1(
703
 
 *     static_cast<const void*>(data),
704
 
 *     N * sizeof(PodType)); @endcode
705
 
 */
706
 
template <typename PodType, std::size_t N>
707
 
inline const_buffers_1 buffer(const PodType (&data)[N])
708
 
{
709
 
  return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
710
 
}
711
 
 
712
 
/// Create a new non-modifiable buffer that represents the given POD array.
713
 
/**
714
 
 * @returns A const_buffers_1 value equivalent to:
715
 
 * @code const_buffers_1(
716
 
 *     static_cast<const void*>(data),
717
 
 *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode
718
 
 */
719
 
template <typename PodType, std::size_t N>
720
 
inline const_buffers_1 buffer(const PodType (&data)[N],
721
 
    std::size_t max_size_in_bytes)
722
 
{
723
 
  return const_buffers_1(
724
 
      const_buffer(data,
725
 
        N * sizeof(PodType) < max_size_in_bytes
726
 
        ? N * sizeof(PodType) : max_size_in_bytes));
727
 
}
728
 
 
729
 
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
730
 
  || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
731
 
 
732
 
// Borland C++ and Sun Studio think the overloads:
733
 
//
734
 
//   unspecified buffer(boost::array<PodType, N>& array ...);
735
 
//
736
 
// and
737
 
//
738
 
//   unspecified buffer(boost::array<const PodType, N>& array ...);
739
 
//
740
 
// are ambiguous. This will be worked around by using a buffer_types traits
741
 
// class that contains typedefs for the appropriate buffer and container
742
 
// classes, based on whether PodType is const or non-const.
743
 
 
744
 
namespace detail {
745
 
 
746
 
template <bool IsConst>
747
 
struct buffer_types_base;
748
 
 
749
 
template <>
750
 
struct buffer_types_base<false>
751
 
{
752
 
  typedef mutable_buffer buffer_type;
753
 
  typedef mutable_buffers_1 container_type;
754
 
};
755
 
 
756
 
template <>
757
 
struct buffer_types_base<true>
758
 
{
759
 
  typedef const_buffer buffer_type;
760
 
  typedef const_buffers_1 container_type;
761
 
};
762
 
 
763
 
template <typename PodType>
764
 
struct buffer_types
765
 
  : public buffer_types_base<boost::is_const<PodType>::value>
766
 
{
767
 
};
768
 
 
769
 
} // namespace detail
770
 
 
771
 
template <typename PodType, std::size_t N>
772
 
inline typename detail::buffer_types<PodType>::container_type
773
 
buffer(boost::array<PodType, N>& data)
774
 
{
775
 
  typedef typename asio::detail::buffer_types<PodType>::buffer_type
776
 
    buffer_type;
777
 
  typedef typename asio::detail::buffer_types<PodType>::container_type
778
 
    container_type;
779
 
  return container_type(
780
 
      buffer_type(data.c_array(), data.size() * sizeof(PodType)));
781
 
}
782
 
 
783
 
template <typename PodType, std::size_t N>
784
 
inline typename detail::buffer_types<PodType>::container_type
785
 
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
786
 
{
787
 
  typedef typename asio::detail::buffer_types<PodType>::buffer_type
788
 
    buffer_type;
789
 
  typedef typename asio::detail::buffer_types<PodType>::container_type
790
 
    container_type;
791
 
  return container_type(
792
 
      buffer_type(data.c_array(),
793
 
        data.size() * sizeof(PodType) < max_size_in_bytes
794
 
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
795
 
}
796
 
 
797
 
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
798
 
      // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
799
 
 
800
 
/// Create a new modifiable buffer that represents the given POD array.
801
 
/**
802
 
 * @returns A mutable_buffers_1 value equivalent to:
803
 
 * @code mutable_buffers_1(
804
 
 *     data.data(),
805
 
 *     data.size() * sizeof(PodType)); @endcode
806
 
 */
807
 
template <typename PodType, std::size_t N>
808
 
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
809
 
{
810
 
  return mutable_buffers_1(
811
 
      mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
812
 
}
813
 
 
814
 
/// Create a new modifiable buffer that represents the given POD array.
815
 
/**
816
 
 * @returns A mutable_buffers_1 value equivalent to:
817
 
 * @code mutable_buffers_1(
818
 
 *     data.data(),
819
 
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
820
 
 */
821
 
template <typename PodType, std::size_t N>
822
 
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
823
 
    std::size_t max_size_in_bytes)
824
 
{
825
 
  return mutable_buffers_1(
826
 
      mutable_buffer(data.c_array(),
827
 
        data.size() * sizeof(PodType) < max_size_in_bytes
828
 
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
829
 
}
830
 
 
831
 
/// Create a new non-modifiable buffer that represents the given POD array.
832
 
/**
833
 
 * @returns A const_buffers_1 value equivalent to:
834
 
 * @code const_buffers_1(
835
 
 *     data.data(),
836
 
 *     data.size() * sizeof(PodType)); @endcode
837
 
 */
838
 
template <typename PodType, std::size_t N>
839
 
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
840
 
{
841
 
  return const_buffers_1(
842
 
      const_buffer(data.data(), data.size() * sizeof(PodType)));
843
 
}
844
 
 
845
 
/// Create a new non-modifiable buffer that represents the given POD array.
846
 
/**
847
 
 * @returns A const_buffers_1 value equivalent to:
848
 
 * @code const_buffers_1(
849
 
 *     data.data(),
850
 
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
851
 
 */
852
 
template <typename PodType, std::size_t N>
853
 
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
854
 
    std::size_t max_size_in_bytes)
855
 
{
856
 
  return const_buffers_1(
857
 
      const_buffer(data.data(),
858
 
        data.size() * sizeof(PodType) < max_size_in_bytes
859
 
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
860
 
}
861
 
 
862
 
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
863
 
       // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
864
 
 
865
 
/// Create a new non-modifiable buffer that represents the given POD array.
866
 
/**
867
 
 * @returns A const_buffers_1 value equivalent to:
868
 
 * @code const_buffers_1(
869
 
 *     data.data(),
870
 
 *     data.size() * sizeof(PodType)); @endcode
871
 
 */
872
 
template <typename PodType, std::size_t N>
873
 
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
874
 
{
875
 
  return const_buffers_1(
876
 
      const_buffer(data.data(), data.size() * sizeof(PodType)));
877
 
}
878
 
 
879
 
/// Create a new non-modifiable buffer that represents the given POD array.
880
 
/**
881
 
 * @returns A const_buffers_1 value equivalent to:
882
 
 * @code const_buffers_1(
883
 
 *     data.data(),
884
 
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
885
 
 */
886
 
template <typename PodType, std::size_t N>
887
 
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
888
 
    std::size_t max_size_in_bytes)
889
 
{
890
 
  return const_buffers_1(
891
 
      const_buffer(data.data(),
892
 
        data.size() * sizeof(PodType) < max_size_in_bytes
893
 
        ? data.size() * sizeof(PodType) : max_size_in_bytes));
894
 
}
895
 
 
896
 
/// Create a new modifiable buffer that represents the given POD vector.
897
 
/**
898
 
 * @returns A mutable_buffers_1 value equivalent to:
899
 
 * @code mutable_buffers_1(
900
 
 *     data.size() ? &data[0] : 0,
901
 
 *     data.size() * sizeof(PodType)); @endcode
902
 
 *
903
 
 * @note The buffer is invalidated by any vector operation that would also
904
 
 * invalidate iterators.
905
 
 */
906
 
template <typename PodType, typename Allocator>
907
 
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
908
 
{
909
 
  return mutable_buffers_1(
910
 
      mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
911
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
912
 
        , detail::buffer_debug_check<
913
 
            typename std::vector<PodType, Allocator>::iterator
914
 
          >(data.begin())
915
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
916
 
        ));
917
 
}
918
 
 
919
 
/// Create a new modifiable buffer that represents the given POD vector.
920
 
/**
921
 
 * @returns A mutable_buffers_1 value equivalent to:
922
 
 * @code mutable_buffers_1(
923
 
 *     data.size() ? &data[0] : 0,
924
 
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
925
 
 *
926
 
 * @note The buffer is invalidated by any vector operation that would also
927
 
 * invalidate iterators.
928
 
 */
929
 
template <typename PodType, typename Allocator>
930
 
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
931
 
    std::size_t max_size_in_bytes)
932
 
{
933
 
  return mutable_buffers_1(
934
 
      mutable_buffer(data.size() ? &data[0] : 0,
935
 
        data.size() * sizeof(PodType) < max_size_in_bytes
936
 
        ? data.size() * sizeof(PodType) : max_size_in_bytes
937
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
938
 
        , detail::buffer_debug_check<
939
 
            typename std::vector<PodType, Allocator>::iterator
940
 
          >(data.begin())
941
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
942
 
        ));
943
 
}
944
 
 
945
 
/// Create a new non-modifiable buffer that represents the given POD vector.
946
 
/**
947
 
 * @returns A const_buffers_1 value equivalent to:
948
 
 * @code const_buffers_1(
949
 
 *     data.size() ? &data[0] : 0,
950
 
 *     data.size() * sizeof(PodType)); @endcode
951
 
 *
952
 
 * @note The buffer is invalidated by any vector operation that would also
953
 
 * invalidate iterators.
954
 
 */
955
 
template <typename PodType, typename Allocator>
956
 
inline const_buffers_1 buffer(
957
 
    const std::vector<PodType, Allocator>& data)
958
 
{
959
 
  return const_buffers_1(
960
 
      const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
961
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
962
 
        , detail::buffer_debug_check<
963
 
            typename std::vector<PodType, Allocator>::const_iterator
964
 
          >(data.begin())
965
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
966
 
        ));
967
 
}
968
 
 
969
 
/// Create a new non-modifiable buffer that represents the given POD vector.
970
 
/**
971
 
 * @returns A const_buffers_1 value equivalent to:
972
 
 * @code const_buffers_1(
973
 
 *     data.size() ? &data[0] : 0,
974
 
 *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
975
 
 *
976
 
 * @note The buffer is invalidated by any vector operation that would also
977
 
 * invalidate iterators.
978
 
 */
979
 
template <typename PodType, typename Allocator>
980
 
inline const_buffers_1 buffer(
981
 
    const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
982
 
{
983
 
  return const_buffers_1(
984
 
      const_buffer(data.size() ? &data[0] : 0,
985
 
        data.size() * sizeof(PodType) < max_size_in_bytes
986
 
        ? data.size() * sizeof(PodType) : max_size_in_bytes
987
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
988
 
        , detail::buffer_debug_check<
989
 
            typename std::vector<PodType, Allocator>::const_iterator
990
 
          >(data.begin())
991
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
992
 
        ));
993
 
}
994
 
 
995
 
/// Create a new non-modifiable buffer that represents the given string.
996
 
/**
997
 
 * @returns <tt>const_buffers_1(data.data(), data.size())</tt>.
998
 
 *
999
 
 * @note The buffer is invalidated by any non-const operation called on the
1000
 
 * given string object.
1001
 
 */
1002
 
inline const_buffers_1 buffer(const std::string& data)
1003
 
{
1004
 
  return const_buffers_1(const_buffer(data.data(), data.size()
1005
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1006
 
        , detail::buffer_debug_check<std::string::const_iterator>(data.begin())
1007
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
1008
 
        ));
1009
 
}
1010
 
 
1011
 
/// Create a new non-modifiable buffer that represents the given string.
1012
 
/**
1013
 
 * @returns A const_buffers_1 value equivalent to:
1014
 
 * @code const_buffers_1(
1015
 
 *     data.data(),
1016
 
 *     min(data.size(), max_size_in_bytes)); @endcode
1017
 
 *
1018
 
 * @note The buffer is invalidated by any non-const operation called on the
1019
 
 * given string object.
1020
 
 */
1021
 
inline const_buffers_1 buffer(const std::string& data,
1022
 
    std::size_t max_size_in_bytes)
1023
 
{
1024
 
  return const_buffers_1(
1025
 
      const_buffer(data.data(),
1026
 
        data.size() < max_size_in_bytes
1027
 
        ? data.size() : max_size_in_bytes
1028
 
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1029
 
        , detail::buffer_debug_check<std::string::const_iterator>(data.begin())
1030
 
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
1031
 
        ));
1032
 
}
1033
 
 
1034
 
/*@}*/
1035
 
 
1036
 
} // namespace asio
1037
 
 
1038
 
#include "asio/detail/pop_options.hpp"
1039
 
 
1040
 
#endif // ASIO_BUFFER_HPP