blob: 37d03b002b10bb041d25fff6469bf37df07b2b8a [file] [log] [blame]
David Valleau46c3f412018-11-14 10:25:47 -08001// Copyright 2018 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Fletcher Woodruff6cdda0a2020-04-22 11:14:07 -06005#ifndef SMART_BUFFER_H__
6#define SMART_BUFFER_H__
David Valleau46c3f412018-11-14 10:25:47 -08007
8#include <memory>
9#include <string>
10#include <vector>
11
Qijiang Fan26b68142021-04-01 00:34:39 +090012#include <base/check.h>
David Valleau46c3f412018-11-14 10:25:47 -080013#include <base/logging.h>
14
15// Wrapper class used for packing bytes to be transferred on a network socket.
16class SmartBuffer {
17 public:
18 SmartBuffer() = default;
19
20 // Initialize the buffer with an initial size of |size|.
21 explicit SmartBuffer(size_t size);
22
23 // Initialize the buffer with the same contents as |v|.
24 explicit SmartBuffer(const std::vector<uint8_t>& v);
25
26 // Convert |data| into uint8_t* and add |data_size| bytes to the internal
27 // buffer.
28 template <typename T>
29 void Add(const T* data, size_t data_size);
30
31 // Add the underlying byte representation of |data| to the buffer.
32 template <typename T>
33 void Add(const T& data);
34
35 // Specialized Add method for std::vector so that we can call |v.data()| and
36 // |v.size()| to extract the underlying pointer and size of the data.
37 template <typename T>
38 void Add(const std::vector<T>& v);
39
40 // Specialized Add method for std::string so that we can call |s.c_str()| and
41 // |s.size()| to extract the underlying pointer and size of the data.
42 void Add(const std::string& s);
43
Fletcher Woodruff86deb602020-05-06 16:43:56 -060044 // Specialized Add method for char* that uses strlen.
45 void Add(const char* s);
46
David Valleau46c3f412018-11-14 10:25:47 -080047 // Adds the contents from |buf|.
48 void Add(const SmartBuffer& buf);
49
50 // Add the contents from |buf|, starting from |start|.
51 void Add(const SmartBuffer& buf, size_t start);
52
53 // Add the subsequence of |buf| starting at |start| and of length |len|.
54 void Add(const SmartBuffer& buf, size_t start, size_t len);
55
56 // Erases the element at |index|.
57 void Erase(size_t index);
58
59 // Erases the subsequence of length |len| starting at |start| from |buffer|.
60 void Erase(size_t start, size_t len);
61
62 // Shrink the underlying vector to |size|.
63 void Shrink(size_t size);
64
Fletcher Woodruffe1bf8392020-04-27 15:15:15 -060065 // Find first occurrence of |target| in the buffer and return the index to
66 // where it begins. If |target| does not appear in |message| then returns -1.
67 ssize_t FindFirstOccurrence(const std::string& target,
68 size_t start = 0) const;
69
David Valleau46c3f412018-11-14 10:25:47 -080070 size_t size() const { return buffer_.size(); }
71 const std::vector<uint8_t>& contents() const { return buffer_; }
72 const uint8_t* data() const { return buffer_.data(); }
73
74 private:
75 std::vector<uint8_t> buffer_;
76};
77
78template <typename T>
79void SmartBuffer::Add(const T* data, size_t data_size) {
80 const uint8_t* packed_data = reinterpret_cast<const uint8_t*>(data);
81 buffer_.insert(buffer_.end(), packed_data, packed_data + data_size);
82}
83
84template <typename T>
85void SmartBuffer::Add(const T& data) {
Fletcher Woodruff86deb602020-05-06 16:43:56 -060086 static_assert(!std::is_pointer<T>::value,
87 "cannot use Add(const T&) for pointer types. If you want to "
88 "Add a pointer type, use Add(const T* data, size)");
David Valleau46c3f412018-11-14 10:25:47 -080089 Add(&data, sizeof(data));
90}
91
92template <typename T>
93void SmartBuffer::Add(const std::vector<T>& v) {
94 CHECK(std::is_fundamental<T>::value)
95 << "Given vector does not contain fundamental elements";
96 size_t byte_size = sizeof(T) * v.size();
97 Add(v.data(), byte_size);
98}
99
Fletcher Woodruff6cdda0a2020-04-22 11:14:07 -0600100#endif // SMART_BUFFER_H__