40 BitCount64 bitsRemaining, quint8*
const bitOffset)
42 Q_ASSERT(*bitOffset < 8);
43 Q_ASSERT(bitCount <= 64);
44 if (bitsRemaining < bitCount)
54 if (bitCount % 8 == 0 && *bitOffset == 0)
57 writeFullBytes(bitCount / 8, newValue, out, byteOrder, address);
63 writeDataLittleEndian(bitCount, newValue, out, address, *bitOffset);
67 writeDataBigEndian(bitCount, newValue, out, address, *bitOffset);
74 *bitOffset = (*bitOffset + bitCount) % 8;
81 quint8*
const bitOffset)
83 Q_ASSERT(bitCount <= 64);
84 Q_ASSERT(*bitOffset < 8);
85 if (bitsRemaining < bitCount)
93 if (bitCount % 8 == 0 && *bitOffset == 0)
96 readFullBytes(bitCount / 8, input, byteOrder, address);
102 readDataLittleEndian(bitCount, input, address, *bitOffset);
106 readDataBigEndian(bitCount, input, address, *bitOffset);
113 *bitOffset = (*bitOffset + bitCount) % 8;
118 void AllPrimitiveTypes::readDataLittleEndian(quint8 bitCount,
121 if (bitCount <= (
unsigned) (8 - bo))
124 const quint8 lowerMask = 0xff << bo;
125 const quint8 higherMask = 0xff >> (8 - (bo + bitCount));
126 const quint8 completeMask = lowerMask & higherMask;
127 const quint8 readByte = input->
byte(address);
128 const quint8 maskedByte = readByte & completeMask;
129 _ubyte.
value = maskedByte >> bo;
133 const quint8 firstByteMask = 0xff << bo;
134 const quint8 firstByte = input->
byte(address);
135 const quint8 firstByteMasked = firstByte & firstByteMask;
136 _ubyte.
value = firstByteMasked >> bo;
138 for (uint i = 8; i < bitCount + bo; i += 8)
140 quint8 readVal = input->
byte(address + (i / 8));
141 if (bitCount + bo < i + 8)
144 const quint8 missingBits = (bitCount + bo) % 8;
145 const quint8 mask = (1 << missingBits) - 1;
150 const quint64 shiftedVal = (quint64) readVal << i;
151 _ulong.
value |= shiftedVal >> bo;
156 void AllPrimitiveTypes::readDataBigEndian(quint8 bitCount,
159 if (bitCount <= (
unsigned) (8 - bo))
161 const quint8 lowerMask = 0xff << (8 - (bo + bitCount));
162 const quint8 higherMask = 0xff >> bo;
163 const quint8 completeMask = lowerMask & higherMask;
165 const quint8 readByte = input->
byte(address);
166 const quint8 maskedByte = readByte & completeMask;
167 _ubyte.
value = maskedByte >> (8 - (bo + bitCount));
171 const quint8 firstByteMask = 0xff >> bo;
172 const quint8 firstByte = input->
byte(address);
174 const quint64 firstByteMasked = firstByte & firstByteMask;
175 const quint64 firstByteShifted = firstByteMasked << (bo + bitCount - 8);
176 _ulong.
value = firstByteShifted;
178 for (uint i = 8; i < bitCount + bo; i += 8)
180 quint8 readVal = input->
byte(address + (i / 8));
181 if (bitCount + bo < i + 8)
184 const quint8 missingBits = (bo + bitCount) % 8;
185 const quint8 mask = 0xff << (8 - missingBits);
186 const quint8 maskedVal = readVal & mask;
187 const quint8 shiftedVal = maskedVal >> (8 - missingBits);
188 _ulong.
value |= shiftedVal;
194 const quint64 shiftedVal = (quint64) readVal << ((bo + bitCount)
196 _ulong.
value |= shiftedVal;
202 void AllPrimitiveTypes::writeDataLittleEndian(quint8 bitCount,
206 if (bitCount <= (
unsigned) (8 - bo))
209 const quint8 lowerMask = (1 << bo) - 1;
210 const quint8 higherMask = 0xff << (bo + bitCount);
211 const quint8 completeMask = lowerMask | higherMask;
212 const quint8 readByte = out->
byte(address);
213 const quint8 maskedByte = readByte & completeMask;
214 const quint8 addedVal = newValue._ubyte.
value << bo;
215 const quint8 newVal = maskedByte | addedVal;
220 const quint8 firstByteMask = (1 << bo) - 1;
221 const quint8 firstByte = out->
byte(address);
222 const quint8 firstByteMasked = firstByte & firstByteMask;
223 const quint8 firstAddedVal = (newValue._ubyte.
value << bo);
224 const quint8 firstByteWithValAdded = firstByteMasked | firstAddedVal;
225 out->
setByte(address, firstByteWithValAdded);
227 for (uint i = 8; i < bitCount + bo; i += 8)
229 const quint8 currentByte = newValue._ulong.
value >> (i - bo);
230 if (bitCount + bo < i + 8)
232 const quint8 readVal = out->
byte(address + (i / 8));
234 const quint8 missingBits = (bitCount + bo) % 8;
235 const quint8 mask = 0xff << missingBits;
236 const quint8 readValMasked = readVal & mask;
237 const quint8 resultingVal = readValMasked | currentByte;
238 out->
setByte(address + (i / 8), resultingVal);
243 out->
setByte(address + (i / 8), currentByte);
249 void AllPrimitiveTypes::writeDataBigEndian(quint8 bitCount,
253 if (bitCount <= (
unsigned) (8 - bo))
256 const quint8 lowerMask = 0xff >> (bo + bitCount);
257 const quint8 higherMask = 0xff << (8 - bo);
258 const quint8 completeMask = lowerMask | higherMask;
259 const quint8 readByte = out->
byte(address);
260 const quint8 maskedByte = readByte & completeMask;
261 const quint8 addedVal = newValue._ubyte.
value << (8 - bo - 1);
262 const quint8 maskedByteWithValueAdded = maskedByte | addedVal;
263 out->
setByte(address, maskedByteWithValueAdded);
267 quint8 missingBits = (bitCount + bo) % 8;
268 missingBits = (missingBits == 0 ? 8 : missingBits);
269 const quint8 lastAddress = address + ((bo + bitCount) / 8) - (missingBits
271 const quint8 lastByte = out->
byte(lastAddress);
272 const quint8 lastByteMask = (1 << missingBits) - 1;
273 const quint8 lastByteMasked = lastByte & lastByteMask;
274 const quint8 lastByteAddedVal = newValue._ubyte.
value << (8 - missingBits);
275 const quint8 lastByteWithValAdded = lastByteMasked | lastByteAddedVal;
276 out->
setByte(lastAddress, lastByteWithValAdded);
277 for (
int currAddress = lastAddress - 1; currAddress >= address; currAddress--)
279 const quint8 currentByte = out->
byte(currAddress);
280 if (currAddress == address)
283 const quint8 firstByteMask = 0xff << (8 - bo);
284 const quint8 firstByteMasked = currentByte & firstByteMask;
285 const quint8 highestByte = newValue._ulong.
value
286 >> (bo + bitCount - 8);
287 const quint8 firstByteWithValAdded = firstByteMasked | highestByte;
288 out->
setByte(address, firstByteWithValAdded);
292 const int bytesNotToShift = 1 + (lastAddress - address)
293 - (lastAddress - currAddress);
294 const quint8 thisByteShifted = newValue._ulong.
value >> (bo + bitCount
295 - (8 * bytesNotToShift));
296 out->
setByte(currAddress, thisByteShifted);
305 Q_ASSERT(byteCount <= 8);
307 for (
int i = 0; i < byteCount; i++)
310 : ((byteCount - 1) - i);
316 void AllPrimitiveTypes::writeFullBytes(quint8 byteCount,
AllPrimitiveTypes newValue,
319 Q_ASSERT(byteCount <= 8);
320 for (
int i = 0; i < byteCount; ++i)
323 : ((byteCount - 1) - i);
could it be useful to hide the data access behind an iterator? * class KDataBufferIterator { public: ...
bool readBits(quint8 bitCount, const Okteta::AbstractByteArrayModel *input, QSysInfo::Endian byteOrder, Okteta::Address address, BitCount64 bitsRemaining, quint8 *const bitOffset)
Reads given number of bits from input and sets value of this union to the new value.
compile_time_assert(sizeof(double)==8)
virtual void setByte(Address offset, Byte byte)=0
sets a single byte if the offset is not valid the behaviour is undefined
virtual Byte byte(Address offset) const =0
locates working range The idea behind is to tell buffer which range will be requested in the followin...
This union holds the value of one primitive datatype.
bool writeBits(quint8 bitCount, AllPrimitiveTypes newValue, Okteta::AbstractByteArrayModel *out, QSysInfo::Endian byteOrder, Okteta::Address address, BitCount64 bitsRemaining, quint8 *const bitOffset)
Writes given number of bits to out.