Skip to content

Commit e2e626b

Browse files
wopozkaWhyNotHugo
authored andcommitted
Optimization of code creation, avoiding to many charset switch. This results in shorter code which according to GS1 spec should not be longer than 165 mm (6.5")
1) For code128, starding encoding set to C 2) Added function that determines whether the char is FNC1 char - defined the same in all three encodings 3) _maybe_switch_charset recognizes that FNC1 char is defined in all three encodings, and avoids changing encodings 4) added testcases for new functionality.
1 parent 389dc5f commit e2e626b

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*.kpf
1010
*.svg
1111
*.db
12+
.idea/*
1213
barcode/__pycache*
1314
build/*
1415
dist/*

barcode/codex.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class Code128(Barcode):
149149
def __init__(self, code: str, writer=None) -> None:
150150
self.code = code
151151
self.writer = writer or self.default_writer()
152-
self._charset = "B"
152+
self._charset = "C"
153153
self._buffer = ""
154154
check_code(self.code, self.name, code128.ALL)
155155

@@ -175,9 +175,15 @@ def _new_charset(self, which: Literal["A", "B", "C"]) -> list[int]:
175175
self._charset = which
176176
return [code]
177177

178+
# to be redefined in subclass if required
179+
def _is_char_FNC1_CHAR(self, char):
180+
# FNC1 char is defined in GS1-128 specification and it is defined just the same for all encodings
181+
# therefore this sing should be treated in a special way.
182+
return False
183+
178184
def _maybe_switch_charset(self, pos: int) -> list[int]:
179185
char = self.code[pos]
180-
next_ = self.code[pos : pos + 10]
186+
next_ = self.code[pos: pos + 10]
181187

182188
def look_next() -> bool:
183189
digits = 0
@@ -190,13 +196,16 @@ def look_next() -> bool:
190196

191197
codes: list[int] = []
192198
if self._charset == "C" and not char.isdigit():
193-
if char in code128.B:
194-
codes = self._new_charset("B")
195-
elif char in code128.A:
196-
codes = self._new_charset("A")
197-
if len(self._buffer) == 1:
198-
codes.append(self._convert(self._buffer[0]))
199-
self._buffer = ""
199+
if self._is_char_FNC1_CHAR(char) and not self._buffer:
200+
return codes
201+
else:
202+
if char in code128.B:
203+
codes = self._new_charset("B")
204+
elif char in code128.A:
205+
codes = self._new_charset("A")
206+
if len(self._buffer) == 1:
207+
codes.append(self._convert(self._buffer[0]))
208+
self._buffer = ""
200209
elif self._charset == "B":
201210
if look_next():
202211
codes = self._new_charset("C")
@@ -288,6 +297,9 @@ def __init__(self, code, writer=None) -> None:
288297
def get_fullcode(self):
289298
return super().get_fullcode()[1:]
290299

300+
def _is_char_FNC1_CHAR(self, char):
301+
return char == self.FNC1_CHAR
302+
291303

292304
# For pre 0.8 compatibility
293305
PZN = PZN7

tests/test_Gs1_128.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import pytest
2+
import sys
3+
import os.path
4+
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
5+
from barcode.codex import Gs1_128
6+
7+
FNC1_CHAR = "\xf1"
8+
FNC1 = 102
9+
START_B = 104
10+
START_C = 105
11+
FROM_AC_TO_B = 100
12+
FROM_AB_TO_C = 99
13+
FROM_BC_TO_A = 101
14+
CODE_BUILD_TEST = (
15+
# '(01)01234567891011(11)200622(17)240622(21)88888888'
16+
('010123456789101111200622172406222188888888', [START_C, FNC1, 1, 1, 23, 45, 67, 89, 10, 11,
17+
11, 20, 6, 22,
18+
17, 24, 6, 22,
19+
21, 88, 88, 88, 88],),
20+
# '(01)01234567891011(11)200622(17)240622(21)888888888'
21+
('0101234567891011112006221724062221888888888', [START_C, FNC1, 1, 1, 23, 45, 67, 89, 10, 11,
22+
11, 20, 6, 22,
23+
17, 24, 6, 22,
24+
21, 88, 88, 88, 88, 100, 24],),
25+
# '(01)01234567891011(11)200622(10)12345(21)1234'
26+
('0101234567891011112006221012345' + FNC1_CHAR + '211234', [START_C, FNC1, 1, 1, 23, 45, 67, 89, 10, 11,
27+
11, 20, 6, 22,
28+
10, 12, 34, FROM_AC_TO_B, 21, FNC1,
29+
FROM_AB_TO_C, 21, 12, 34],),
30+
# '(01)01234567891011(11)200622(10)1234(21)1234'
31+
('010123456789101111200622101234' + FNC1_CHAR + '211234', [START_C, FNC1, 1, 1, 23, 45, 67, 89, 10, 11,
32+
11, 20, 6, 22,
33+
10, 12, 34, FNC1,
34+
21, 12, 34],),
35+
# '(01)01234567891011(11)200622(10)240622(21)888888888'
36+
('01012345678910111120062210240622' + FNC1_CHAR + '21888888888', [START_C, FNC1, 1, 1, 23, 45, 67, 89, 10, 11,
37+
11, 20, 6, 22,
38+
10, 24, 6, 22, FNC1,
39+
21, 88, 88, 88, 88, 100, 24],),
40+
# '(01)08720299927469(11)240621(17)250621(10)20240621/0001(21)xyz'
41+
('010872029992746911240621172506211020240621/0001' + FNC1_CHAR + '21xyz', [105, 102, 1, 8, 72, 2, 99, 92, 74, 69,
42+
11, 24, 6, 21,
43+
17, 25, 6, 21,
44+
10, 20, 24, 6, 21, 100, 15, 99, 0, 1,
45+
102, 21, 100, 88, 89, 90]),
46+
)
47+
@pytest.mark.parametrize('target, answer', CODE_BUILD_TEST)
48+
def test_code_build(target, answer):
49+
gs1_128 = Gs1_128(target)
50+
assert gs1_128._build() == answer

0 commit comments

Comments
 (0)