Chromium Code Reviews| Index: client/libs/logdog/streamname.py |
| diff --git a/client/libs/logdog/streamname.py b/client/libs/logdog/streamname.py |
| index 3b92fa72980a69d9ec3180c1e257c1ffe895d20b..0243bc214a818f9faf9c046a6d301a91073c6bd4 100644 |
| --- a/client/libs/logdog/streamname.py |
| +++ b/client/libs/logdog/streamname.py |
| @@ -13,6 +13,7 @@ _MAX_STREAM_NAME_LENGTH = 4096 |
| _MAX_TAG_KEY_LENGTH = 64 |
| _MAX_TAG_VALUE_LENGTH = 4096 |
| + |
| def validate_stream_name(v, maxlen=None): |
| """Verifies that a given stream name is valid. |
| @@ -42,3 +43,66 @@ def validate_tag(key, value): |
| """ |
| validate_stream_name(key, maxlen=_MAX_TAG_KEY_LENGTH) |
| validate_stream_name(value, maxlen=_MAX_TAG_VALUE_LENGTH) |
| + |
| + |
| +def normalize(v, prefix=None): |
| + """Given a string, "v", mutate it into a valid stream name. |
| + |
| + This operates by replacing invalid stream naem characters with underscores (_) |
| + when encountered. |
| + |
| + A special case is when "v" begins with an invalid character. In this case, we |
| + will replace it with the "prefix", if one is supplied. |
| + |
| + See _STREAM_NAME_RE for a description of a valid stream name. |
| + |
| + Raises: |
| + ValueError: If normalization could not be successfully performed. |
| + """ |
| + if len(v) == 0: |
| + if not prefix: |
| + raise ValueError('Cannot normalize empty name with no prefix.') |
| + v = prefix |
| + else: |
| + out = [] |
| + for i, ch in enumerate(v): |
| + if i == 0 and not _is_valid_stream_char(ch, first=True): |
| + # The first letter is special, and must be alphanumeric. |
| + # If we have a prefix, prepend that to the resulting string. |
| + if prefix is None: |
| + raise ValueError('Name has invalid beginning, and no prefix was ' |
| + 'provided.') |
| + out.append(prefix) |
|
martiniss
2016/08/11 20:24:43
Doing iteration over every character in a string l
dnj
2016/08/11 20:42:29
If you know a better way to do this, LMK.
|
| + |
| + if not _is_valid_stream_char(ch): |
| + ch = '_' |
| + out.append(ch) |
| + v = ''.join(out) |
| + |
| + # Validate the resulting string. |
| + validate_stream_name(v) |
| + return v |
| + |
| + |
| +def _is_valid_stream_char(ch, first=False): |
| + """Returns (bool): True if a character is alphanumeric. |
| + |
| + The first character must be alphanumeric, matching [a-zA-Z0-9]. |
| + Additional characters must either be alphanumeric or one of: (: _ - .). |
| + |
| + Args: |
| + ch (str): the character to evaluate. |
| + first (bool): if true, apply special first-character constraints. |
| + """ |
| + # Alphanumeric check. |
| + ch_ord = ord(ch) |
| + if ((ch_ord >= ord('0') and ch_ord <= ord('9')) or |
|
martiniss
2016/08/11 20:24:43
Why not use https://docs.python.org/2/library/stri
dnj
2016/08/11 20:42:29
This seems faster, but might as well.
|
| + (ch_ord >= ord('a') and ch_ord <= ord('z')) or |
| + (ch_ord >= ord('A') and ch_ord <= ord('Z'))): |
| + return True |
| + if first: |
| + # The first character must be alphanumeric. |
| + return False |
| + |
| + # Check additional middle-name characters: |
| + return ch in ':_-./' |