Encode the given binary byte array as a compact UTF-8 string. Each byte value is encoded as UTF-8, except for specific byte values that are escaped as two bytes. This kind of encoding results in a string that will compress well by both gzip and brotli, unlike base64 encoding binary data wou
(filename)
| 2961 | |
| 2962 | |
| 2963 | def binary_encode(filename): |
| 2964 | """Encode the given binary byte array as a compact UTF-8 string. |
| 2965 | |
| 2966 | Each byte value is encoded as UTF-8, except for specific byte values that |
| 2967 | are escaped as two bytes. This kind of encoding results in a string that will |
| 2968 | compress well by both gzip and brotli, unlike base64 encoding binary data |
| 2969 | would do. |
| 2970 | """ |
| 2971 | data = utils.read_binary(filename) |
| 2972 | |
| 2973 | # Decide whether to enclose the generated binary data in single-quotes '' or |
| 2974 | # double-quotes "" by looking at which character ends up requiring fewer |
| 2975 | # escapes of that string character. |
| 2976 | num_single_quotes = data.count(ord("'")) |
| 2977 | num_double_quotes = data.count(ord('"')) |
| 2978 | quote_char = ord("'") if num_single_quotes < num_double_quotes else ord('"') |
| 2979 | |
| 2980 | out = bytearray(len(data) * 2 + 2) # Size output buffer conservatively |
| 2981 | out[0] = quote_char # Emit string start quote |
| 2982 | i = 1 |
| 2983 | for d in data: |
| 2984 | if d == quote_char: |
| 2985 | buf = [ord('\\'), d] # Escape the string quote character with a backslash since we are writing the binary data inside a string. |
| 2986 | elif d == ord('\r'): |
| 2987 | buf = [ord('\\'), ord('r')] # Escape carriage return 0x0D as \r -> 2 bytes |
| 2988 | elif d == ord('\n'): |
| 2989 | buf = [ord('\\'), ord('n')] # Escape newline 0x0A as \n -> 2 bytes |
| 2990 | elif d == ord('\\'): |
| 2991 | buf = [ord('\\'), ord('\\')] # Escape backslash \ as \\ -> 2 bytes |
| 2992 | else: |
| 2993 | buf = chr(d).encode('utf-8') # Otherwise write the original value encoded in UTF-8 (1 or 2 bytes). |
| 2994 | for b in buf: # Write the bytes to output buffer |
| 2995 | out[i] = b |
| 2996 | i += 1 |
| 2997 | out[i] = quote_char # Emit string end quote |
| 2998 | i += 1 |
| 2999 | return out[0:i].decode('utf-8') # Crop output buffer to the actual used size |
| 3000 | |
| 3001 | |
| 3002 | # Returns the subresource location for run-time access |