oracle_rs/buffer/
read.rs

1//! Read buffer for decoding TNS protocol data
2//!
3//! Provides methods for reading various data types from a byte buffer,
4//! following the Oracle TNS wire format conventions.
5
6use bytes::Bytes;
7
8use crate::constants::length;
9use crate::error::{Error, Result};
10
11/// A buffer for reading TNS protocol data
12#[derive(Debug)]
13pub struct ReadBuffer {
14    /// The underlying byte data
15    data: Bytes,
16    /// Current read position
17    pos: usize,
18}
19
20impl ReadBuffer {
21    /// Create a new ReadBuffer from bytes
22    pub fn new(data: Bytes) -> Self {
23        Self { data, pos: 0 }
24    }
25
26    /// Create a new ReadBuffer from a byte slice
27    pub fn from_slice(data: &[u8]) -> Self {
28        Self {
29            data: Bytes::copy_from_slice(data),
30            pos: 0,
31        }
32    }
33
34    /// Create a new ReadBuffer from a Vec
35    pub fn from_vec(data: Vec<u8>) -> Self {
36        Self {
37            data: Bytes::from(data),
38            pos: 0,
39        }
40    }
41
42    /// Get the current position in the buffer
43    #[inline]
44    pub fn position(&self) -> usize {
45        self.pos
46    }
47
48    /// Get the total length of the buffer
49    #[inline]
50    pub fn len(&self) -> usize {
51        self.data.len()
52    }
53
54    /// Check if the buffer is empty
55    #[inline]
56    pub fn is_empty(&self) -> bool {
57        self.data.is_empty()
58    }
59
60    /// Get the number of bytes remaining to be read
61    #[inline]
62    pub fn remaining(&self) -> usize {
63        self.data.len().saturating_sub(self.pos)
64    }
65
66    /// Get a slice of the remaining bytes (without advancing position)
67    #[inline]
68    pub fn remaining_bytes(&self) -> &[u8] {
69        &self.data[self.pos..]
70    }
71
72    /// Check if there are at least `n` bytes remaining
73    #[inline]
74    pub fn has_remaining(&self, n: usize) -> bool {
75        self.remaining() >= n
76    }
77
78    /// Skip `n` bytes in the buffer
79    pub fn skip(&mut self, n: usize) -> Result<()> {
80        self.ensure_remaining(n)?;
81        self.pos += n;
82        Ok(())
83    }
84
85    /// Skip raw bytes that may be chunked
86    ///
87    /// This is used for skipping variable-length data in Oracle's TTC protocol.
88    /// The first byte gives the length. If the length is TNS_LONG_LENGTH_INDICATOR (254),
89    /// then chunks are read and discarded until a chunk with length 0 is found.
90    pub fn skip_raw_bytes_chunked(&mut self) -> Result<()> {
91        let length = self.read_u8()?;
92        if length != length::LONG_INDICATOR {
93            // Simple case: skip the specified number of bytes
94            self.skip(length as usize)?;
95        } else {
96            // Chunked case: keep reading and skipping chunks until chunk size is 0
97            loop {
98                let chunk_size = self.read_ub4()? as usize;
99                if chunk_size == 0 {
100                    break;
101                }
102                self.skip(chunk_size)?;
103            }
104        }
105        Ok(())
106    }
107
108    /// Read raw bytes that may be chunked
109    ///
110    /// This is used for reading variable-length data in Oracle's TTC protocol.
111    /// The first byte gives the length. If the length is TNS_LONG_LENGTH_INDICATOR (254),
112    /// then chunks are read and concatenated until a chunk with length 0 is found.
113    pub fn read_raw_bytes_chunked(&mut self) -> Result<Vec<u8>> {
114        let length = self.read_u8()?;
115        if length != length::LONG_INDICATOR {
116            // Simple case: read the specified number of bytes
117            self.read_bytes_vec(length as usize)
118        } else {
119            // Chunked case: keep reading chunks until chunk size is 0
120            let mut result = Vec::new();
121            loop {
122                let chunk_size = self.read_ub4()? as usize;
123                if chunk_size == 0 {
124                    break;
125                }
126                let chunk = self.read_bytes_vec(chunk_size)?;
127                result.extend_from_slice(&chunk);
128            }
129            Ok(result)
130        }
131    }
132
133    /// Reset the buffer position to the beginning
134    pub fn reset(&mut self) {
135        self.pos = 0;
136    }
137
138    /// Set the buffer position
139    pub fn set_position(&mut self, pos: usize) -> Result<()> {
140        if pos > self.data.len() {
141            return Err(Error::BufferUnderflow {
142                needed: pos,
143                available: self.data.len(),
144            });
145        }
146        self.pos = pos;
147        Ok(())
148    }
149
150    /// Get a slice of the remaining data
151    pub fn remaining_slice(&self) -> &[u8] {
152        &self.data[self.pos..]
153    }
154
155    /// Get the underlying bytes
156    pub fn as_bytes(&self) -> &Bytes {
157        &self.data
158    }
159
160    // =========================================================================
161    // Internal helpers
162    // =========================================================================
163
164    #[inline]
165    fn ensure_remaining(&self, n: usize) -> Result<()> {
166        if self.remaining() < n {
167            Err(Error::BufferUnderflow {
168                needed: n,
169                available: self.remaining(),
170            })
171        } else {
172            Ok(())
173        }
174    }
175
176    // =========================================================================
177    // Raw byte reads
178    // =========================================================================
179
180    /// Read a single byte
181    pub fn read_u8(&mut self) -> Result<u8> {
182        self.ensure_remaining(1)?;
183        let value = self.data[self.pos];
184        self.pos += 1;
185        Ok(value)
186    }
187
188    /// Read raw bytes into a slice
189    pub fn read_bytes(&mut self, buf: &mut [u8]) -> Result<()> {
190        let n = buf.len();
191        self.ensure_remaining(n)?;
192        buf.copy_from_slice(&self.data[self.pos..self.pos + n]);
193        self.pos += n;
194        Ok(())
195    }
196
197    /// Read raw bytes and return as a new Bytes
198    pub fn read_bytes_owned(&mut self, n: usize) -> Result<Bytes> {
199        self.ensure_remaining(n)?;
200        let bytes = self.data.slice(self.pos..self.pos + n);
201        self.pos += n;
202        Ok(bytes)
203    }
204
205    /// Read raw bytes and return as a Vec
206    pub fn read_bytes_vec(&mut self, n: usize) -> Result<Vec<u8>> {
207        self.ensure_remaining(n)?;
208        let bytes = self.data[self.pos..self.pos + n].to_vec();
209        self.pos += n;
210        Ok(bytes)
211    }
212
213    // =========================================================================
214    // Big-endian integer reads (network byte order)
215    // =========================================================================
216
217    /// Read a 16-bit unsigned integer in big-endian format
218    pub fn read_u16_be(&mut self) -> Result<u16> {
219        self.ensure_remaining(2)?;
220        let value = u16::from_be_bytes([self.data[self.pos], self.data[self.pos + 1]]);
221        self.pos += 2;
222        Ok(value)
223    }
224
225    /// Read a 16-bit signed integer in big-endian format
226    pub fn read_i16_be(&mut self) -> Result<i16> {
227        self.ensure_remaining(2)?;
228        let value = i16::from_be_bytes([self.data[self.pos], self.data[self.pos + 1]]);
229        self.pos += 2;
230        Ok(value)
231    }
232
233    /// Read a 16-bit unsigned integer in little-endian format
234    pub fn read_u16_le(&mut self) -> Result<u16> {
235        self.ensure_remaining(2)?;
236        let value = u16::from_le_bytes([self.data[self.pos], self.data[self.pos + 1]]);
237        self.pos += 2;
238        Ok(value)
239    }
240
241    /// Read a 32-bit unsigned integer in big-endian format
242    pub fn read_u32_be(&mut self) -> Result<u32> {
243        self.ensure_remaining(4)?;
244        let value = u32::from_be_bytes([
245            self.data[self.pos],
246            self.data[self.pos + 1],
247            self.data[self.pos + 2],
248            self.data[self.pos + 3],
249        ]);
250        self.pos += 4;
251        Ok(value)
252    }
253
254    /// Read a 64-bit unsigned integer in big-endian format
255    pub fn read_u64_be(&mut self) -> Result<u64> {
256        self.ensure_remaining(8)?;
257        let value = u64::from_be_bytes([
258            self.data[self.pos],
259            self.data[self.pos + 1],
260            self.data[self.pos + 2],
261            self.data[self.pos + 3],
262            self.data[self.pos + 4],
263            self.data[self.pos + 5],
264            self.data[self.pos + 6],
265            self.data[self.pos + 7],
266        ]);
267        self.pos += 8;
268        Ok(value)
269    }
270
271    // =========================================================================
272    // TNS-specific reads (Oracle's variable-length encoding)
273    // =========================================================================
274
275    /// Read a TNS UB1 (unsigned byte)
276    #[inline]
277    pub fn read_ub1(&mut self) -> Result<u8> {
278        self.read_u8()
279    }
280
281    /// Read a TNS UB2 (unsigned 2-byte, variable length encoded)
282    ///
283    /// TNS UB2 uses a length-prefixed encoding where:
284    /// - First byte is the length (0, 1, or 2)
285    /// - If length is 0: value is 0
286    /// - If length is 1: read 1 byte
287    /// - If length is 2: read 2 bytes as big-endian u16
288    pub fn read_ub2(&mut self) -> Result<u16> {
289        let len = self.read_ub_length()?;
290        match len {
291            0 => Ok(0),
292            1 => Ok(self.read_u8()? as u16),
293            2 => self.read_u16_be(),
294            _ => Err(Error::InvalidLengthIndicator(len)),
295        }
296    }
297
298    /// Read a TNS SB2 (signed 2-byte, variable length encoded)
299    ///
300    /// Same encoding as UB2 but returns signed i16
301    pub fn read_sb2(&mut self) -> Result<i16> {
302        let len = self.read_ub_length()?;
303        match len {
304            0 => Ok(0),
305            1 => Ok(self.read_u8()? as i8 as i16),
306            2 => Ok(self.read_i16_be()?),
307            _ => Err(Error::InvalidLengthIndicator(len)),
308        }
309    }
310
311    /// Read a TNS UB4 (unsigned 4-byte, variable length encoded)
312    ///
313    /// TNS UB4 uses a length-prefixed encoding where:
314    /// - First byte is the length (0, 1, 2, 3, or 4)
315    /// - If length is 0: value is 0
316    /// - If length is 1: read 1 byte
317    /// - If length is 2: read 2 bytes as big-endian u16
318    /// - If length is 3: read 3 bytes
319    /// - If length is 4: read 4 bytes as big-endian u32
320    pub fn read_ub4(&mut self) -> Result<u32> {
321        let len = self.read_ub_length()?;
322        match len {
323            0 => Ok(0),
324            1 => Ok(self.read_u8()? as u32),
325            2 => Ok(self.read_u16_be()? as u32),
326            3 => {
327                let bytes = self.read_bytes_vec(3)?;
328                Ok((bytes[0] as u32) << 16 | (bytes[1] as u32) << 8 | (bytes[2] as u32))
329            }
330            4 => self.read_u32_be(),
331            _ => Err(Error::InvalidLengthIndicator(len)),
332        }
333    }
334
335    /// Read a TNS UB8 (unsigned 8-byte, variable length encoded)
336    ///
337    /// TNS UB8 uses a length-prefixed encoding where:
338    /// - First byte is the length (0-8)
339    /// - Read that many bytes and interpret as big-endian integer
340    pub fn read_ub8(&mut self) -> Result<u64> {
341        let len = self.read_ub_length()?;
342        match len {
343            0 => Ok(0),
344            1 => Ok(self.read_u8()? as u64),
345            2 => Ok(self.read_u16_be()? as u64),
346            3 => {
347                let bytes = self.read_bytes_vec(3)?;
348                Ok((bytes[0] as u64) << 16 | (bytes[1] as u64) << 8 | (bytes[2] as u64))
349            }
350            4 => Ok(self.read_u32_be()? as u64),
351            5..=7 => {
352                let bytes = self.read_bytes_vec(len as usize)?;
353                let mut result = 0u64;
354                for &b in &bytes {
355                    result = (result << 8) | (b as u64);
356                }
357                Ok(result)
358            }
359            8 => self.read_u64_be(),
360            _ => Err(Error::InvalidLengthIndicator(len)),
361        }
362    }
363
364    /// Read the UB length byte (masks off the high bit which indicates sign)
365    fn read_ub_length(&mut self) -> Result<u8> {
366        let len = self.read_u8()?;
367        Ok(len & 0x7F)  // Mask off high bit (sign indicator)
368    }
369
370    /// Read a TNS length-prefixed byte sequence
371    ///
372    /// Returns None if the length indicator is NULL_INDICATOR (255).
373    /// For data > 252 bytes, uses chunked decoding:
374    /// - Read LONG_INDICATOR (254)
375    /// - Read chunks: ub4(chunk_len) + raw bytes, until chunk_len is 0
376    pub fn read_bytes_with_length(&mut self) -> Result<Option<Vec<u8>>> {
377        let len = self.read_u8()?;
378
379        if len == length::NULL_INDICATOR {
380            return Ok(None);
381        }
382
383        if len == length::LONG_INDICATOR {
384            // Chunked format: read chunks until we get a 0-length chunk
385            let mut result = Vec::new();
386            loop {
387                let chunk_len = self.read_ub4()? as usize;
388                if chunk_len == 0 {
389                    break;
390                }
391                let chunk = self.read_bytes_vec(chunk_len)?;
392                result.extend(chunk);
393            }
394            return Ok(Some(result));
395        }
396
397        let actual_len = if len == length::ESCAPE_CHAR {
398            // Escape sequence - next byte is the actual length
399            self.read_u8()? as usize
400        } else {
401            len as usize
402        };
403
404        if actual_len == 0 {
405            return Ok(Some(Vec::new()));
406        }
407
408        self.read_bytes_vec(actual_len).map(Some)
409    }
410
411    /// Read a TNS length-prefixed string (UTF-8)
412    pub fn read_string_with_length(&mut self) -> Result<Option<String>> {
413        match self.read_bytes_with_length()? {
414            None => Ok(None),
415            Some(bytes) => String::from_utf8(bytes)
416                .map(Some)
417                .map_err(|e| Error::DataConversionError(e.to_string())),
418        }
419    }
420
421    /// Read a string with UB4 outer length prefix (used for metadata strings)
422    ///
423    /// This is the format used by Oracle for column names, schema names, etc.
424    /// The format is:
425    /// 1. UB4 (length-prefixed u32) giving the byte count as an indicator
426    /// 2. If > 0, a TNS length-prefixed byte sequence (another length prefix + data)
427    ///
428    /// Python's `read_str_with_length` uses this format.
429    pub fn read_string_with_ub4_length(&mut self) -> Result<Option<String>> {
430        let outer_len = self.read_ub4()?;
431        if outer_len == 0 {
432            return Ok(None);
433        }
434        // Now read the actual string with its own TNS length prefix
435        self.read_string_with_length()
436    }
437
438    /// Read a fixed-size Oracle integer (used in various places)
439    ///
440    /// Oracle encodes integers with a length prefix indicating the number of bytes.
441    /// The actual bytes follow in big-endian order.
442    pub fn read_oracle_int(&mut self) -> Result<i64> {
443        let len_byte = self.read_u8()?;
444
445        // Check for negative (high bit set in length byte)
446        let is_negative = (len_byte & 0x80) != 0;
447        let len = (len_byte & 0x7f) as usize;
448
449        if len == 0 {
450            return Ok(0);
451        }
452
453        if len > 8 {
454            return Err(Error::DataConversionError(format!(
455                "integer too large: {} bytes",
456                len
457            )));
458        }
459
460        let mut value: u64 = 0;
461        for _ in 0..len {
462            value = (value << 8) | (self.read_u8()? as u64);
463        }
464
465        if is_negative {
466            Ok(-(value as i64))
467        } else {
468            Ok(value as i64)
469        }
470    }
471
472    /// Read an Oracle unsigned integer
473    pub fn read_oracle_uint(&mut self) -> Result<u64> {
474        let len = self.read_u8()? as usize;
475
476        if len == 0 {
477            return Ok(0);
478        }
479
480        if len > 8 {
481            return Err(Error::DataConversionError(format!(
482                "integer too large: {} bytes",
483                len
484            )));
485        }
486
487        let mut value: u64 = 0;
488        for _ in 0..len {
489            value = (value << 8) | (self.read_u8()? as u64);
490        }
491
492        Ok(value)
493    }
494
495    /// Skip a UB1
496    pub fn skip_ub1(&mut self) -> Result<()> {
497        self.skip(1)
498    }
499
500    /// Skip a UB2 (length-prefixed 2-byte integer)
501    ///
502    /// Format: first byte is length (0-2), followed by that many bytes
503    pub fn skip_ub2(&mut self) -> Result<()> {
504        let len = self.read_ub_length()?;
505        if len > 0 {
506            self.skip(len as usize)?;
507        }
508        Ok(())
509    }
510
511    /// Skip a UB4 (length-prefixed 4-byte integer)
512    ///
513    /// Format: first byte is length (0-4), followed by that many bytes
514    pub fn skip_ub4(&mut self) -> Result<()> {
515        let len = self.read_ub_length()?;
516        if len > 0 {
517            self.skip(len as usize)?;
518        }
519        Ok(())
520    }
521
522    /// Skip a UB8 (length-prefixed 8-byte integer)
523    ///
524    /// Format: first byte is length (0-8), followed by that many bytes
525    pub fn skip_ub8(&mut self) -> Result<()> {
526        let len = self.read_ub_length()?;
527        if len > 0 {
528            self.skip(len as usize)?;
529        }
530        Ok(())
531    }
532
533    /// Peek at the next byte without consuming it
534    pub fn peek_u8(&self) -> Result<u8> {
535        self.ensure_remaining(1)?;
536        Ok(self.data[self.pos])
537    }
538
539    /// Peek at the next n bytes without consuming them
540    pub fn peek_bytes(&self, n: usize) -> Result<&[u8]> {
541        self.ensure_remaining(n)?;
542        Ok(&self.data[self.pos..self.pos + n])
543    }
544}
545
546impl From<Bytes> for ReadBuffer {
547    fn from(data: Bytes) -> Self {
548        Self::new(data)
549    }
550}
551
552impl From<Vec<u8>> for ReadBuffer {
553    fn from(data: Vec<u8>) -> Self {
554        Self::from_vec(data)
555    }
556}
557
558impl From<&[u8]> for ReadBuffer {
559    fn from(data: &[u8]) -> Self {
560        Self::from_slice(data)
561    }
562}
563
564#[cfg(test)]
565mod tests {
566    use super::*;
567
568    #[test]
569    fn test_read_u8() {
570        let mut buf = ReadBuffer::from_slice(&[0x42, 0x43]);
571        assert_eq!(buf.read_u8().unwrap(), 0x42);
572        assert_eq!(buf.read_u8().unwrap(), 0x43);
573        assert!(buf.read_u8().is_err());
574    }
575
576    #[test]
577    fn test_read_u16_be() {
578        let mut buf = ReadBuffer::from_slice(&[0x01, 0x02]);
579        assert_eq!(buf.read_u16_be().unwrap(), 0x0102);
580    }
581
582    #[test]
583    fn test_read_u32_be() {
584        let mut buf = ReadBuffer::from_slice(&[0x01, 0x02, 0x03, 0x04]);
585        assert_eq!(buf.read_u32_be().unwrap(), 0x01020304);
586    }
587
588    #[test]
589    fn test_read_u64_be() {
590        let mut buf = ReadBuffer::from_slice(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
591        assert_eq!(buf.read_u64_be().unwrap(), 0x0102030405060708);
592    }
593
594    #[test]
595    fn test_read_ub2_zero() {
596        let mut buf = ReadBuffer::from_slice(&[0x00]);
597        assert_eq!(buf.read_ub2().unwrap(), 0);
598    }
599
600    #[test]
601    fn test_read_ub2_short() {
602        // Length 1, value 0x42
603        let mut buf = ReadBuffer::from_slice(&[0x01, 0x42]);
604        assert_eq!(buf.read_ub2().unwrap(), 0x42);
605    }
606
607    #[test]
608    fn test_read_ub2_long() {
609        // Length 2, value 0x0102
610        let mut buf = ReadBuffer::from_slice(&[0x02, 0x01, 0x02]);
611        assert_eq!(buf.read_ub2().unwrap(), 0x0102);
612    }
613
614    #[test]
615    fn test_read_ub4_zero() {
616        let mut buf = ReadBuffer::from_slice(&[0x00]);
617        assert_eq!(buf.read_ub4().unwrap(), 0);
618    }
619
620    #[test]
621    fn test_read_ub4_short() {
622        // Length 1, value 0x42
623        let mut buf = ReadBuffer::from_slice(&[0x01, 0x42]);
624        assert_eq!(buf.read_ub4().unwrap(), 0x42);
625    }
626
627    #[test]
628    fn test_read_ub4_medium() {
629        // Length 2, value 0x0102
630        let mut buf = ReadBuffer::from_slice(&[0x02, 0x01, 0x02]);
631        assert_eq!(buf.read_ub4().unwrap(), 0x0102);
632    }
633
634    #[test]
635    fn test_read_ub4_long() {
636        // Length 4, value 0x01020304
637        let mut buf = ReadBuffer::from_slice(&[0x04, 0x01, 0x02, 0x03, 0x04]);
638        assert_eq!(buf.read_ub4().unwrap(), 0x01020304);
639    }
640
641    #[test]
642    fn test_read_bytes_with_length_null() {
643        let mut buf = ReadBuffer::from_slice(&[0xff]);
644        assert!(buf.read_bytes_with_length().unwrap().is_none());
645    }
646
647    #[test]
648    fn test_read_bytes_with_length_short() {
649        let mut buf = ReadBuffer::from_slice(&[0x03, 0x41, 0x42, 0x43]);
650        let bytes = buf.read_bytes_with_length().unwrap().unwrap();
651        assert_eq!(bytes, vec![0x41, 0x42, 0x43]);
652    }
653
654    #[test]
655    fn test_read_bytes_with_length_empty() {
656        let mut buf = ReadBuffer::from_slice(&[0x00]);
657        let bytes = buf.read_bytes_with_length().unwrap().unwrap();
658        assert!(bytes.is_empty());
659    }
660
661    #[test]
662    fn test_skip() {
663        let mut buf = ReadBuffer::from_slice(&[0x01, 0x02, 0x03, 0x04]);
664        buf.skip(2).unwrap();
665        assert_eq!(buf.read_u8().unwrap(), 0x03);
666    }
667
668    #[test]
669    fn test_remaining() {
670        let buf = ReadBuffer::from_slice(&[0x01, 0x02, 0x03]);
671        assert_eq!(buf.remaining(), 3);
672        assert!(buf.has_remaining(3));
673        assert!(!buf.has_remaining(4));
674    }
675
676    #[test]
677    fn test_peek() {
678        let buf = ReadBuffer::from_slice(&[0x42, 0x43]);
679        assert_eq!(buf.peek_u8().unwrap(), 0x42);
680        assert_eq!(buf.peek_u8().unwrap(), 0x42); // Still 0x42, not consumed
681    }
682
683    #[test]
684    fn test_read_oracle_int_positive() {
685        // Length 2, value 0x0102 = 258
686        let mut buf = ReadBuffer::from_slice(&[0x02, 0x01, 0x02]);
687        assert_eq!(buf.read_oracle_int().unwrap(), 258);
688    }
689
690    #[test]
691    fn test_read_oracle_int_negative() {
692        // Length 2 with sign bit, value 0x0102 = -258
693        let mut buf = ReadBuffer::from_slice(&[0x82, 0x01, 0x02]);
694        assert_eq!(buf.read_oracle_int().unwrap(), -258);
695    }
696
697    #[test]
698    fn test_read_oracle_int_zero() {
699        let mut buf = ReadBuffer::from_slice(&[0x00]);
700        assert_eq!(buf.read_oracle_int().unwrap(), 0);
701    }
702}