1 // Copyright 2013 The Flutter 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 5 #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_ 6 #define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_ 7 8 // Utility classes for interacting with a buffer of bytes as a stream, for use 9 // in message channel codecs. 10 11 #include <cstdint> 12 #include <cstring> 13 #include <iostream> 14 #include <vector> 15 16 namespace flutter { 17 18 // Wraps an array of bytes with utility methods for treating it as a readable 19 // stream. 20 class ByteBufferStreamReader { 21 public: 22 // Createa a reader reading from |bytes|, which must have a length of |size|. 23 // |bytes| must remain valid for the lifetime of this object. ByteBufferStreamReader(const uint8_t * bytes,size_t size)24 explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size) 25 : bytes_(bytes), size_(size) {} 26 27 // Reads and returns the next byte from the stream. ReadByte()28 uint8_t ReadByte() { 29 if (location_ >= size_) { 30 std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl; 31 return 0; 32 } 33 return bytes_[location_++]; 34 } 35 36 // Reads the next |length| bytes from the stream into |buffer|. The caller 37 // is responsible for ensuring that |buffer| is large enough. ReadBytes(uint8_t * buffer,size_t length)38 void ReadBytes(uint8_t* buffer, size_t length) { 39 if (location_ + length > size_) { 40 std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl; 41 return; 42 } 43 std::memcpy(buffer, &bytes_[location_], length); 44 location_ += length; 45 } 46 47 // Advances the read cursor to the next multiple of |alignment| relative to 48 // the start of the wrapped byte buffer, unless it is already aligned. ReadAlignment(uint8_t alignment)49 void ReadAlignment(uint8_t alignment) { 50 uint8_t mod = location_ % alignment; 51 if (mod) { 52 location_ += alignment - mod; 53 } 54 } 55 56 private: 57 // The buffer to read from. 58 const uint8_t* bytes_; 59 // The total size of the buffer. 60 size_t size_; 61 // The current read location. 62 size_t location_ = 0; 63 }; 64 65 // Wraps an array of bytes with utility methods for treating it as a writable 66 // stream. 67 class ByteBufferStreamWriter { 68 public: 69 // Createa a writter that writes into |buffer|. 70 // |buffer| must remain valid for the lifetime of this object. ByteBufferStreamWriter(std::vector<uint8_t> * buffer)71 explicit ByteBufferStreamWriter(std::vector<uint8_t>* buffer) 72 : bytes_(buffer) { 73 assert(buffer); 74 } 75 76 // Writes |byte| to the wrapped buffer. WriteByte(uint8_t byte)77 void WriteByte(uint8_t byte) { bytes_->push_back(byte); } 78 79 // Writes the next |length| bytes from |bytes| into the wrapped buffer. 80 // The caller is responsible for ensuring that |buffer| is large enough. WriteBytes(const uint8_t * bytes,size_t length)81 void WriteBytes(const uint8_t* bytes, size_t length) { 82 assert(length > 0); 83 bytes_->insert(bytes_->end(), bytes, bytes + length); 84 } 85 86 // Writes 0s until the next multiple of |alignment| relative to 87 // the start of the wrapped byte buffer, unless the write positition is 88 // already aligned. WriteAlignment(uint8_t alignment)89 void WriteAlignment(uint8_t alignment) { 90 uint8_t mod = bytes_->size() % alignment; 91 if (mod) { 92 for (int i = 0; i < alignment - mod; ++i) { 93 WriteByte(0); 94 } 95 } 96 } 97 98 private: 99 // The buffer to write to. 100 std::vector<uint8_t>* bytes_; 101 }; 102 103 } // namespace flutter 104 105 #endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_ 106