1use crate::error::{bound, require, Error, Rule};
4use crate::value::Value;
5use crate::wire::{Decoder, Encoder, Wire, MAX_BYTES, MAX_ITEMS};
6
7pub fn encode_key(values: &[Value]) -> Result<Vec<u8>, Error> {
13 require(!values.is_empty(), "row key", Rule::Required)?;
14 bound(values.len(), MAX_ITEMS, "key components")?;
15 let mut out = Encoder::new();
16 for value in values {
17 value.validate()?;
18 match value {
19 Value::Null => return Err(Error::Invalid { field: "row key", rule: Rule::NullKey }),
20 Value::Integer(0) | Value::Real(0) => 0x12u8.put(&mut out)?,
21 Value::Integer(n) => {
22 let magnitude = n.unsigned_abs();
23 let shift = magnitude.leading_zeros();
24 number(*n < 0, (63 - shift) as i32, magnitude << shift, &mut out)?;
25 }
26 Value::Real(bits) => {
27 let negative = bits >> 63 != 0;
28 let exponent = ((bits >> 52) & 0x7ff) as i32;
29 let fraction = bits & ((1u64 << 52) - 1);
30 if exponent == 0x7ff {
31 (if negative { 0x10u8 } else { 0x14 }).put(&mut out)?;
32 } else if exponent == 0 {
33 let shift = fraction.leading_zeros();
34 number(negative, 63 - shift as i32 - 1074, fraction << shift, &mut out)?;
35 } else {
36 number(negative, exponent - 1023, ((1u64 << 52) | fraction) << 11, &mut out)?;
37 }
38 }
39 Value::Text(text) => escaped(0x20, text.as_bytes(), &mut out)?,
40 Value::Blob(bytes) => escaped(0x30, bytes, &mut out)?,
41 }
42 }
43 bound(out.bytes.len(), MAX_BYTES, "key bytes")?;
44 Ok(out.bytes)
45}
46
47fn number(negative: bool, exponent: i32, mantissa: u64, out: &mut Encoder) -> Result<(), Error> {
48 let exponent = (exponent + 1074) as u16;
49 if negative {
50 0x11u8.put(out)?;
51 (!exponent).put(out)?;
52 (!mantissa).put(out)
53 } else {
54 0x13u8.put(out)?;
55 exponent.put(out)?;
56 mantissa.put(out)
57 }
58}
59
60fn escaped(tag: u8, bytes: &[u8], out: &mut Encoder) -> Result<(), Error> {
61 tag.put(out)?;
62 for byte in bytes {
63 byte.put(out)?;
64 if *byte == 0 {
65 255u8.put(out)?;
66 }
67 }
68 out.bytes(&[0, 0])
69}
70
71pub fn decode_key(bytes: &[u8]) -> Result<Vec<Value>, Error> {
75 bound(bytes.len(), MAX_BYTES, "key bytes")?;
76 let mut input = Decoder::new(bytes)?;
77 let mut values = Vec::new();
78 while !input.is_empty() {
79 bound(values.len() + 1, MAX_ITEMS, "key components")?;
80 let tag = u8::get(&mut input)?;
81 let value = match tag {
82 0x10 => Value::Real(f64::NEG_INFINITY.to_bits()),
83 0x14 => Value::Real(f64::INFINITY.to_bits()),
84 0x12 => Value::Integer(0),
85 0x11 | 0x13 => {
86 let mut exponent = u16::get(&mut input)?;
87 let mut mantissa = u64::get(&mut input)?;
88 if tag == 0x11 {
89 exponent = !exponent;
90 mantissa = !mantissa;
91 }
92 decode_number(tag == 0x11, i32::from(exponent) - 1074, mantissa)?
93 }
94 0x20 | 0x30 => {
95 let mut value = Vec::new();
96 loop {
97 let byte = u8::get(&mut input)?;
98 if byte == 0 {
99 match u8::get(&mut input)? {
100 0 => break,
101 255 => {}
102 _ => return Err(key_error()),
103 }
104 }
105 value.try_reserve(1)?;
106 value.push(byte);
107 }
108 if tag == 0x20 {
109 Value::Text(String::from_utf8(value).map_err(Error::from)?)
110 } else {
111 Value::Blob(value)
112 }
113 }
114 _ => return Err(key_error()),
115 };
116 values.try_reserve(1)?;
117 values.push(value);
118 }
119 require(encode_key(&values)? == bytes, "key", Rule::KeyEncoding)?;
120 Ok(values)
121}
122
123fn key_error() -> Error {
124 Error::Invalid { field: "key", rule: Rule::KeyEncoding }
125}
126
127fn decode_number(negative: bool, exponent: i32, mantissa: u64) -> Result<Value, Error> {
128 if !(-1074..=1023).contains(&exponent) || mantissa >> 63 != 1 {
129 return Err(key_error());
130 }
131 if (0..=63).contains(&exponent) {
132 let shift = 63 - exponent as u32;
133 let magnitude = mantissa >> shift;
134 if magnitude << shift == mantissa {
135 if negative && magnitude == 1u64 << 63 {
136 return Ok(Value::Integer(i64::MIN));
137 }
138 if let Ok(n) = i64::try_from(magnitude) {
139 return Ok(Value::Integer(if negative { -n } else { n }));
140 }
141 }
142 }
143 let bits = if exponent >= -1022 {
144 if mantissa & 0x7ff != 0 {
145 return Err(key_error());
146 }
147 (((exponent + 1023) as u64) << 52) | ((mantissa >> 11) & ((1u64 << 52) - 1))
148 } else {
149 let shift = (63 - (exponent + 1074)) as u32;
150 let fraction = mantissa >> shift;
151 if fraction << shift != mantissa {
152 return Err(key_error());
153 }
154 fraction
155 };
156 Ok(Value::Real(bits | (u64::from(negative) << 63)))
157}
158
159#[cfg(test)]
160#[path = "key_tests.rs"]
161mod tests;