MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / read_string

Method read_string

std/json/src/main/tokenizer.rs:87–139  ·  view source on GitHub ↗
(&mut self)

Source from the content-addressed store, hash-verified

85 }
86
87 fn read_string(&mut self) -> Result<Token, JsonError> {
88 self.pos += 1;
89 let mut out = String::new();
90 while self.pos < self.src.len() {
91 let c = self.src[self.pos];
92 if c == b'"' { self.pos += 1; return Ok(Token::Str(out)); }
93 if c == b'\\' {
94 self.pos += 1;
95 if self.pos >= self.src.len() { return Err(self.err("dangling escape")); }
96 let esc = self.src[self.pos];
97 self.pos += 1;
98 match esc {
99 b'"' => out.push('"'),
100 b'\\' => out.push('\\'),
101 b'/' => out.push('/'),
102 b'b' => out.push('\u{08}'),
103 b'f' => out.push('\u{0C}'),
104 b'n' => out.push('\n'),
105 b'r' => out.push('\r'),
106 b't' => out.push('\t'),
107 b'u' => {
108 let cp = self.read_hex4()?;
109 if (0xD800..=0xDBFF).contains(&cp) {
110 if self.src.len() < self.pos + 2 || self.src[self.pos] != b'\\' || self.src[self.pos + 1] != b'u' {
111 return Err(self.err("unpaired high surrogate"));
112 }
113 self.pos += 2;
114 let low = self.read_hex4()?;
115 if !(0xDC00..=0xDFFF).contains(&low) {
116 return Err(self.err("invalid low surrogate"));
117 }
118 let combined = 0x10000 + ((cp - 0xD800) << 10) + (low - 0xDC00);
119 out.push(char::from_u32(combined).ok_or_else(|| self.err("invalid surrogate pair"))?);
120 } else if (0xDC00..=0xDFFF).contains(&cp) {
121 return Err(self.err("unexpected low surrogate"));
122 } else {
123 out.push(char::from_u32(cp).ok_or_else(|| self.err("invalid unicode escape"))?);
124 }
125 }
126 _ => return Err(self.err("invalid escape")),
127 }
128 continue;
129 }
130 if c < 0x20 { return Err(self.err("control character in string")); }
131 let len = utf8_len(c).ok_or_else(|| self.err("invalid utf-8 lead byte"))?;
132 if self.pos + len > self.src.len() { return Err(self.err("truncated utf-8")); }
133 let bytes = &self.src[self.pos..self.pos + len];
134 let s = core::str::from_utf8(bytes).map_err(|_| self.err("invalid utf-8"))?;
135 out.push_str(s);
136 self.pos += len;
137 }
138 Err(self.err("unterminated string"))
139 }
140
141 fn read_hex4(&mut self) -> Result<u32, JsonError> {
142 if self.pos + 4 > self.src.len() { return Err(self.err("truncated \\u escape")); }

Callers 1

next_tokenMethod · 0.45

Calls 6

utf8_lenFunction · 0.85
pushMethod · 0.80
read_hex4Method · 0.80
lenMethod · 0.45
errMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected