File indexing completed on 2025-01-05 05:23:34
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2007, 2009 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 "poddata.hpp" 0010 0011 namespace Okteta { 0012 0013 static inline void copyInvertedBytes(Byte* data, const Byte* sourceData, const int length) 0014 { 0015 const int last = length - 1; 0016 for (int i = 0, j = last; i < length; ++i, --j) { 0017 data[i] = sourceData[j]; 0018 } 0019 } 0020 0021 PODData::PODData() = default; 0022 0023 const Byte* PODData::originalData() const { return mCurrentOriginalData; } 0024 const Byte* PODData::byteOrderSetData() const { return mCurrentEndiannessSetData; } 0025 QSysInfo::Endian PODData::byteOrder() const { return mByteOrder; } 0026 int PODData::size() const { return mCurrentSize; } 0027 0028 Byte* PODData::rawData() { return mOriginalAligned64Bit.mBytes; } 0029 0030 void PODData::setByteOrder(QSysInfo::Endian byteOrder) 0031 { 0032 if (mByteOrder == byteOrder) { 0033 return; 0034 } 0035 0036 mByteOrder = byteOrder; 0037 0038 // swap data 0039 if (mCurrentOriginalData) { 0040 copyInvertedBytes(mByteOrderSetAligned64Bit.mBytes, mOriginalAligned64Bit.mBytes, Size); 0041 } else { 0042 mByteOrderSetAligned64Bit = mOriginalAligned64Bit; 0043 } 0044 } 0045 0046 unsigned long PODData::bitValue(int noOfBitsToRead) const 0047 { 0048 constexpr int BitsPerByte = 8; 0049 constexpr unsigned char BitMask[9] = { 0050 0, 1 << 7, 3 << 6, 7 << 5, 15 << 4, 31 << 3, 63 << 2, 127 << 1, 255 0051 }; 0052 0053 unsigned long result = 0; 0054 0055 if (noOfBitsToRead < 1) { 0056 noOfBitsToRead = 1; 0057 } 0058 0059 // TODO: the cursor currently does not go into the byte 0060 int noOfUsedBits = 0;// 7 - state.cell; 0061 0062 const bool isReverse = (mByteOrder != QSysInfo::ByteOrder); 0063 const Byte* data = mByteOrderSetAligned64Bit.mBytes; 0064 if (isReverse) { 0065 data += 7; 0066 } 0067 0068 while (noOfBitsToRead > 0) { 0069 Byte byte = (*data << noOfUsedBits); 0070 0071 const int noOfNextBits = 0072 ((BitsPerByte - noOfUsedBits) >= noOfBitsToRead) ? noOfBitsToRead : (BitsPerByte - noOfUsedBits); 0073 0074 byte &= BitMask[noOfNextBits]; 0075 0076 byte >>= BitsPerByte - noOfNextBits; 0077 0078 result = (result << noOfNextBits) | byte; 0079 0080 noOfBitsToRead -= noOfNextBits; 0081 noOfUsedBits += noOfNextBits; 0082 0083 if (noOfUsedBits >= BitsPerByte) { 0084 noOfUsedBits = 0; 0085 if (isReverse) { 0086 --data; 0087 } else { 0088 ++data; 0089 } 0090 } 0091 } 0092 0093 return result; 0094 } 0095 0096 bool PODData::updateRawData(int size) 0097 { 0098 const Byte* oldCurrentOriginalData = mCurrentOriginalData; 0099 0100 if (size > 0) { 0101 if (mByteOrder != QSysInfo::ByteOrder) { 0102 copyInvertedBytes(mByteOrderSetAligned64Bit.mBytes, mOriginalAligned64Bit.mBytes, Size); 0103 } else { 0104 mByteOrderSetAligned64Bit = mOriginalAligned64Bit; 0105 } 0106 0107 mCurrentOriginalData = mOriginalAligned64Bit.mBytes; 0108 mCurrentEndiannessSetData = mByteOrderSetAligned64Bit.mBytes; 0109 mCurrentSize = size; 0110 } else { 0111 mCurrentOriginalData = nullptr; 0112 mCurrentEndiannessSetData = nullptr; 0113 mCurrentSize = 0; 0114 } 0115 0116 return (mCurrentOriginalData || oldCurrentOriginalData); 0117 } 0118 0119 void PODData::getPointers(const void** P8Bit, const void** P16Bit, const void** P32Bit, const void** P64Bit) const 0120 { 0121 constexpr int MachineOffsets[4] = { 0, 0, 0, 0 }; 0122 constexpr int ReversedOffsets[4] = { 7, 6, 4, 0 }; 0123 0124 const int* offsets = (mByteOrder == QSysInfo::ByteOrder) ? MachineOffsets : ReversedOffsets; 0125 const Byte* data = mByteOrderSetAligned64Bit.mBytes; 0126 0127 *P8Bit = (mCurrentSize >= 1) ? data + offsets[0] : nullptr; 0128 *P16Bit = (mCurrentSize >= 2) ? data + offsets[1] : nullptr; 0129 *P32Bit = (mCurrentSize >= 4) ? data + offsets[2] : nullptr; 0130 *P64Bit = (mCurrentSize >= 8) ? data + offsets[3] : nullptr; 0131 } 0132 0133 const void* PODData::pointer(int byteCount) const 0134 { 0135 if (byteCount > mCurrentSize) { 0136 byteCount = 0; 0137 } 0138 0139 const int offset = (mByteOrder == QSysInfo::ByteOrder) ? 0 : 8 - byteCount; 0140 const Byte* data = mByteOrderSetAligned64Bit.mBytes; 0141 0142 return (byteCount > 0) ? data + offset : nullptr; 0143 } 0144 0145 }