summaryrefslogtreecommitdiffstats
path: root/vendor/ciborium-ll/src/enc.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
commitd1b2d29528b7794b41e66fc2136e395a02f8529b (patch)
treea4a17504b260206dec3cf55b2dca82929a348ac2 /vendor/ciborium-ll/src/enc.rs
parentReleasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz
rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/ciborium-ll/src/enc.rs')
-rw-r--r--vendor/ciborium-ll/src/enc.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/vendor/ciborium-ll/src/enc.rs b/vendor/ciborium-ll/src/enc.rs
new file mode 100644
index 000000000..b8b8a20d6
--- /dev/null
+++ b/vendor/ciborium-ll/src/enc.rs
@@ -0,0 +1,127 @@
+use super::*;
+
+use ciborium_io::Write;
+
+/// An encoder for serializing CBOR items
+///
+/// This structure wraps a writer and provides convenience functions for
+/// writing `Header` objects to the wire.
+pub struct Encoder<W: Write>(W);
+
+impl<W: Write> From<W> for Encoder<W> {
+ #[inline]
+ fn from(value: W) -> Self {
+ Self(value)
+ }
+}
+
+impl<W: Write> Write for Encoder<W> {
+ type Error = W::Error;
+
+ fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> {
+ self.0.write_all(data)
+ }
+
+ fn flush(&mut self) -> Result<(), Self::Error> {
+ self.0.flush()
+ }
+}
+
+impl<W: Write> Encoder<W> {
+ /// Push a `Header` to the wire
+ #[inline]
+ pub fn push(&mut self, header: Header) -> Result<(), W::Error> {
+ let title = Title::from(header);
+
+ let major = match title.0 {
+ Major::Positive => 0,
+ Major::Negative => 1,
+ Major::Bytes => 2,
+ Major::Text => 3,
+ Major::Array => 4,
+ Major::Map => 5,
+ Major::Tag => 6,
+ Major::Other => 7,
+ };
+
+ let minor = match title.1 {
+ Minor::This(x) => x,
+ Minor::Next1(..) => 24,
+ Minor::Next2(..) => 25,
+ Minor::Next4(..) => 26,
+ Minor::Next8(..) => 27,
+ Minor::More => 31,
+ };
+
+ self.0.write_all(&[major << 5 | minor])?;
+ self.0.write_all(title.1.as_ref())
+ }
+
+ /// Serialize a byte slice as CBOR
+ ///
+ /// Optionally, segment the output into `segment` size segments. Note that
+ /// if `segment == Some(0)` it will be silently upgraded to `Some(1)`. This
+ /// minimum value is highly inefficient and should not be relied upon.
+ #[inline]
+ pub fn bytes(
+ &mut self,
+ value: &[u8],
+ segment: impl Into<Option<usize>>,
+ ) -> Result<(), W::Error> {
+ let max = segment.into().unwrap_or(value.len());
+ let max = core::cmp::max(max, 1);
+
+ if max >= value.len() {
+ self.push(Header::Bytes(Some(value.len())))?;
+ self.write_all(value)?;
+ } else {
+ self.push(Header::Bytes(None))?;
+
+ for chunk in value.chunks(max) {
+ self.push(Header::Bytes(Some(chunk.len())))?;
+ self.write_all(chunk)?;
+ }
+
+ self.push(Header::Break)?;
+ }
+
+ Ok(())
+ }
+
+ /// Serialize a string slice as CBOR
+ ///
+ /// Optionally, segment the output into `segment` size segments. Note that
+ /// since care is taken to ensure that each segment is itself a valid UTF-8
+ /// string, if `segment` contains a value of less than 4, it will be
+ /// silently upgraded to 4. This minimum value is highly inefficient and
+ /// should not be relied upon.
+ #[inline]
+ pub fn text(&mut self, value: &str, segment: impl Into<Option<usize>>) -> Result<(), W::Error> {
+ let max = segment.into().unwrap_or(value.len());
+ let max = core::cmp::max(max, 4);
+
+ if max >= value.len() {
+ self.push(Header::Text(Some(value.len())))?;
+ self.write_all(value.as_bytes())?;
+ } else {
+ self.push(Header::Text(None))?;
+
+ let mut bytes = value.as_bytes();
+ while !bytes.is_empty() {
+ let mut len = core::cmp::min(bytes.len(), max);
+ while len > 0 && core::str::from_utf8(&bytes[..len]).is_err() {
+ len -= 1
+ }
+
+ let (prefix, suffix) = bytes.split_at(len);
+ self.push(Header::Text(Some(prefix.len())))?;
+ self.write_all(prefix)?;
+ bytes = suffix;
+ }
+
+ self.push(Header::Break)?;
+ }
+
+ Ok(())
+ }
+}