Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Unified Diff: mojo/public/rust/src/bindings/encoding.rs

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/rust/src/bindings/decoding.rs ('k') | mojo/public/rust/src/bindings/macros.rs » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/public/rust/src/bindings/encoding.rs
diff --git a/mojo/public/rust/src/bindings/encoding.rs b/mojo/public/rust/src/bindings/encoding.rs
deleted file mode 100644
index 4e30628983e6392bb95c3acc59f6617cc7859f41..0000000000000000000000000000000000000000
--- a/mojo/public/rust/src/bindings/encoding.rs
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use bindings::mojom::MOJOM_NULL_POINTER;
-use bindings::util;
-
-use std::mem;
-use std::ptr;
-use std::ops::{Add, AddAssign, Sub, Mul, Div, Rem};
-use std::vec::Vec;
-
-use system::UntypedHandle;
-
-/// Represents some count of bits.
-///
-/// Used to distinguish when we have a bit and a byte
-/// count. The byte count will go in a usize, while we
-/// can use this structure to safely count bits without
-/// running into some subtle bugs or crazy errors.
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
-pub struct Bits(pub usize);
-
-impl Bits {
- /// Convert bit representation to bytes, rounding up to the nearest byte.
- pub fn as_bytes(self) -> usize {
- util::bits_to_bytes(self.0)
- }
-
- /// Convert to a number of bytes plus the number of bits leftover
- /// that could not fit in a full byte.
- pub fn as_bits_and_bytes(self) -> (Bits, usize) {
- (Bits(self.0 & 7), self.0 >> 3)
- }
-
- /// Return 1 left-shifted by the amount of bits stored here.
- ///
- /// Only guaranteed to work for up to 8 bits.
- pub fn as_set_bit(self) -> u8 {
- debug_assert!(self.0 < 8);
- 1 << (self.0 & 7)
- }
-
- pub fn checked_mul(self, val: usize) -> Option<Bits> {
- match val.checked_mul(self.0) {
- Some(result) => Some(Bits(result)),
- None => None,
- }
- }
-
- /// Align the bits to some number of bytes.
- pub fn align_to_bytes(&mut self, bytes: usize) {
- self.0 = util::align_bytes(self.0, 8 * bytes);
- }
-}
-
-impl Add for Bits {
- type Output = Self;
- fn add(self, rhs: Self) -> Self {
- Bits(self.0 + rhs.0)
- }
-}
-
-impl AddAssign for Bits {
- fn add_assign(&mut self, rhs: Self) {
- self.0 += rhs.0
- }
-}
-
-impl Mul<usize> for Bits {
- type Output = Self;
- fn mul(self, rhs: usize) -> Self {
- Bits(self.0 * rhs)
- }
-}
-
-/// This trait is intended to be used by Mojom primitive values
-/// in order to be identified in generic contexts.
-pub trait MojomNumeric: Copy + Clone + Sized + Add<Self> + Sub<Self, Output=Self> + Mul<Self> +
- Div<Self, Output=Self> + Rem<Self, Output=Self> + PartialEq<Self> + Default {
-
-/// Converts the primitive to a little-endian representation (the mojom endianness).
- fn to_mojom_endian(self) -> Self;
-}
-
-macro_rules! impl_mojom_numeric_for_prim {
- ($($t:ty),*) => {
- $(
- impl MojomNumeric for $t {
- fn to_mojom_endian(self) -> $t { self.to_le() }
- }
- )*
- }
-}
-
-impl_mojom_numeric_for_prim!(i8, i16, i32, i64, u8, u16, u32, u64);
-
-impl MojomNumeric for f32 {
- fn to_mojom_endian(self) -> f32 {
- unsafe { mem::transmute::<u32, f32>(mem::transmute::<f32, u32>(self).to_le()) }
- }
-}
-
-impl MojomNumeric for f64 {
- fn to_mojom_endian(self) -> f64 {
- unsafe { mem::transmute::<u64, f64>(mem::transmute::<f64, u64>(self).to_le()) }
- }
-}
-
-/// Align to the Mojom default of 8 bytes.
-pub fn align_default(bytes: usize) -> usize {
- util::align_bytes(bytes, 8)
-}
-
-/// The size in bytes of any data header.
-pub const DATA_HEADER_SIZE: usize = 8;
-
-/// A value that goes in the second u32 of a
-/// a data header.
-///
-/// Since the data header can head many types,
-/// this enum represents all the kinds of data
-/// that can end up in a data header.
-#[derive(Clone, Copy)]
-pub enum DataHeaderValue {
- Elements(u32),
- Version(u32),
- UnionTag(u32),
-}
-
-impl DataHeaderValue {
- /// Get the raw u32 value.
- fn as_raw(self) -> u32 {
- match self {
- DataHeaderValue::Elements(v) => v,
- DataHeaderValue::Version(v) => v,
- DataHeaderValue::UnionTag(v) => v,
- }
- }
-}
-
-/// A data header is placed at the beginning of every serialized
-/// Mojom object, providing its size as well as some extra meta-data.
-///
-/// The meta-data should always come from a DataHeaderValue.
-pub struct DataHeader {
- size: u32,
- data: u32,
-}
-
-impl DataHeader {
- /// Create a new DataHeader.
- pub fn new(size: usize, data: DataHeaderValue) -> DataHeader {
- DataHeader {
- size: size as u32,
- data: data.as_raw(),
- }
- }
-
- /// Getter for size.
- pub fn size(&self) -> u32 {
- self.size
- }
-
- /// Getter for extra meta-data.
- pub fn data(&self) -> u32 {
- self.data
- }
-}
-
-/// This context object represents an encoding/decoding context.
-#[derive(Clone, Default)]
-pub struct Context {
- /// An index representing an encoding state.
- id: usize,
-
- /// Whether or not our current context is directly inside of
- /// a union.
- is_union: bool,
-}
-
-impl Context {
- /// Create a new context with all data default.
- pub fn new(id: usize) -> Context {
- Context {
- id: id,
- is_union: false,
- }
- }
-
- /// Getter for the encoding state ID.
- pub fn id(&self) -> usize {
- self.id
- }
-
- /// Getter for whether or not we are in a union.
- pub fn is_union(&self) -> bool {
- self.is_union
- }
-
- /// Change whether or not we are inside of a union and create that
- /// as a new context.
- pub fn set_is_union(&self, value: bool) -> Context {
- let mut new_context = self.clone();
- new_context.is_union = value;
- new_context
- }
-}
-
-/// An encoding state represents the encoding logic for a single
-/// Mojom object that is NOT inlined, such as a struct or an array.
-pub struct EncodingState<'slice> {
- /// The buffer the state may write to.
- data: &'slice mut [u8],
-
- /// The offset of this serialized object into the overall buffer.
- global_offset: usize,
-
- /// The current offset within 'data'.
- offset: usize,
-
- /// The current bit offset within 'data'.
- bit_offset: Bits,
-}
-
-impl<'slice> EncodingState<'slice> {
- /// Create a new encoding state.
- ///
- /// Note: the encoder will not allocate a buffer for you, rather
- /// a pre-allocated buffer must be passed in.
- pub fn new(buffer: &'slice mut [u8],
- header: &DataHeader,
- offset: usize)
- -> EncodingState<'slice> {
- let mut state = EncodingState {
- data: buffer,
- global_offset: offset,
- offset: 0,
- bit_offset: Bits(0),
- };
- state.write(header.size());
- state.write(header.data());
- state
- }
-
- /// Align the encoding state to the next byte.
- pub fn align_to_byte(&mut self) {
- if self.bit_offset > Bits(0) {
- self.offset += 1;
- self.bit_offset = Bits(0);
- }
- }
-
- /// Align the encoding state to the next 'bytes' boundary.
- pub fn align_to_bytes(&mut self, bytes: usize) {
- self.offset = util::align_bytes(self.offset, bytes);
- }
-
- /// Write a primitive into the buffer.
- fn write<T: MojomNumeric>(&mut self, data: T) {
- let num_bytes = mem::size_of::<T>();
- let bytes = data.to_mojom_endian();
- debug_assert!(num_bytes + self.offset <= self.data.len());
- unsafe {
- ptr::copy_nonoverlapping(mem::transmute::<&T, *const u8>(&bytes),
- (&mut self.data[self.offset..]).as_mut_ptr(),
- num_bytes);
- }
- self.bit_offset = Bits(0);
- self.offset += num_bytes;
- }
-
- /// Encode a primitive into the buffer, naturally aligning it.
- pub fn encode<T: MojomNumeric>(&mut self, data: T) {
- self.align_to_byte();
- self.align_to_bytes(mem::size_of::<T>());
- self.write(data);
- }
-
- /// Encode a boolean value into the buffer as one bit.
- pub fn encode_bool(&mut self, data: bool) {
- let offset = self.offset;
- if data {
- self.data[offset] |= self.bit_offset.as_set_bit();
- }
- self.bit_offset += Bits(1);
- let (bits, bytes) = self.bit_offset.as_bits_and_bytes();
- self.offset += bytes;
- self.bit_offset = bits;
- }
-
- /// Encode a null union into the buffer.
- pub fn encode_null_union(&mut self) {
- self.align_to_byte();
- self.align_to_bytes(8);
- self.write(0 as u32); // Size
- self.write(0 as u32); // Tag
- self.write(0 as u64); // Data
- }
-
- /// Encode a null pointer into the buffer.
- pub fn encode_null_pointer(&mut self) {
- self.align_to_byte();
- self.align_to_bytes(8);
- self.encode(MOJOM_NULL_POINTER);
- }
-
- /// Encode a null handle into the buffer.
- pub fn encode_null_handle(&mut self) {
- self.align_to_byte();
- self.align_to_bytes(4);
- self.encode(-1 as i32);
- }
-
- /// Encode a non-null pointer into the buffer.
- ///
- /// 'location' is an absolute location in the global buffer, but
- /// Mojom pointers are offsets relative to the pointer, so we
- /// perform that conversion here before writing.
- pub fn encode_pointer(&mut self, location: u64) {
- self.align_to_byte();
- self.align_to_bytes(8);
- let current_location = (self.global_offset + self.offset) as u64;
- debug_assert!(location >= current_location);
- self.encode(location - current_location);
- }
-}
-
-/// A struct that will encode a given Mojom object and convert it into
-/// bytes and a vector of handles.
-pub struct Encoder<'slice> {
- bytes: usize,
- buffer: Option<&'slice mut [u8]>,
- states: Vec<EncodingState<'slice>>,
- handles: Vec<UntypedHandle>,
-}
-
-impl<'slice> Encoder<'slice> {
- /// Create a new Encoder.
- pub fn new(buffer: &'slice mut [u8]) -> Encoder<'slice> {
- Encoder {
- bytes: 0,
- buffer: Some(buffer),
- states: Vec::new(),
- handles: Vec::new(),
- }
- }
-
- /// Get the current encoded size (useful for writing pointers).
- pub fn size(&self) -> usize {
- self.bytes
- }
-
- /// Start encoding a new object with its data header.
- ///
- /// Creates a new encoding state for the object.
- pub fn add(&mut self, header: &DataHeader) -> Option<Context> {
- let buf = self.buffer.take().unwrap();
- if buf.len() < (header.size() as usize) {
- self.buffer = Some(buf);
- return None;
- }
- let obj_bytes = header.size() as usize;
- let (claimed, rest) = buf.split_at_mut(obj_bytes);
- self.states.push(EncodingState::new(claimed, header, self.bytes));
- self.bytes += obj_bytes;
- let padding_bytes = align_default(obj_bytes) - obj_bytes;
- if padding_bytes <= rest.len() {
- let (_, new_buffer) = rest.split_at_mut(padding_bytes);
- self.bytes += padding_bytes;
- self.buffer = Some(new_buffer);
- } else {
- self.buffer = Some(rest);
- }
- Some(Context::new(self.states.len() - 1))
- }
-
- /// Adds a handle and returns an offset to that handle in the
- /// final handle vector.
- pub fn add_handle(&mut self, handle: UntypedHandle) -> usize {
- self.handles.push(handle);
- self.handles.len() - 1
- }
-
- /// Immutably borrow an encoding state via Context.
- pub fn get(&self, context: &Context) -> &EncodingState<'slice> {
- &self.states[context.id()]
- }
-
- /// Mutably borrow an encoding state via Context.
- pub fn get_mut(&mut self, context: &Context) -> &mut EncodingState<'slice> {
- &mut self.states[context.id()]
- }
-
- /// Signal to finish encoding by destroying the Encoder and returning the final
- /// handle vector.
- ///
- /// Note: No byte buffer is returned as that is pre-allocated.
- pub fn unwrap(self) -> Vec<UntypedHandle> {
- self.handles
- }
-}
« no previous file with comments | « mojo/public/rust/src/bindings/decoding.rs ('k') | mojo/public/rust/src/bindings/macros.rs » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698