123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- #ifndef __mqtt_buffer_ref_h
- #define __mqtt_buffer_ref_h
- #include "mqtt/types.h"
- #include <iostream>
- #include <cstring>
- namespace mqtt {
- template <typename T>
- class buffer_ref
- {
- public:
-
- using value_type = T;
-
- using blob = std::basic_string<value_type>;
-
- using pointer_type = std::shared_ptr<const blob>;
- private:
-
- pointer_type data_;
- public:
-
- buffer_ref() =default;
-
- buffer_ref(const buffer_ref& buf) =default;
-
- buffer_ref(buffer_ref&& buf) =default;
-
- buffer_ref(const blob& b) : data_{std::make_shared<blob>(b)} {}
-
- buffer_ref(blob&& b) : data_{std::make_shared<blob>(std::move(b))} {}
-
- buffer_ref(const pointer_type& p) : data_(p) {}
-
- buffer_ref(pointer_type&& p) : data_(std::move(p)) {}
-
- buffer_ref(const value_type* buf, size_t n) : data_{std::make_shared<blob>(buf,n)} {}
-
- buffer_ref(const char* buf) : buffer_ref(reinterpret_cast<const value_type*>(buf),
- std::strlen(buf)) {
- static_assert(sizeof(char) == sizeof(T), "can only use C arr with char or byte buffers");
- }
-
- buffer_ref& operator=(const buffer_ref& rhs) =default;
-
- buffer_ref& operator=(buffer_ref&& rhs) =default;
-
- buffer_ref& operator=(const blob& b) {
- data_.reset(new blob(b));
- return *this;
- }
-
- buffer_ref& operator=(blob&& b) {
- data_.reset(new blob(std::move(b)));
- return *this;
- }
-
- buffer_ref& operator=(const char* cstr) {
- static_assert(sizeof(char) == sizeof(T), "can only use C arr with char or byte buffers");
- data_.reset(new blob(reinterpret_cast<const value_type*>(cstr), strlen(cstr)));
- return *this;
- }
-
- template <typename OT>
- buffer_ref& operator=(const buffer_ref<OT>& rhs) {
- static_assert(sizeof(OT) == sizeof(T), "Can only assign buffers if values the same size");
- data_.reset(new blob(reinterpret_cast<const value_type*>(rhs.data()), rhs.size()));
- return *this;
- }
-
- void reset() { data_.reset(); }
-
- explicit operator bool() const { return bool(data_); }
-
- bool is_null() const { return !data_; }
-
- bool empty() const { return !data_ || data_->empty(); }
-
- const value_type* data() const { return data_->data(); }
-
- size_t size() const { return data_->size(); }
-
- size_t length() const { return data_->length(); }
-
- const blob& str() const { return *data_; }
-
- const blob& to_string() const { return str(); }
-
- const char* c_str() const { return data_->c_str(); }
-
- const pointer_type& ptr() const { return data_; }
-
- const value_type& operator[](size_t i) const { return (*data_)[i]; }
- };
- template <typename T>
- std::ostream& operator<<(std::ostream& os, const buffer_ref<T>& buf) {
- if (!buf.empty())
- os.write(buf.data(), buf.size());
- return os;
- }
- using string_ref = buffer_ref<char>;
- using binary_ref = buffer_ref<char>;
- }
- #endif
|