MCPcopy Index your code
hub / github.com/python/cpython / header_encode_lines

Method header_encode_lines

Lib/email/charset.py:293–352  ·  view source on GitHub ↗

Header-encode a string by converting it first to bytes. This is similar to `header_encode()` except that the string is fit into maximum line lengths as given by the argument. :param string: A unicode string for the header. It must be possible to encode this str

(self, string, maxlengths)

Source from the content-addressed store, hash-verified

291 return encoder_module.header_encode(header_bytes, codec)
292
293 def header_encode_lines(self, string, maxlengths):
294 """Header-encode a string by converting it first to bytes.
295
296 This is similar to `header_encode()` except that the string is fit
297 into maximum line lengths as given by the argument.
298
299 :param string: A unicode string for the header. It must be possible
300 to encode this string to bytes using the character set's
301 output codec.
302 :param maxlengths: Maximum line length iterator. Each element
303 returned from this iterator will provide the next maximum line
304 length. This parameter is used as an argument to built-in next()
305 and should never be exhausted. The maximum line lengths should
306 not count the RFC 2047 chrome. These line lengths are only a
307 hint; the splitter does the best it can.
308 :return: Lines of encoded strings, each with RFC 2047 chrome.
309 """
310 # See which encoding we should use.
311 codec = self.output_codec or 'us-ascii'
312 header_bytes = _encode(string, codec)
313 encoder_module = self._get_encoder(header_bytes)
314 encoder = partial(encoder_module.header_encode, charset=codec)
315 # Calculate the number of characters that the RFC 2047 chrome will
316 # contribute to each line.
317 charset = self.get_output_charset()
318 extra = len(charset) + RFC2047_CHROME_LEN
319 # Now comes the hard part. We must encode bytes but we can't split on
320 # bytes because some character sets are variable length and each
321 # encoded word must stand on its own. So the problem is you have to
322 # encode to bytes to figure out this word's length, but you must split
323 # on characters. This causes two problems: first, we don't know how
324 # many octets a specific substring of unicode characters will get
325 # encoded to, and second, we don't know how many ASCII characters
326 # those octets will get encoded to. Unless we try it. Which seems
327 # inefficient. In the interest of being correct rather than fast (and
328 # in the hope that there will be few encoded headers in any such
329 # message), brute force it. :(
330 lines = []
331 current_line = []
332 maxlen = next(maxlengths) - extra
333 for character in string:
334 current_line.append(character)
335 this_line = EMPTYSTRING.join(current_line)
336 length = encoder_module.header_length(_encode(this_line, charset))
337 if length > maxlen:
338 # This last character doesn't fit so pop it off.
339 current_line.pop()
340 # Does nothing fit on the first line?
341 if not lines and not current_line:
342 lines.append(None)
343 else:
344 joined_line = EMPTYSTRING.join(current_line)
345 header_bytes = _encode(joined_line, codec)
346 lines.append(encoder(header_bytes))
347 current_line = [character]
348 maxlen = next(maxlengths) - extra
349 joined_line = EMPTYSTRING.join(current_line)
350 header_bytes = _encode(joined_line, codec)

Callers 1

feedMethod · 0.80

Calls 7

_get_encoderMethod · 0.95
get_output_charsetMethod · 0.95
partialClass · 0.90
_encodeFunction · 0.70
appendMethod · 0.45
joinMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected