Return a POSIX.1-2008 extended or global header sequence that contains a list of keyword, value pairs. The values must be strings.
(cls, pax_headers, type, encoding)
| 1224 | |
| 1225 | @classmethod |
| 1226 | def _create_pax_generic_header(cls, pax_headers, type, encoding): |
| 1227 | """Return a POSIX.1-2008 extended or global header sequence |
| 1228 | that contains a list of keyword, value pairs. The values |
| 1229 | must be strings. |
| 1230 | """ |
| 1231 | # Check if one of the fields contains surrogate characters and thereby |
| 1232 | # forces hdrcharset=BINARY, see _proc_pax() for more information. |
| 1233 | binary = False |
| 1234 | for keyword, value in pax_headers.items(): |
| 1235 | try: |
| 1236 | value.encode("utf-8", "strict") |
| 1237 | except UnicodeEncodeError: |
| 1238 | binary = True |
| 1239 | break |
| 1240 | |
| 1241 | records = b"" |
| 1242 | if binary: |
| 1243 | # Put the hdrcharset field at the beginning of the header. |
| 1244 | records += b"21 hdrcharset=BINARY\n" |
| 1245 | |
| 1246 | for keyword, value in pax_headers.items(): |
| 1247 | keyword = keyword.encode("utf-8") |
| 1248 | if binary: |
| 1249 | # Try to restore the original byte representation of 'value'. |
| 1250 | # Needless to say, that the encoding must match the string. |
| 1251 | value = value.encode(encoding, "surrogateescape") |
| 1252 | else: |
| 1253 | value = value.encode("utf-8") |
| 1254 | |
| 1255 | l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' |
| 1256 | n = p = 0 |
| 1257 | while True: |
| 1258 | n = l + len(str(p)) |
| 1259 | if n == p: |
| 1260 | break |
| 1261 | p = n |
| 1262 | records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" |
| 1263 | |
| 1264 | # We use a hardcoded "././@PaxHeader" name like star does |
| 1265 | # instead of the one that POSIX recommends. |
| 1266 | info = {} |
| 1267 | info["name"] = "././@PaxHeader" |
| 1268 | info["type"] = type |
| 1269 | info["size"] = len(records) |
| 1270 | info["magic"] = POSIX_MAGIC |
| 1271 | |
| 1272 | # Create pax header + record blocks. |
| 1273 | return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ |
| 1274 | cls._create_payload(records) |
| 1275 | |
| 1276 | @classmethod |
| 1277 | def frombuf(cls, buf, encoding, errors): |
no test coverage detected