mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
arch: Helper functions for 64-bit hex (de-)serialization
We create 64-bit analogues of the already existing hex (de-)serializer helper functions for the 32-bit case. These are necessary because the CPU profile needs associated data describing how to adjust feature MSRs whose values are 64-bits. In this case we prefer some small amount of code duplication over macros and/or traits since we do not expect the need for further variants of these helpers. Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de> On-behalf-of: SAP oliver.anderson@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
2eb64a2b4f
commit
838d01b0bc
@@ -3,8 +3,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
use std::result;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer, Serializer, de};
|
use serde::{Deserialize, Deserializer, Serializer, de};
|
||||||
|
|
||||||
/// Serializes the given `input` as a hex string (starting with "0x").
|
/// Serializes the given `input` as a hex string (starting with "0x").
|
||||||
@@ -14,22 +12,42 @@ use serde::{Deserialize, Deserializer, Serializer, de};
|
|||||||
pub(crate) fn serialize_u32_hex<S: Serializer>(
|
pub(crate) fn serialize_u32_hex<S: Serializer>(
|
||||||
input: &u32,
|
input: &u32,
|
||||||
serializer: S,
|
serializer: S,
|
||||||
) -> result::Result<S::Ok, S::Error> {
|
) -> Result<S::Ok, S::Error> {
|
||||||
serializer.serialize_str(&format!("{input:#x}"))
|
serializer.serialize_str(&format!("{input:#x}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes a u32 from a hex string representation.
|
/// Deserializes a u32 from a hex string representation.
|
||||||
pub(crate) fn deserialize_u32_hex<'de, D: Deserializer<'de>>(
|
pub(crate) fn deserialize_u32_hex<'de, D: Deserializer<'de>>(
|
||||||
deserializer: D,
|
deserializer: D,
|
||||||
) -> result::Result<u32, D::Error> {
|
) -> Result<u32, D::Error> {
|
||||||
let hex: &str = <&str>::deserialize(deserializer)?;
|
let hex: &str = <&str>::deserialize(deserializer)?;
|
||||||
u32::from_str_radix(hex.strip_prefix("0x").unwrap_or(""), 16).map_err(|_| {
|
u32::from_str_radix(hex.strip_prefix("0x").unwrap_or(""), 16).map_err(|_| {
|
||||||
<D::Error as de::Error>::custom(format!("{hex} is not a hex encoded 32 bit integer"))
|
<D::Error as de::Error>::custom(format!("{hex} is not a hex encoded 32 bit integer"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 64-bit version of `serialize_u32_hex`
|
||||||
|
pub(crate) fn serialize_u64_hex<S: Serializer>(
|
||||||
|
input: &u64,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<S::Ok, S::Error> {
|
||||||
|
serializer.serialize_str(&format!("{input:#x}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 64-bit version of `deserialize_u32_hex`
|
||||||
|
pub(crate) fn deserialize_u64_hex<'de, D: Deserializer<'de>>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> Result<u64, D::Error> {
|
||||||
|
let hex: &str = <&str>::deserialize(deserializer)?;
|
||||||
|
u64::from_str_radix(hex.strip_prefix("0x").unwrap_or(""), 16).map_err(|_| {
|
||||||
|
<D::Error as de::Error>::custom(format!("{hex} is not a hex encoded 64 bit integer"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod unit_tests {
|
mod unit_tests {
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -49,15 +67,29 @@ mod unit_tests {
|
|||||||
bar: u32,
|
bar: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||||
|
struct TestStruct64 {
|
||||||
|
#[serde(
|
||||||
|
serialize_with = "serialize_u64_hex",
|
||||||
|
deserialize_with = "deserialize_u64_hex"
|
||||||
|
)]
|
||||||
|
foo: u64,
|
||||||
|
#[serde(
|
||||||
|
serialize_with = "serialize_u64_hex",
|
||||||
|
deserialize_with = "deserialize_u64_hex"
|
||||||
|
)]
|
||||||
|
bar: u64,
|
||||||
|
}
|
||||||
|
|
||||||
// Check that our hex serializers satisfy the two following invariants
|
// Check that our hex serializers satisfy the two following invariants
|
||||||
// 1. Serialization followed by deserialization is the identity.
|
// 1. Serialization followed by deserialization is the identity.
|
||||||
// 2. Values of type u32 are serialized to strings starting with "0x" and then
|
// 2. Values of type u32/u64 are serialized to strings starting with "0x" and then
|
||||||
// a sub-string where all characters are ascii hex digits (with the letters [a-f] always in lowercase).
|
// a sub-string where all characters are ascii hex digits (with the letters [a-f] always in lowercase).
|
||||||
proptest! {
|
fn test_hex_serialization<T>(t: T) -> Result<(), TestCaseError>
|
||||||
#[test]
|
where
|
||||||
fn hex_serialization_works(foo in any::<u32>(), bar in any::<u32>()) {
|
T: Serialize + Debug + Eq + Copy,
|
||||||
let t = TestStruct { foo , bar };
|
for<'de> T: Deserialize<'de>,
|
||||||
|
{
|
||||||
let t_string = serde_json::to_string(&t).unwrap();
|
let t_string = serde_json::to_string(&t).unwrap();
|
||||||
let t_deserialized = serde_json::from_str(&t_string).unwrap();
|
let t_deserialized = serde_json::from_str(&t_string).unwrap();
|
||||||
prop_assert_eq!(t, t_deserialized);
|
prop_assert_eq!(t, t_deserialized);
|
||||||
@@ -76,7 +108,22 @@ mod unit_tests {
|
|||||||
|
|
||||||
check_str_invariants(foo_str)?;
|
check_str_invariants(foo_str)?;
|
||||||
check_str_invariants(bar_str)?;
|
check_str_invariants(bar_str)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn hex_serialization_works_32(foo in any::<u32>(), bar in any::<u32>()) {
|
||||||
|
let t = TestStruct { foo , bar };
|
||||||
|
test_hex_serialization(t)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proptest! {
|
||||||
|
#[test]
|
||||||
|
fn hex_serialization_works_64(foo in any::<u64>(), bar in any::<u64>()) {
|
||||||
|
let t = TestStruct64 { foo , bar };
|
||||||
|
test_hex_serialization(t)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user