1/*
2 * IXWebSocketSendData.h
3 *
4 * WebSocket (Binary/Text) send data buffer
5 */
6
7#pragma once
8
9#include <string>
10#include <vector>
11#include <iterator>
12
13namespace ix
14{
15 /*
16 * IXWebSocketSendData implements a wrapper for std::string, std:vector<char/uint8_t> and char*.
17 * It removes the necessarity to copy the data or string into a std::string
18 */
19 class IXWebSocketSendData {
20 public:
21
22 template<typename T>
23 struct IXWebSocketSendData_const_iterator
24 //: public std::iterator<std::forward_iterator_tag, T>
25 {
26 typedef IXWebSocketSendData_const_iterator<T> const_iterator;
27
28 using iterator_category = std::forward_iterator_tag;
29 using difference_type = std::ptrdiff_t;
30 using value_type = T;
31 using pointer = value_type*;
32 using reference = const value_type&;
33
34 pointer _ptr;
35 public:
36 IXWebSocketSendData_const_iterator() : _ptr(nullptr) {}
37 IXWebSocketSendData_const_iterator(pointer ptr) : _ptr(ptr) {}
38 ~IXWebSocketSendData_const_iterator() {}
39
40 const_iterator operator++(int) { return const_iterator(_ptr++); }
41 const_iterator& operator++() { ++_ptr; return *this; }
42 reference operator* () const { return *_ptr; }
43 pointer operator->() const { return _ptr; }
44 const_iterator operator+ (const difference_type offset) const { return const_iterator(_ptr + offset); }
45 const_iterator operator- (const difference_type offset) const { return const_iterator(_ptr - offset); }
46 difference_type operator- (const const_iterator& rhs) const { return _ptr - rhs._ptr; }
47 bool operator==(const const_iterator& rhs) const { return _ptr == rhs._ptr; }
48 bool operator!=(const const_iterator& rhs) const { return _ptr != rhs._ptr; }
49 const_iterator& operator+=(const difference_type offset) { _ptr += offset; return *this; }
50 const_iterator& operator-=(const difference_type offset) { _ptr -= offset; return *this; }
51 };
52
53 using const_iterator = IXWebSocketSendData_const_iterator<char>;
54
55 /* The assigned std::string must be kept alive for the lifetime of the input buffer */
56 IXWebSocketSendData(const std::string& str)
57 : _data(str.data())
58 , _size(str.size())
59 {
60 }
61
62 /* The assigned std::vector must be kept alive for the lifetime of the input buffer */
63 IXWebSocketSendData(const std::vector<char>& v)
64 : _data(v.data())
65 , _size(v.size())
66 {
67 }
68
69 /* The assigned std::vector must be kept alive for the lifetime of the input buffer */
70 IXWebSocketSendData(const std::vector<uint8_t>& v)
71 : _data(reinterpret_cast<const char*>(v.data()))
72 , _size(v.size())
73 {
74 }
75
76 /* The assigned memory must be kept alive for the lifetime of the input buffer */
77 IXWebSocketSendData(const char* data, size_t size)
78 : _data(data)
79 , _size(data == nullptr ? 0 : size)
80 {
81 }
82
83 bool empty() const
84 {
85 return _data == nullptr || _size == 0;
86 }
87
88 const char* c_str() const
89 {
90 return _data;
91 }
92
93 const char* data() const
94 {
95 return _data;
96 }
97
98 size_t size() const
99 {
100 return _size;
101 }
102
103 inline const_iterator begin() const
104 {
105 return const_iterator(const_cast<char*>(_data));
106 }
107
108 inline const_iterator end() const
109 {
110 return const_iterator(const_cast<char*>(_data) + _size);
111 }
112
113 inline const_iterator cbegin() const
114 {
115 return begin();
116 }
117
118 inline const_iterator cend() const
119 {
120 return end();
121 }
122
123 private:
124 const char* _data;
125 const size_t _size;
126 };
127
128}