#ifndef PLATFORM_BASE_BYTE_ARRAY_H_ #define PLATFORM_BASE_BYTE_ARRAY_H_ #include #include #include #include #include namespace location { namespace nearby { class ByteArray { public: // Create an empty ByteArray ByteArray() = default; template explicit ByteArray(const std::array& data) { SetData(data.data(), data.size()); } ByteArray(const ByteArray&) = default; ByteArray& operator=(const ByteArray&) = default; ByteArray(ByteArray&&) = default; ByteArray& operator=(ByteArray&&) = default; // Moves string out of temporary, allowing for a zero-copy constructions. // This is an optimization for very large strings. explicit ByteArray(std::string&& source) : data_(std::move(source)) {} // Create ByteArray by copy of a std::string. This can't be a string_view, // because it will conflict with std::string&& version of constructor. explicit ByteArray(const std::string& source) { SetData(source.data(), source.size()); } // Create default-initialized ByteArray of a given size. explicit ByteArray(size_t size) { SetData(size); } // Create value-initialized ByteArray of a given size. ByteArray(const char* data, size_t size) { SetData(data, size); } // Assign a new value to this ByteArray, as a copy of data, with a given size. void SetData(const char* data, size_t size) { if (data == nullptr) { size = 0; } data_.assign(data, size); } // Assign a new value of a given size to this ByteArray // (as a repeated char value). void SetData(size_t size, char value = 0) { data_.assign(size, value); } // Returns true, if changes were performed to container, false otherwise. bool CopyAt(size_t offset, const ByteArray& from, size_t source_offset = 0) { if (offset >= size()) return false; if (source_offset >= from.size()) return false; memcpy(data() + offset, from.data() + source_offset, std::min(size() - offset, from.size() - source_offset)); return true; } char* data() { return &data_[0]; } const char* data() const { return data_.data(); } size_t size() const { return data_.size(); } bool Empty() const { return data_.empty(); } friend bool operator==(const ByteArray& lhs, const ByteArray& rhs); friend bool operator!=(const ByteArray& lhs, const ByteArray& rhs); friend bool operator<(const ByteArray& lhs, const ByteArray& rhs); // Returns a copy of internal representation as std::string. explicit operator std::string() const& { return data_; } // Moves string out of temporary ByteArray, allowing for a zero-copy // operation. explicit operator std::string() && { return std::move(data_); } private: std::string data_; }; inline bool operator==(const ByteArray& lhs, const ByteArray& rhs) { return lhs.data_ == rhs.data_; } inline bool operator!=(const ByteArray& lhs, const ByteArray& rhs) { return !(lhs == rhs); } inline bool operator<(const ByteArray& lhs, const ByteArray& rhs) { return lhs.data_ < rhs.data_; } } // namespace nearby } // namespace location #endif // PLATFORM_BASE_BYTE_ARRAY_H_