@@ -190,3 +190,121 @@ uint16_t sempRtcmGetMessageNumber(const SEMP_PARSE_STATE *parse)
190
190
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad ;
191
191
return scratchPad->rtcm .message ;
192
192
}
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