| 3964 | } |
| 3965 | |
| 3966 | fn take_decoded_chars( |
| 3967 | &mut self, |
| 3968 | append: Option<PyStrRef>, |
| 3969 | vm: &VirtualMachine, |
| 3970 | ) -> PyStrRef { |
| 3971 | let empty_str = || vm.ctx.empty_str.to_owned(); |
| 3972 | let chars_pos = core::mem::take(&mut self.decoded_chars_used).bytes; |
| 3973 | let decoded_chars = match core::mem::take(&mut self.decoded_chars) { |
| 3974 | None => return append.unwrap_or_else(empty_str), |
| 3975 | Some(s) if s.is_empty() => return append.unwrap_or_else(empty_str), |
| 3976 | Some(s) => s, |
| 3977 | }; |
| 3978 | let append_len = append.as_ref().map_or(0, |s| s.byte_len()); |
| 3979 | if append_len == 0 && chars_pos == 0 { |
| 3980 | return decoded_chars; |
| 3981 | } |
| 3982 | // TODO: in-place editing of `str` when refcount == 1 |
| 3983 | let decoded_chars_unused = &decoded_chars.as_wtf8()[chars_pos..]; |
| 3984 | let mut s = Wtf8Buf::with_capacity(decoded_chars_unused.len() + append_len); |
| 3985 | s.push_wtf8(decoded_chars_unused); |
| 3986 | if let Some(append) = append { |
| 3987 | s.push_wtf8(append.as_wtf8()) |
| 3988 | } |
| 3989 | PyStr::from(s).into_ref(&vm.ctx) |
| 3990 | } |
| 3991 | } |
| 3992 | |
| 3993 | impl Destructor for TextIOWrapper { |