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,62 @@ 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 :
544+ return contents [pos : pos + 1 ].decode ("ascii" ), pos + 1
545+
546+ if first_ok and (first != ord (b"#" ) or second != ord (b"{" )):
531547 end = pos + 1
532548 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
549+ char : int = second # ty: ignore[invalid-assignment]
550+ with contextlib .suppress (IndexError ):
551+ while True :
552+ if (depth == 0 and _IS_TOKEN_CONTINUATION [char ]) or (
553+ depth > 0 and char not in b";(){}[]"
554+ ):
555+ end += 1
556+ elif char == ord (b"(" ):
557+ depth += 1
558+ end += 1
559+ elif char == ord (b")" ) and depth > 0 :
560+ depth -= 1
561+ end += 1
562+ else :
563+ break
564+ char = contents [end ]
548565
549566 if depth != 0 :
550567 raise FoamFileDecodeError (contents , pos , expected = ")" )
551568
552569 return contents [pos :end ].decode ("ascii" ), end
553570
554- if contents [ pos : pos + 1 ] == b'"' :
571+ if first == ord ( b'"' ) :
555572 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
573+ with contextlib .suppress (IndexError ):
574+ while True :
575+ char = contents [end ]
576+ if char == ord (b"\\ " ):
577+ end += 2
578+ elif char == ord (b'"' ):
579+ return contents [pos : end + 1 ].decode (), end + 1
580+ else :
581+ end += 1
582+
569583 raise FoamFileDecodeError (contents , pos , expected = "end of quoted string" )
570584
585+ if first == ord (b"#" ) and second == ord (b"{" ):
586+ if (end := contents .find (b"#}" , pos + 2 )) == - 1 :
587+ raise FoamFileDecodeError (contents , len (contents ), expected = "#}" )
588+ return contents [pos : end + 2 ].decode (), end + 2
589+
571590 raise ParseError (contents , pos , expected = "token" )
572591
573592
0 commit comments