3838)
3939_T = TypeVar ("_T" , FileDict , Data , StandaloneData , str )
4040
41+ _WHITESPACE = b" \n \t \r \f \v "
42+ _WHITESPACE_NO_NEWLINE = b" \t \r \f \v "
43+
44+ _IS_TOKEN_START = [False ] * 256
45+ for c in b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_#$" :
46+ _IS_TOKEN_START [c ] = True
47+
48+ _IS_TOKEN_CONTINUATION = _IS_TOKEN_START .copy ()
49+ for c in b"0123456789._<>#$:+-*/|^%&=!" :
50+ _IS_TOKEN_CONTINUATION [c ] = True
51+
4152
4253class ParseError (Exception ):
4354 def __init__ (self , contents : bytes | bytearray , pos : int , * , expected : str ) -> None :
@@ -50,18 +61,12 @@ def make_fatal(self) -> FoamFileDecodeError:
5061 return FoamFileDecodeError (self ._contents , self .pos , expected = self ._expected )
5162
5263
53- _WHITESPACE = b" \n \t \r \f \v "
54- _WHITESPACE_NO_NEWLINE = b" \t \r \f \v "
55- # Characters that can continue a token (used for boundary checking)
56- _TOKEN_CONTINUATION_CHARS = b"._<>#$:+-*/|^%&=!"
57-
58-
5964def _is_token_boundary (contents : bytes | bytearray , pos : int ) -> bool :
60- """Check if position is at a token boundary (not followed by a token continuation character)."""
61- if pos >= len (contents ):
65+ try :
66+ char = contents [pos ]
67+ except IndexError :
6268 return True
63- next_char = contents [pos : pos + 1 ]
64- return not (next_char .isalnum () or next_char in _TOKEN_CONTINUATION_CHARS )
69+ return not _IS_TOKEN_CONTINUATION [char ]
6570
6671
6772def _skip (
@@ -526,48 +531,64 @@ def _parse_field(contents: bytes | bytearray, pos: int) -> tuple[Field, int]:
526531
527532
528533def _parse_token (contents : bytes | bytearray , pos : int ) -> tuple [str , int ]:
529- c = contents [pos : pos + 1 ]
530- if c .isalpha () or (c and c in b"_#$" ):
534+ try :
535+ first = contents [pos ]
536+ except IndexError :
537+ raise ParseError (contents , pos , expected = "token" ) from None
538+ try :
539+ second = contents [pos + 1 ]
540+ except IndexError :
541+ second = None
542+
543+ if ((first_ok := _IS_TOKEN_START [first ]) and second is None ) or (
544+ first != ord (b"#" ) and second == ord (b"{" )
545+ ):
546+ return contents [pos : pos + 1 ].decode ("ascii" ), pos + 1
547+
548+ if first_ok :
531549 end = pos + 1
532550 depth = 0
533- while end < len (contents ):
534- c = contents [end : end + 1 ]
535- assert c
536- if (depth == 0 and (c .isalnum () or c in _TOKEN_CONTINUATION_CHARS )) or (
537- depth > 0 and c not in b";(){}[]"
538- ):
539- end += 1
540- elif c == b"(" :
541- depth += 1
542- end += 1
543- elif c == b")" and depth > 0 :
544- depth -= 1
545- end += 1
546- else :
547- break
551+ char : int = second # ty: ignore[invalid-assignment]
552+ with contextlib .suppress (IndexError ):
553+ while True :
554+ if (depth == 0 and _IS_TOKEN_CONTINUATION [char ]) or (
555+ depth > 0 and char not in b";(){}[]"
556+ ):
557+ end += 1
558+ elif char == ord (b"(" ):
559+ depth += 1
560+ end += 1
561+ elif char == ord (b")" ) and depth > 0 :
562+ depth -= 1
563+ end += 1
564+ else :
565+ break
566+ char = contents [end ]
548567
549568 if depth != 0 :
550569 raise FoamFileDecodeError (contents , pos , expected = ")" )
551570
552571 return contents [pos :end ].decode ("ascii" ), end
553572
554- if contents [ pos : pos + 1 ] == b'"' :
573+ if first == ord ( b'"' ) :
555574 end = pos + 1
556- while end < len (contents ):
557- c = contents [end : end + 1 ]
558- if c == b"\\ " :
559- if end + 1 >= len (contents ):
560- raise FoamFileDecodeError (
561- contents , pos , expected = "end of quoted string"
562- )
563- end += 2
564- elif c == b'"' :
565- end += 1
566- return contents [pos :end ].decode (), end
567- else :
568- end += 1
575+ with contextlib .suppress (IndexError ):
576+ while True :
577+ char = contents [end ]
578+ if char == ord (b"\\ " ):
579+ end += 2
580+ elif char == ord (b'"' ):
581+ return contents [pos : end + 1 ].decode (), end + 1
582+ else :
583+ end += 1
584+
569585 raise FoamFileDecodeError (contents , pos , expected = "end of quoted string" )
570586
587+ if first == ord (b"#" ) and second == ord (b"{" ):
588+ if (end := contents .find (b"#}" , pos + 2 )) == - 1 :
589+ raise FoamFileDecodeError (contents , len (contents ), expected = "#}" )
590+ return contents [pos : end + 2 ].decode (), end + 2
591+
571592 raise ParseError (contents , pos , expected = "token" )
572593
573594
0 commit comments