## Coverage Report

#### Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/arrow-rs/arrow-avro/src/reader/cursor.rs

    Line
    Count
    Source
    1
    // Licensed to the Apache Software Foundation (ASF) under one
    2
    // or more contributor license agreements.  See the NOTICE file
    3
    // distributed with this work for additional information
    4
    // regarding copyright ownership.  The ASF licenses this file
    5
    // to you under the Apache License, Version 2.0 (the
    6
    // "License"); you may not use this file except in compliance
    7
    // with the License.  You may obtain a copy of the License at
    8
    //
    9
    //   http://www.apache.org/licenses/LICENSE-2.0
    10
    //
    11
    // Unless required by applicable law or agreed to in writing,
    12
    // software distributed under the License is distributed on an
    13
    // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14
    // KIND, either express or implied.  See the License for the
    15
    // specific language governing permissions and limitations
    16
    // under the License.
    17
    18
    use crate::reader::vlq::read_varint;
    19
    use arrow_schema::ArrowError;
    20
    21
    /// A wrapper around a byte slice, providing low-level decoding for Avro
    22
    ///
    23
    /// <https://avro.apache.org/docs/1.11.1/specification/#encodings>
    24
    #[derive(Debug)]
    25
    pub(crate) struct AvroCursor<'a> {
    26
        buf: &'a [u8],
    27
        start_len: usize,
    28
    }
    29
    30
    impl<'a> AvroCursor<'a> {
    31
    189
        pub(crate) fn new(buf: &'a [u8]) -> Self {
    32
    189
            Self {
    33
    189
                buf,
    34
    189
                start_len: buf.len(),
    35
    189
            }
    36
    189
        }
    37
    38
        /// Returns the current cursor position
    39
        #[inline]
    40
    144
        pub(crate) fn position(&self) -> usize {
    41
    144
            self.start_len - self.buf.len()
    42
    144
        }
    43
    44
        /// Read a single `u8`
    45
        #[inline]
    46
    311
        pub(crate) fn get_u8(&mut self) -> Result<u8, ArrowError> {
    47
    311
            match self.buf.first().copied() {
    48
    311
                Some(x) => {
    49
    311
                    self.buf = &self.buf[1..];
    50
    311
                    Ok(x)
    51
                }
    52
    0
                None => Err(ArrowError::ParseError("Unexpected EOF".to_string())),
    53
            }
    54
    311
        }
    55
    56
        #[inline]
    57
    311
        pub(crate) fn get_bool(&mut self) -> Result<bool, ArrowError> {
    58
    311
            Ok(self.get_u8()?0 != 0)
    59
    311
        }
    60
    61
    7.39k
        pub(crate) fn read_vlq(&mut self) -> Result<u64, ArrowError> {
    62
    7.39k
            let (val7.39k, offset7.39k) = read_varint(self.buf)
    63
    7.39k
                .ok_or_else(|| ArrowError::ParseError("bad varint"1.to_string1()))?1;
    64
    7.39k
            self.buf = &self.buf[offset..];
    65
    7.39k
            Ok(val)
    66
    7.39k
        }
    67
    68
        #[inline]
    69
    1.43k
        pub(crate) fn get_int(&mut self) -> Result<i32, ArrowError> {
    70
    1.43k
            let varint1.43k = self.read_vlq()?1;
    71
    1.43k
            let val: u32 = varint
    72
    1.43k
                .try_into()
    73
    1.43k
                .map_err(|_| ArrowError::ParseError("varint overflow"0.to_string0()))?0;
    74
    1.43k
            Ok((val >> 1) as i32 ^ -((val & 1) as i32))
    75
    1.43k
        }
    76
    77
        #[inline]
    78
    1.74k
        pub(crate) fn get_long(&mut self) -> Result<i64, ArrowError> {
    79
    1.74k
            let val = self.read_vlq()?0;
    80
    1.74k
            Ok((val >> 1) as i64 ^ -((val & 1) as i64))
    81
    1.74k
        }
    82
    83
    734
        pub(crate) fn get_bytes(&mut self) -> Result<&'a [u8], ArrowError> {
    84
    734
            let len: usize = self.get_long()?0.try_into().map_err(|_| {0
    85
    0
                ArrowError::ParseError("offset overflow reading avro bytes".to_string())
    86
    0
            })?;
    87
    88
    734
            if (self.buf.len() < len) {
    89
    0
                return Err(ArrowError::ParseError(
    90
    0
                    "Unexpected EOF reading bytes".to_string(),
    91
    0
                ));
    92
    734
            }
    93
    734
            let ret = &self.buf[..len];
    94
    734
            self.buf = &self.buf[len..];
    95
    734
            Ok(ret)
    96
    734
        }
    97
    98
        #[inline]
    99
    309
        pub(crate) fn get_float(&mut self) -> Result<f32, ArrowError> {
    100
    309
            if (self.buf.len() < 4) {
    101
    0
                return Err(ArrowError::ParseError(
    102
    0
                    "Unexpected EOF reading float".to_string(),
    103
    0
                ));
    104
    309
            }
    105
    309
            let ret = f32::from_le_bytes(self.buf[..4].try_into().unwrap());
    106
    309
            self.buf = &self.buf[4..];
    107
    309
            Ok(ret)
    108
    309
        }
    109
    110
        #[inline]
    111
    317
        pub(crate) fn get_double(&mut self) -> Result<f64, ArrowError> {
    112
    317
            if (self.buf.len() < 8) {
    113
    0
                return Err(ArrowError::ParseError(
    114
    0
                    "Unexpected EOF reading float".to_string(),
    115
    0
                ));
    116
    317
            }
    117
    317
            let ret = f64::from_le_bytes(self.buf[..8].try_into().unwrap());
    118
    317
            self.buf = &self.buf[8..];
    119
    317
            Ok(ret)
    120
    317
        }
    121
    122
        /// Read exactly `n` bytes from the buffer (e.g. for Avro `fixed`).
    123
    218
        pub(crate) fn get_fixed(&mut self, n: usize) -> Result<&'a [u8], ArrowError> {
    124
    218
            if self.buf.len() < n {
    125
    0
                return Err(ArrowError::ParseError(
    126
    0
                    "Unexpected EOF reading fixed".to_string(),
    127
    0
                ));
    128
    218
            }
    129
    218
            let ret = &self.buf[..n];
    130
    218
            self.buf = &self.buf[n..];
    131
    218
            Ok(ret)
    132
    218
        }
    133
    }