1 /* 2 * Copyright 2019 Google 3 * SPDX-License-Identifier: MIT 4 */ 5 6 #pragma once 7 8 #include <inttypes.h> 9 #include <sys/types.h> 10 11 #include <string> 12 13 namespace gfxstream { 14 namespace aemu { 15 16 // Abstract interface to byte streams of all kind. 17 // This is mainly used to implement disk serialization. 18 class Stream { 19 public: 20 // Default constructor. 21 Stream() = default; 22 23 // Destructor. 24 virtual ~Stream() = default; 25 26 // Read up to |size| bytes and copy them to |buffer|. Return the number 27 // of bytes that were actually transferred, or -errno value on error. 28 virtual ssize_t read(void* buffer, size_t size) = 0; 29 30 // Write up to |size| bytes from |buffer| into the stream. Return the 31 // number of bytes that were actually transferred, or -errno value on 32 // error. 33 virtual ssize_t write(const void* buffer, size_t size) = 0; 34 getProtobuf()35 virtual void* getProtobuf() { return nullptr; } 36 37 // Write a single byte |value| into the stream. Ignore errors. 38 void putByte(uint8_t value); 39 40 // Write a 16-bit |value| as big-endian into the stream. Ignore errors. 41 void putBe16(uint16_t value); 42 43 // Write a 32-bit |value| as big-endian into the stream. Ignore errors. 44 void putBe32(uint32_t value); 45 46 // Write a 64-bit |value| as big-endian into the stream. Ignore errors. 47 void putBe64(uint64_t value); 48 49 // Read a single byte from the stream. Return 0 on error. 50 uint8_t getByte(); 51 52 // Read a single big-endian 16-bit value from the stream. 53 // Return 0 on error. 54 uint16_t getBe16(); 55 56 // Read a single big-endian 32-bit value from the stream. 57 // Return 0 on error. 58 uint32_t getBe32(); 59 60 // Read a single big-endian 64-bit value from the stream. 61 // Return 0 on error. 62 uint64_t getBe64(); 63 64 // Write a 32-bit float |value| to the stream. 65 void putFloat(float value); 66 67 // Read a single 32-bit float value from the stream. 68 float getFloat(); 69 70 // Write a 0-terminated C string |str| into the stream. Ignore error. 71 void putString(const char* str); 72 void putString(const std::string& str); 73 74 // Write a string |str| of |strlen| bytes into the stream. 75 // Ignore errors. 76 void putString(const char* str, size_t strlen); 77 78 // Read a string from the stream. Return a new string instance, 79 // which will be empty on error. Note that this can only be used 80 // to read strings that were written with putString(). 81 std::string getString(); 82 83 // Put/gen an integer number into the stream, making it use as little space 84 // there as possible. 85 // It uses a simple byte-by-byte encoding scheme, putting 7 bits of the 86 // number with the 8th bit set when there's more data to read, until the 87 // whole number is read. 88 // The compression is efficient if the number range is small, but it starts 89 // wasting space when values approach 14 bits for int16 (16K), 28 bits for 90 // int32 (268M) or 56 bits for int64 (still a lot). 91 void putPackedNum(uint64_t num); 92 uint64_t getPackedNum(); 93 94 // Same thing, but encode negative numbers efficiently as well (single sign 95 // bit + packed unsigned representation) 96 void putPackedSignedNum(int64_t num); 97 int64_t getPackedSignedNum(); 98 99 // Static big-endian conversions 100 static void toByte(uint8_t*); 101 static void toBe16(uint8_t*); 102 static void toBe32(uint8_t*); 103 static void toBe64(uint8_t*); 104 static void fromByte(uint8_t*); 105 static void fromBe16(uint8_t*); 106 static void fromBe32(uint8_t*); 107 static void fromBe64(uint8_t*); 108 }; 109 110 void saveStringArray(Stream* stream, const char* const* strings, uint32_t count); 111 112 } // namespace aemu 113 } // namespace gfxstream 114