| 2373 | return position, dec_flags, bytes_to_feed, bool(need_eof), chars_to_skip |
| 2374 | |
| 2375 | def tell(self): |
| 2376 | if not self._seekable: |
| 2377 | raise UnsupportedOperation("underlying stream is not seekable") |
| 2378 | if not self._telling: |
| 2379 | raise OSError("telling position disabled by next() call") |
| 2380 | self.flush() |
| 2381 | position = self.buffer.tell() |
| 2382 | decoder = self._decoder |
| 2383 | if decoder is None or self._snapshot is None: |
| 2384 | if self._decoded_chars: |
| 2385 | # This should never happen. |
| 2386 | raise AssertionError("pending decoded text") |
| 2387 | return position |
| 2388 | |
| 2389 | # Skip backward to the snapshot point (see _read_chunk). |
| 2390 | dec_flags, next_input = self._snapshot |
| 2391 | position -= len(next_input) |
| 2392 | |
| 2393 | # How many decoded characters have been used up since the snapshot? |
| 2394 | chars_to_skip = self._decoded_chars_used |
| 2395 | if chars_to_skip == 0: |
| 2396 | # We haven't moved from the snapshot point. |
| 2397 | return self._pack_cookie(position, dec_flags) |
| 2398 | |
| 2399 | # Starting from the snapshot position, we will walk the decoder |
| 2400 | # forward until it gives us enough decoded characters. |
| 2401 | saved_state = decoder.getstate() |
| 2402 | try: |
| 2403 | # Fast search for an acceptable start point, close to our |
| 2404 | # current pos. |
| 2405 | # Rationale: calling decoder.decode() has a large overhead |
| 2406 | # regardless of chunk size; we want the number of such calls to |
| 2407 | # be O(1) in most situations (common decoders, sensible input). |
| 2408 | # Actually, it will be exactly 1 for fixed-size codecs (all |
| 2409 | # 8-bit codecs, also UTF-16 and UTF-32). |
| 2410 | skip_bytes = int(self._b2cratio * chars_to_skip) |
| 2411 | skip_back = 1 |
| 2412 | assert skip_bytes <= len(next_input) |
| 2413 | while skip_bytes > 0: |
| 2414 | decoder.setstate((b'', dec_flags)) |
| 2415 | # Decode up to temptative start point |
| 2416 | n = len(decoder.decode(next_input[:skip_bytes])) |
| 2417 | if n <= chars_to_skip: |
| 2418 | b, d = decoder.getstate() |
| 2419 | if not b: |
| 2420 | # Before pos and no bytes buffered in decoder => OK |
| 2421 | dec_flags = d |
| 2422 | chars_to_skip -= n |
| 2423 | break |
| 2424 | # Skip back by buffered amount and reset heuristic |
| 2425 | skip_bytes -= len(b) |
| 2426 | skip_back = 1 |
| 2427 | else: |
| 2428 | # We're too far ahead, skip back a bit |
| 2429 | skip_bytes -= skip_back |
| 2430 | skip_back = skip_back * 2 |
| 2431 | else: |
| 2432 | skip_bytes = 0 |