File indexing completed on 2025-01-30 09:33:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_BUFFER_HPP
0012 #define BOOST_ASIO_BUFFER_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <cstddef>
0020 #include <cstring>
0021 #include <limits>
0022 #include <stdexcept>
0023 #include <string>
0024 #include <vector>
0025 #include <boost/asio/detail/array_fwd.hpp>
0026 #include <boost/asio/detail/memory.hpp>
0027 #include <boost/asio/detail/string_view.hpp>
0028 #include <boost/asio/detail/throw_exception.hpp>
0029 #include <boost/asio/detail/type_traits.hpp>
0030 #include <boost/asio/is_contiguous_iterator.hpp>
0031
0032 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700)
0033 # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
0034 # if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
0035 # define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
0036 # endif
0037 # endif
0038 #endif
0039
0040 #if defined(__GNUC__)
0041 # if defined(_GLIBCXX_DEBUG)
0042 # if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
0043 # define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
0044 # endif
0045 # endif
0046 #endif
0047
0048 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0049 # include <boost/asio/detail/functional.hpp>
0050 #endif
0051
0052 #include <boost/asio/detail/push_options.hpp>
0053
0054 namespace boost {
0055 namespace asio {
0056
0057 class mutable_buffer;
0058 class const_buffer;
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 class mutable_buffer
0080 {
0081 public:
0082
0083 mutable_buffer() noexcept
0084 : data_(0),
0085 size_(0)
0086 {
0087 }
0088
0089
0090 mutable_buffer(void* data, std::size_t size) noexcept
0091 : data_(data),
0092 size_(size)
0093 {
0094 }
0095
0096 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0097 mutable_buffer(void* data, std::size_t size,
0098 boost::asio::detail::function<void()> debug_check)
0099 : data_(data),
0100 size_(size),
0101 debug_check_(debug_check)
0102 {
0103 }
0104
0105 const boost::asio::detail::function<void()>& get_debug_check() const
0106 {
0107 return debug_check_;
0108 }
0109 #endif
0110
0111
0112 void* data() const noexcept
0113 {
0114 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0115 if (size_ && debug_check_)
0116 debug_check_();
0117 #endif
0118 return data_;
0119 }
0120
0121
0122 std::size_t size() const noexcept
0123 {
0124 return size_;
0125 }
0126
0127
0128 mutable_buffer& operator+=(std::size_t n) noexcept
0129 {
0130 std::size_t offset = n < size_ ? n : size_;
0131 data_ = static_cast<char*>(data_) + offset;
0132 size_ -= offset;
0133 return *this;
0134 }
0135
0136 private:
0137 void* data_;
0138 std::size_t size_;
0139
0140 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0141 boost::asio::detail::function<void()> debug_check_;
0142 #endif
0143 };
0144
0145 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0146
0147
0148
0149 class mutable_buffers_1
0150 : public mutable_buffer
0151 {
0152 public:
0153
0154 typedef mutable_buffer value_type;
0155
0156
0157 typedef const mutable_buffer* const_iterator;
0158
0159
0160 mutable_buffers_1(void* data, std::size_t size) noexcept
0161 : mutable_buffer(data, size)
0162 {
0163 }
0164
0165 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0166 mutable_buffers_1(void* data, std::size_t size,
0167 boost::asio::detail::function<void()> debug_check)
0168 : mutable_buffer(data, size, debug_check)
0169 {
0170 }
0171 #endif
0172
0173
0174 explicit mutable_buffers_1(const mutable_buffer& b) noexcept
0175 : mutable_buffer(b)
0176 {
0177 }
0178
0179
0180 const_iterator begin() const noexcept
0181 {
0182 return this;
0183 }
0184
0185
0186 const_iterator end() const noexcept
0187 {
0188 return begin() + 1;
0189 }
0190 };
0191
0192 #endif
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 class const_buffer
0214 {
0215 public:
0216
0217 const_buffer() noexcept
0218 : data_(0),
0219 size_(0)
0220 {
0221 }
0222
0223
0224 const_buffer(const void* data, std::size_t size) noexcept
0225 : data_(data),
0226 size_(size)
0227 {
0228 }
0229
0230
0231 const_buffer(const mutable_buffer& b) noexcept
0232 : data_(b.data()),
0233 size_(b.size())
0234 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0235 , debug_check_(b.get_debug_check())
0236 #endif
0237 {
0238 }
0239
0240 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0241 const_buffer(const void* data, std::size_t size,
0242 boost::asio::detail::function<void()> debug_check)
0243 : data_(data),
0244 size_(size),
0245 debug_check_(debug_check)
0246 {
0247 }
0248
0249 const boost::asio::detail::function<void()>& get_debug_check() const
0250 {
0251 return debug_check_;
0252 }
0253 #endif
0254
0255
0256 const void* data() const noexcept
0257 {
0258 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0259 if (size_ && debug_check_)
0260 debug_check_();
0261 #endif
0262 return data_;
0263 }
0264
0265
0266 std::size_t size() const noexcept
0267 {
0268 return size_;
0269 }
0270
0271
0272 const_buffer& operator+=(std::size_t n) noexcept
0273 {
0274 std::size_t offset = n < size_ ? n : size_;
0275 data_ = static_cast<const char*>(data_) + offset;
0276 size_ -= offset;
0277 return *this;
0278 }
0279
0280 private:
0281 const void* data_;
0282 std::size_t size_;
0283
0284 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0285 boost::asio::detail::function<void()> debug_check_;
0286 #endif
0287 };
0288
0289 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0290
0291
0292
0293 class const_buffers_1
0294 : public const_buffer
0295 {
0296 public:
0297
0298 typedef const_buffer value_type;
0299
0300
0301 typedef const const_buffer* const_iterator;
0302
0303
0304 const_buffers_1(const void* data, std::size_t size) noexcept
0305 : const_buffer(data, size)
0306 {
0307 }
0308
0309 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0310 const_buffers_1(const void* data, std::size_t size,
0311 boost::asio::detail::function<void()> debug_check)
0312 : const_buffer(data, size, debug_check)
0313 {
0314 }
0315 #endif
0316
0317
0318 explicit const_buffers_1(const const_buffer& b) noexcept
0319 : const_buffer(b)
0320 {
0321 }
0322
0323
0324 const_iterator begin() const noexcept
0325 {
0326 return this;
0327 }
0328
0329
0330 const_iterator end() const noexcept
0331 {
0332 return begin() + 1;
0333 }
0334 };
0335
0336 #endif
0337
0338
0339
0340
0341 class null_buffers
0342 {
0343 public:
0344
0345 typedef mutable_buffer value_type;
0346
0347
0348 typedef const mutable_buffer* const_iterator;
0349
0350
0351 const_iterator begin() const noexcept
0352 {
0353 return &buf_;
0354 }
0355
0356
0357 const_iterator end() const noexcept
0358 {
0359 return &buf_;
0360 }
0361
0362 private:
0363 mutable_buffer buf_;
0364 };
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 template <typename MutableBuffer>
0375 inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
0376 constraint_t<
0377 is_convertible<const MutableBuffer*, const mutable_buffer*>::value
0378 > = 0) noexcept
0379 {
0380 return static_cast<const mutable_buffer*>(detail::addressof(b));
0381 }
0382
0383
0384 template <typename ConstBuffer>
0385 inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
0386 constraint_t<
0387 is_convertible<const ConstBuffer*, const const_buffer*>::value
0388 > = 0) noexcept
0389 {
0390 return static_cast<const const_buffer*>(detail::addressof(b));
0391 }
0392
0393
0394 template <typename C>
0395 inline auto buffer_sequence_begin(C& c,
0396 constraint_t<
0397 !is_convertible<const C*, const mutable_buffer*>::value
0398 && !is_convertible<const C*, const const_buffer*>::value
0399 > = 0) noexcept -> decltype(c.begin())
0400 {
0401 return c.begin();
0402 }
0403
0404
0405 template <typename C>
0406 inline auto buffer_sequence_begin(const C& c,
0407 constraint_t<
0408 !is_convertible<const C*, const mutable_buffer*>::value
0409 && !is_convertible<const C*, const const_buffer*>::value
0410 > = 0) noexcept -> decltype(c.begin())
0411 {
0412 return c.begin();
0413 }
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 template <typename MutableBuffer>
0426 inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
0427 constraint_t<
0428 is_convertible<const MutableBuffer*, const mutable_buffer*>::value
0429 > = 0) noexcept
0430 {
0431 return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;
0432 }
0433
0434
0435 template <typename ConstBuffer>
0436 inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
0437 constraint_t<
0438 is_convertible<const ConstBuffer*, const const_buffer*>::value
0439 > = 0) noexcept
0440 {
0441 return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
0442 }
0443
0444
0445 template <typename C>
0446 inline auto buffer_sequence_end(C& c,
0447 constraint_t<
0448 !is_convertible<const C*, const mutable_buffer*>::value
0449 && !is_convertible<const C*, const const_buffer*>::value
0450 > = 0) noexcept -> decltype(c.end())
0451 {
0452 return c.end();
0453 }
0454
0455
0456 template <typename C>
0457 inline auto buffer_sequence_end(const C& c,
0458 constraint_t<
0459 !is_convertible<const C*, const mutable_buffer*>::value
0460 && !is_convertible<const C*, const const_buffer*>::value
0461 > = 0) noexcept -> decltype(c.end())
0462 {
0463 return c.end();
0464 }
0465
0466
0467
0468 namespace detail {
0469
0470
0471 struct one_buffer {};
0472 struct multiple_buffers {};
0473
0474
0475 template <typename BufferSequence>
0476 struct buffer_sequence_cardinality :
0477 conditional_t<
0478 is_same<BufferSequence, mutable_buffer>::value
0479 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0480 || is_same<BufferSequence, mutable_buffers_1>::value
0481 || is_same<BufferSequence, const_buffers_1>::value
0482 #endif
0483 || is_same<BufferSequence, const_buffer>::value,
0484 one_buffer, multiple_buffers> {};
0485
0486 template <typename Iterator>
0487 inline std::size_t buffer_size(one_buffer,
0488 Iterator begin, Iterator) noexcept
0489 {
0490 return const_buffer(*begin).size();
0491 }
0492
0493 template <typename Iterator>
0494 inline std::size_t buffer_size(multiple_buffers,
0495 Iterator begin, Iterator end) noexcept
0496 {
0497 std::size_t total_buffer_size = 0;
0498
0499 Iterator iter = begin;
0500 for (; iter != end; ++iter)
0501 {
0502 const_buffer b(*iter);
0503 total_buffer_size += b.size();
0504 }
0505
0506 return total_buffer_size;
0507 }
0508
0509 }
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529 template <typename BufferSequence>
0530 inline std::size_t buffer_size(const BufferSequence& b) noexcept
0531 {
0532 return detail::buffer_size(
0533 detail::buffer_sequence_cardinality<BufferSequence>(),
0534 boost::asio::buffer_sequence_begin(b),
0535 boost::asio::buffer_sequence_end(b));
0536 }
0537
0538 #if !defined(BOOST_ASIO_NO_DEPRECATED)
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 template <typename PointerToPodType>
0565 inline PointerToPodType buffer_cast(const mutable_buffer& b) noexcept
0566 {
0567 return static_cast<PointerToPodType>(b.data());
0568 }
0569
0570
0571 template <typename PointerToPodType>
0572 inline PointerToPodType buffer_cast(const const_buffer& b) noexcept
0573 {
0574 return static_cast<PointerToPodType>(b.data());
0575 }
0576
0577
0578
0579 #endif
0580
0581
0582
0583
0584
0585 inline mutable_buffer operator+(const mutable_buffer& b,
0586 std::size_t n) noexcept
0587 {
0588 std::size_t offset = n < b.size() ? n : b.size();
0589 char* new_data = static_cast<char*>(b.data()) + offset;
0590 std::size_t new_size = b.size() - offset;
0591 return mutable_buffer(new_data, new_size
0592 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0593 , b.get_debug_check()
0594 #endif
0595 );
0596 }
0597
0598
0599
0600
0601
0602 inline mutable_buffer operator+(std::size_t n,
0603 const mutable_buffer& b) noexcept
0604 {
0605 return b + n;
0606 }
0607
0608
0609
0610
0611
0612 inline const_buffer operator+(const const_buffer& b,
0613 std::size_t n) noexcept
0614 {
0615 std::size_t offset = n < b.size() ? n : b.size();
0616 const char* new_data = static_cast<const char*>(b.data()) + offset;
0617 std::size_t new_size = b.size() - offset;
0618 return const_buffer(new_data, new_size
0619 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0620 , b.get_debug_check()
0621 #endif
0622 );
0623 }
0624
0625
0626
0627
0628
0629 inline const_buffer operator+(std::size_t n,
0630 const const_buffer& b) noexcept
0631 {
0632 return b + n;
0633 }
0634
0635 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0636 namespace detail {
0637
0638 template <typename Iterator>
0639 class buffer_debug_check
0640 {
0641 public:
0642 buffer_debug_check(Iterator iter)
0643 : iter_(iter)
0644 {
0645 }
0646
0647 ~buffer_debug_check()
0648 {
0649 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
0650
0651
0652
0653 iter_ = Iterator();
0654 #endif
0655 }
0656
0657 void operator()()
0658 {
0659 (void)*iter_;
0660 }
0661
0662 private:
0663 Iterator iter_;
0664 };
0665
0666 }
0667 #endif
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851 #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
0852 # define BOOST_ASIO_MUTABLE_BUFFER mutable_buffer
0853 # define BOOST_ASIO_CONST_BUFFER const_buffer
0854 #else
0855 # define BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_1
0856 # define BOOST_ASIO_CONST_BUFFER const_buffers_1
0857 #endif
0858
0859
0860
0861
0862
0863 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
0864 const mutable_buffer& b) noexcept
0865 {
0866 return BOOST_ASIO_MUTABLE_BUFFER(b);
0867 }
0868
0869
0870
0871
0872
0873
0874
0875
0876 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
0877 const mutable_buffer& b,
0878 std::size_t max_size_in_bytes) noexcept
0879 {
0880 return BOOST_ASIO_MUTABLE_BUFFER(
0881 mutable_buffer(b.data(),
0882 b.size() < max_size_in_bytes
0883 ? b.size() : max_size_in_bytes
0884 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0885 , b.get_debug_check()
0886 #endif
0887 ));
0888 }
0889
0890
0891
0892
0893
0894 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
0895 const const_buffer& b) noexcept
0896 {
0897 return BOOST_ASIO_CONST_BUFFER(b);
0898 }
0899
0900
0901
0902
0903
0904
0905
0906
0907 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
0908 const const_buffer& b,
0909 std::size_t max_size_in_bytes) noexcept
0910 {
0911 return BOOST_ASIO_CONST_BUFFER(b.data(),
0912 b.size() < max_size_in_bytes
0913 ? b.size() : max_size_in_bytes
0914 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
0915 , b.get_debug_check()
0916 #endif
0917 );
0918 }
0919
0920
0921
0922
0923
0924 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
0925 void* data, std::size_t size_in_bytes) noexcept
0926 {
0927 return BOOST_ASIO_MUTABLE_BUFFER(data, size_in_bytes);
0928 }
0929
0930
0931
0932
0933
0934 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
0935 const void* data, std::size_t size_in_bytes) noexcept
0936 {
0937 return BOOST_ASIO_CONST_BUFFER(data, size_in_bytes);
0938 }
0939
0940
0941
0942
0943
0944
0945
0946
0947 template <typename PodType, std::size_t N>
0948 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
0949 PodType (&data)[N]) noexcept
0950 {
0951 return BOOST_ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType));
0952 }
0953
0954
0955
0956
0957
0958
0959
0960
0961 template <typename PodType, std::size_t N>
0962 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
0963 PodType (&data)[N],
0964 std::size_t max_size_in_bytes) noexcept
0965 {
0966 return BOOST_ASIO_MUTABLE_BUFFER(data,
0967 N * sizeof(PodType) < max_size_in_bytes
0968 ? N * sizeof(PodType) : max_size_in_bytes);
0969 }
0970
0971
0972
0973
0974
0975
0976
0977
0978 template <typename PodType, std::size_t N>
0979 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
0980 const PodType (&data)[N]) noexcept
0981 {
0982 return BOOST_ASIO_CONST_BUFFER(data, N * sizeof(PodType));
0983 }
0984
0985
0986
0987
0988
0989
0990
0991
0992 template <typename PodType, std::size_t N>
0993 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
0994 const PodType (&data)[N],
0995 std::size_t max_size_in_bytes) noexcept
0996 {
0997 return BOOST_ASIO_CONST_BUFFER(data,
0998 N * sizeof(PodType) < max_size_in_bytes
0999 ? N * sizeof(PodType) : max_size_in_bytes);
1000 }
1001
1002
1003
1004
1005
1006
1007
1008
1009 template <typename PodType, std::size_t N>
1010 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1011 boost::array<PodType, N>& data) noexcept
1012 {
1013 return BOOST_ASIO_MUTABLE_BUFFER(
1014 data.c_array(), data.size() * sizeof(PodType));
1015 }
1016
1017
1018
1019
1020
1021
1022
1023
1024 template <typename PodType, std::size_t N>
1025 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1026 boost::array<PodType, N>& data,
1027 std::size_t max_size_in_bytes) noexcept
1028 {
1029 return BOOST_ASIO_MUTABLE_BUFFER(data.c_array(),
1030 data.size() * sizeof(PodType) < max_size_in_bytes
1031 ? data.size() * sizeof(PodType) : max_size_in_bytes);
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1041 template <typename PodType, std::size_t N>
1042 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1043 boost::array<const PodType, N>& data) noexcept
1044 {
1045 return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
1046 }
1047
1048
1049
1050
1051
1052
1053
1054
1055 template <typename PodType, std::size_t N>
1056 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1057 boost::array<const PodType, N>& data,
1058 std::size_t max_size_in_bytes) noexcept
1059 {
1060 return BOOST_ASIO_CONST_BUFFER(data.data(),
1061 data.size() * sizeof(PodType) < max_size_in_bytes
1062 ? data.size() * sizeof(PodType) : max_size_in_bytes);
1063 }
1064
1065
1066
1067
1068
1069
1070
1071
1072 template <typename PodType, std::size_t N>
1073 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1074 const boost::array<PodType, N>& data) noexcept
1075 {
1076 return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
1077 }
1078
1079
1080
1081
1082
1083
1084
1085
1086 template <typename PodType, std::size_t N>
1087 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1088 const boost::array<PodType, N>& data,
1089 std::size_t max_size_in_bytes) noexcept
1090 {
1091 return BOOST_ASIO_CONST_BUFFER(data.data(),
1092 data.size() * sizeof(PodType) < max_size_in_bytes
1093 ? data.size() * sizeof(PodType) : max_size_in_bytes);
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103 template <typename PodType, std::size_t N>
1104 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1105 std::array<PodType, N>& data) noexcept
1106 {
1107 return BOOST_ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType));
1108 }
1109
1110
1111
1112
1113
1114
1115
1116
1117 template <typename PodType, std::size_t N>
1118 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1119 std::array<PodType, N>& data,
1120 std::size_t max_size_in_bytes) noexcept
1121 {
1122 return BOOST_ASIO_MUTABLE_BUFFER(data.data(),
1123 data.size() * sizeof(PodType) < max_size_in_bytes
1124 ? data.size() * sizeof(PodType) : max_size_in_bytes);
1125 }
1126
1127
1128
1129
1130
1131
1132
1133
1134 template <typename PodType, std::size_t N>
1135 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1136 std::array<const PodType, N>& data) noexcept
1137 {
1138 return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
1139 }
1140
1141
1142
1143
1144
1145
1146
1147
1148 template <typename PodType, std::size_t N>
1149 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1150 std::array<const PodType, N>& data,
1151 std::size_t max_size_in_bytes) noexcept
1152 {
1153 return BOOST_ASIO_CONST_BUFFER(data.data(),
1154 data.size() * sizeof(PodType) < max_size_in_bytes
1155 ? data.size() * sizeof(PodType) : max_size_in_bytes);
1156 }
1157
1158
1159
1160
1161
1162
1163
1164
1165 template <typename PodType, std::size_t N>
1166 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1167 const std::array<PodType, N>& data) noexcept
1168 {
1169 return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
1170 }
1171
1172
1173
1174
1175
1176
1177
1178
1179 template <typename PodType, std::size_t N>
1180 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1181 const std::array<PodType, N>& data,
1182 std::size_t max_size_in_bytes) noexcept
1183 {
1184 return BOOST_ASIO_CONST_BUFFER(data.data(),
1185 data.size() * sizeof(PodType) < max_size_in_bytes
1186 ? data.size() * sizeof(PodType) : max_size_in_bytes);
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199 template <typename PodType, typename Allocator>
1200 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1201 std::vector<PodType, Allocator>& data) noexcept
1202 {
1203 return BOOST_ASIO_MUTABLE_BUFFER(
1204 data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
1205 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1206 , detail::buffer_debug_check<
1207 typename std::vector<PodType, Allocator>::iterator
1208 >(data.begin())
1209 #endif
1210 );
1211 }
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 template <typename PodType, typename Allocator>
1224 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1225 std::vector<PodType, Allocator>& data,
1226 std::size_t max_size_in_bytes) noexcept
1227 {
1228 return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
1229 data.size() * sizeof(PodType) < max_size_in_bytes
1230 ? data.size() * sizeof(PodType) : max_size_in_bytes
1231 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1232 , detail::buffer_debug_check<
1233 typename std::vector<PodType, Allocator>::iterator
1234 >(data.begin())
1235 #endif
1236 );
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249 template <typename PodType, typename Allocator>
1250 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1251 const std::vector<PodType, Allocator>& data) noexcept
1252 {
1253 return BOOST_ASIO_CONST_BUFFER(
1254 data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
1255 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1256 , detail::buffer_debug_check<
1257 typename std::vector<PodType, Allocator>::const_iterator
1258 >(data.begin())
1259 #endif
1260 );
1261 }
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273 template <typename PodType, typename Allocator>
1274 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1275 const std::vector<PodType, Allocator>& data,
1276 std::size_t max_size_in_bytes) noexcept
1277 {
1278 return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
1279 data.size() * sizeof(PodType) < max_size_in_bytes
1280 ? data.size() * sizeof(PodType) : max_size_in_bytes
1281 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1282 , detail::buffer_debug_check<
1283 typename std::vector<PodType, Allocator>::const_iterator
1284 >(data.begin())
1285 #endif
1286 );
1287 }
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297 template <typename Elem, typename Traits, typename Allocator>
1298 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1299 std::basic_string<Elem, Traits, Allocator>& data) noexcept
1300 {
1301 return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
1302 data.size() * sizeof(Elem)
1303 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1304 , detail::buffer_debug_check<
1305 typename std::basic_string<Elem, Traits, Allocator>::iterator
1306 >(data.begin())
1307 #endif
1308 );
1309 }
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321 template <typename Elem, typename Traits, typename Allocator>
1322 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1323 std::basic_string<Elem, Traits, Allocator>& data,
1324 std::size_t max_size_in_bytes) noexcept
1325 {
1326 return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
1327 data.size() * sizeof(Elem) < max_size_in_bytes
1328 ? data.size() * sizeof(Elem) : max_size_in_bytes
1329 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1330 , detail::buffer_debug_check<
1331 typename std::basic_string<Elem, Traits, Allocator>::iterator
1332 >(data.begin())
1333 #endif
1334 );
1335 }
1336
1337
1338
1339
1340
1341
1342
1343
1344 template <typename Elem, typename Traits, typename Allocator>
1345 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1346 const std::basic_string<Elem, Traits, Allocator>& data) noexcept
1347 {
1348 return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem)
1349 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1350 , detail::buffer_debug_check<
1351 typename std::basic_string<Elem, Traits, Allocator>::const_iterator
1352 >(data.begin())
1353 #endif
1354 );
1355 }
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367 template <typename Elem, typename Traits, typename Allocator>
1368 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1369 const std::basic_string<Elem, Traits, Allocator>& data,
1370 std::size_t max_size_in_bytes) noexcept
1371 {
1372 return BOOST_ASIO_CONST_BUFFER(data.data(),
1373 data.size() * sizeof(Elem) < max_size_in_bytes
1374 ? data.size() * sizeof(Elem) : max_size_in_bytes
1375 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1376 , detail::buffer_debug_check<
1377 typename std::basic_string<Elem, Traits, Allocator>::const_iterator
1378 >(data.begin())
1379 #endif
1380 );
1381 }
1382
1383 #if defined(BOOST_ASIO_HAS_STRING_VIEW) \
1384 || defined(GENERATING_DOCUMENTATION)
1385
1386
1387
1388
1389
1390
1391 template <typename Elem, typename Traits>
1392 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1393 basic_string_view<Elem, Traits> data) noexcept
1394 {
1395 return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
1396 data.size() * sizeof(Elem)
1397 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1398 , detail::buffer_debug_check<
1399 typename basic_string_view<Elem, Traits>::iterator
1400 >(data.begin())
1401 #endif
1402 );
1403 }
1404
1405
1406
1407
1408
1409
1410
1411
1412 template <typename Elem, typename Traits>
1413 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1414 basic_string_view<Elem, Traits> data,
1415 std::size_t max_size_in_bytes) noexcept
1416 {
1417 return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
1418 data.size() * sizeof(Elem) < max_size_in_bytes
1419 ? data.size() * sizeof(Elem) : max_size_in_bytes
1420 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
1421 , detail::buffer_debug_check<
1422 typename basic_string_view<Elem, Traits>::iterator
1423 >(data.begin())
1424 #endif
1425 );
1426 }
1427
1428 #endif
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438 template <typename T>
1439 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1440 T& data,
1441 constraint_t<
1442 is_contiguous_iterator<typename T::iterator>::value,
1443 defaulted_constraint
1444 > = defaulted_constraint(),
1445 constraint_t<
1446 !is_convertible<T, const_buffer>::value,
1447 defaulted_constraint
1448 > = defaulted_constraint(),
1449 constraint_t<
1450 !is_convertible<T, mutable_buffer>::value,
1451 defaulted_constraint
1452 > = defaulted_constraint(),
1453 constraint_t<
1454 !is_const<
1455 remove_reference_t<
1456 typename std::iterator_traits<typename T::iterator>::reference
1457 >
1458 >::value,
1459 defaulted_constraint
1460 > = defaulted_constraint()) noexcept
1461 {
1462 return BOOST_ASIO_MUTABLE_BUFFER(
1463 data.size() ? detail::to_address(data.begin()) : 0,
1464 data.size() * sizeof(typename T::value_type));
1465 }
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476 template <typename T>
1477 BOOST_ASIO_NODISCARD inline BOOST_ASIO_MUTABLE_BUFFER buffer(
1478 T& data, std::size_t max_size_in_bytes,
1479 constraint_t<
1480 is_contiguous_iterator<typename T::iterator>::value,
1481 defaulted_constraint
1482 > = defaulted_constraint(),
1483 constraint_t<
1484 !is_convertible<T, const_buffer>::value,
1485 defaulted_constraint
1486 > = defaulted_constraint(),
1487 constraint_t<
1488 !is_convertible<T, mutable_buffer>::value,
1489 defaulted_constraint
1490 > = defaulted_constraint(),
1491 constraint_t<
1492 !is_const<
1493 remove_reference_t<
1494 typename std::iterator_traits<typename T::iterator>::reference
1495 >
1496 >::value,
1497 defaulted_constraint
1498 > = defaulted_constraint()) noexcept
1499 {
1500 return BOOST_ASIO_MUTABLE_BUFFER(
1501 data.size() ? detail::to_address(data.begin()) : 0,
1502 data.size() * sizeof(typename T::value_type) < max_size_in_bytes
1503 ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);
1504 }
1505
1506
1507
1508
1509
1510
1511
1512
1513 template <typename T>
1514 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1515 T& data,
1516 constraint_t<
1517 is_contiguous_iterator<typename T::iterator>::value,
1518 defaulted_constraint
1519 > = defaulted_constraint(),
1520 constraint_t<
1521 !is_convertible<T, const_buffer>::value,
1522 defaulted_constraint
1523 > = defaulted_constraint(),
1524 constraint_t<
1525 !is_convertible<T, mutable_buffer>::value,
1526 defaulted_constraint
1527 > = defaulted_constraint(),
1528 constraint_t<
1529 is_const<
1530 remove_reference_t<
1531 typename std::iterator_traits<typename T::iterator>::reference
1532 >
1533 >::value,
1534 defaulted_constraint
1535 > = defaulted_constraint()) noexcept
1536 {
1537 return BOOST_ASIO_CONST_BUFFER(
1538 data.size() ? detail::to_address(data.begin()) : 0,
1539 data.size() * sizeof(typename T::value_type));
1540 }
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551 template <typename T>
1552 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1553 T& data, std::size_t max_size_in_bytes,
1554 constraint_t<
1555 is_contiguous_iterator<typename T::iterator>::value,
1556 defaulted_constraint
1557 > = defaulted_constraint(),
1558 constraint_t<
1559 !is_convertible<T, const_buffer>::value,
1560 defaulted_constraint
1561 > = defaulted_constraint(),
1562 constraint_t<
1563 !is_convertible<T, mutable_buffer>::value,
1564 defaulted_constraint
1565 > = defaulted_constraint(),
1566 constraint_t<
1567 is_const<
1568 remove_reference_t<
1569 typename std::iterator_traits<typename T::iterator>::reference
1570 >
1571 >::value,
1572 defaulted_constraint
1573 > = defaulted_constraint()) noexcept
1574 {
1575 return BOOST_ASIO_CONST_BUFFER(
1576 data.size() ? detail::to_address(data.begin()) : 0,
1577 data.size() * sizeof(typename T::value_type) < max_size_in_bytes
1578 ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);
1579 }
1580
1581
1582
1583
1584
1585
1586
1587
1588 template <typename T>
1589 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1590 const T& data,
1591 constraint_t<
1592 is_contiguous_iterator<typename T::const_iterator>::value,
1593 defaulted_constraint
1594 > = defaulted_constraint(),
1595 constraint_t<
1596 !is_convertible<T, const_buffer>::value,
1597 defaulted_constraint
1598 > = defaulted_constraint(),
1599 constraint_t<
1600 !is_convertible<T, mutable_buffer>::value,
1601 defaulted_constraint
1602 > = defaulted_constraint()) noexcept
1603 {
1604 return BOOST_ASIO_CONST_BUFFER(
1605 data.size() ? detail::to_address(data.begin()) : 0,
1606 data.size() * sizeof(typename T::value_type));
1607 }
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 template <typename T>
1619 BOOST_ASIO_NODISCARD inline BOOST_ASIO_CONST_BUFFER buffer(
1620 const T& data, std::size_t max_size_in_bytes,
1621 constraint_t<
1622 is_contiguous_iterator<typename T::const_iterator>::value,
1623 defaulted_constraint
1624 > = defaulted_constraint(),
1625 constraint_t<
1626 !is_convertible<T, const_buffer>::value,
1627 defaulted_constraint
1628 > = defaulted_constraint(),
1629 constraint_t<
1630 !is_convertible<T, mutable_buffer>::value,
1631 defaulted_constraint
1632 > = defaulted_constraint()) noexcept
1633 {
1634 return BOOST_ASIO_CONST_BUFFER(
1635 data.size() ? detail::to_address(data.begin()) : 0,
1636 data.size() * sizeof(typename T::value_type) < max_size_in_bytes
1637 ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);
1638 }
1639
1640
1641
1642
1643
1644
1645
1646 template <typename Elem, typename Traits, typename Allocator>
1647 class dynamic_string_buffer
1648 {
1649 public:
1650
1651
1652 typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
1653
1654
1655
1656 typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670 explicit dynamic_string_buffer(std::basic_string<Elem, Traits, Allocator>& s,
1671 std::size_t maximum_size =
1672 (std::numeric_limits<std::size_t>::max)()) noexcept
1673 : string_(s),
1674 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1675 size_((std::numeric_limits<std::size_t>::max)()),
1676 #endif
1677 max_size_(maximum_size)
1678 {
1679 }
1680
1681
1682 dynamic_string_buffer(const dynamic_string_buffer& other) noexcept
1683 : string_(other.string_),
1684 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1685 size_(other.size_),
1686 #endif
1687 max_size_(other.max_size_)
1688 {
1689 }
1690
1691
1692 dynamic_string_buffer(dynamic_string_buffer&& other) noexcept
1693 : string_(other.string_),
1694 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1695 size_(other.size_),
1696 #endif
1697 max_size_(other.max_size_)
1698 {
1699 }
1700
1701
1702
1703
1704
1705
1706
1707
1708 std::size_t size() const noexcept
1709 {
1710 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1711 if (size_ != (std::numeric_limits<std::size_t>::max)())
1712 return size_;
1713 #endif
1714 return (std::min)(string_.size(), max_size());
1715 }
1716
1717
1718
1719
1720
1721 std::size_t max_size() const noexcept
1722 {
1723 return max_size_;
1724 }
1725
1726
1727
1728
1729
1730
1731
1732 std::size_t capacity() const noexcept
1733 {
1734 return (std::min)(string_.capacity(), max_size());
1735 }
1736
1737 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748 const_buffers_type data() const noexcept
1749 {
1750 return const_buffers_type(boost::asio::buffer(string_, size_));
1751 }
1752 #endif
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769 mutable_buffers_type data(std::size_t pos, std::size_t n) noexcept
1770 {
1771 return mutable_buffers_type(boost::asio::buffer(
1772 boost::asio::buffer(string_, max_size_) + pos, n));
1773 }
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787 const_buffers_type data(std::size_t pos,
1788 std::size_t n) const noexcept
1789 {
1790 return const_buffers_type(boost::asio::buffer(
1791 boost::asio::buffer(string_, max_size_) + pos, n));
1792 }
1793
1794 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811 mutable_buffers_type prepare(std::size_t n)
1812 {
1813 if (size() > max_size() || max_size() - size() < n)
1814 {
1815 std::length_error ex("dynamic_string_buffer too long");
1816 boost::asio::detail::throw_exception(ex);
1817 }
1818
1819 if (size_ == (std::numeric_limits<std::size_t>::max)())
1820 size_ = string_.size();
1821
1822 string_.resize(size_ + n);
1823
1824 return boost::asio::buffer(boost::asio::buffer(string_) + size_, n);
1825 }
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840 void commit(std::size_t n)
1841 {
1842 size_ += (std::min)(n, string_.size() - size_);
1843 string_.resize(size_);
1844 }
1845 #endif
1846
1847
1848
1849
1850
1851
1852
1853
1854 void grow(std::size_t n)
1855 {
1856 if (size() > max_size() || max_size() - size() < n)
1857 {
1858 std::length_error ex("dynamic_string_buffer too long");
1859 boost::asio::detail::throw_exception(ex);
1860 }
1861
1862 string_.resize(size() + n);
1863 }
1864
1865
1866
1867
1868
1869
1870
1871
1872 void shrink(std::size_t n)
1873 {
1874 string_.resize(n > size() ? 0 : size() - n);
1875 }
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889 void consume(std::size_t n)
1890 {
1891 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1892 if (size_ != (std::numeric_limits<std::size_t>::max)())
1893 {
1894 std::size_t consume_length = (std::min)(n, size_);
1895 string_.erase(0, consume_length);
1896 size_ -= consume_length;
1897 return;
1898 }
1899 #endif
1900 string_.erase(0, n);
1901 }
1902
1903 private:
1904 std::basic_string<Elem, Traits, Allocator>& string_;
1905 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1906 std::size_t size_;
1907 #endif
1908 const std::size_t max_size_;
1909 };
1910
1911
1912
1913
1914
1915 template <typename Elem, typename Allocator>
1916 class dynamic_vector_buffer
1917 {
1918 public:
1919
1920
1921 typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
1922
1923
1924
1925 typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936 explicit dynamic_vector_buffer(std::vector<Elem, Allocator>& v,
1937 std::size_t maximum_size =
1938 (std::numeric_limits<std::size_t>::max)()) noexcept
1939 : vector_(v),
1940 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1941 size_((std::numeric_limits<std::size_t>::max)()),
1942 #endif
1943 max_size_(maximum_size)
1944 {
1945 }
1946
1947
1948 dynamic_vector_buffer(const dynamic_vector_buffer& other) noexcept
1949 : vector_(other.vector_),
1950 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1951 size_(other.size_),
1952 #endif
1953 max_size_(other.max_size_)
1954 {
1955 }
1956
1957
1958 dynamic_vector_buffer(dynamic_vector_buffer&& other) noexcept
1959 : vector_(other.vector_),
1960 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1961 size_(other.size_),
1962 #endif
1963 max_size_(other.max_size_)
1964 {
1965 }
1966
1967
1968
1969
1970
1971
1972
1973
1974 std::size_t size() const noexcept
1975 {
1976 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
1977 if (size_ != (std::numeric_limits<std::size_t>::max)())
1978 return size_;
1979 #endif
1980 return (std::min)(vector_.size(), max_size());
1981 }
1982
1983
1984
1985
1986
1987
1988
1989 std::size_t max_size() const noexcept
1990 {
1991 return max_size_;
1992 }
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002 std::size_t capacity() const noexcept
2003 {
2004 return (std::min)(vector_.capacity(), max_size());
2005 }
2006
2007 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019 const_buffers_type data() const noexcept
2020 {
2021 return const_buffers_type(boost::asio::buffer(vector_, size_));
2022 }
2023 #endif
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040 mutable_buffers_type data(std::size_t pos, std::size_t n) noexcept
2041 {
2042 return mutable_buffers_type(boost::asio::buffer(
2043 boost::asio::buffer(vector_, max_size_) + pos, n));
2044 }
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058 const_buffers_type data(std::size_t pos,
2059 std::size_t n) const noexcept
2060 {
2061 return const_buffers_type(boost::asio::buffer(
2062 boost::asio::buffer(vector_, max_size_) + pos, n));
2063 }
2064
2065 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082 mutable_buffers_type prepare(std::size_t n)
2083 {
2084 if (size () > max_size() || max_size() - size() < n)
2085 {
2086 std::length_error ex("dynamic_vector_buffer too long");
2087 boost::asio::detail::throw_exception(ex);
2088 }
2089
2090 if (size_ == (std::numeric_limits<std::size_t>::max)())
2091 size_ = vector_.size();
2092
2093 vector_.resize(size_ + n);
2094
2095 return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n);
2096 }
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111 void commit(std::size_t n)
2112 {
2113 size_ += (std::min)(n, vector_.size() - size_);
2114 vector_.resize(size_);
2115 }
2116 #endif
2117
2118
2119
2120
2121
2122
2123
2124
2125 void grow(std::size_t n)
2126 {
2127 if (size() > max_size() || max_size() - size() < n)
2128 {
2129 std::length_error ex("dynamic_vector_buffer too long");
2130 boost::asio::detail::throw_exception(ex);
2131 }
2132
2133 vector_.resize(size() + n);
2134 }
2135
2136
2137
2138
2139
2140
2141
2142
2143 void shrink(std::size_t n)
2144 {
2145 vector_.resize(n > size() ? 0 : size() - n);
2146 }
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160 void consume(std::size_t n)
2161 {
2162 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2163 if (size_ != (std::numeric_limits<std::size_t>::max)())
2164 {
2165 std::size_t consume_length = (std::min)(n, size_);
2166 vector_.erase(vector_.begin(), vector_.begin() + consume_length);
2167 size_ -= consume_length;
2168 return;
2169 }
2170 #endif
2171 vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));
2172 }
2173
2174 private:
2175 std::vector<Elem, Allocator>& vector_;
2176 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2177 std::size_t size_;
2178 #endif
2179 const std::size_t max_size_;
2180 };
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193 template <typename Elem, typename Traits, typename Allocator>
2194 BOOST_ASIO_NODISCARD inline
2195 dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
2196 std::basic_string<Elem, Traits, Allocator>& data) noexcept
2197 {
2198 return dynamic_string_buffer<Elem, Traits, Allocator>(data);
2199 }
2200
2201
2202
2203
2204
2205
2206 template <typename Elem, typename Traits, typename Allocator>
2207 BOOST_ASIO_NODISCARD inline
2208 dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
2209 std::basic_string<Elem, Traits, Allocator>& data,
2210 std::size_t max_size) noexcept
2211 {
2212 return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);
2213 }
2214
2215
2216
2217
2218
2219 template <typename Elem, typename Allocator>
2220 BOOST_ASIO_NODISCARD inline
2221 dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
2222 std::vector<Elem, Allocator>& data) noexcept
2223 {
2224 return dynamic_vector_buffer<Elem, Allocator>(data);
2225 }
2226
2227
2228
2229
2230
2231 template <typename Elem, typename Allocator>
2232 BOOST_ASIO_NODISCARD inline
2233 dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
2234 std::vector<Elem, Allocator>& data,
2235 std::size_t max_size) noexcept
2236 {
2237 return dynamic_vector_buffer<Elem, Allocator>(data, max_size);
2238 }
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270 namespace detail {
2271
2272 inline std::size_t buffer_copy_1(const mutable_buffer& target,
2273 const const_buffer& source)
2274 {
2275 using namespace std;
2276 std::size_t target_size = target.size();
2277 std::size_t source_size = source.size();
2278 std::size_t n = target_size < source_size ? target_size : source_size;
2279 if (n > 0)
2280 memcpy(target.data(), source.data(), n);
2281 return n;
2282 }
2283
2284 template <typename TargetIterator, typename SourceIterator>
2285 inline std::size_t buffer_copy(one_buffer, one_buffer,
2286 TargetIterator target_begin, TargetIterator,
2287 SourceIterator source_begin, SourceIterator) noexcept
2288 {
2289 return (buffer_copy_1)(*target_begin, *source_begin);
2290 }
2291
2292 template <typename TargetIterator, typename SourceIterator>
2293 inline std::size_t buffer_copy(one_buffer, one_buffer,
2294 TargetIterator target_begin, TargetIterator,
2295 SourceIterator source_begin, SourceIterator,
2296 std::size_t max_bytes_to_copy) noexcept
2297 {
2298 return (buffer_copy_1)(*target_begin,
2299 boost::asio::buffer(*source_begin, max_bytes_to_copy));
2300 }
2301
2302 template <typename TargetIterator, typename SourceIterator>
2303 std::size_t buffer_copy(one_buffer, multiple_buffers,
2304 TargetIterator target_begin, TargetIterator,
2305 SourceIterator source_begin, SourceIterator source_end,
2306 std::size_t max_bytes_to_copy
2307 = (std::numeric_limits<std::size_t>::max)()) noexcept
2308 {
2309 std::size_t total_bytes_copied = 0;
2310 SourceIterator source_iter = source_begin;
2311
2312 for (mutable_buffer target_buffer(
2313 boost::asio::buffer(*target_begin, max_bytes_to_copy));
2314 target_buffer.size() && source_iter != source_end; ++source_iter)
2315 {
2316 const_buffer source_buffer(*source_iter);
2317 std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
2318 total_bytes_copied += bytes_copied;
2319 target_buffer += bytes_copied;
2320 }
2321
2322 return total_bytes_copied;
2323 }
2324
2325 template <typename TargetIterator, typename SourceIterator>
2326 std::size_t buffer_copy(multiple_buffers, one_buffer,
2327 TargetIterator target_begin, TargetIterator target_end,
2328 SourceIterator source_begin, SourceIterator,
2329 std::size_t max_bytes_to_copy
2330 = (std::numeric_limits<std::size_t>::max)()) noexcept
2331 {
2332 std::size_t total_bytes_copied = 0;
2333 TargetIterator target_iter = target_begin;
2334
2335 for (const_buffer source_buffer(
2336 boost::asio::buffer(*source_begin, max_bytes_to_copy));
2337 source_buffer.size() && target_iter != target_end; ++target_iter)
2338 {
2339 mutable_buffer target_buffer(*target_iter);
2340 std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
2341 total_bytes_copied += bytes_copied;
2342 source_buffer += bytes_copied;
2343 }
2344
2345 return total_bytes_copied;
2346 }
2347
2348 template <typename TargetIterator, typename SourceIterator>
2349 std::size_t buffer_copy(multiple_buffers, multiple_buffers,
2350 TargetIterator target_begin, TargetIterator target_end,
2351 SourceIterator source_begin, SourceIterator source_end) noexcept
2352 {
2353 std::size_t total_bytes_copied = 0;
2354
2355 TargetIterator target_iter = target_begin;
2356 std::size_t target_buffer_offset = 0;
2357
2358 SourceIterator source_iter = source_begin;
2359 std::size_t source_buffer_offset = 0;
2360
2361 while (target_iter != target_end && source_iter != source_end)
2362 {
2363 mutable_buffer target_buffer =
2364 mutable_buffer(*target_iter) + target_buffer_offset;
2365
2366 const_buffer source_buffer =
2367 const_buffer(*source_iter) + source_buffer_offset;
2368
2369 std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
2370 total_bytes_copied += bytes_copied;
2371
2372 if (bytes_copied == target_buffer.size())
2373 {
2374 ++target_iter;
2375 target_buffer_offset = 0;
2376 }
2377 else
2378 target_buffer_offset += bytes_copied;
2379
2380 if (bytes_copied == source_buffer.size())
2381 {
2382 ++source_iter;
2383 source_buffer_offset = 0;
2384 }
2385 else
2386 source_buffer_offset += bytes_copied;
2387 }
2388
2389 return total_bytes_copied;
2390 }
2391
2392 template <typename TargetIterator, typename SourceIterator>
2393 std::size_t buffer_copy(multiple_buffers, multiple_buffers,
2394 TargetIterator target_begin, TargetIterator target_end,
2395 SourceIterator source_begin, SourceIterator source_end,
2396 std::size_t max_bytes_to_copy) noexcept
2397 {
2398 std::size_t total_bytes_copied = 0;
2399
2400 TargetIterator target_iter = target_begin;
2401 std::size_t target_buffer_offset = 0;
2402
2403 SourceIterator source_iter = source_begin;
2404 std::size_t source_buffer_offset = 0;
2405
2406 while (total_bytes_copied != max_bytes_to_copy
2407 && target_iter != target_end && source_iter != source_end)
2408 {
2409 mutable_buffer target_buffer =
2410 mutable_buffer(*target_iter) + target_buffer_offset;
2411
2412 const_buffer source_buffer =
2413 const_buffer(*source_iter) + source_buffer_offset;
2414
2415 std::size_t bytes_copied = (buffer_copy_1)(
2416 target_buffer, boost::asio::buffer(source_buffer,
2417 max_bytes_to_copy - total_bytes_copied));
2418 total_bytes_copied += bytes_copied;
2419
2420 if (bytes_copied == target_buffer.size())
2421 {
2422 ++target_iter;
2423 target_buffer_offset = 0;
2424 }
2425 else
2426 target_buffer_offset += bytes_copied;
2427
2428 if (bytes_copied == source_buffer.size())
2429 {
2430 ++source_iter;
2431 source_buffer_offset = 0;
2432 }
2433 else
2434 source_buffer_offset += bytes_copied;
2435 }
2436
2437 return total_bytes_copied;
2438 }
2439
2440 }
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461 template <typename MutableBufferSequence, typename ConstBufferSequence>
2462 inline std::size_t buffer_copy(const MutableBufferSequence& target,
2463 const ConstBufferSequence& source) noexcept
2464 {
2465 return detail::buffer_copy(
2466 detail::buffer_sequence_cardinality<MutableBufferSequence>(),
2467 detail::buffer_sequence_cardinality<ConstBufferSequence>(),
2468 boost::asio::buffer_sequence_begin(target),
2469 boost::asio::buffer_sequence_end(target),
2470 boost::asio::buffer_sequence_begin(source),
2471 boost::asio::buffer_sequence_end(source));
2472 }
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498 template <typename MutableBufferSequence, typename ConstBufferSequence>
2499 inline std::size_t buffer_copy(const MutableBufferSequence& target,
2500 const ConstBufferSequence& source,
2501 std::size_t max_bytes_to_copy) noexcept
2502 {
2503 return detail::buffer_copy(
2504 detail::buffer_sequence_cardinality<MutableBufferSequence>(),
2505 detail::buffer_sequence_cardinality<ConstBufferSequence>(),
2506 boost::asio::buffer_sequence_begin(target),
2507 boost::asio::buffer_sequence_end(target),
2508 boost::asio::buffer_sequence_begin(source),
2509 boost::asio::buffer_sequence_end(source), max_bytes_to_copy);
2510 }
2511
2512
2513
2514 }
2515 }
2516
2517 #include <boost/asio/detail/pop_options.hpp>
2518 #include <boost/asio/detail/is_buffer_sequence.hpp>
2519 #include <boost/asio/detail/push_options.hpp>
2520
2521 namespace boost {
2522 namespace asio {
2523
2524
2525
2526 template <typename T>
2527 struct is_mutable_buffer_sequence
2528 #if defined(GENERATING_DOCUMENTATION)
2529 : integral_constant<bool, automatically_determined>
2530 #else
2531 : boost::asio::detail::is_buffer_sequence<T, mutable_buffer>
2532 #endif
2533 {
2534 };
2535
2536
2537
2538 template <typename T>
2539 struct is_const_buffer_sequence
2540 #if defined(GENERATING_DOCUMENTATION)
2541 : integral_constant<bool, automatically_determined>
2542 #else
2543 : boost::asio::detail::is_buffer_sequence<T, const_buffer>
2544 #endif
2545 {
2546 };
2547
2548 #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2549
2550
2551 template <typename T>
2552 struct is_dynamic_buffer_v1
2553 #if defined(GENERATING_DOCUMENTATION)
2554 : integral_constant<bool, automatically_determined>
2555 #else
2556 : boost::asio::detail::is_dynamic_buffer_v1<T>
2557 #endif
2558 {
2559 };
2560 #endif
2561
2562
2563
2564 template <typename T>
2565 struct is_dynamic_buffer_v2
2566 #if defined(GENERATING_DOCUMENTATION)
2567 : integral_constant<bool, automatically_determined>
2568 #else
2569 : boost::asio::detail::is_dynamic_buffer_v2<T>
2570 #endif
2571 {
2572 };
2573
2574
2575
2576
2577
2578
2579
2580
2581 template <typename T>
2582 struct is_dynamic_buffer
2583 #if defined(GENERATING_DOCUMENTATION)
2584 : integral_constant<bool, automatically_determined>
2585 #elif defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
2586 : boost::asio::is_dynamic_buffer_v2<T>
2587 #else
2588 : boost::asio::is_dynamic_buffer_v1<T>
2589 #endif
2590 {
2591 };
2592
2593 namespace buffer_literals {
2594 namespace detail {
2595
2596 template <char... Chars>
2597 struct chars {};
2598
2599 template <unsigned char... Bytes>
2600 struct bytes {};
2601
2602
2603
2604 template <typename Bytes, char... Chars>
2605 struct bin_literal;
2606
2607 template <unsigned char... Bytes>
2608 struct bin_literal<bytes<Bytes...>>
2609 {
2610 static const std::size_t size = sizeof...(Bytes);
2611 static const unsigned char data[sizeof...(Bytes)];
2612 };
2613
2614 template <unsigned char... Bytes>
2615 const unsigned char bin_literal<bytes<Bytes...>>::data[sizeof...(Bytes)]
2616 = { Bytes... };
2617
2618 template <unsigned char... Bytes, char Bit7, char Bit6, char Bit5,
2619 char Bit4, char Bit3, char Bit2, char Bit1, char Bit0, char... Chars>
2620 struct bin_literal<bytes<Bytes...>, Bit7, Bit6,
2621 Bit5, Bit4, Bit3, Bit2, Bit1, Bit0, Chars...> :
2622 bin_literal<
2623 bytes<Bytes...,
2624 static_cast<unsigned char>(
2625 (Bit7 == '1' ? 0x80 : 0) |
2626 (Bit6 == '1' ? 0x40 : 0) |
2627 (Bit5 == '1' ? 0x20 : 0) |
2628 (Bit4 == '1' ? 0x10 : 0) |
2629 (Bit3 == '1' ? 0x08 : 0) |
2630 (Bit2 == '1' ? 0x04 : 0) |
2631 (Bit1 == '1' ? 0x02 : 0) |
2632 (Bit0 == '1' ? 0x01 : 0))
2633 >, Chars...> {};
2634
2635 template <unsigned char... Bytes, char... Chars>
2636 struct bin_literal<bytes<Bytes...>, Chars...>
2637 {
2638 static_assert(sizeof...(Chars) == 0,
2639 "number of digits in a binary buffer literal must be a multiple of 8");
2640
2641 static const std::size_t size = 0;
2642 static const unsigned char data[1];
2643 };
2644
2645 template <unsigned char... Bytes, char... Chars>
2646 const unsigned char bin_literal<bytes<Bytes...>, Chars...>::data[1] = {};
2647
2648
2649
2650 template <typename Bytes, char... Chars>
2651 struct hex_literal;
2652
2653 template <unsigned char... Bytes>
2654 struct hex_literal<bytes<Bytes...>>
2655 {
2656 static const std::size_t size = sizeof...(Bytes);
2657 static const unsigned char data[sizeof...(Bytes)];
2658 };
2659
2660 template <unsigned char... Bytes>
2661 const unsigned char hex_literal<bytes<Bytes...>>::data[sizeof...(Bytes)]
2662 = { Bytes... };
2663
2664 template <unsigned char... Bytes, char Hi, char Lo, char... Chars>
2665 struct hex_literal<bytes<Bytes...>, Hi, Lo, Chars...> :
2666 hex_literal<
2667 bytes<Bytes...,
2668 static_cast<unsigned char>(
2669 Lo >= 'A' && Lo <= 'F' ? Lo - 'A' + 10 :
2670 (Lo >= 'a' && Lo <= 'f' ? Lo - 'a' + 10 : Lo - '0')) |
2671 ((static_cast<unsigned char>(
2672 Hi >= 'A' && Hi <= 'F' ? Hi - 'A' + 10 :
2673 (Hi >= 'a' && Hi <= 'f' ? Hi - 'a' + 10 : Hi - '0'))) << 4)
2674 >, Chars...> {};
2675
2676 template <unsigned char... Bytes, char Char>
2677 struct hex_literal<bytes<Bytes...>, Char>
2678 {
2679 static_assert(!Char,
2680 "a hexadecimal buffer literal must have an even number of digits");
2681
2682 static const std::size_t size = 0;
2683 static const unsigned char data[1];
2684 };
2685
2686 template <unsigned char... Bytes, char Char>
2687 const unsigned char hex_literal<bytes<Bytes...>, Char>::data[1] = {};
2688
2689
2690
2691
2692 template <template <typename, char...> class Literal,
2693 typename Clean, char... Raw>
2694 struct remove_separators;
2695
2696 template <template <typename, char...> class Literal,
2697 char... Clean, char... Raw>
2698 struct remove_separators<Literal, chars<Clean...>, '\'', Raw...> :
2699 remove_separators<Literal, chars<Clean...>, Raw...> {};
2700
2701 template <template <typename, char...> class Literal,
2702 char... Clean, char C, char... Raw>
2703 struct remove_separators<Literal, chars<Clean...>, C, Raw...> :
2704 remove_separators<Literal, chars<Clean..., C>, Raw...> {};
2705
2706 template <template <typename, char...> class Literal, char... Clean>
2707 struct remove_separators<Literal, chars<Clean...>> :
2708 Literal<bytes<>, Clean...> {};
2709
2710
2711
2712 template <char... Chars>
2713 struct literal;
2714
2715 template <char... Chars>
2716 struct literal<'0', 'b', Chars...> :
2717 remove_separators<bin_literal, chars<>, Chars...>{};
2718
2719 template <char... Chars>
2720 struct literal<'0', 'B', Chars...> :
2721 remove_separators<bin_literal, chars<>, Chars...>{};
2722
2723 template <char... Chars>
2724 struct literal<'0', 'x', Chars...> :
2725 remove_separators<hex_literal, chars<>, Chars...>{};
2726
2727 template <char... Chars>
2728 struct literal<'0', 'X', Chars...> :
2729 remove_separators<hex_literal, chars<>, Chars...>{};
2730
2731 }
2732
2733
2734 inline BOOST_ASIO_CONST_BUFFER operator ""_buf(const char* data, std::size_t n)
2735 {
2736 return BOOST_ASIO_CONST_BUFFER(data, n);
2737 }
2738
2739
2740
2741 template <char... Chars>
2742 inline BOOST_ASIO_CONST_BUFFER operator ""_buf()
2743 {
2744 return BOOST_ASIO_CONST_BUFFER(
2745 +detail::literal<Chars...>::data,
2746 detail::literal<Chars...>::size);
2747 }
2748
2749 }
2750 }
2751 }
2752
2753 #include <boost/asio/detail/pop_options.hpp>
2754
2755 #endif