File indexing completed on 2024-05-19 05:56:08
0001 /* 0002 This file is part of the Okteta Core library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2004, 2011 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "hexadecimalbytecodec.hpp" 0010 0011 // Qt 0012 #include <QString> 0013 0014 namespace Okteta { 0015 0016 static constexpr QChar upperCaseDigits[16] = 0017 { // '0', '1', '2', '3', 0018 QChar(0x0030), QChar(0x0031), QChar(0x0032), QChar(0x0033), 0019 // '4', '5', '6', '7', 0020 QChar(0x0034), QChar(0x0035), QChar(0x0036), QChar(0x0037), 0021 // '8', '9', 'A', 'B', 0022 QChar(0x0038), QChar(0x0039), QChar(0x0041), QChar(0x0042), 0023 // 'C', 'D', 'E', 'F' 0024 QChar(0x0043), QChar(0x0044), QChar(0x0045), QChar(0x0046), 0025 }; 0026 static constexpr QChar lowerCaseDigits[16] = 0027 { // '0', '1', '2', '3', 0028 QChar(0x0030), QChar(0x0031), QChar(0x0032), QChar(0x0033), 0029 // '4', '5', '6', '7', 0030 QChar(0x0034), QChar(0x0035), QChar(0x0036), QChar(0x0037), 0031 // '8', '9', 'a', 'b', 0032 QChar(0x0038), QChar(0x0039), QChar(0x0061), QChar(0x0062), 0033 // 'c', 'd', 'e', 'f' 0034 QChar(0x0063), QChar(0x0064), QChar(0x0065), QChar(0x0066), 0035 }; 0036 static constexpr Byte hexadecimalDigitsFilledLimit = 16; 0037 0038 HexadecimalByteCodec::HexadecimalByteCodec(bool useLowerCaseDigits) 0039 : mDigits(useLowerCaseDigits ? lowerCaseDigits : upperCaseDigits) 0040 { 0041 } 0042 0043 bool HexadecimalByteCodec::setLowerCaseDigits(bool useLowerCaseDigits) 0044 { 0045 const QChar* const digits = useLowerCaseDigits ? lowerCaseDigits : upperCaseDigits; 0046 0047 if (digits == mDigits) { 0048 return false; 0049 } 0050 0051 mDigits = digits; 0052 return true; 0053 } 0054 0055 bool HexadecimalByteCodec::isLowerCaseDigits() const { return mDigits == lowerCaseDigits; } 0056 0057 unsigned int HexadecimalByteCodec::encodingWidth() const { return 2; } 0058 Byte HexadecimalByteCodec::digitsFilledLimit() const { return hexadecimalDigitsFilledLimit; } 0059 0060 void HexadecimalByteCodec::encode(QString* digits, unsigned int pos, Byte byte) const 0061 { 0062 const int minSizeNeeded = pos + 2; 0063 if (digits->size() < minSizeNeeded) { 0064 digits->resize(minSizeNeeded); 0065 } 0066 0067 (*digits)[pos++] = mDigits[byte >> 4]; 0068 (*digits)[pos] = mDigits[byte & 0x0F]; 0069 } 0070 0071 void HexadecimalByteCodec::encodeShort(QString* digits, unsigned int pos, Byte byte) const 0072 { 0073 const int encodingLength = (byte > 0xF) ? 2 : 1; 0074 const int minSizeNeeded = pos + encodingLength; 0075 if (digits->size() < minSizeNeeded) { 0076 digits->resize(minSizeNeeded); 0077 } 0078 0079 unsigned char digitValue = byte >> 4; 0080 0081 if (digitValue > 0) { 0082 (*digits)[pos++] = mDigits[digitValue]; 0083 } 0084 (*digits)[pos] = mDigits[byte & 0x0F]; 0085 } 0086 0087 static inline constexpr bool isValidBigDigit(unsigned char digit) 0088 { 0089 return ('A' <= digit && digit <= 'F'); 0090 } 0091 0092 static inline constexpr bool isValidSmallDigit(unsigned char digit) 0093 { 0094 return ('a' <= digit && digit <= 'f'); 0095 } 0096 0097 static inline constexpr bool isValidDecimalDigit(unsigned char digit) 0098 { 0099 return ('0' <= digit && digit <= '9'); 0100 } 0101 0102 bool HexadecimalByteCodec::isValidDigit(unsigned char digit) const 0103 { 0104 return isValidDecimalDigit(digit) || isValidBigDigit(digit) || isValidSmallDigit(digit); 0105 } 0106 0107 bool HexadecimalByteCodec::turnToValue(unsigned char* digit) const 0108 { 0109 if (isValidDecimalDigit(*digit)) { 0110 *digit -= '0'; 0111 } else if (isValidBigDigit(*digit)) { 0112 *digit -= 'A' - 10; 0113 } else if (isValidSmallDigit(*digit)) { 0114 *digit -= 'a' - 10; 0115 } else { 0116 return false; 0117 } 0118 0119 return true; 0120 } 0121 0122 bool HexadecimalByteCodec::appendDigit(Byte* byte, unsigned char digit) const 0123 { 0124 if (turnToValue(&digit)) { 0125 Byte _byte = *byte; 0126 if (_byte < hexadecimalDigitsFilledLimit) { 0127 _byte <<= 4; 0128 _byte += digit; 0129 *byte = _byte; 0130 return true; 0131 } 0132 } 0133 return false; 0134 } 0135 0136 void HexadecimalByteCodec::removeLastDigit(Byte* byte) const 0137 { 0138 *byte >>= 4; 0139 } 0140 0141 }