File indexing completed on 2024-05-05 17:57:58
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', '4', '5', '6', '7' ,'8', '9', 0018 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0019 // 'A', 'B', 'C', 'D', 'E', 'F' 0020 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046 0021 }; 0022 static constexpr QChar lowerCaseDigits[16] = 0023 { // '0', '1', '2', '3', '4', '5', '6', '7' ,'8', '9', 0024 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0025 // 'a', 'b', 'c', 'd', 'e', 'f' 0026 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066 0027 }; 0028 static constexpr Byte hexadecimalDigitsFilledLimit = 16; 0029 0030 HexadecimalByteCodec::HexadecimalByteCodec(bool useLowerCaseDigits) 0031 : mDigits(useLowerCaseDigits ? lowerCaseDigits : upperCaseDigits) 0032 { 0033 } 0034 0035 bool HexadecimalByteCodec::setLowerCaseDigits(bool useLowerCaseDigits) 0036 { 0037 const QChar* const digits = useLowerCaseDigits ? lowerCaseDigits : upperCaseDigits; 0038 0039 if (digits == mDigits) { 0040 return false; 0041 } 0042 0043 mDigits = digits; 0044 return true; 0045 } 0046 0047 bool HexadecimalByteCodec::isLowerCaseDigits() const { return mDigits == lowerCaseDigits; } 0048 0049 unsigned int HexadecimalByteCodec::encodingWidth() const { return 2; } 0050 Byte HexadecimalByteCodec::digitsFilledLimit() const { return hexadecimalDigitsFilledLimit; } 0051 0052 void HexadecimalByteCodec::encode(QString* digits, unsigned int pos, Byte byte) const 0053 { 0054 const int minSizeNeeded = pos + 2; 0055 if (digits->size() < minSizeNeeded) { 0056 digits->resize(minSizeNeeded); 0057 } 0058 0059 (*digits)[pos++] = mDigits[byte >> 4]; 0060 (*digits)[pos] = mDigits[byte & 0x0F]; 0061 } 0062 0063 void HexadecimalByteCodec::encodeShort(QString* digits, unsigned int pos, Byte byte) const 0064 { 0065 const int encodingLength = (byte > 0xF) ? 2 : 1; 0066 const int minSizeNeeded = pos + encodingLength; 0067 if (digits->size() < minSizeNeeded) { 0068 digits->resize(minSizeNeeded); 0069 } 0070 0071 unsigned char digitValue = byte >> 4; 0072 0073 if (digitValue > 0) { 0074 (*digits)[pos++] = mDigits[digitValue]; 0075 } 0076 (*digits)[pos] = mDigits[byte & 0x0F]; 0077 } 0078 0079 static inline constexpr bool isValidBigDigit(unsigned char digit) 0080 { 0081 return ('A' <= digit && digit <= 'F'); 0082 } 0083 0084 static inline constexpr bool isValidSmallDigit(unsigned char digit) 0085 { 0086 return ('a' <= digit && digit <= 'f'); 0087 } 0088 0089 static inline constexpr bool isValidDecimalDigit(unsigned char digit) 0090 { 0091 return ('0' <= digit && digit <= '9'); 0092 } 0093 0094 bool HexadecimalByteCodec::isValidDigit(unsigned char digit) const 0095 { 0096 return isValidDecimalDigit(digit) || isValidBigDigit(digit) || isValidSmallDigit(digit); 0097 } 0098 0099 bool HexadecimalByteCodec::turnToValue(unsigned char* digit) const 0100 { 0101 if (isValidDecimalDigit(*digit)) { 0102 *digit -= '0'; 0103 } else if (isValidBigDigit(*digit)) { 0104 *digit -= 'A' - 10; 0105 } else if (isValidSmallDigit(*digit)) { 0106 *digit -= 'a' - 10; 0107 } else { 0108 return false; 0109 } 0110 0111 return true; 0112 } 0113 0114 bool HexadecimalByteCodec::appendDigit(Byte* byte, unsigned char digit) const 0115 { 0116 if (turnToValue(&digit)) { 0117 Byte _byte = *byte; 0118 if (_byte < hexadecimalDigitsFilledLimit) { 0119 _byte <<= 4; 0120 _byte += digit; 0121 *byte = _byte; 0122 return true; 0123 } 0124 } 0125 return false; 0126 } 0127 0128 void HexadecimalByteCodec::removeLastDigit(Byte* byte) const 0129 { 0130 *byte >>= 4; 0131 } 0132 0133 }