@@ -174,6 +174,84 @@ struct context {
174174 GSList * prev_sr_channels ;
175175};
176176
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+
177255/*
178256 * Primitive operations for text input: Strip comments off text lines.
179257 * Split text lines into columns. Process input text for individual
@@ -210,25 +288,22 @@ static void strip_comment(char *buf, const GString *prefix)
210288static int parse_binstr (const char * str , struct context * inc )
211289{
212290 gsize i , j , length ;
291+ char c ;
213292
214293 length = strlen (str );
215-
216294 if (!length ) {
217295 sr_err ("Column %zu in line %zu is empty." , inc -> single_column ,
218296 inc -> line_number );
219297 return SR_ERR ;
220298 }
221299
222- /* Clear buffer in order to set bits only. */
223- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
224-
225300 i = inc -> first_channel ;
226-
227301 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." ,
232307 str , inc -> single_column , inc -> line_number );
233308 return SR_ERR ;
234309 }
@@ -256,37 +331,26 @@ static int parse_hexstr(const char *str, struct context *inc)
256331 char c ;
257332
258333 length = strlen (str );
259-
260334 if (!length ) {
261335 sr_err ("Column %zu in line %zu is empty." , inc -> single_column ,
262336 inc -> line_number );
263337 return SR_ERR ;
264338 }
265339
266- /* Clear buffer in order to set bits only. */
267- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
268-
269340 /* Calculate the position of the first hexadecimal digit. */
270341 i = inc -> first_channel / 4 ;
271-
272342 for (j = 0 ; i < length && j < inc -> num_channels ; i ++ ) {
273343 c = str [length - i - 1 ];
274-
275344 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." ,
277346 str , inc -> single_column , inc -> line_number );
278347 return SR_ERR ;
279348 }
280349
281350 value = g_ascii_xdigit_value (c );
282-
283351 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 ));
290354 }
291355 }
292356
@@ -312,37 +376,26 @@ static int parse_octstr(const char *str, struct context *inc)
312376 char c ;
313377
314378 length = strlen (str );
315-
316379 if (!length ) {
317380 sr_err ("Column %zu in line %zu is empty." , inc -> single_column ,
318381 inc -> line_number );
319382 return SR_ERR ;
320383 }
321384
322- /* Clear buffer in order to set bits only. */
323- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
324-
325385 /* Calculate the position of the first octal digit. */
326386 i = inc -> first_channel / 3 ;
327-
328387 for (j = 0 ; i < length && j < inc -> num_channels ; i ++ ) {
329388 c = str [length - i - 1 ];
330-
331389 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." ,
333391 str , inc -> single_column , inc -> line_number );
334392 return SR_ERR ;
335393 }
336394
337395 value = g_ascii_xdigit_value (c );
338-
339396 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 ));
346399 }
347400 }
348401
@@ -441,19 +494,16 @@ static int parse_multi_columns(char **columns, struct context *inc)
441494 gsize i ;
442495 char * column ;
443496
444- /* Clear buffer in order to set bits only. */
445- memset (inc -> sample_buffer , 0 , inc -> sample_unit_size );
446-
447497 for (i = 0 ; i < inc -> num_channels ; i ++ ) {
448498 column = columns [i ];
449499 if (strcmp (column , "1" ) == 0 ) {
450- inc -> sample_buffer [ i / 8 ] |= ( 1 << ( i % 8 ) );
500+ set_logic_level ( inc , i , 1 );
451501 } else if (!strlen (column )) {
452502 sr_err ("Column %zu in line %zu is empty." ,
453503 inc -> first_channel + i , inc -> line_number );
454504 return SR_ERR ;
455505 } 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." ,
457507 column , inc -> first_channel + i ,
458508 inc -> line_number );
459509 return SR_ERR ;
@@ -463,50 +513,6 @@ static int parse_multi_columns(char **columns, struct context *inc)
463513 return SR_OK ;
464514}
465515
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-
510516static int init (struct sr_input * in , GHashTable * options )
511517{
512518 struct context * inc ;
@@ -731,15 +737,14 @@ static int initial_parse(const struct sr_input *in, GString *buf)
731737 * Calculate the minimum buffer size to store the set of samples
732738 * of all channels (unit size). Determine a larger buffer size
733739 * 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 .
736742 */
737743 inc -> sample_unit_size = (inc -> num_channels + 7 ) / 8 ;
738744 inc -> datafeed_buf_size = CHUNK_SIZE ;
739745 inc -> datafeed_buf_size *= inc -> sample_unit_size ;
740746 inc -> datafeed_buffer = g_malloc (inc -> datafeed_buf_size );
741747 inc -> datafeed_buf_fill = 0 ;
742- inc -> sample_buffer = & inc -> datafeed_buffer [inc -> datafeed_buf_fill ];
743748
744749out :
745750 if (columns )
@@ -919,6 +924,8 @@ static int process_buffer(struct sr_input *in, gboolean is_eof)
919924 return SR_ERR ;
920925 }
921926
927+ clear_logic_samples (inc );
928+
922929 if (inc -> multi_column_mode )
923930 ret = parse_multi_columns (columns , inc );
924931 else
@@ -929,8 +936,8 @@ static int process_buffer(struct sr_input *in, gboolean is_eof)
929936 return SR_ERR ;
930937 }
931938
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 );
934941 if (ret != SR_OK ) {
935942 sr_err ("Sending samples failed." );
936943 g_strfreev (columns );
@@ -984,7 +991,7 @@ static int end(struct sr_input *in)
984991 if (ret != SR_OK )
985992 return ret ;
986993
987- ret = flush_samples (in );
994+ ret = flush_logic_samples (in );
988995 if (ret != SR_OK )
989996 return ret ;
990997
0 commit comments