@@ -174,6 +174,84 @@ struct context {
174
174
GSList * prev_sr_channels ;
175
175
};
176
176
177
+ /*
178
+ * Primitive operations to handle sample sets:
179
+ * - Keep a buffer for datafeed submission, capable of holding many
180
+ * samples (reduces call overhead, improves throughput).
181
+ * - Have a "current sample set" pointer reference one position in that
182
+ * large samples buffer.
183
+ * - Clear the current sample set before text line inspection, then set
184
+ * the bits which are found active in the current line of text input.
185
+ * Phrase the API such that call sites can be kept simple. Advance to
186
+ * the next sample set between lines, flush the larger buffer as needed
187
+ * (when it is full, or upon EOF).
188
+ */
189
+
190
+ static void clear_logic_samples (struct context * inc )
191
+ {
192
+ inc -> sample_buffer = & inc -> datafeed_buffer [inc -> datafeed_buf_fill ];
193
+ memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
194
+ }
195
+
196
+ static void set_logic_level (struct context * inc , size_t ch_idx , int on )
197
+ {
198
+ size_t byte_idx , bit_idx ;
199
+ uint8_t bit_mask ;
200
+
201
+ if (ch_idx >= inc -> num_channels )
202
+ return ;
203
+ if (!on )
204
+ return ;
205
+
206
+ byte_idx = ch_idx / 8 ;
207
+ bit_idx = ch_idx % 8 ;
208
+ bit_mask = 1 << bit_idx ;
209
+ inc -> sample_buffer [byte_idx ] |= bit_mask ;
210
+ }
211
+
212
+ static int flush_logic_samples (const struct sr_input * in )
213
+ {
214
+ struct context * inc ;
215
+ struct sr_datafeed_packet packet ;
216
+ struct sr_datafeed_logic logic ;
217
+ int rc ;
218
+
219
+ inc = in -> priv ;
220
+ if (!inc -> datafeed_buf_fill )
221
+ return SR_OK ;
222
+
223
+ memset (& packet , 0 , sizeof (packet ));
224
+ memset (& logic , 0 , sizeof (logic ));
225
+ packet .type = SR_DF_LOGIC ;
226
+ packet .payload = & logic ;
227
+ logic .unitsize = inc -> sample_unit_size ;
228
+ logic .length = inc -> datafeed_buf_fill ;
229
+ logic .data = inc -> datafeed_buffer ;
230
+
231
+ rc = sr_session_send (in -> sdi , & packet );
232
+ if (rc != SR_OK )
233
+ return rc ;
234
+
235
+ inc -> datafeed_buf_fill = 0 ;
236
+ return SR_OK ;
237
+ }
238
+
239
+ static int queue_logic_samples (const struct sr_input * in )
240
+ {
241
+ struct context * inc ;
242
+ int rc ;
243
+
244
+ inc = in -> priv ;
245
+
246
+ inc -> datafeed_buf_fill += inc -> sample_unit_size ;
247
+ if (inc -> datafeed_buf_fill == inc -> datafeed_buf_size ) {
248
+ rc = flush_logic_samples (in );
249
+ if (rc != SR_OK )
250
+ return rc ;
251
+ }
252
+ return SR_OK ;
253
+ }
254
+
177
255
/*
178
256
* Primitive operations for text input: Strip comments off text lines.
179
257
* Split text lines into columns. Process input text for individual
@@ -210,25 +288,22 @@ static void strip_comment(char *buf, const GString *prefix)
210
288
static int parse_binstr (const char * str , struct context * inc )
211
289
{
212
290
gsize i , j , length ;
291
+ char c ;
213
292
214
293
length = strlen (str );
215
-
216
294
if (!length ) {
217
295
sr_err ("Column %zu in line %zu is empty." , inc -> single_column ,
218
296
inc -> line_number );
219
297
return SR_ERR ;
220
298
}
221
299
222
- /* Clear buffer in order to set bits only. */
223
- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
224
-
225
300
i = inc -> first_channel ;
226
-
227
301
for (j = 0 ; i < length && j < inc -> num_channels ; i ++ , j ++ ) {
228
- if (str [length - i - 1 ] == '1' ) {
229
- inc -> sample_buffer [j / 8 ] |= (1 << (j % 8 ));
230
- } else if (str [length - i - 1 ] != '0' ) {
231
- sr_err ("Invalid value '%s' in column %zu in line %zu." ,
302
+ c = str [length - i - 1 ];
303
+ if (c == '1' ) {
304
+ set_logic_level (inc , j , 1 );
305
+ } else if (c != '0' ) {
306
+ sr_err ("Invalid text '%s' in binary column %zu in line %zu." ,
232
307
str , inc -> single_column , inc -> line_number );
233
308
return SR_ERR ;
234
309
}
@@ -256,37 +331,26 @@ static int parse_hexstr(const char *str, struct context *inc)
256
331
char c ;
257
332
258
333
length = strlen (str );
259
-
260
334
if (!length ) {
261
335
sr_err ("Column %zu in line %zu is empty." , inc -> single_column ,
262
336
inc -> line_number );
263
337
return SR_ERR ;
264
338
}
265
339
266
- /* Clear buffer in order to set bits only. */
267
- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
268
-
269
340
/* Calculate the position of the first hexadecimal digit. */
270
341
i = inc -> first_channel / 4 ;
271
-
272
342
for (j = 0 ; i < length && j < inc -> num_channels ; i ++ ) {
273
343
c = str [length - i - 1 ];
274
-
275
344
if (!g_ascii_isxdigit (c )) {
276
- sr_err ("Invalid value '%s' in column %zu in line %zu." ,
345
+ sr_err ("Invalid text '%s' in hex column %zu in line %zu." ,
277
346
str , inc -> single_column , inc -> line_number );
278
347
return SR_ERR ;
279
348
}
280
349
281
350
value = g_ascii_xdigit_value (c );
282
-
283
351
k = (inc -> first_channel + j ) % 4 ;
284
-
285
- for (; j < inc -> num_channels && k < 4 ; k ++ ) {
286
- if (value & (1 << k ))
287
- inc -> sample_buffer [j / 8 ] |= (1 << (j % 8 ));
288
-
289
- j ++ ;
352
+ for (; j < inc -> num_channels && k < 4 ; j ++ , k ++ ) {
353
+ set_logic_level (inc , j , value & (1 << k ));
290
354
}
291
355
}
292
356
@@ -312,37 +376,26 @@ static int parse_octstr(const char *str, struct context *inc)
312
376
char c ;
313
377
314
378
length = strlen (str );
315
-
316
379
if (!length ) {
317
380
sr_err ("Column %zu in line %zu is empty." , inc -> single_column ,
318
381
inc -> line_number );
319
382
return SR_ERR ;
320
383
}
321
384
322
- /* Clear buffer in order to set bits only. */
323
- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
324
-
325
385
/* Calculate the position of the first octal digit. */
326
386
i = inc -> first_channel / 3 ;
327
-
328
387
for (j = 0 ; i < length && j < inc -> num_channels ; i ++ ) {
329
388
c = str [length - i - 1 ];
330
-
331
389
if (c < '0' || c > '7' ) {
332
- sr_err ("Invalid value '%s' in column %zu in line %zu." ,
390
+ sr_err ("Invalid text '%s' in oct column %zu in line %zu." ,
333
391
str , inc -> single_column , inc -> line_number );
334
392
return SR_ERR ;
335
393
}
336
394
337
395
value = g_ascii_xdigit_value (c );
338
-
339
396
k = (inc -> first_channel + j ) % 3 ;
340
-
341
- for (; j < inc -> num_channels && k < 3 ; k ++ ) {
342
- if (value & (1 << k ))
343
- inc -> sample_buffer [j / 8 ] |= (1 << (j % 8 ));
344
-
345
- j ++ ;
397
+ for (; j < inc -> num_channels && k < 3 ; j ++ , k ++ ) {
398
+ set_logic_level (inc , j , value & (1 << k ));
346
399
}
347
400
}
348
401
@@ -441,19 +494,16 @@ static int parse_multi_columns(char **columns, struct context *inc)
441
494
gsize i ;
442
495
char * column ;
443
496
444
- /* Clear buffer in order to set bits only. */
445
- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
446
-
447
497
for (i = 0 ; i < inc -> num_channels ; i ++ ) {
448
498
column = columns [i ];
449
499
if (strcmp (column , "1" ) == 0 ) {
450
- inc -> sample_buffer [ i / 8 ] |= ( 1 << ( i % 8 ) );
500
+ set_logic_level ( inc , i , 1 );
451
501
} else if (!strlen (column )) {
452
502
sr_err ("Column %zu in line %zu is empty." ,
453
503
inc -> first_channel + i , inc -> line_number );
454
504
return SR_ERR ;
455
505
} else if (strcmp (column , "0" ) != 0 ) {
456
- sr_err ("Invalid value '%s' in column %zu in line %zu." ,
506
+ sr_err ("Invalid text '%s' in bit column %zu in line %zu." ,
457
507
column , inc -> first_channel + i ,
458
508
inc -> line_number );
459
509
return SR_ERR ;
@@ -463,50 +513,6 @@ static int parse_multi_columns(char **columns, struct context *inc)
463
513
return SR_OK ;
464
514
}
465
515
466
- static int flush_samples (const struct sr_input * in )
467
- {
468
- struct context * inc ;
469
- struct sr_datafeed_packet packet ;
470
- struct sr_datafeed_logic logic ;
471
- int rc ;
472
-
473
- inc = in -> priv ;
474
- if (!inc -> datafeed_buf_fill )
475
- return SR_OK ;
476
-
477
- memset (& packet , 0 , sizeof (packet ));
478
- memset (& logic , 0 , sizeof (logic ));
479
- packet .type = SR_DF_LOGIC ;
480
- packet .payload = & logic ;
481
- logic .unitsize = inc -> sample_unit_size ;
482
- logic .length = inc -> datafeed_buf_fill ;
483
- logic .data = inc -> datafeed_buffer ;
484
-
485
- rc = sr_session_send (in -> sdi , & packet );
486
- if (rc != SR_OK )
487
- return rc ;
488
-
489
- inc -> datafeed_buf_fill = 0 ;
490
- return SR_OK ;
491
- }
492
-
493
- static int queue_samples (const struct sr_input * in )
494
- {
495
- struct context * inc ;
496
- int rc ;
497
-
498
- inc = in -> priv ;
499
-
500
- inc -> datafeed_buf_fill += inc -> sample_unit_size ;
501
- if (inc -> datafeed_buf_fill == inc -> datafeed_buf_size ) {
502
- rc = flush_samples (in );
503
- if (rc != SR_OK )
504
- return rc ;
505
- }
506
- inc -> sample_buffer = & inc -> datafeed_buffer [inc -> datafeed_buf_fill ];
507
- return SR_OK ;
508
- }
509
-
510
516
static int init (struct sr_input * in , GHashTable * options )
511
517
{
512
518
struct context * inc ;
@@ -731,15 +737,14 @@ static int initial_parse(const struct sr_input *in, GString *buf)
731
737
* Calculate the minimum buffer size to store the set of samples
732
738
* of all channels (unit size). Determine a larger buffer size
733
739
* for datafeed submission that is a multiple of the unit size.
734
- * Allocate the larger buffer, and have the "sample buffer" point
735
- * to a location within that large buffer.
740
+ * Allocate the larger buffer, the "sample buffer" will point
741
+ * to a location within that large buffer later .
736
742
*/
737
743
inc -> sample_unit_size = (inc -> num_channels + 7 ) / 8 ;
738
744
inc -> datafeed_buf_size = CHUNK_SIZE ;
739
745
inc -> datafeed_buf_size *= inc -> sample_unit_size ;
740
746
inc -> datafeed_buffer = g_malloc (inc -> datafeed_buf_size );
741
747
inc -> datafeed_buf_fill = 0 ;
742
- inc -> sample_buffer = & inc -> datafeed_buffer [inc -> datafeed_buf_fill ];
743
748
744
749
out :
745
750
if (columns )
@@ -919,6 +924,8 @@ static int process_buffer(struct sr_input *in, gboolean is_eof)
919
924
return SR_ERR ;
920
925
}
921
926
927
+ clear_logic_samples (inc );
928
+
922
929
if (inc -> multi_column_mode )
923
930
ret = parse_multi_columns (columns , inc );
924
931
else
@@ -929,8 +936,8 @@ static int process_buffer(struct sr_input *in, gboolean is_eof)
929
936
return SR_ERR ;
930
937
}
931
938
932
- /* Send sample data to the session bus. */
933
- ret = queue_samples (in );
939
+ /* Send sample data to the session bus (buffered) . */
940
+ ret = queue_logic_samples (in );
934
941
if (ret != SR_OK ) {
935
942
sr_err ("Sending samples failed." );
936
943
g_strfreev (columns );
@@ -984,7 +991,7 @@ static int end(struct sr_input *in)
984
991
if (ret != SR_OK )
985
992
return ret ;
986
993
987
- ret = flush_samples (in );
994
+ ret = flush_logic_samples (in );
988
995
if (ret != SR_OK )
989
996
return ret ;
990
997
0 commit comments