GS1 Syntax Dictionary: Linter reference
A reference to the AI component linter routines referred to by the GS1 Syntax Dictionary.
lint_pieceoftotal.c File Reference

Purpose

The pieceoftotal linter ensures that the data represents a meaningful piece of total, i.e. a concatenation of non-zero piece number follow by an equal-width, non-zero total number of pieces.

Functional Description

◆ gs1_lint_pieceoftotal()

GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_pieceoftotal ( const char *const  data,
size_t *const  err_pos,
size_t *const  err_len 
)

Used to ensure that an AI component conforms to a PPTT format, where PP and TT have equal width.

Parameters
[in]dataPointer to the null-terminated data to be linted. Must not be NULL.
[out]err_posTo facilitate error highlighting, the start position of the bad data is written to this pointer, if not NULL.
[out]err_lenThe length of the bad data is written to this pointer, if not NULL.
Returns
GS1_LINTER_OK if okay.
GS1_LINTER_INVALID_LENGTH_FOR_PIECE_OF_TOTAL if the data is not an even length.
GS1_LINTER_NON_DIGIT_CHARACTER if the data contains a non-digit character.
GS1_LINTER_ZERO_PIECE_NUMBER if the data contains a piece number with a zero value.
GS1_LINTER_ZERO_TOTAL_PIECES if the data contains a total piece count with a zero value.
GS1_LINTER_PIECE_NUMBER_EXCEEDS_TOTAL if the data contains a piece number that is larger than the total piece count.
56 {
57 
58 /// \cond
59 #define P(i) data[i]
60 #define T(i) data[len / 2 + i]
61 /// \endcond
62 
63  size_t pos, len, i;
64  int pieceiszero, totaliszero, compare;
65 
66  assert(data);
67 
68  len = strlen(data);
69 
70  /*
71  * Data must be a non-zero, even number of characters.
72  *
73  */
74  if (len == 0 || len % 2 != 0) {
75  if (err_pos) *err_pos = 0;
76  if (err_len) *err_len = len;
78  }
79 
80  /*
81  * Data must consist of all digits.
82  *
83  */
84  if ((pos = strspn(data, "0123456789")) != len) {
85  if (err_pos) *err_pos = pos;
86  if (err_len) *err_len = 1;
88  }
89 
90  /*
91  * Determine whether either the piece number or total piece count is
92  * zero and whether the piece number exceeds the total piece count.
93  *
94  */
95  pieceiszero = totaliszero = 1;
96  compare = 0; /* -1:P<T ; 0:P==T ; 1:P>T */
97  for (i = 0; i < len / 2; i++) {
98  if (pieceiszero && P(i) != '0') pieceiszero = 0;
99  if (totaliszero && T(i) != '0') totaliszero = 0;
100  if (!compare && P(i) != T(i)) compare = P(i) < T(i) ? -1 : 1;
101  }
102 
103  /*
104  * Neither piece nor total may be zero.
105  *
106  */
107  if (pieceiszero || totaliszero) {
108  if (err_pos) *err_pos = pieceiszero ? 0 : len / 2;
109  if (err_len) *err_len = len / 2;
111  }
112 
113  /*
114  * The piece number must not exceed the total piece count.
115  *
116  */
117  if (compare == 1) {
118  if (err_pos) *err_pos = 0;
119  if (err_len) *err_len = len;
121  }
122 
123  return GS1_LINTER_OK;
124 
125 }
@ GS1_LINTER_PIECE_NUMBER_EXCEEDS_TOTAL
The piece number must not exceed the piece total.
Definition: gs1syntaxdictionary.h:109
@ GS1_LINTER_ZERO_PIECE_NUMBER
The piece number must not have a value of zero.
Definition: gs1syntaxdictionary.h:107
@ GS1_LINTER_INVALID_LENGTH_FOR_PIECE_OF_TOTAL
The piece with total must have an even length, having equal-length components.
Definition: gs1syntaxdictionary.h:106
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition: gs1syntaxdictionary.h:66
@ GS1_LINTER_ZERO_TOTAL_PIECES
The piece total must not have a value of zero.
Definition: gs1syntaxdictionary.h:108
@ GS1_LINTER_NON_DIGIT_CHARACTER
A non-digit character was found where a digit is expected.
Definition: gs1syntaxdictionary.h:67