@@ -223,12 +223,33 @@ def look_next() -> bool:
223223 codes = self ._new_charset ("B" )
224224 return codes
225225
226- def _convert (self , char : str ):
226+ def _convert (self , char : str ) -> int :
227+ """Convert a character to a code number for the current charset.
228+
229+ NOTE: encoding digits with charset C requires buffering and is not supported
230+ here. Use _convert_or_buffer instead.
231+ """
227232 if self ._charset == "A" :
228233 return code128 .A [char ]
229234 if self ._charset == "B" :
230235 return code128 .B [char ]
231236 if self ._charset == "C" :
237+ if char in ["TO_A" , "TO_B" ]:
238+ return code128 .C [char ]
239+ raise RuntimeError ("Use _convert_or_buffer for charset C." )
240+ raise RuntimeError (
241+ f"Character { char } could not be converted in charset { self ._charset } ."
242+ )
243+
244+ def _convert_or_buffer (self , char : str ) -> int | None :
245+ """Convert a character to a code number for the current charset.
246+
247+ If charset C is active then digits are encoded in pairs. When the first digit
248+ is encountered, it is buffered and None is returned.
249+ """
250+ if self ._charset != "C" :
251+ return self ._convert (char )
252+ else :
232253 if char in code128 .C :
233254 return code128 .C [char ]
234255 if char .isdigit ():
@@ -257,7 +278,7 @@ def _build(self) -> list[int]:
257278 encoded : list [int ] = [code128 .START_CODES [self ._charset ]]
258279 for i , char in enumerate (self .code ):
259280 encoded .extend (self ._maybe_switch_charset (i ))
260- code_num = self ._convert (char )
281+ code_num = self ._convert_or_buffer (char )
261282 if code_num is not None :
262283 encoded .append (code_num )
263284 # Finally look in the buffer
0 commit comments