@@ -190,3 +190,121 @@ uint16_t sempRtcmGetMessageNumber(const SEMP_PARSE_STATE *parse)
190190 SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad ;
191191 return scratchPad->rtcm .message ;
192192}
193+
194+ // Get unsigned integer with width bits, starting at bit start
195+ uint64_t sempRtcmGetUnsignedBits (const SEMP_PARSE_STATE *parse, uint16_t start, uint16_t width)
196+ {
197+ uint8_t *ptr = parse->buffer ;
198+ ptr += 3 ; // Skip the preamble and length bytes
199+
200+ uint64_t result = 0 ;
201+ uint16_t count = 0 ;
202+ uint8_t bitMask = 0x80 ;
203+
204+ // Skip whole bytes (8 bits)
205+ ptr += start / 8 ;
206+ count += (start / 8 ) * 8 ;
207+
208+ // Loop until we reach the start bit
209+ while (count < start)
210+ {
211+ bitMask >>= 1 ; // Shift the bit mask
212+ count++; // Increment the count
213+
214+ if (bitMask == 0 ) // Have we counted 8 bits?
215+ {
216+ ptr++; // Point to the next byte
217+ bitMask = 0x80 ; // Reset the bit mask
218+ }
219+ }
220+
221+ // We have reached the start bit and ptr is pointing at the correct byte
222+ // Now extract width bits, incrementing ptr and shifting bitMask as we go
223+ while (count < (start + width))
224+ {
225+ if (*ptr & bitMask) // Is the bit set?
226+ result |= 1 ; // Set the corresponding bit in result
227+
228+ bitMask >>= 1 ; // Shift the bit mask
229+ count++; // Increment the count
230+
231+ if (bitMask == 0 ) // Have we counted 8 bits?
232+ {
233+ ptr++; // Point to the next byte
234+ bitMask = 0x80 ; // Reset the bit mask
235+ }
236+
237+ if (count < (start + width)) // Do we need to shift result?
238+ result <<= 1 ; // Shift the result
239+ }
240+
241+ return result;
242+ }
243+
244+ // Get signed integer with width bits, starting at bit start
245+ int64_t sempRtcmGetSignedBits (const SEMP_PARSE_STATE *parse, uint16_t start, uint16_t width)
246+ {
247+ uint8_t *ptr = parse->buffer ;
248+ ptr += 3 ; // Skip the preamble and length bytes
249+
250+ union
251+ {
252+ uint64_t unsigned64;
253+ int64_t signed64;
254+ } result;
255+
256+ result.unsigned64 = 0 ;
257+
258+ uint64_t twosComplement = 0xFFFFFFFFFFFFFFFF ;
259+
260+ bool isNegative;
261+
262+ uint16_t count = 0 ;
263+ uint8_t bitMask = 0x80 ;
264+
265+ // Skip whole bytes (8 bits)
266+ ptr += start / 8 ;
267+ count += (start / 8 ) * 8 ;
268+
269+ // Loop until we reach the start bit
270+ while (count < start)
271+ {
272+ bitMask >>= 1 ; // Shift the bit mask
273+ count++; // Increment the count
274+
275+ if (bitMask == 0 ) // Have we counted 8 bits?
276+ {
277+ ptr++; // Point to the next byte
278+ bitMask = 0x80 ; // Reset the bit mask
279+ }
280+ }
281+
282+ isNegative = *ptr & bitMask; // Record the first bit - indicates in the number is negative
283+
284+ // We have reached the start bit and ptr is pointing at the correct byte
285+ // Now extract width bits, incrementing ptr and shifting bitMask as we go
286+ while (count < (start + width))
287+ {
288+ if (*ptr & bitMask) // Is the bit set?
289+ result.unsigned64 |= 1 ; // Set the corresponding bit in result
290+
291+ bitMask >>= 1 ; // Shift the bit mask
292+ count++; // Increment the count
293+ twosComplement <<= 1 ; // Shift the two's complement mask (clear LSB)
294+
295+ if (bitMask == 0 ) // Have we counted 8 bits?
296+ {
297+ ptr++; // Point to the next byte
298+ bitMask = 0x80 ; // Reset the bit mask
299+ }
300+
301+ if (count < (start + width)) // Do we need to shift result?
302+ result.unsigned64 <<= 1 ; // Shift the result
303+ }
304+
305+ // Handle negative number
306+ if (isNegative)
307+ result.unsigned64 |= twosComplement; // OR in the two's complement mask
308+
309+ return result.signed64 ;
310+ }
0 commit comments