| 339 | } |
| 340 | |
| 341 | pub fn decode(&mut self, buf: &[u8]) -> Result<usize, ArrowError> { |
| 342 | let mut iter = BufIter::new(buf); |
| 343 | |
| 344 | while !iter.is_empty() { |
| 345 | let state = match self.stack.last_mut() { |
| 346 | Some(l) => l, |
| 347 | None => { |
| 348 | iter.skip_whitespace(); |
| 349 | if iter.is_empty() || self.cur_row >= self.batch_size { |
| 350 | break; |
| 351 | } |
| 352 | |
| 353 | // Start of row |
| 354 | self.cur_row += 1; |
| 355 | self.stack.push(DecoderState::Value); |
| 356 | self.stack.last_mut().unwrap() |
| 357 | } |
| 358 | }; |
| 359 | |
| 360 | match state { |
| 361 | // Decoding an object |
| 362 | DecoderState::Object(start_idx) => { |
| 363 | iter.advance_until(|b| !json_whitespace(b) && b != b','); |
| 364 | match next!(iter) { |
| 365 | b'"' => { |
| 366 | self.stack.push(DecoderState::Value); |
| 367 | self.stack.push(DecoderState::Colon); |
| 368 | self.stack.push(DecoderState::String); |
| 369 | } |
| 370 | b'}' => { |
| 371 | let start_idx = *start_idx; |
| 372 | let end_idx = self.elements.len() as u32; |
| 373 | self.elements[start_idx as usize] = TapeElement::StartObject(end_idx); |
| 374 | self.elements.push(TapeElement::EndObject(start_idx)); |
| 375 | self.stack.pop(); |
| 376 | } |
| 377 | b => return Err(err(b, "parsing object")), |
| 378 | } |
| 379 | } |
| 380 | // Decoding a list |
| 381 | DecoderState::List(start_idx) => { |
| 382 | iter.advance_until(|b| !json_whitespace(b) && b != b','); |
| 383 | match iter.peek() { |
| 384 | Some(b']') => { |
| 385 | iter.next(); |
| 386 | let start_idx = *start_idx; |
| 387 | let end_idx = self.elements.len() as u32; |
| 388 | self.elements[start_idx as usize] = TapeElement::StartList(end_idx); |
| 389 | self.elements.push(TapeElement::EndList(start_idx)); |
| 390 | self.stack.pop(); |
| 391 | } |
| 392 | Some(_) => self.stack.push(DecoderState::Value), |
| 393 | None => break, |
| 394 | } |
| 395 | } |
| 396 | // Decoding a string |
| 397 | DecoderState::String => { |
| 398 | let s = iter.skip_chrs(b'\\', b'"'); |