Skip to content

Commit

Permalink
Negative number encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
sorokya committed Jan 1, 2024
1 parent b6d8367 commit aecd7a0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 33 deletions.
2 changes: 1 addition & 1 deletion eo-protocol
25 changes: 14 additions & 11 deletions src/data/eo_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub enum EoWriterError {
#[error("Invalid three value {0} must be between 0 and {}", THREE_MAX)]
InvalidThreeValue(i32),
#[error("Invalid int value {0} must be between 0 and {}", INT_MAX)]
InvalidIntValue(i32),
InvalidIntValue(i64),
#[error("{0}")]
Other(String),
}
Expand Down Expand Up @@ -78,7 +78,7 @@ impl EoWriter {
return Err(EoWriterError::InvalidCharValue(char));
}

let encoded = encode_number(char);
let encoded = encode_number(char)?;
self.data.put_slice(&encoded[0..1]);
Ok(())
}
Expand All @@ -89,7 +89,7 @@ impl EoWriter {
return Err(EoWriterError::InvalidShortValue(short));
}

let encoded = encode_number(short);
let encoded = encode_number(short)?;
self.data.put_slice(&encoded[0..2]);
Ok(())
}
Expand All @@ -100,18 +100,14 @@ impl EoWriter {
return Err(EoWriterError::InvalidThreeValue(three));
}

let encoded = encode_number(three);
let encoded = encode_number(three)?;
self.data.put_slice(&encoded[0..3]);
Ok(())
}

/// adds an int to the data stream
pub fn add_int(&mut self, int: i32) -> Result<(), EoWriterError> {
if int < 0 {
return Err(EoWriterError::InvalidIntValue(int));
}

let encoded = encode_number(int);
let encoded = encode_number(int)?;
self.data.put_slice(&encoded[0..4]);
Ok(())
}
Expand Down Expand Up @@ -207,8 +203,8 @@ mod tests {
#[test]
fn add_negative_int() {
let mut writer = EoWriter::with_capacity(4);
let result = writer.add_int(-1).unwrap_err();
assert_eq!(result, EoWriterError::InvalidIntValue(-1));
let result = writer.add_int(-1);
assert_eq!(result, Ok(()));
}

#[test]
Expand All @@ -231,4 +227,11 @@ mod tests {
let result = writer.add_three(THREE_MAX + 1).unwrap_err();
assert_eq!(result, EoWriterError::InvalidThreeValue(THREE_MAX + 1));
}

#[test]
fn add_large_int() {
let mut writer = EoWriter::with_capacity(4);
let result = writer.add_int(-i32::MAX).unwrap_err();
assert_eq!(result, EoWriterError::InvalidIntValue(i32::MAX as i64 * 2));
}
}
52 changes: 32 additions & 20 deletions src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub const SHORT_MAX: i32 = CHAR_MAX * CHAR_MAX;
pub const THREE_MAX: i32 = CHAR_MAX * CHAR_MAX * CHAR_MAX;

/// The maximum value of an EO int (4-byte encoded integer type)
pub const INT_MAX: i32 = i32::MAX;
pub const INT_MAX: i64 = CHAR_MAX as i64 * CHAR_MAX as i64 * CHAR_MAX as i64 * CHAR_MAX as i64;

/// Returns an encoded byte array from `number`
///
Expand Down Expand Up @@ -41,7 +41,7 @@ pub const INT_MAX: i32 = i32::MAX;
/// ```
/// use eolib::data::encode_number;
///
/// let result = encode_number(42);
/// let result = encode_number(42).unwrap();
/// assert_eq!(result, [43, 254, 254, 254]);
/// ```
/// since 42 is less than CHAR_MAX it is simply incremented by 1
Expand All @@ -50,7 +50,7 @@ pub const INT_MAX: i32 = i32::MAX;
/// ## Number less than SHORT_MAX
/// ```
/// use eolib::data::encode_number;
/// let result = encode_number(533);
/// let result = encode_number(533).unwrap();
/// assert_eq!(result, [28, 3, 254, 254]);
/// ```
///
Expand All @@ -67,7 +67,7 @@ pub const INT_MAX: i32 = i32::MAX;
/// ## Number less than THREE_MAX
/// ```
/// use eolib::data::encode_number;
/// let result = encode_number(888888);
/// let result = encode_number(888888).unwrap();
/// assert_eq!(result, [100, 225, 14, 254]);
/// ```
///
Expand All @@ -88,7 +88,7 @@ pub const INT_MAX: i32 = i32::MAX;
/// ## Number less than MAX4
/// ```
/// use eolib::data::encode_number;
/// let result = encode_number(18994242);
/// let result = encode_number(18994242).unwrap();
/// assert_eq!(result, [15, 189, 44, 2]);
/// ```
///
Expand All @@ -107,28 +107,40 @@ pub const INT_MAX: i32 = i32::MAX;
/// byte 1 is set to the the remainder + 1
///
/// `(18994242 % THREE_MAX % SHORT_MAX % CHAR_MAX) + 1 // 15`
pub fn encode_number(mut number: i32) -> [u8; 4] {
pub fn encode_number(number: i32) -> Result<[u8; 4], EoWriterError> {
let mut bytes: [u8; 4] = [254, 254, 254, 254];

// Unwrap negative i32 to positive i64
let mut number = if number < 0 {
number.abs() as i64 + i32::MAX as i64
} else {
number as i64
};

let original_number = number;

if original_number >= THREE_MAX {
bytes[3] = (number / THREE_MAX) as u8 + 1;
number %= THREE_MAX;
if original_number >= INT_MAX {
return Err(EoWriterError::InvalidIntValue(original_number));
}

if original_number >= THREE_MAX as i64 {
bytes[3] = (number / THREE_MAX as i64) as u8 + 1;
number %= THREE_MAX as i64;
}

if original_number >= SHORT_MAX {
bytes[2] = (number / SHORT_MAX) as u8 + 1;
number %= SHORT_MAX;
if original_number >= SHORT_MAX as i64 {
bytes[2] = (number / SHORT_MAX as i64) as u8 + 1;
number %= SHORT_MAX as i64;
}

if original_number >= CHAR_MAX {
bytes[1] = (number / CHAR_MAX) as u8 + 1;
number %= CHAR_MAX;
if original_number >= CHAR_MAX as i64 {
bytes[1] = (number / CHAR_MAX as i64) as u8 + 1;
number %= CHAR_MAX as i64;
}

bytes[0] = number as u8 + 1;

bytes
Ok(bytes)
}

/// Returns a decoded number from an EO Byte array
Expand Down Expand Up @@ -174,10 +186,10 @@ pub fn decode_number(bytes: &[u8]) -> i32 {
data[i] -= 1;
}

(data[3] as i32 * THREE_MAX)
+ (data[2] as i32 * SHORT_MAX)
+ (data[1] as i32 * CHAR_MAX)
+ data[0] as i32
((data[3] as i32).wrapping_mul(THREE_MAX))
.wrapping_add((data[2] as i32).wrapping_mul(SHORT_MAX))
.wrapping_add((data[1] as i32).wrapping_mul(CHAR_MAX))
.wrapping_add(data[0] as i32)
}

/// Decodes a string in place
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod data;
pub mod encrypt;
pub mod packet;
pub mod protocol;
pub mod protocol;

0 comments on commit aecd7a0

Please sign in to comment.