From 236bd6b409af7682c944c6f50394bb23f1d0cabe Mon Sep 17 00:00:00 2001 From: Edwin Date: Fri, 8 Mar 2024 11:08:46 -0800 Subject: [PATCH] Make changes to PerCharacterEscaper, uses __escape_code_point --- .../selfie_lib/PerCharacterEscaper.py | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/python/selfie-lib/selfie_lib/PerCharacterEscaper.py b/python/selfie-lib/selfie_lib/PerCharacterEscaper.py index 277df098..59085c6c 100644 --- a/python/selfie-lib/selfie_lib/PerCharacterEscaper.py +++ b/python/selfie-lib/selfie_lib/PerCharacterEscaper.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List class PerCharacterEscaper: @@ -12,16 +12,12 @@ def __init__( self.__escaped_code_points = escaped_code_points self.__escaped_by_code_points = escaped_by_code_points - def __first_offset_needing_escape( - self, input_string: str, escape_code_point: Optional[int] = None - ) -> int: - if escape_code_point is None: - escape_code_point = self.__escape_code_point + def __first_offset_needing_escape(self, input_string: str) -> int: length = len(input_string) for offset in range(length): codepoint = ord(input_string[offset]) if ( - codepoint == escape_code_point + codepoint == self.__escape_code_point or codepoint in self.__escaped_code_points ): return offset @@ -45,41 +41,43 @@ def escape(self, input_string: str) -> str: return "".join(result) def unescape(self, input_string: str) -> str: - if input_string.endswith( - chr(self.__escape_code_point) - ) and not input_string.endswith(chr(self.__escape_code_point) * 2): - raise ValueError( - f"Escape character '{chr(self.__escape_code_point)}' can't be the last character in a string." - ) - - no_escapes = self.__first_offset_needing_escape( - input_string, self.__escape_code_point - ) - if no_escapes == -1: + if not input_string: return input_string - else: - result = [] - result.append(input_string[:no_escapes]) - skip_next = False - for i in range(no_escapes, len(input_string)): - if skip_next: - skip_next = False - continue - codepoint = ord(input_string[i]) - if codepoint == self.__escape_code_point and (i + 1) < len( - input_string - ): - next_codepoint = ord(input_string[i + 1]) - if next_codepoint in self.__escaped_by_code_points: - idx = self.__escaped_by_code_points.index(next_codepoint) - result.append(chr(self.__escaped_code_points[idx])) - skip_next = True + + result = [] + i = 0 + + while i < len(input_string): + if ord(input_string[i]) == self.__escape_code_point: + if i + 1 < len(input_string): + next_char = input_string[i + 1] + next_codepoint = ord(next_char) + + if next_codepoint == self.__escape_code_point: + result.append(chr(next_codepoint)) + i += 2 else: - result.append(input_string[i + 1]) - skip_next = True + try: + idx = self.__escaped_by_code_points.index(next_codepoint) + result.append(chr(self.__escaped_code_points[idx])) + i += 2 + continue + except ValueError: + result.append(next_char) + i += 2 else: - result.append(chr(codepoint)) - return "".join(result) + raise ValueError( + f"Escape character '{chr(self.__escape_code_point)}' can't be the last character in a string." + ) + else: + result.append(input_string[i]) + i += 1 + + processed_string = "".join(result) + if processed_string == input_string: + return input_string + else: + return processed_string @classmethod def self_escape(cls, escape_policy):