Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | None | 0 0
  1. extern crate mc_varint;
  2.  
  3. use bytes::{Buf, BufMut};
  4. use mc_varint::{VarIntRead, VarLongRead, VarLongWrite};
  5. use std::{
  6. i32,
  7. io::{ErrorKind, Read, Result},
  8. usize,
  9. };
  10.  
  11. pub trait VarReadExt {
  12. fn read_var_i32(&mut self) -> Result<i32>;
  13.  
  14. fn read_var_i64(&mut self) -> Result<i64>;
  15.  
  16. fn read_str(&mut self) -> Result<String>;
  17.  
  18. fn read_var_len(&mut self) -> Result<usize> {
  19. let len = self.read_var_i32()?;
  20. match len {
  21. x if x >= 0 => Ok(x as usize),
  22. _ => Err(ErrorKind::InvalidData.into()),
  23. }
  24. }
  25. }
  26.  
  27. pub trait VarWriteExt {
  28. fn write_var_i64(&mut self, val: i64) -> Result<()>;
  29.  
  30. fn write_str(&mut self, data: &str) -> Result<()>;
  31.  
  32. fn write_var_i32(&mut self, val: i32) -> Result<()> {
  33. // Double cast to prevent sign-extending
  34. self.write_var_i64(val as u32 as i64)
  35. }
  36.  
  37. fn write_var_len(&mut self, len: usize) -> Result<()> {
  38. if len > (i32::MAX as usize) {
  39. return Err(ErrorKind::InvalidData.into());
  40. }
  41.  
  42. self.write_var_i32(len as i32)
  43. }
  44. }
  45.  
  46. impl<B: Buf> VarReadExt for B {
  47. fn read_var_i32(&mut self) -> Result<i32> {
  48. Ok(self.by_ref().reader().read_var_int()?.into())
  49. }
  50.  
  51. fn read_var_i64(&mut self) -> Result<i64> {
  52. Ok(self.by_ref().reader().read_var_long()?.into())
  53. }
  54.  
  55. fn read_str(&mut self) -> Result<String> {
  56. let length = self.read_var_len()?;
  57.  
  58. if self.remaining() < length {
  59. return Err(ErrorKind::UnexpectedEof.into());
  60. }
  61.  
  62. let mut res = String::with_capacity(length);
  63. self.by_ref().take(length).reader().read_to_string(&mut res)?;
  64. Ok(res)
  65. }
  66. }
  67.  
  68. impl<B: BufMut> VarWriteExt for B {
  69. fn write_var_i64(&mut self, val: i64) -> Result<()> {
  70. if self.remaining_mut() < var_int_length(val) {
  71. return Err(ErrorKind::UnexpectedEof.into());
  72. }
  73.  
  74. self.by_ref().writer().write_var_long(val.into())
  75. }
  76.  
  77. fn write_str(&mut self, data: &str) -> Result<()> {
  78. if self.remaining_mut() < var_int_length(data.len() as i64) + data.len() {
  79. return Err(ErrorKind::UnexpectedEof.into());
  80. }
  81.  
  82. self.write_var_len(data.len())?;
  83. self.put(data);
  84. Ok(())
  85. }
  86. }
  87.  
  88. fn var_int_length(val: i64) -> usize {
  89. let mut val = val as u64; // Prevent sign-extend during shift
  90. let mut count = 0;
  91. while val != 0 {
  92. count += 1;
  93. val = val >> 7;
  94. }
  95. count
  96. }
  97.  
  98. #[cfg(test)]
  99. mod tests {
  100. use super::*;
  101. use std::io::Cursor;
  102.  
  103. #[test]
  104. fn var_length() {
  105. assert_eq!(var_int_length(1), 1);
  106. assert_eq!(var_int_length(2147483647), 5);
  107. assert_eq!(var_int_length(-1 as i32 as u32 as i64), 5);
  108. assert_eq!(var_int_length(-1), 10);
  109. }
  110.  
  111. #[test]
  112. fn var_read() {
  113. let data = [
  114. 0x7fu8,
  115. 0x80, 0x01,
  116. 0xff, 0xff, 0xff, 0xff, 0x07,
  117. 0xff, 0xff, 0xff, 0xff, 0x0f,
  118. ];
  119. let mut cur = Cursor::new(&data);
  120.  
  121. assert_eq!(cur.read_var_i32().unwrap(), 127);
  122. assert_eq!(cur.read_var_i32().unwrap(), 128);
  123. assert_eq!(cur.read_var_i32().unwrap(), 2147483647);
  124. assert_eq!(cur.read_var_i32().unwrap(), -1);
  125. }
  126.  
  127. #[test]
  128. fn var_write() {
  129. let mut data = Vec::new();
  130.  
  131. data.write_var_i32(127).unwrap();
  132. assert_eq!(&data, &[0x7f]);
  133. data.clear();
  134.  
  135. data.write_var_i32(-1).unwrap();
  136. assert_eq!(&data, &[0xff, 0xff, 0xff, 0xff, 0x0f]);
  137. data.clear();
  138. }
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement