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 }