1
+ #include < string.h>
1
2
#include " include/spead_packet.h"
2
3
3
4
// Return data at the specified offset (in bits) and # of bits as
@@ -175,6 +176,7 @@ void spead_heap_init(SpeadHeap *heap) {
175
176
heap->is_valid = 0 ;
176
177
heap->heap_cnt = SPEAD_ERR;
177
178
heap->heap_len = SPEAD_ERR;
179
+ heap->received_len = 0 ;
178
180
heap->has_all_packets = SPEAD_ERR;
179
181
heap->head_pkt = NULL ;
180
182
heap->last_pkt = NULL ;
@@ -213,22 +215,29 @@ int spead_heap_add_packet(SpeadHeap *heap, SpeadPacket *pkt) {
213
215
}
214
216
else { // We need to insert this packet in the correct order
215
217
if (heap->heap_cnt != pkt->heap_cnt ) return SPEAD_ERR;
216
- _pkt = heap->head_pkt ;
217
- // Find the right slot to insert this pkt
218
- if (pkt->payload_off < _pkt->payload_off ) {
219
- pkt->next = heap->head_pkt ;
220
- heap->head_pkt = pkt;
218
+ if (pkt->payload_off >= heap->last_pkt ->payload_off ) {
219
+ // Fast path: in-order packet gets added to the tail
220
+ heap->last_pkt ->next = pkt;
221
+ heap->last_pkt = pkt;
221
222
} else {
222
- while (_pkt->next != NULL && _pkt->next ->payload_off < pkt->payload_off ) {
223
- _pkt = _pkt->next ;
224
- }
225
- // Insert the pkt
226
- pkt->next = _pkt->next ;
227
- _pkt->next = pkt;
228
- if (pkt->next == NULL ) heap->last_pkt = pkt;
229
- } // else if packet does not belong at head
223
+ _pkt = heap->head_pkt ;
224
+ // Find the right slot to insert this pkt
225
+ if (pkt->payload_off < _pkt->payload_off ) {
226
+ pkt->next = heap->head_pkt ;
227
+ heap->head_pkt = pkt;
228
+ } else {
229
+ while (_pkt->next != NULL && _pkt->next ->payload_off < pkt->payload_off ) {
230
+ _pkt = _pkt->next ;
231
+ }
232
+ // Insert the pkt
233
+ pkt->next = _pkt->next ;
234
+ _pkt->next = pkt;
235
+ if (pkt->next == NULL ) heap->last_pkt = pkt;
236
+ } // else if packet does not belong at head
237
+ }
230
238
}
231
239
if (pkt->heap_len != SPEAD_ERR) heap->heap_len = pkt->heap_len ;
240
+ heap->received_len += pkt->payload_len ;
232
241
heap->has_all_packets = SPEAD_ERR;
233
242
return spead_heap_got_all_packets (heap);
234
243
}
@@ -238,6 +247,10 @@ int spead_heap_got_all_packets(SpeadHeap *heap) {
238
247
if (heap->heap_len == SPEAD_ERR || pkt == NULL ) return 0 ; // Don't compute if we can't know the answer
239
248
if (heap->has_all_packets != SPEAD_ERR) return heap->has_all_packets ; // Don't recompute if we do know the answer
240
249
heap->has_all_packets = 0 ;
250
+ // If we haven't received as much payload as we're expecting, we're not
251
+ // done. If we have, we still need to check the actual packets because
252
+ // there might be duplicates.
253
+ if (heap->received_len < heap->heap_len ) return 0 ;
241
254
while (pkt->next != NULL ) {
242
255
if (pkt->payload_off + pkt->payload_len != pkt->next ->payload_off ) return 0 ;
243
256
pkt = pkt->next ;
@@ -313,20 +326,24 @@ int spead_heap_finalize(SpeadHeap *heap) {
313
326
if (item->val == NULL ) return SPEAD_ERR;
314
327
// Dig through the payloads to retrieve item value
315
328
pkt2 = heap->head_pkt ;
316
- for (o=0 ; o < item->len ; o++) {
329
+ o = 0 ;
330
+ while (o < item->len ) {
317
331
while (pkt2 != NULL && (pkt2->payload_off + pkt2->payload_len <= off + o)) {
318
332
pkt2 = pkt2->next ;
319
333
}
320
334
// If packet with relevant data is missing, fill with zeros and mark invalid
321
335
if (pkt2 == NULL || pkt2->payload_off > off + o) {
322
336
// printf("Copying value[%d] = 00 (missing)\n", o);
323
- item->val [o] = ' \x00 ' ;
337
+ int64_t end = (pkt2 == NULL ) ? item->len : pkt2->payload_off - off;
338
+ memset (&item->val [o], 0 , end - o);
324
339
item->is_valid = 0 ;
340
+ o = end;
325
341
} else {
326
- item->val [o] = pkt2->payload [off + o - pkt2->payload_off ];
327
- // printf("o=%d, off=%d, payload_off=%d, index=%d\n",
328
- // o, off, pkt2->payload->offset, off + o - pkt2->payload->offset);
329
- // printf("Copying value[%d] = %02x\n", o, (uint8_t)item->val[o]);
342
+ int64_t end = pkt2->payload_off + pkt2->payload_len - off;
343
+ if (item->len < end)
344
+ end = item->len ;
345
+ memcpy (&item->val [o], &pkt2->payload [off + o - pkt2->payload_off ], end - o);
346
+ o = end;
330
347
}
331
348
}
332
349
}
0 commit comments