1 #ifndef IMAGE_IO_BASE_BYTE_DATA_H_ // NOLINT 2 #define IMAGE_IO_BASE_BYTE_DATA_H_ // NOLINT 3 4 #include <cctype> 5 #include <string> 6 7 #include "image_io/base/types.h" 8 9 namespace photos_editing_formats { 10 namespace image_io { 11 12 /// A string representation of byte data destined to be added to a ByteBuffer, 13 /// and thence defining a portion of a DataSegment. 14 class ByteData { 15 public: 16 /// The type of data represented in the string value. 17 enum Type { 18 /// The string value contains hex digits. 19 kHex, 20 21 /// The string value contains ascii text. When adding the string to 22 /// a ByteBuffer, do not add the terminating null character. 23 kAscii, 24 25 /// The string value contains ascii text. When adding the string to 26 /// a ByteBuffer, add the terminating null character as well. 27 kAscii0 28 }; 29 30 /// @param type The type of byte data 31 /// @param value The string value of the byte data. ByteData(Type type,const std::string & value)32 ByteData(Type type, const std::string& value) : type_(type), value_(value) {} 33 34 /// @return The type of byte data. GetType()35 Type GetType() const { return type_; } 36 37 /// @return The string value of the byte data. GetValue()38 const std::string& GetValue() const { return value_; } 39 40 /// @return Whether the byte data string value has a valid length and is made 41 /// up of a valid set of characters. IsValid()42 bool IsValid() const { return IsValidLength() && HasValidCharacters(); } 43 44 /// @return Whether the byte data string value has a valid length. The kAscii 45 /// and kAscii0 type values have no restrictions, but the kHex type values 46 /// must have an even number of characters (zero length is ok). IsValidLength()47 bool IsValidLength() const { 48 return type_ != kHex || ((value_.length() % 2) == 0u); 49 } 50 51 /// @return Whether the byte data string value is made up of valid characters. 52 /// The kAscii and kAscii0 type values have no restrictions, but the kHex 53 /// type values can only have these characters: [0-9][a-f][A-F] HasValidCharacters()54 bool HasValidCharacters() const { 55 if (type_ != kHex) { 56 return true; 57 } 58 for (const auto& chr : value_) { 59 if (!isxdigit(chr)) { 60 return false; 61 } 62 } 63 return true; 64 } 65 66 /// @return The number of bytes this data requires when converted to Bytes, 67 /// or 0 if the byte data is invalid. GetByteCount()68 size_t GetByteCount() const { 69 if (!IsValid()) { 70 return 0; 71 } else if (type_ == kHex) { 72 return value_.length() / 2; 73 } else if (type_ == kAscii) { 74 return value_.length(); 75 } else { 76 return value_.length() + 1; 77 } 78 } 79 80 /// @param hex_digit The hex character to convert to its decimal equivalent. 81 /// @return The decimal equivalent of the hex_digit, or -1 if the character is 82 /// not a valid hex digit. Hex2Decimal(char hex_digit)83 static int Hex2Decimal(char hex_digit) { 84 if (hex_digit >= '0' && hex_digit <= '9') { 85 return static_cast<int>(hex_digit - '0'); 86 } else if (hex_digit >= 'a' && hex_digit <= 'f') { 87 return static_cast<int>(hex_digit - 'a' + 10); 88 } else if (hex_digit >= 'A' && hex_digit <= 'F') { 89 return static_cast<int>(hex_digit - 'A' + 10); 90 } else { 91 return -1; 92 } 93 } 94 95 /// @param hi_char The hi-order nibble of the byte. 96 /// @param hi_char The lo-order nibble of the byte. 97 /// @param value The pointer to the Byte to receive the value. 98 /// @return Whether the conversion was successful. Hex2Byte(char hi_char,char lo_char,Byte * value)99 static bool Hex2Byte(char hi_char, char lo_char, Byte* value) { 100 int hi = Hex2Decimal(hi_char); 101 int lo = Hex2Decimal(lo_char); 102 if (hi < 0 || lo < 0 || value == nullptr) { 103 return false; 104 } 105 *value = ((hi << 4) | lo); 106 return true; 107 } 108 109 /// @param value The byte value to convert to a two digit hex string. 110 /// @return The hex string equivalent of the value. Byte2Hex(Byte value)111 static std::string Byte2Hex(Byte value) { 112 const char kHexChars[] = "0123456789ABCDEF"; 113 std::string str(2, ' '); 114 str[0] = kHexChars[(value >> 4) & 0xF]; 115 str[1] = kHexChars[value & 0xF]; 116 return str; 117 } 118 119 /// @param value The size_t value to convert to an eight digit hex string. 120 /// @return The big endian hex string equivalent of the value. Size2BigEndianHex(size_t value)121 static std::string Size2BigEndianHex(size_t value) { 122 std::string hex_string = Byte2Hex((value >> 24) & 0xFF); 123 hex_string += Byte2Hex((value >> 16) & 0xFF); 124 hex_string += Byte2Hex((value >> 8) & 0xFF); 125 hex_string += Byte2Hex(value & 0xFF); 126 return hex_string; 127 } 128 129 private: 130 Type type_; 131 std::string value_; 132 }; 133 134 } // namespace image_io 135 } // namespace photos_editing_formats 136 137 #endif // IMAGE_IO_BASE_BYTE_DATA_H_ // NOLINT 138