• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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