1use nom::{bytes::complete::take, IResult};
14
15type VintParseResult<'a> = Result<Option<(usize, i64)>, nom::Err<nom::error::Error<&'a [u8]>>>;
17
18#[allow(dead_code)]
25fn detect_ascii_corruption(input: &[u8]) -> bool {
26 if input.len() < 4 {
27 return false;
28 }
29
30 let bytes = &input[0..4];
32
33 let corrupted_patterns: &[&[u8]] = &[
35 b"data", b"bin", b"node", b"base", b"temp", b"logs", b"meta", b"main", b"root", b"home",
36 ];
37
38 for pattern in corrupted_patterns {
39 if bytes.starts_with(pattern) {
40 return true;
41 }
42 }
43
44 let ascii_count = bytes
46 .iter()
47 .filter(|&&b| (0x20..=0x7E).contains(&b))
48 .count();
49 if ascii_count >= 3 {
50 return true;
51 }
52
53 let value = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
55 match value {
56 2959239534 | 1684108385 => true, _ => false,
58 }
59}
60
61pub const MAX_VINT_SIZE: usize = 9;
63
64pub const MAX_VINT_LENGTH: i64 = 1024 * 1024 * 1024; pub fn parse_vint(input: &[u8]) -> IResult<&[u8], i64> {
83 if input.is_empty() {
84 return Err(nom::Err::Error(nom::error::Error::new(
85 input,
86 nom::error::ErrorKind::Eof,
87 )));
88 }
89
90 let _first_byte = input[0];
91
92 match crate::parser::vint_fixed::parse_vint_fixed(input) {
104 Ok(result) => Ok(result),
105 Err(_) => {
106 parse_zigzag_vint(input)
109 }
110 }
111}
112
113fn parse_zigzag_vint(input: &[u8]) -> IResult<&[u8], i64> {
115 if input.is_empty() {
116 return Err(nom::Err::Error(nom::error::Error::new(
117 input,
118 nom::error::ErrorKind::Eof,
119 )));
120 }
121
122 let first_byte = input[0];
123 let (bytes_used, unsigned_value) = if first_byte < 0x80 {
124 (1, first_byte as u64)
126 } else if first_byte < 0xC0 {
127 if input.len() < 2 {
129 return Err(nom::Err::Error(nom::error::Error::new(
130 input,
131 nom::error::ErrorKind::Eof,
132 )));
133 }
134 let value = ((first_byte & 0x3F) as u64) << 8 | input[1] as u64;
135 (2, value)
136 } else if first_byte < 0xE0 {
137 if input.len() < 3 {
139 return Err(nom::Err::Error(nom::error::Error::new(
140 input,
141 nom::error::ErrorKind::Eof,
142 )));
143 }
144 let value = ((first_byte & 0x1F) as u64) << 16 | (input[1] as u64) << 8 | input[2] as u64;
145 (3, value)
146 } else if first_byte == 0xF0 {
147 if input.len() < 9 {
151 return Err(nom::Err::Error(nom::error::Error::new(
152 input,
153 nom::error::ErrorKind::Eof,
154 )));
155 }
156 let mut value = 0u64;
158 #[allow(clippy::needless_range_loop)]
159 for i in 1..9 {
160 value = (value << 8) | (input[i] as u64);
161 }
162 (9usize, value)
163 } else if first_byte == 0xFF {
164 if input.len() < 9 {
167 return Err(nom::Err::Error(nom::error::Error::new(
168 input,
169 nom::error::ErrorKind::Eof,
170 )));
171 }
172 let mut value = 0u64;
174 #[allow(clippy::needless_range_loop)]
175 for i in 1..9 {
176 value = (value << 8) | (input[i] as u64);
177 }
178 (9usize, value)
179 } else {
180 return Err(nom::Err::Error(nom::error::Error::new(
182 input,
183 nom::error::ErrorKind::Verify,
184 )));
185 };
186
187 let signed_value = zigzag_decode(unsigned_value);
188 let (remaining_input, _) = take(bytes_used)(input)?;
189 Ok((remaining_input, signed_value))
190}
191
192#[allow(dead_code)]
194fn parse_cassandra_vint_format(input: &[u8]) -> VintParseResult<'_> {
195 if input.is_empty() {
196 return Ok(None);
197 }
198
199 let first_byte = input[0];
200
201 let leading_ones = first_byte.leading_ones() as usize;
203 let total_length = leading_ones + 1;
204
205 if total_length > 9 || input.len() < total_length {
206 return Ok(None); }
208
209 let value = if total_length == 1 {
211 if first_byte & 0x80 == 0x80 {
213 (first_byte & 0x7F) as i64
215 } else if first_byte == 0xFF {
216 -1
217 } else if first_byte & 0xC0 == 0xC0 {
218 -((first_byte & 0x3F) as i64)
220 } else {
221 return Ok(None);
223 }
224 } else {
225 let data_bits = (total_length * 8) - leading_ones - 1;
227 let first_data_bits = 8 - leading_ones - 1;
229 let first_data_mask = (1u8 << first_data_bits) - 1;
230 let mut value = (first_byte & first_data_mask) as i64;
231
232 #[allow(clippy::needless_range_loop)]
234 for i in 1..total_length {
235 value = (value << 8) | (input[i] as i64);
236 }
237
238 let max_positive = (1i64 << (data_bits - 1)) - 1;
241 if value > max_positive {
242 value -= 1i64 << data_bits;
244 }
245
246 value
247 };
248
249 Ok(Some((total_length, value)))
250}
251
252#[allow(dead_code)]
254fn parse_custom_vint_format(input: &[u8]) -> VintParseResult<'_> {
255 if input.is_empty() {
256 return Ok(None);
257 }
258
259 let first_byte = input[0];
260
261 let (total_length, value) = if first_byte < 0x80 {
262 let unsigned_value = first_byte & 0x7F;
264 let value = if unsigned_value < 64 {
265 unsigned_value as i64
266 } else {
267 (unsigned_value as i64) - 128
268 };
269 (1, value)
270 } else if first_byte < 0xC0 {
271 let value = (first_byte & 0x3F) as i64;
273 (1, value)
274 } else if first_byte == 0xFF {
275 (1, -1)
277 } else if first_byte >= 0xC0 {
278 if input.len() == 1 {
279 let value = -64 + (first_byte - 0xC0) as i64;
281 (1, value)
282 } else if first_byte == 0xC0 && input.len() >= 2 {
283 let second_byte = input[1];
285 let value = if second_byte <= 0x7F {
286 second_byte as i64
287 } else if second_byte == 0x80 {
288 -128
289 } else {
290 second_byte as i64
291 };
292 (2, value)
293 } else {
294 return Ok(None); }
296 } else {
297 return Ok(None);
298 };
299
300 if input.len() < total_length {
301 return Err(nom::Err::Error(nom::error::Error::new(
302 input,
303 nom::error::ErrorKind::Eof,
304 )));
305 }
306
307 Ok(Some((total_length, value)))
308}
309
310#[allow(dead_code)]
312fn encode_cassandra_vint(value: i64) -> Vec<u8> {
313 let _unsigned_value = if value >= 0 {
315 value as u64
316 } else {
317 value as u64 };
320
321 let bytes_needed = if value == 0 {
323 1
324 } else if (-63..=63).contains(&value) {
325 1 } else if (-8192..=8191).contains(&value) {
327 2 } else if (-1048576..=1048575).contains(&value) {
329 3 } else if (-134217728..=134217727).contains(&value) {
331 4 } else {
333 let abs_value = value.unsigned_abs();
335 if abs_value <= 0xFF {
336 2
337 } else if abs_value <= 0xFFFF {
338 3
339 } else if abs_value <= 0xFFFFFF {
340 4
341 } else if abs_value <= 0xFFFFFFFF {
342 5
343 } else {
344 8 }
346 };
347
348 match bytes_needed {
349 1 => {
350 if (0..=63).contains(&value) {
352 vec![0x80 | (value as u8)]
353 } else if value == -1 {
354 vec![0xFF]
355 } else if (-63..0).contains(&value) {
356 vec![0xC0 | ((-value) as u8)]
357 } else {
358 encode_cassandra_vint_multi_byte(value, 2)
360 }
361 }
362 2 => encode_cassandra_vint_multi_byte(value, 2),
363 3 => encode_cassandra_vint_multi_byte(value, 3),
364 4 => encode_cassandra_vint_multi_byte(value, 4),
365 _ => encode_cassandra_vint_multi_byte(value, bytes_needed),
366 }
367}
368
369#[allow(dead_code)]
371fn encode_cassandra_vint_multi_byte(value: i64, num_bytes: usize) -> Vec<u8> {
372 let mut result = vec![0u8; num_bytes];
373
374 let leading_ones = num_bytes - 1;
376 let first_byte_mask = (0xFF << (8 - leading_ones)) & 0xFF;
377
378 let value_bytes = if value >= 0 {
380 value.to_be_bytes()
381 } else {
382 (value as u64).to_be_bytes() };
384
385 let data_bits = (num_bytes * 8) - leading_ones - 1; let data_bytes = data_bits.div_ceil(8); let start_idx = 8 - data_bytes;
391 for (i, &byte) in value_bytes[start_idx..].iter().enumerate() {
392 if i == 0 {
393 let data_mask = (1u8 << (8 - leading_ones - 1)) - 1;
395 result[0] = first_byte_mask as u8 | (byte & data_mask);
396 } else {
397 result[i] = byte;
398 }
399 }
400
401 result
402}
403
404#[allow(dead_code)]
406fn encode_zigzag_vint(value: i64) -> Vec<u8> {
407 let unsigned_value = zigzag_encode(value);
408
409 if unsigned_value <= 0x7F {
410 vec![unsigned_value as u8]
412 } else if unsigned_value <= 0x3FFF {
413 let high = ((unsigned_value >> 8) & 0x3F) | 0x80;
415 let low = unsigned_value & 0xFF;
416 vec![high as u8, low as u8]
417 } else if unsigned_value <= 0x1FFFFF {
418 let high = ((unsigned_value >> 16) & 0x1F) | 0xC0;
420 let mid = (unsigned_value >> 8) & 0xFF;
421 let low = unsigned_value & 0xFF;
422 vec![high as u8, mid as u8, low as u8]
423 } else {
424 let bytes = unsigned_value.to_be_bytes();
426 let mut result = vec![0xF0]; let start = bytes.iter().position(|&b| b != 0).unwrap_or(7);
430 result.extend_from_slice(&bytes[start..]);
431 result
432 }
433}
434
435#[allow(dead_code)]
441pub fn zigzag_encode(value: i64) -> u64 {
442 ((value << 1) ^ (value >> 63)) as u64
443}
444
445#[allow(dead_code)]
447pub fn zigzag_decode(value: u64) -> i64 {
448 ((value >> 1) ^ ((!0u64).wrapping_mul(value & 1))) as i64
449}
450
451#[allow(dead_code)]
459fn vint_size(value: u64) -> usize {
460 if value == 0 {
461 return 1;
462 }
463
464 if value <= 127 {
466 1
468 } else if value <= 16383 {
469 2
471 } else if value <= 2097151 {
472 3
474 } else if value <= 268435455 {
475 4
477 } else if value <= 34359738367 {
478 5
480 } else if value <= 4398046511103 {
481 6
483 } else if value <= 562949953421311 {
484 7
486 } else if value <= 72057594037927935 {
487 8
489 } else {
490 9 }
492}
493
494pub fn encode_vint(value: i64) -> Vec<u8> {
507 encode_vint_zigzag(value)
508}
509
510pub fn encode_vint_zigzag(value: i64) -> Vec<u8> {
512 let unsigned_value = zigzag_encode(value);
513
514 if unsigned_value <= 0x7F {
515 vec![unsigned_value as u8]
517 } else if unsigned_value <= 0x3FFF {
518 let byte0 = 0x80 | ((unsigned_value >> 8) & 0x3F) as u8;
520 let byte1 = (unsigned_value & 0xFF) as u8;
521 vec![byte0, byte1]
522 } else if unsigned_value <= 0x1FFFFF {
523 let byte0 = 0xC0 | ((unsigned_value >> 16) & 0x1F) as u8;
525 let byte1 = ((unsigned_value >> 8) & 0xFF) as u8;
526 let byte2 = (unsigned_value & 0xFF) as u8;
527 vec![byte0, byte1, byte2]
528 } else if unsigned_value <= 0xFFFFFFF {
529 let byte0 = 0xE0 | ((unsigned_value >> 24) & 0x0F) as u8;
531 let byte1 = ((unsigned_value >> 16) & 0xFF) as u8;
532 let byte2 = ((unsigned_value >> 8) & 0xFF) as u8;
533 let byte3 = (unsigned_value & 0xFF) as u8;
534 vec![byte0, byte1, byte2, byte3]
535 } else if unsigned_value <= 0x7FFFFFFFF {
536 let byte0 = 0xF0 | ((unsigned_value >> 32) & 0x07) as u8;
538 let byte1 = ((unsigned_value >> 24) & 0xFF) as u8;
539 let byte2 = ((unsigned_value >> 16) & 0xFF) as u8;
540 let byte3 = ((unsigned_value >> 8) & 0xFF) as u8;
541 let byte4 = (unsigned_value & 0xFF) as u8;
542 vec![byte0, byte1, byte2, byte3, byte4]
543 } else if unsigned_value <= 0x3FFFFFFFFFF {
544 let byte0 = 0xF8 | ((unsigned_value >> 40) & 0x03) as u8;
546 let byte1 = ((unsigned_value >> 32) & 0xFF) as u8;
547 let byte2 = ((unsigned_value >> 24) & 0xFF) as u8;
548 let byte3 = ((unsigned_value >> 16) & 0xFF) as u8;
549 let byte4 = ((unsigned_value >> 8) & 0xFF) as u8;
550 let byte5 = (unsigned_value & 0xFF) as u8;
551 vec![byte0, byte1, byte2, byte3, byte4, byte5]
552 } else if unsigned_value <= 0x1FFFFFFFFFFFF {
553 let byte0 = 0xFC | ((unsigned_value >> 48) & 0x01) as u8;
555 let byte1 = ((unsigned_value >> 40) & 0xFF) as u8;
556 let byte2 = ((unsigned_value >> 32) & 0xFF) as u8;
557 let byte3 = ((unsigned_value >> 24) & 0xFF) as u8;
558 let byte4 = ((unsigned_value >> 16) & 0xFF) as u8;
559 let byte5 = ((unsigned_value >> 8) & 0xFF) as u8;
560 let byte6 = (unsigned_value & 0xFF) as u8;
561 vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6]
562 } else if unsigned_value <= 0xFFFFFFFFFFFFFF {
563 let byte0 = 0xFE;
565 let byte1 = ((unsigned_value >> 48) & 0xFF) as u8;
566 let byte2 = ((unsigned_value >> 40) & 0xFF) as u8;
567 let byte3 = ((unsigned_value >> 32) & 0xFF) as u8;
568 let byte4 = ((unsigned_value >> 24) & 0xFF) as u8;
569 let byte5 = ((unsigned_value >> 16) & 0xFF) as u8;
570 let byte6 = ((unsigned_value >> 8) & 0xFF) as u8;
571 let byte7 = (unsigned_value & 0xFF) as u8;
572 vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7]
573 } else {
574 let byte0 = 0xFF;
576 let byte1 = ((unsigned_value >> 56) & 0xFF) as u8;
577 let byte2 = ((unsigned_value >> 48) & 0xFF) as u8;
578 let byte3 = ((unsigned_value >> 40) & 0xFF) as u8;
579 let byte4 = ((unsigned_value >> 32) & 0xFF) as u8;
580 let byte5 = ((unsigned_value >> 24) & 0xFF) as u8;
581 let byte6 = ((unsigned_value >> 16) & 0xFF) as u8;
582 let byte7 = ((unsigned_value >> 8) & 0xFF) as u8;
583 let byte8 = (unsigned_value & 0xFF) as u8;
584 vec![
585 byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8,
586 ]
587 }
588}
589
590pub fn encode_vint_cassandra(value: i64) -> Vec<u8> {
592 crate::parser::vint_fixed::encode_vint_fixed(value)
593}
594
595pub fn parse_vint_cassandra(input: &[u8]) -> IResult<&[u8], i64> {
597 crate::parser::vint_fixed::parse_vint_fixed(input)
598}
599
600pub fn parse_unsigned_vint32(input: &[u8]) -> IResult<&[u8], u32> {
618 if input.is_empty() {
619 return Err(nom::Err::Error(nom::error::Error::new(
620 input,
621 nom::error::ErrorKind::Eof,
622 )));
623 }
624
625 let first_byte = input[0];
626 let num_extra_bytes = first_byte.leading_ones() as usize;
627
628 if num_extra_bytes > 4 || num_extra_bytes + 1 > input.len() {
629 return Err(nom::Err::Error(nom::error::Error::new(
630 input,
631 nom::error::ErrorKind::Eof,
632 )));
633 }
634
635 let value = if num_extra_bytes == 0 {
636 (first_byte & 0x7F) as u32
638 } else {
639 let data_bits_first = 8 - num_extra_bytes - 1;
641 let mask = (1u8 << data_bits_first) - 1;
642 let mut value = (first_byte & mask) as u32;
643
644 for &byte in input.iter().skip(1).take(num_extra_bytes) {
645 value = (value << 8) | (byte as u32);
646 }
647 value
648 };
649
650 let bytes_consumed = num_extra_bytes + 1;
651 let (remaining, _) = take(bytes_consumed)(input)?;
652 Ok((remaining, value))
653}
654
655pub fn parse_vuint(input: &[u8]) -> IResult<&[u8], u64> {
674 if input.is_empty() {
675 return Err(nom::Err::Error(nom::error::Error::new(
676 input,
677 nom::error::ErrorKind::Eof,
678 )));
679 }
680
681 let first_byte = input[0];
682 let num_extra_bytes = first_byte.leading_ones() as usize;
683
684 if num_extra_bytes > 8 || num_extra_bytes + 1 > input.len() {
685 return Err(nom::Err::Error(nom::error::Error::new(
686 input,
687 nom::error::ErrorKind::Eof,
688 )));
689 }
690
691 let value = if num_extra_bytes == 0 {
692 (first_byte & 0x7F) as u64
694 } else if num_extra_bytes == 8 {
695 let mut value = 0u64;
697 for &byte in input.iter().skip(1).take(num_extra_bytes) {
698 value = (value << 8) | (byte as u64);
699 }
700 value
701 } else {
702 let data_bits_first = 8 - num_extra_bytes - 1;
704 let mask = (1u8 << data_bits_first) - 1;
705 let mut value = (first_byte & mask) as u64;
706
707 for &byte in input.iter().skip(1).take(num_extra_bytes) {
708 value = (value << 8) | (byte as u64);
709 }
710 value
711 };
712
713 let bytes_consumed = num_extra_bytes + 1;
714 let (remaining, _) = take(bytes_consumed)(input)?;
715 Ok((remaining, value))
716}
717
718pub fn encode_vuint(value: u64) -> Vec<u8> {
720 if value <= 0x7F {
721 vec![value as u8]
723 } else if value <= 0x3FFF {
724 let byte0 = 0x80 | ((value >> 8) & 0x3F) as u8;
726 let byte1 = (value & 0xFF) as u8;
727 vec![byte0, byte1]
728 } else if value <= 0x1FFFFF {
729 let byte0 = 0xC0 | ((value >> 16) & 0x1F) as u8;
731 let byte1 = ((value >> 8) & 0xFF) as u8;
732 let byte2 = (value & 0xFF) as u8;
733 vec![byte0, byte1, byte2]
734 } else if value <= 0xFFFFFFF {
735 let byte0 = 0xE0 | ((value >> 24) & 0x0F) as u8;
737 let byte1 = ((value >> 16) & 0xFF) as u8;
738 let byte2 = ((value >> 8) & 0xFF) as u8;
739 let byte3 = (value & 0xFF) as u8;
740 vec![byte0, byte1, byte2, byte3]
741 } else if value <= 0x7FFFFFFFF {
742 let byte0 = 0xF0 | ((value >> 32) & 0x07) as u8;
744 let byte1 = ((value >> 24) & 0xFF) as u8;
745 let byte2 = ((value >> 16) & 0xFF) as u8;
746 let byte3 = ((value >> 8) & 0xFF) as u8;
747 let byte4 = (value & 0xFF) as u8;
748 vec![byte0, byte1, byte2, byte3, byte4]
749 } else if value <= 0x3FFFFFFFFFF {
750 let byte0 = 0xF8 | ((value >> 40) & 0x03) as u8;
752 let byte1 = ((value >> 32) & 0xFF) as u8;
753 let byte2 = ((value >> 24) & 0xFF) as u8;
754 let byte3 = ((value >> 16) & 0xFF) as u8;
755 let byte4 = ((value >> 8) & 0xFF) as u8;
756 let byte5 = (value & 0xFF) as u8;
757 vec![byte0, byte1, byte2, byte3, byte4, byte5]
758 } else if value <= 0x1FFFFFFFFFFFF {
759 let byte0 = 0xFC | ((value >> 48) & 0x01) as u8;
761 let byte1 = ((value >> 40) & 0xFF) as u8;
762 let byte2 = ((value >> 32) & 0xFF) as u8;
763 let byte3 = ((value >> 24) & 0xFF) as u8;
764 let byte4 = ((value >> 16) & 0xFF) as u8;
765 let byte5 = ((value >> 8) & 0xFF) as u8;
766 let byte6 = (value & 0xFF) as u8;
767 vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6]
768 } else if value <= 0xFFFFFFFFFFFFFF {
769 let byte0 = 0xFE;
771 let byte1 = ((value >> 48) & 0xFF) as u8;
772 let byte2 = ((value >> 40) & 0xFF) as u8;
773 let byte3 = ((value >> 32) & 0xFF) as u8;
774 let byte4 = ((value >> 24) & 0xFF) as u8;
775 let byte5 = ((value >> 16) & 0xFF) as u8;
776 let byte6 = ((value >> 8) & 0xFF) as u8;
777 let byte7 = (value & 0xFF) as u8;
778 vec![byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7]
779 } else {
780 let byte0 = 0xFF;
782 let byte1 = ((value >> 56) & 0xFF) as u8;
783 let byte2 = ((value >> 48) & 0xFF) as u8;
784 let byte3 = ((value >> 40) & 0xFF) as u8;
785 let byte4 = ((value >> 32) & 0xFF) as u8;
786 let byte5 = ((value >> 24) & 0xFF) as u8;
787 let byte6 = ((value >> 16) & 0xFF) as u8;
788 let byte7 = ((value >> 8) & 0xFF) as u8;
789 let byte8 = (value & 0xFF) as u8;
790 vec![
791 byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8,
792 ]
793 }
794}
795
796pub fn parse_vint_length(input: &[u8]) -> IResult<&[u8], usize> {
844 let (remaining, value) = parse_vuint(input)?;
845 if value > MAX_VINT_LENGTH as u64 {
850 return Err(nom::Err::Error(nom::error::Error::new(
851 input,
852 nom::error::ErrorKind::TooLarge,
853 )));
854 }
855 Ok((remaining, value as usize))
856}
857
858pub fn parse_vint_length_signed(input: &[u8]) -> IResult<&[u8], usize> {
873 let (remaining, value) = parse_vint(input)?;
874 if value < 0 {
875 return Err(nom::Err::Error(nom::error::Error::new(
876 input,
877 nom::error::ErrorKind::Verify,
878 )));
879 }
880 if value > MAX_VINT_LENGTH {
881 return Err(nom::Err::Error(nom::error::Error::new(
882 input,
883 nom::error::ErrorKind::TooLarge,
884 )));
885 }
886 Ok((remaining, value as usize))
887}
888
889#[cfg(test)]
890mod tests {
891 use super::*;
892
893 #[test]
894 fn test_zigzag_encoding() {
895 assert_eq!(zigzag_encode(0), 0);
897 assert_eq!(zigzag_encode(-1), 1);
898 assert_eq!(zigzag_encode(1), 2);
899 assert_eq!(zigzag_encode(-2), 3);
900 assert_eq!(zigzag_encode(2), 4);
901 assert_eq!(zigzag_encode(-3), 5);
902 assert_eq!(zigzag_encode(i64::MAX), u64::MAX - 1);
903 assert_eq!(zigzag_encode(i64::MIN), u64::MAX);
904 }
905
906 #[test]
907 fn test_zigzag_roundtrip() {
908 let test_values = vec![0, 1, -1, 127, -128, 32767, -32768, i64::MAX, i64::MIN];
909 for value in test_values {
910 let encoded = zigzag_encode(value);
911 let decoded = zigzag_decode(encoded);
912 assert_eq!(decoded, value, "ZigZag roundtrip failed for {}", value);
913 }
914 }
915
916 #[test]
917 fn test_vint_size_calculation() {
918 assert_eq!(vint_size(0), 1);
919 assert_eq!(vint_size(0x7F), 1); assert_eq!(vint_size(0x80), 2); assert_eq!(vint_size(0x3FFF), 2); assert_eq!(vint_size(0x4000), 3); }
924
925 #[test]
926 fn test_vint_single_byte_encoding() {
927 for i in 0..=63 {
929 let encoded = encode_vint(i);
930 assert_eq!(encoded.len(), 1, "Value {} should encode to 1 byte", i);
931 assert_eq!(encoded[0] & 0x80, 0, "Single byte should have leading 0");
932
933 let (_, decoded) = parse_vint(&encoded).unwrap();
934 assert_eq!(decoded, i, "Roundtrip failed for {}", i);
935 }
936
937 for i in -63..=0 {
939 let encoded = encode_vint(i);
940 assert_eq!(encoded.len(), 1, "Value {} should encode to 1 byte", i);
941
942 let (_, decoded) = parse_vint(&encoded).unwrap();
943 assert_eq!(decoded, i, "Roundtrip failed for {}", i);
944 }
945 }
946
947 #[test]
948 fn test_vint_multi_byte_encoding() {
949 let value = 128;
951 let encoded = encode_vint(value);
952 assert_eq!(encoded.len(), 2, "Value {} should encode to 2 bytes", value);
953 assert_eq!(
954 encoded[0] & 0x80,
955 0x80,
956 "Two-byte encoding should start with 10"
957 );
958 assert_eq!(
959 encoded[0] & 0x40,
960 0,
961 "Two-byte encoding should start with 10"
962 );
963
964 let (_, decoded) = parse_vint(&encoded).unwrap();
965 assert_eq!(decoded, value);
966
967 let value = 16384; let encoded = encode_vint(value);
970 assert_eq!(encoded.len(), 3, "Value {} should encode to 3 bytes", value);
971 assert_eq!(
972 encoded[0] & 0xE0,
973 0xC0,
974 "Three-byte encoding should start with 110"
975 );
976
977 let (_, decoded) = parse_vint(&encoded).unwrap();
978 assert_eq!(decoded, value);
979 }
980
981 #[test]
982 fn test_vint_comprehensive_roundtrip() {
983 let test_values = vec![
984 0,
986 1,
987 -1,
988 63,
989 -63,
990 64,
991 -64,
992 127,
994 -127,
995 128,
996 -128,
997 255,
998 -255,
999 256,
1000 -256,
1001 1023,
1002 -1023,
1003 1024,
1004 -1024,
1005 2047,
1006 -2047,
1007 2048,
1008 -2048,
1009 32767,
1011 -32768,
1012 65535,
1013 -65535,
1014 1000000,
1015 -1000000,
1016 i32::MAX as i64,
1018 i32::MIN as i64,
1019 i64::MAX / 2,
1021 i64::MIN / 2,
1022 ];
1023
1024 for value in test_values {
1025 let encoded = encode_vint(value);
1026 assert!(
1027 encoded.len() <= MAX_VINT_SIZE,
1028 "Encoded length {} exceeds maximum {} for value {}",
1029 encoded.len(),
1030 MAX_VINT_SIZE,
1031 value
1032 );
1033
1034 let (remaining, decoded) = parse_vint(&encoded).unwrap();
1035 assert!(remaining.is_empty(), "Parsing should consume all bytes");
1036 assert_eq!(decoded, value, "Roundtrip failed for value {}", value);
1037 }
1038 }
1039
1040 #[test]
1041 fn test_vint_format_compliance() {
1042 let encoded = encode_vint(0);
1046 assert_eq!(encoded, vec![0x00]);
1047
1048 let encoded = encode_vint(1);
1049 assert_eq!(encoded, vec![0x02]); let encoded = encode_vint(-1);
1052 assert_eq!(encoded, vec![0x01]); let encoded = encode_vint(64);
1056 assert_eq!(encoded.len(), 2);
1057 assert_eq!(encoded[0] & 0xC0, 0x80); let (_, decoded) = parse_vint(&encoded).unwrap();
1061 assert_eq!(decoded, 64);
1062 }
1063
1064 #[test]
1065 fn test_vuint_positive() {
1066 let value = 1000u64;
1067 let encoded = encode_vuint(value);
1068 let (_, decoded) = parse_vuint(&encoded).unwrap();
1069 assert_eq!(decoded, value);
1070 }
1071
1072 #[test]
1073 fn test_vint_length() {
1074 let bytes = encode_vuint(42);
1077 let (_, length) = parse_vint_length(&bytes).unwrap();
1078 assert_eq!(length, 42);
1079 }
1080
1081 #[test]
1088 fn test_parse_vint_length_unsigned_single_byte_ac() {
1089 assert_eq!(parse_vint_length(&[0x05]).unwrap().1, 5);
1090 }
1091
1092 #[test]
1095 fn test_parse_vint_length_unsigned_bit_patterns() {
1096 assert_eq!(parse_vint_length(&[0x04]).unwrap().1, 4);
1097 assert_eq!(parse_vint_length(&[0x7F]).unwrap().1, 127);
1098 assert_eq!(parse_vint_length(&[0x00]).unwrap().1, 0);
1099 assert_eq!(parse_vint_length(&[0x80, 0x80]).unwrap().1, 128);
1101 }
1102
1103 #[test]
1107 fn test_parse_vint_length_unsigned_roundtrip() {
1108 for value in [
1109 0u64, 1, 2, 3, 4, 5, 63, 64, 127, 128, 255, 256, 16383, 16384, 100_000,
1110 ] {
1111 let bytes = encode_vuint(value);
1112 let (_, decoded) = parse_vint_length(&bytes)
1113 .unwrap_or_else(|_| panic!("unsigned length decode failed for {value}"));
1114 assert_eq!(decoded as u64, value, "roundtrip failed for {value}");
1115 }
1116 }
1117
1118 #[test]
1121 fn test_parse_vint_length_signed_zigzag_roundtrip() {
1122 for value in [0i64, 1, 5, 13, 42, 63, 64, 127, 1000] {
1123 let bytes = encode_vint(value); let (_, decoded) = parse_vint_length_signed(&bytes)
1125 .unwrap_or_else(|_| panic!("signed length decode failed for {value}"));
1126 assert_eq!(decoded as i64, value, "signed roundtrip failed for {value}");
1127 }
1128 assert!(parse_vint_length_signed(&encode_vint(-10)).is_err());
1130 }
1131
1132 #[test]
1133 fn test_collection_vint_debug() {
1134 let encoded_4 = encode_vint(4);
1136 println!("encode_vint(4) = {:?}", encoded_4);
1137 let (_, decoded_4) = parse_vint(&encoded_4).unwrap();
1138 println!("parse_vint({:?}) = {}", encoded_4, decoded_4);
1139
1140 let test_10 = [10u8];
1142 let (_, decoded_10) = parse_vint(&test_10).unwrap();
1143 println!("parse_vint([10]) = {}", decoded_10);
1144
1145 for i in 0..20 {
1147 let encoded = encode_vint(i);
1148 if encoded == vec![10] {
1149 println!("Value {} encodes to [10]", i);
1150 }
1151 }
1152
1153 assert_eq!(decoded_4, 4, "Roundtrip test for 4");
1154
1155 let long_string = "this is a longer string";
1157 let encoded_23 = encode_vint(long_string.len() as i64);
1158 println!("encode_vint(23) = {:?}", encoded_23);
1159 println!(
1160 "String length: {}, bytes: {:?}",
1161 long_string.len(),
1162 long_string.as_bytes()
1163 );
1164
1165 match parse_vint(&encoded_23) {
1167 Ok((_, decoded)) => println!("parse_vint({:?}) = {}", encoded_23, decoded),
1168 Err(e) => println!("parse_vint({:?}) failed: {:?}", encoded_23, e),
1169 }
1170
1171 println!("\nš Debug failing VInt cases:");
1173 let failing_values = vec![256, 1048576, 64];
1174 for value in failing_values {
1175 let encoded = encode_vint(value);
1176 println!(
1177 "Value {}: encoded={:?}, hex={:02X?}, len={}",
1178 value,
1179 encoded,
1180 encoded,
1181 encoded.len()
1182 );
1183 if !encoded.is_empty() {
1184 let first_byte = encoded[0];
1185 println!(
1186 " First byte: 0x{:02X} ({:08b}), leading_ones: {}",
1187 first_byte,
1188 first_byte,
1189 first_byte.leading_ones()
1190 );
1191 if encoded.len() > 1 {
1192 println!(
1193 " Expected leading ones: {}, got: {}",
1194 encoded.len() - 1,
1195 first_byte.leading_ones()
1196 );
1197 }
1198 }
1199 }
1200
1201 println!("\nš Testing Cassandra format:");
1203 let cassandra_bytes = vec![0xE0, 0x01, 0x00]; match parse_vint(&cassandra_bytes) {
1205 Ok((_, decoded)) => println!("Cassandra bytes {:?} -> {}", cassandra_bytes, decoded),
1206 Err(e) => println!(
1207 "Failed to parse Cassandra bytes {:?}: {:?}",
1208 cassandra_bytes, e
1209 ),
1210 }
1211 }
1212
1213 #[test]
1214 fn test_vint_errors() {
1215 assert!(parse_vint(&[]).is_err());
1217
1218 assert!(parse_vint_length_signed(&encode_vint(-10)).is_err());
1221 assert!(parse_vint_length(&encode_vuint(2_000_000_000u64)).is_err());
1223
1224 assert!(parse_vint(&[0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).is_ok());
1226
1227 assert!(parse_vint(&[0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).is_ok()); assert!(parse_vint(&[0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).is_err());
1234
1235 assert!(parse_vint(&[0x80, 0x00]).is_ok()); assert!(parse_vint(&[0xC0, 0x00, 0x00]).is_ok()); let _corrupted_data = b"data"; }
1245
1246 #[test]
1251 fn test_parse_vint_truncated_lead_byte_is_err_1624() {
1252 assert!(
1254 parse_vint(&[0xC0]).is_err(),
1255 "bare 0xC0 is a truncated 3-byte vint, must be Err"
1256 );
1257 assert!(
1259 parse_vint(&[0x80]).is_err(),
1260 "bare 0x80 is a truncated 2-byte vint, must be Err"
1261 );
1262 }
1263
1264 #[test]
1270 fn test_parse_vint_framing_agreement_1624() {
1271 let (rem_a, val_a) = parse_vint(&[0x80, 0x80]).expect("complete 2-byte vint");
1272 let (rem_b, val_b) =
1273 parse_vint(&[0x80, 0x80, 0xAA, 0xBB]).expect("2-byte vint + trailing junk");
1274 assert_eq!(val_a, val_b, "decoded value must not depend on framing");
1275 assert!(rem_a.is_empty(), "first form consumes all bytes");
1276 assert_eq!(rem_b, &[0xAA, 0xBB], "second form leaves exactly the junk");
1277 assert!(parse_vint(&[0x80]).is_err());
1279 }
1280
1281 #[test]
1285 fn test_parse_zigzag_vint_extended_consumes_exactly_nine_1624() {
1286 let (rem, _) = parse_zigzag_vint(&[0xF0, 1, 2, 3, 4, 5, 6, 7, 8, 0xAA, 0xBB])
1287 .expect("0xF0 + 8 continuation bytes");
1288 assert_eq!(rem, &[0xAA, 0xBB], "0xF0 arm must consume exactly 9 bytes");
1289
1290 let (rem, _) = parse_zigzag_vint(&[0xFF, 1, 2, 3, 4, 5, 6, 7, 8, 0xAA, 0xBB])
1291 .expect("0xFF + 8 continuation bytes");
1292 assert_eq!(rem, &[0xAA, 0xBB], "0xFF arm must consume exactly 9 bytes");
1293
1294 assert!(parse_zigzag_vint(&[0xF0, 1, 2, 3]).is_err());
1296 assert!(parse_zigzag_vint(&[0xFF, 1, 2, 3]).is_err());
1297 }
1298
1299 #[test]
1300 fn test_vint_edge_case_patterns() {
1301 let max_single = 63;
1303 let encoded = encode_vint(max_single);
1304 assert_eq!(encoded.len(), 1);
1305 assert_eq!(encoded[0] & 0x80, 0); let min_double = 64;
1309 let encoded = encode_vint(min_double);
1310 assert_eq!(encoded.len(), 2);
1311 assert_eq!(encoded[0] & 0xC0, 0x80); }
1313
1314 #[test]
1315 fn test_detect_ascii_corruption_patterns() {
1316 assert!(detect_ascii_corruption(b"data_payload"));
1317 assert!(detect_ascii_corruption(b"node_meta"));
1318 assert!(!detect_ascii_corruption(&[0x00, 0x80, 0xFF, 0x10]));
1319 }
1320
1321 #[test]
1322 fn test_parse_vint_extended_formats() {
1323 let bytes = [0xF0, 0x00, 0x00, 0x00, 0x10];
1326 let _ = parse_vint(&bytes).expect("0xF0 5-byte vint parses");
1327
1328 let bytes = [0xFF, 0x00, 0x00, 0x00, 0x05];
1332 assert!(
1333 parse_vint(&bytes).is_err(),
1334 "truncated 0xFF vint (5 bytes, needs 9) must be Err"
1335 );
1336 }
1337
1338 #[test]
1340 fn test_vint_overflow_protection() {
1341 let max = MAX_VINT_LENGTH as u64;
1342
1343 let large_value = encode_vuint(2_000_000_000u64); let result = parse_vint_length(&large_value);
1346 assert!(
1347 result.is_err(),
1348 "Should reject values > 1GB for length fields"
1349 );
1350
1351 let safe_value = encode_vuint(max - 1);
1353 let result = parse_vint_length(&safe_value);
1354 assert!(result.is_ok(), "Should accept values < 1GB");
1355 let (_, length) = result.unwrap();
1356 assert_eq!(length as u64, max - 1);
1357
1358 let at_limit = encode_vuint(max);
1360 assert!(
1361 parse_vint_length(&at_limit).is_ok(),
1362 "Should accept exactly MAX_VINT_LENGTH"
1363 );
1364 let over_limit = encode_vuint(max + 1);
1365 assert!(
1366 parse_vint_length(&over_limit).is_err(),
1367 "Should reject values > MAX_VINT_LENGTH"
1368 );
1369
1370 let zero_value = encode_vuint(0u64);
1372 let result = parse_vint_length(&zero_value);
1373 assert!(result.is_ok(), "Should accept zero");
1374 let (_, length) = result.unwrap();
1375 assert_eq!(length, 0);
1376
1377 let sixteen_mb = encode_vuint(16 * 1024 * 1024u64);
1379 let result = parse_vint_length(&sixteen_mb);
1380 assert!(result.is_ok(), "Should accept 16MB (common limit)");
1381 }
1382}