1 | { lbc_telepen.pas - Handles telepen alpha, and telepen numeric barcodes.
|
---|
2 |
|
---|
3 | Based on Zint (done by Robin Stuart and the Zint team)
|
---|
4 | http://github.com/zint/zint
|
---|
5 | and Pascal adaption by TheUnknownOnes
|
---|
6 | http://theunknownones.net
|
---|
7 |
|
---|
8 | Refactoring: W.Pamler
|
---|
9 |
|
---|
10 | Fixes: Usage of character 'X' in input string.
|
---|
11 | }
|
---|
12 | unit lbc_telepen;
|
---|
13 |
|
---|
14 | {$mode objfpc}{$H+}
|
---|
15 |
|
---|
16 | interface
|
---|
17 |
|
---|
18 | uses
|
---|
19 | SysUtils, zint;
|
---|
20 |
|
---|
21 | function telepen(ASymbol: PZintSymbol; const ASource: String): Integer;
|
---|
22 | function telepen_num(ASymbol: PZintSymbol; const ASource: String): Integer;
|
---|
23 |
|
---|
24 | implementation
|
---|
25 |
|
---|
26 | uses
|
---|
27 | lbc_helper;
|
---|
28 |
|
---|
29 | const TeleTable: array[0..126] of String = (
|
---|
30 | '1111111111111111', '1131313111', '33313111', '1111313131', '3111313111',
|
---|
31 | '11333131', '13133131', '111111313111', '31333111', '1131113131',
|
---|
32 | '33113131', '1111333111', '3111113131', '1113133111', '1311133111',
|
---|
33 | '111111113131', '3131113111', '11313331', '333331', '111131113111',
|
---|
34 | '31113331', '1133113111', '1313113111', '1111113331', '31131331',
|
---|
35 | '113111113111', '3311113111', '1111131331', '311111113111', '1113111331',
|
---|
36 | '1311111331', '11111111113111', '31313311', '1131311131', '33311131',
|
---|
37 | '1111313311', '3111311131', '11333311', '13133311', '111111311131',
|
---|
38 | '31331131', '1131113311', '33113311', '1111331131', '3111113311',
|
---|
39 | '1113131131', '1311131131', '111111113311', '3131111131', '1131131311',
|
---|
40 | '33131311', '111131111131', '3111131311', '1133111131', '1313111131',
|
---|
41 | '111111131311', '3113111311', '113111111131', '3311111131', '111113111311',
|
---|
42 | '311111111131', '111311111311', '131111111311', '11111111111131', '3131311111',
|
---|
43 | '11313133', '333133', '111131311111', '31113133', '1133311111',
|
---|
44 | '1313311111', '1111113133', '313333', '113111311111', '3311311111',
|
---|
45 | '11113333', '311111311111', '11131333', '13111333', '11111111311111',
|
---|
46 | '31311133', '1131331111', '33331111', '1111311133', '3111331111',
|
---|
47 | '11331133', '13131133', '111111331111', '3113131111', '1131111133',
|
---|
48 | '33111133', '111113131111', '3111111133', '111311131111', '131111131111',
|
---|
49 | '111111111133', '31311313', '113131111111', '3331111111', '1111311313',
|
---|
50 | '311131111111', '11331313', '13131313', '11111131111111', '3133111111',
|
---|
51 | '1131111313', '33111313', '111133111111', '3111111313', '111313111111',
|
---|
52 | '131113111111', '111111111313', '313111111111', '1131131113', '33131113',
|
---|
53 | '11113111111111', '3111131113', '113311111111', '131311111111', '111111131113',
|
---|
54 | '3113111113', '11311111111111', '331111111111', '111113111113', '31111111111111',
|
---|
55 | '111311111113', '131111111113'
|
---|
56 | );
|
---|
57 |
|
---|
58 | function CheckSum_telepen(ASource: String): String;
|
---|
59 | var
|
---|
60 | i, sum: Integer;
|
---|
61 | check_digit: Integer;
|
---|
62 | begin
|
---|
63 | sum := 0;
|
---|
64 | for i := 1 to Length(ASource) do
|
---|
65 | inc(sum, ord(ASource[i]));
|
---|
66 |
|
---|
67 | check_digit := 127 - sum mod 127;
|
---|
68 | if (check_digit = 127) then check_digit := 0;
|
---|
69 |
|
---|
70 | Result := char(check_digit);
|
---|
71 | end;
|
---|
72 |
|
---|
73 | function telepen(ASymbol: PZintSymbol; const ASource: String): Integer;
|
---|
74 | var
|
---|
75 | i: Integer;
|
---|
76 | begin
|
---|
77 | for i := 1 to Length(ASource) do
|
---|
78 | if ASource[i] > #126 then
|
---|
79 | begin
|
---|
80 | // Cannot encode extended ASCII
|
---|
81 | ASymbol^.SetErrorText('Invalid characters in input data.');
|
---|
82 | Result := ERROR_INVALID_DATA;
|
---|
83 | exit;
|
---|
84 | end;
|
---|
85 |
|
---|
86 | Result := basic_encoder(ASymbol, ASource,
|
---|
87 | 30, '', TeleTable[ord('_')], TeleTable, TeleTable[ord('z')], @CheckSum_telepen, false);
|
---|
88 | end;
|
---|
89 |
|
---|
90 | function telepen_num(ASymbol: PZintSymbol; const ASource: String): Integer;
|
---|
91 | const
|
---|
92 | VALID_CHARS = NEON + 'X';
|
---|
93 | var
|
---|
94 | src, dest: String;
|
---|
95 | i, pair, checksum: Integer;
|
---|
96 | begin
|
---|
97 | if Length(ASource) > 60 then
|
---|
98 | begin
|
---|
99 | ASymbol^.SetErrorText('Input too long (max 60 characters).');
|
---|
100 | Result := ERROR_TOO_LONG;
|
---|
101 | exit;
|
---|
102 | end;
|
---|
103 |
|
---|
104 | src := UpperCase(ASource);
|
---|
105 | Result := is_sane(VALID_CHARS, src);
|
---|
106 | if Result = ERROR_INVALID_DATA then
|
---|
107 | begin
|
---|
108 | ASymbol^.SetErrorText('Invalid characters in data.');
|
---|
109 | exit;
|
---|
110 | end;
|
---|
111 |
|
---|
112 | // Add a leading zero if required (the input string length must be even).
|
---|
113 | if odd(Length(src)) then
|
---|
114 | src := '0' +src;
|
---|
115 |
|
---|
116 | // START character
|
---|
117 | dest := TeleTable[ord('_')];
|
---|
118 |
|
---|
119 | // Extract pairs of digits. Their numerical value is encoded. An 'X' is
|
---|
120 | // allowed to identify single-digit numbers; it must be the LAST character of
|
---|
121 | // a pair.
|
---|
122 | // Example: 466X33 is valid (pairs 46, 6X, 33)
|
---|
123 | // 46X333 is not valid (pairs 46, X3, 33)
|
---|
124 | i := 1;
|
---|
125 | checksum := 0;
|
---|
126 | while i < Length(src) do
|
---|
127 | begin
|
---|
128 | if src[i] = 'X' then
|
---|
129 | begin
|
---|
130 | ASymbol^.SetErrorText('Invalid position of X in Telepen data.');
|
---|
131 | Result := ERROR_INVALID_DATA;
|
---|
132 | exit;
|
---|
133 | end;
|
---|
134 | if src[i+1] = 'X' then
|
---|
135 | pair := StrToInt(src[i]) + 17
|
---|
136 | else
|
---|
137 | pair := StrToInt(src[i] + src[i+1]) + 27;
|
---|
138 | dest := dest + TeleTable[pair];
|
---|
139 | inc(checksum, pair);
|
---|
140 | inc(i, 2);
|
---|
141 | end;
|
---|
142 |
|
---|
143 | checksum := 127 - checksum mod 127;
|
---|
144 | if checksum = 127 then checksum := 0;
|
---|
145 | dest := dest + TeleTable[checksum];
|
---|
146 |
|
---|
147 | // STOP character
|
---|
148 | dest := dest + TeleTable[ord('z')];
|
---|
149 |
|
---|
150 | // Expand to modules
|
---|
151 | expand(ASymbol, dest);
|
---|
152 |
|
---|
153 | // Store human-readable text.
|
---|
154 | ASymbol^.SetText(src);
|
---|
155 | end;
|
---|
156 |
|
---|
157 | end.
|
---|
158 |
|
---|
159 |
|
---|