| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 use bindings::decoding::{Decoder, ValidationError}; |
| 5 use bindings::encoding; | 6 use bindings::encoding; |
| 6 use bindings::encoding::{Bits, Encoder, Context, DATA_HEADER_SIZE, DataHeader, D
ataHeaderValue}; | 7 use bindings::encoding::{Bits, Encoder, Context, DATA_HEADER_SIZE, DataHeader, D
ataHeaderValue}; |
| 7 use bindings::decoding::Decoder; | |
| 8 | |
| 9 use bindings::message::MessageHeader; | 8 use bindings::message::MessageHeader; |
| 10 | 9 |
| 11 use std::cmp::Eq; | 10 use std::cmp::Eq; |
| 12 use std::collections::HashMap; | 11 use std::collections::HashMap; |
| 13 use std::hash::Hash; | 12 use std::hash::Hash; |
| 14 use std::mem; | 13 use std::mem; |
| 15 use std::ptr; | 14 use std::ptr; |
| 16 use std::vec::Vec; | 15 use std::vec::Vec; |
| 17 | 16 |
| 18 use system::{CastHandle, Handle, UntypedHandle}; | 17 use system::{CastHandle, Handle, UntypedHandle}; |
| 19 use system::data_pipe; | 18 use system::data_pipe; |
| 20 use system::message_pipe; | 19 use system::message_pipe; |
| 21 use system::shared_buffer; | 20 use system::shared_buffer; |
| 22 use system::wait_set; | 21 use system::wait_set; |
| 23 | 22 |
| 24 /// The size of a Mojom map plus header in bytes. | 23 /// The size of a Mojom map plus header in bytes. |
| 25 const MAP_SIZE: usize = 24; | 24 const MAP_SIZE: usize = 24; |
| 26 | 25 |
| 26 /// The sorted set of versions for a map. |
| 27 const MAP_VERSIONS: [(u32, u32); 1] = [(0, MAP_SIZE as u32)]; |
| 28 |
| 27 /// The size of a Mojom union in bytes (header included). | 29 /// The size of a Mojom union in bytes (header included). |
| 28 pub const UNION_SIZE: usize = 16; | 30 pub const UNION_SIZE: usize = 16; |
| 29 | 31 |
| 30 /// The size of a Mojom pointer in bits. | 32 /// The size of a Mojom pointer in bits. |
| 31 pub const POINTER_BIT_SIZE: Bits = Bits(64); | 33 pub const POINTER_BIT_SIZE: Bits = Bits(64); |
| 32 | 34 |
| 33 /// The value of a Mojom null pointer. | 35 /// The value of a Mojom null pointer. |
| 34 pub const MOJOM_NULL_POINTER: u64 = 0; | 36 pub const MOJOM_NULL_POINTER: u64 = 0; |
| 35 | 37 |
| 36 /// An enumeration of all the possible low-level Mojom types. | 38 /// An enumeration of all the possible low-level Mojom types. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 55 fn embed_size(context: &Context) -> Bits; | 57 fn embed_size(context: &Context) -> Bits; |
| 56 | 58 |
| 57 /// Recursively computes the size of the complete Mojom archive | 59 /// Recursively computes the size of the complete Mojom archive |
| 58 /// starting from this type. | 60 /// starting from this type. |
| 59 fn compute_size(&self, context: Context) -> usize; | 61 fn compute_size(&self, context: Context) -> usize; |
| 60 | 62 |
| 61 /// Encodes this type into the encoder given a context. | 63 /// Encodes this type into the encoder given a context. |
| 62 fn encode(self, encoder: &mut Encoder, context: Context); | 64 fn encode(self, encoder: &mut Encoder, context: Context); |
| 63 | 65 |
| 64 /// Using a decoder, decodes itself out of a byte buffer. | 66 /// Using a decoder, decodes itself out of a byte buffer. |
| 65 fn decode(decoder: &mut Decoder, context: Context) -> Self; | 67 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, Validatio
nError>; |
| 66 } | 68 } |
| 67 | 69 |
| 68 /// Whatever implements this trait is a Mojom pointer type which means | 70 /// Whatever implements this trait is a Mojom pointer type which means |
| 69 /// that on encode, a pointer is inlined and the implementer is | 71 /// that on encode, a pointer is inlined and the implementer is |
| 70 /// serialized elsewhere in the output buffer. | 72 /// serialized elsewhere in the output buffer. |
| 71 pub trait MojomPointer: MojomEncodable { | 73 pub trait MojomPointer: MojomEncodable { |
| 72 /// Get the DataHeader meta-data for this pointer type. | 74 /// Get the DataHeader meta-data for this pointer type. |
| 73 fn header_data(&self) -> DataHeaderValue; | 75 fn header_data(&self) -> DataHeaderValue; |
| 74 | 76 |
| 75 /// Get the size of only this type when serialized. | 77 /// Get the size of only this type when serialized. |
| 76 fn serialized_size(&self, context: &Context) -> usize; | 78 fn serialized_size(&self, context: &Context) -> usize; |
| 77 | 79 |
| 78 /// Encodes the actual values of the type into the encoder. | 80 /// Encodes the actual values of the type into the encoder. |
| 79 fn encode_value(self, encoder: &mut Encoder, context: Context); | 81 fn encode_value(self, encoder: &mut Encoder, context: Context); |
| 80 | 82 |
| 81 /// Decodes the actual values of the type into the decoder. | 83 /// Decodes the actual values of the type into the decoder. |
| 82 fn decode_value(decoder: &mut Decoder, context: Context) -> Self; | 84 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, Val
idationError>; |
| 83 | 85 |
| 84 /// Writes a pointer inlined into the current context before calling | 86 /// Writes a pointer inlined into the current context before calling |
| 85 /// encode_value. | 87 /// encode_value. |
| 86 fn encode_new(self, encoder: &mut Encoder, context: Context) { | 88 fn encode_new(self, encoder: &mut Encoder, context: Context) { |
| 87 let data_size = self.serialized_size(&context); | 89 let data_size = self.serialized_size(&context); |
| 88 let data_header = DataHeader::new(data_size, self.header_data()); | 90 let data_header = DataHeader::new(data_size, self.header_data()); |
| 89 let new_context = encoder.add(&data_header).unwrap(); | 91 let new_context = encoder.add(&data_header).unwrap(); |
| 90 self.encode_value(encoder, new_context); | 92 self.encode_value(encoder, new_context); |
| 91 } | 93 } |
| 92 | 94 |
| 93 /// Reads a pointer inlined into the current context before calling | 95 /// Reads a pointer inlined into the current context before calling |
| 94 /// decode_value. | 96 /// decode_value. |
| 95 fn decode_new(decoder: &mut Decoder, _context: Context, pointer: u64) -> Sel
f { | 97 fn decode_new(decoder: &mut Decoder, _context: Context, pointer: u64) -> Res
ult<Self, ValidationError> { |
| 96 let new_context = decoder.claim(pointer as usize).unwrap(); | 98 match decoder.claim(pointer as usize) { |
| 97 Self::decode_value(decoder, new_context) | 99 Ok(new_context) => Self::decode_value(decoder, new_context), |
| 100 Err(err) => Err(err), |
| 101 } |
| 98 } | 102 } |
| 99 } | 103 } |
| 100 | 104 |
| 101 /// Whatever implements this trait is a Mojom union type which means that | 105 /// Whatever implements this trait is a Mojom union type which means that |
| 102 /// on encode it is inlined, but if the union is nested inside of another | 106 /// on encode it is inlined, but if the union is nested inside of another |
| 103 /// union type, it is treated as a pointer type. | 107 /// union type, it is treated as a pointer type. |
| 104 pub trait MojomUnion: MojomEncodable { | 108 pub trait MojomUnion: MojomEncodable { |
| 105 /// Get the union's current tag. | 109 /// Get the union's current tag. |
| 106 fn get_tag(&self) -> u32; | 110 fn get_tag(&self) -> u32; |
| 107 | 111 |
| 108 /// Encode the actual value of the union. | 112 /// Encode the actual value of the union. |
| 109 fn encode_value(self, encoder: &mut Encoder, context: Context); | 113 fn encode_value(self, encoder: &mut Encoder, context: Context); |
| 110 | 114 |
| 111 /// Decode the actual value of the union. | 115 /// Decode the actual value of the union. |
| 112 fn decode_value(decoder: &mut Decoder, context: Context) -> Self; | 116 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Self, Val
idationError>; |
| 113 | 117 |
| 114 /// The embed_size for when the union acts as a pointer type. | 118 /// The embed_size for when the union acts as a pointer type. |
| 115 fn nested_embed_size() -> Bits { | 119 fn nested_embed_size() -> Bits { |
| 116 POINTER_BIT_SIZE | 120 POINTER_BIT_SIZE |
| 117 } | 121 } |
| 118 | 122 |
| 119 /// The encoding routine for when the union acts as a pointer type. | 123 /// The encoding routine for when the union acts as a pointer type. |
| 120 fn nested_encode(self, encoder: &mut Encoder, context: Context) { | 124 fn nested_encode(self, encoder: &mut Encoder, context: Context) { |
| 121 let loc = encoder.size() as u64; | 125 let loc = encoder.size() as u64; |
| 122 { | 126 { |
| 123 let state = encoder.get_mut(&context); | 127 let state = encoder.get_mut(&context); |
| 124 state.encode_pointer(loc); | 128 state.encode_pointer(loc); |
| 125 } | 129 } |
| 126 let tag = DataHeaderValue::UnionTag(self.get_tag()); | 130 let tag = DataHeaderValue::UnionTag(self.get_tag()); |
| 127 let data_header = DataHeader::new(UNION_SIZE, tag); | 131 let data_header = DataHeader::new(UNION_SIZE, tag); |
| 128 let new_context = encoder.add(&data_header).unwrap(); | 132 let new_context = encoder.add(&data_header).unwrap(); |
| 129 self.encode_value(encoder, new_context.set_is_union(true)); | 133 self.encode_value(encoder, new_context.set_is_union(true)); |
| 130 } | 134 } |
| 131 | 135 |
| 132 /// The decoding routine for when the union acts as a pointer type. | 136 /// The decoding routine for when the union acts as a pointer type. |
| 133 fn nested_decode(decoder: &mut Decoder, context: Context) -> Self { | 137 fn nested_decode(decoder: &mut Decoder, context: Context) -> Result<Self, Va
lidationError> { |
| 134 let global_offset = { | 138 let global_offset = { |
| 135 let state = decoder.get_mut(&context); | 139 let state = decoder.get_mut(&context); |
| 136 state.decode_pointer() as usize | 140 match state.decode_pointer() { |
| 141 Some(ptr) => ptr as usize, |
| 142 None => return Err(ValidationError::IllegalPointer), |
| 143 } |
| 137 }; | 144 }; |
| 138 let new_context = decoder.claim(global_offset).unwrap(); | 145 if global_offset == (MOJOM_NULL_POINTER as usize) { |
| 139 Self::decode_value(decoder, new_context) | 146 return Err(ValidationError::UnexpectedNullPointer); |
| 147 } |
| 148 match decoder.claim(global_offset as usize) { |
| 149 Ok(new_context) => Self::decode_value(decoder, new_context), |
| 150 Err(err) => Err(err), |
| 151 } |
| 140 } | 152 } |
| 141 | 153 |
| 142 /// The embed_size for when the union is inlined into the current context. | 154 /// The embed_size for when the union is inlined into the current context. |
| 143 fn inline_embed_size() -> Bits { | 155 fn inline_embed_size() -> Bits { |
| 144 Bits(8 * (UNION_SIZE as usize)) | 156 Bits(8 * (UNION_SIZE as usize)) |
| 145 } | 157 } |
| 146 | 158 |
| 147 /// The encoding routine for when the union is inlined into the current cont
ext. | 159 /// The encoding routine for when the union is inlined into the current cont
ext. |
| 148 fn inline_encode(self, encoder: &mut Encoder, context: Context) { | 160 fn inline_encode(self, encoder: &mut Encoder, context: Context) { |
| 149 { | 161 { |
| 150 let mut state = encoder.get_mut(&context); | 162 let mut state = encoder.get_mut(&context); |
| 151 state.align_to_bytes(8); | 163 state.align_to_bytes(8); |
| 152 state.encode(UNION_SIZE as u32); | 164 state.encode(UNION_SIZE as u32); |
| 153 state.encode(self.get_tag()); | 165 state.encode(self.get_tag()); |
| 154 } | 166 } |
| 155 self.encode_value(encoder, context.clone()); | 167 self.encode_value(encoder, context.clone()); |
| 156 { | 168 { |
| 157 let mut state = encoder.get_mut(&context); | 169 let mut state = encoder.get_mut(&context); |
| 158 state.align_to_bytes(8); | 170 state.align_to_bytes(8); |
| 159 state.align_to_byte(); | 171 state.align_to_byte(); |
| 160 } | 172 } |
| 161 } | 173 } |
| 162 | 174 |
| 163 /// The decoding routine for when the union is inlined into the current cont
ext. | 175 /// The decoding routine for when the union is inlined into the current cont
ext. |
| 164 fn inline_decode(decoder: &mut Decoder, context: Context) -> Self { | 176 fn inline_decode(decoder: &mut Decoder, context: Context) -> Result<Self, Va
lidationError> { |
| 165 { | 177 { |
| 166 let mut state = decoder.get_mut(&context); | 178 let mut state = decoder.get_mut(&context); |
| 167 state.align_to_byte(); | 179 state.align_to_byte(); |
| 168 state.align_to_bytes(8); | 180 state.align_to_bytes(8); |
| 169 } | 181 } |
| 170 let value = Self::decode_value(decoder, context.clone()); | 182 let value = Self::decode_value(decoder, context.clone()); |
| 171 { | 183 { |
| 172 let mut state = decoder.get_mut(&context); | 184 let mut state = decoder.get_mut(&context); |
| 173 state.align_to_byte(); | 185 state.align_to_byte(); |
| 174 state.align_to_bytes(8); | 186 state.align_to_bytes(8); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 /// interface that may recieve messages for some interface. | 248 /// interface that may recieve messages for some interface. |
| 237 /// | 249 /// |
| 238 /// When implementing this trait, specify the container "union" type | 250 /// When implementing this trait, specify the container "union" type |
| 239 /// which can contain any of the potential messages that may be recieved. | 251 /// which can contain any of the potential messages that may be recieved. |
| 240 /// This way, we can return that type and let the user multiplex over | 252 /// This way, we can return that type and let the user multiplex over |
| 241 /// what message was received. | 253 /// what message was received. |
| 242 pub trait MojomInterfaceRecv: MojomInterface { | 254 pub trait MojomInterfaceRecv: MojomInterface { |
| 243 type Container: MojomMessageOption; | 255 type Container: MojomMessageOption; |
| 244 | 256 |
| 245 /// Tries to read a message from a pipe and decodes it. | 257 /// Tries to read a message from a pipe and decodes it. |
| 246 fn recv_response(&self) -> Self::Container { | 258 fn recv_response(&self) -> Result<Self::Container, ValidationError> { |
| 247 // TODO(mknyszek): Actually handle errors with reading | 259 // TODO(mknyszek): Actually handle errors with reading |
| 248 let (buffer, handles) = self.pipe().read(mpflags!(Read::None)).unwrap(); | 260 let (buffer, handles) = self.pipe().read(mpflags!(Read::None)).unwrap(); |
| 249 Self::Container::decode_message(buffer, handles) | 261 Self::Container::decode_message(buffer, handles) |
| 250 } | 262 } |
| 251 } | 263 } |
| 252 | 264 |
| 253 /// Whatever implements this trait is considered to be a Mojom struct. | 265 /// Whatever implements this trait is considered to be a Mojom struct. |
| 254 /// | 266 /// |
| 255 /// Mojom structs are always the root of any Mojom message. Thus, we | 267 /// Mojom structs are always the root of any Mojom message. Thus, we |
| 256 /// provide convenience functions for serialization here. | 268 /// provide convenience functions for serialization here. |
| 257 pub trait MojomStruct: MojomPointer { | 269 pub trait MojomStruct: MojomPointer { |
| 258 /// Given a pre-allocated buffer, the struct serializes itself. | 270 /// Given a pre-allocated buffer, the struct serializes itself. |
| 259 fn serialize(self, buffer: &mut [u8]) -> Vec<UntypedHandle> { | 271 fn serialize(self, buffer: &mut [u8]) -> Vec<UntypedHandle> { |
| 260 let mut encoder = Encoder::new(buffer); | 272 let mut encoder = Encoder::new(buffer); |
| 261 self.encode_new(&mut encoder, Default::default()); | 273 self.encode_new(&mut encoder, Default::default()); |
| 262 encoder.unwrap() | 274 encoder.unwrap() |
| 263 } | 275 } |
| 264 | 276 |
| 265 /// The struct computes its own size, allocates a buffer, and then | 277 /// The struct computes its own size, allocates a buffer, and then |
| 266 /// serializes itself into that buffer. | 278 /// serializes itself into that buffer. |
| 267 fn auto_serialize(self) -> (Vec<u8>, Vec<UntypedHandle>) { | 279 fn auto_serialize(self) -> (Vec<u8>, Vec<UntypedHandle>) { |
| 268 let size = self.compute_size(Default::default()); | 280 let size = self.compute_size(Default::default()); |
| 269 let mut buf = Vec::with_capacity(size); | 281 let mut buf = Vec::with_capacity(size); |
| 270 buf.resize(size, 0); | 282 buf.resize(size, 0); |
| 271 let handles = self.serialize(&mut buf); | 283 let handles = self.serialize(&mut buf); |
| 272 (buf, handles) | 284 (buf, handles) |
| 273 } | 285 } |
| 274 | 286 |
| 275 /// Decode the type from a byte array and a set of handles. | 287 /// Decode the type from a byte array and a set of handles. |
| 276 fn deserialize(buffer: &mut [u8], handles: Vec<UntypedHandle>) -> Self { | 288 fn deserialize(buffer: &mut [u8], handles: Vec<UntypedHandle>) -> Result<Sel
f, ValidationError> { |
| 277 let mut decoder = Decoder::new(buffer, handles); | 289 let mut decoder = Decoder::new(buffer, handles); |
| 278 Self::decode_new(&mut decoder, Default::default(), 0) | 290 Self::decode_new(&mut decoder, Default::default(), 0) |
| 279 } | 291 } |
| 280 } | 292 } |
| 281 | 293 |
| 282 /// Marks a MojomStruct as being capable of being sent across some | 294 /// Marks a MojomStruct as being capable of being sent across some |
| 283 /// Mojom interface. | 295 /// Mojom interface. |
| 284 pub trait MojomMessage: MojomStruct { | 296 pub trait MojomMessage: MojomStruct { |
| 285 fn create_header() -> MessageHeader; | 297 fn create_header() -> MessageHeader; |
| 286 } | 298 } |
| 287 | 299 |
| 288 /// The trait for a "container" type intended to be used in MojomInterfaceRecv. | 300 /// The trait for a "container" type intended to be used in MojomInterfaceRecv. |
| 289 /// | 301 /// |
| 290 /// This trait contains the decode logic which decodes based on the message head
er | 302 /// This trait contains the decode logic which decodes based on the message head
er |
| 291 /// and returns itself: a union type which may contain any of the possible messa
ges | 303 /// and returns itself: a union type which may contain any of the possible messa
ges |
| 292 /// that may be sent across this interface. | 304 /// that may be sent across this interface. |
| 293 pub trait MojomMessageOption: Sized { | 305 pub trait MojomMessageOption: Sized { |
| 294 /// Decodes the actual payload of the message. | 306 /// Decodes the actual payload of the message. |
| 295 /// | 307 /// |
| 296 /// Implemented by a code generator. | 308 /// Implemented by a code generator. |
| 297 fn decode_payload(name: u32, buffer: &mut [u8], handles: Vec<UntypedHandle>)
-> Self; | 309 fn decode_payload(header: MessageHeader, buffer: &mut [u8], handles: Vec<Unt
ypedHandle>) -> Result<Self, ValidationError>; |
| 298 | 310 |
| 299 /// Decodes the message header and then the payload, returning a new | 311 /// Decodes the message header and then the payload, returning a new |
| 300 /// copy of itself. | 312 /// copy of itself. |
| 301 fn decode_message(mut buffer: Vec<u8>, handles: Vec<UntypedHandle>) -> Self
{ | 313 fn decode_message(mut buffer: Vec<u8>, handles: Vec<UntypedHandle>) -> Resul
t<Self, ValidationError> { |
| 302 let header = MessageHeader::deserialize(&mut buffer[..], Vec::new()); | 314 let header = match MessageHeader::deserialize(&mut buffer[..], Vec::new(
)) { |
| 315 Ok(header) => header, |
| 316 Err(err) => return Err(err), |
| 317 }; |
| 303 let payload_buffer = &mut buffer[header.serialized_size(&Default::defaul
t())..]; | 318 let payload_buffer = &mut buffer[header.serialized_size(&Default::defaul
t())..]; |
| 304 Self::decode_payload(header.name, payload_buffer, handles) | 319 Self::decode_payload(header, payload_buffer, handles) |
| 305 } | 320 } |
| 306 } | 321 } |
| 307 | 322 |
| 308 // ********************************************** // | 323 // ********************************************** // |
| 309 // ****** IMPLEMENTATIONS FOR COMMON TYPES ****** // | 324 // ****** IMPLEMENTATIONS FOR COMMON TYPES ****** // |
| 310 // ********************************************** // | 325 // ********************************************** // |
| 311 | 326 |
| 312 macro_rules! impl_encodable_for_prim { | 327 macro_rules! impl_encodable_for_prim { |
| 313 ($($prim_type:ty),*) => { | 328 ($($prim_type:ty),*) => { |
| 314 $( | 329 $( |
| 315 impl MojomEncodable for $prim_type { | 330 impl MojomEncodable for $prim_type { |
| 316 fn mojom_type() -> MojomType { | 331 fn mojom_type() -> MojomType { |
| 317 MojomType::Simple | 332 MojomType::Simple |
| 318 } | 333 } |
| 319 fn mojom_alignment() -> usize { | 334 fn mojom_alignment() -> usize { |
| 320 mem::size_of::<$prim_type>() | 335 mem::size_of::<$prim_type>() |
| 321 } | 336 } |
| 322 fn embed_size(_context: &Context) -> Bits { | 337 fn embed_size(_context: &Context) -> Bits { |
| 323 Bits(8 * mem::size_of::<$prim_type>()) | 338 Bits(8 * mem::size_of::<$prim_type>()) |
| 324 } | 339 } |
| 325 fn compute_size(&self, _context: Context) -> usize { | 340 fn compute_size(&self, _context: Context) -> usize { |
| 326 0 // Indicates that this type is inlined and it adds nothing ext
ernal to the size | 341 0 // Indicates that this type is inlined and it adds nothing ext
ernal to the size |
| 327 } | 342 } |
| 328 fn encode(self, encoder: &mut Encoder, context: Context) { | 343 fn encode(self, encoder: &mut Encoder, context: Context) { |
| 329 let mut state = encoder.get_mut(&context); | 344 let mut state = encoder.get_mut(&context); |
| 330 state.encode(self); | 345 state.encode(self); |
| 331 } | 346 } |
| 332 fn decode(decoder: &mut Decoder, context: Context) -> Self { | 347 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, V
alidationError> { |
| 333 let mut state = decoder.get_mut(&context); | 348 let mut state = decoder.get_mut(&context); |
| 334 state.decode::<Self>() | 349 Ok(state.decode::<Self>()) |
| 335 } | 350 } |
| 336 } | 351 } |
| 337 )* | 352 )* |
| 338 } | 353 } |
| 339 } | 354 } |
| 340 | 355 |
| 341 impl_encodable_for_prim!(i8, i16, i32, i64, u8, u16, u32, u64, f32, f64); | 356 impl_encodable_for_prim!(i8, i16, i32, i64, u8, u16, u32, u64, f32, f64); |
| 342 | 357 |
| 343 impl MojomEncodable for bool { | 358 impl MojomEncodable for bool { |
| 344 fn mojom_alignment() -> usize { | 359 fn mojom_alignment() -> usize { |
| 345 panic!("Should never check mojom_alignment of bools (they're bit-aligned
)!"); | 360 panic!("Should never check_decode mojom_alignment of bools (they're bit-
aligned)!"); |
| 346 } | 361 } |
| 347 fn mojom_type() -> MojomType { | 362 fn mojom_type() -> MojomType { |
| 348 MojomType::Simple | 363 MojomType::Simple |
| 349 } | 364 } |
| 350 fn embed_size(_context: &Context) -> Bits { | 365 fn embed_size(_context: &Context) -> Bits { |
| 351 Bits(1) | 366 Bits(1) |
| 352 } | 367 } |
| 353 fn compute_size(&self, _context: Context) -> usize { | 368 fn compute_size(&self, _context: Context) -> usize { |
| 354 0 // Indicates that this type is inlined and it adds nothing external to
the size | 369 0 // Indicates that this type is inlined and it adds nothing external to
the size |
| 355 } | 370 } |
| 356 fn encode(self, encoder: &mut Encoder, context: Context) { | 371 fn encode(self, encoder: &mut Encoder, context: Context) { |
| 357 let mut state = encoder.get_mut(&context); | 372 let mut state = encoder.get_mut(&context); |
| 358 state.encode_bool(self); | 373 state.encode_bool(self); |
| 359 } | 374 } |
| 360 fn decode(decoder: &mut Decoder, context: Context) -> Self { | 375 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, Validatio
nError> { |
| 361 let mut state = decoder.get_mut(&context); | 376 let mut state = decoder.get_mut(&context); |
| 362 state.decode_bool() | 377 Ok(state.decode_bool()) |
| 363 } | 378 } |
| 364 } | 379 } |
| 365 | 380 |
| 366 // Options should be considered to represent nullability the Mojom IDL. | 381 // Options should be considered to represent nullability the Mojom IDL. |
| 367 // Any type wrapped in an Option type is nullable. | 382 // Any type wrapped in an Option type is nullable. |
| 368 | 383 |
| 369 impl<T: MojomEncodable> MojomEncodable for Option<T> { | 384 impl<T: MojomEncodable> MojomEncodable for Option<T> { |
| 370 fn mojom_alignment() -> usize { | 385 fn mojom_alignment() -> usize { |
| 371 T::mojom_alignment() | 386 T::mojom_alignment() |
| 372 } | 387 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 393 MojomType::Handle => state.encode_null_handle(), | 408 MojomType::Handle => state.encode_null_handle(), |
| 394 MojomType::Interface => { | 409 MojomType::Interface => { |
| 395 state.encode_null_handle(); | 410 state.encode_null_handle(); |
| 396 state.encode(0 as u32); | 411 state.encode(0 as u32); |
| 397 }, | 412 }, |
| 398 MojomType::Simple => panic!("Unexpected simple type in Optio
n!"), | 413 MojomType::Simple => panic!("Unexpected simple type in Optio
n!"), |
| 399 } | 414 } |
| 400 }, | 415 }, |
| 401 } | 416 } |
| 402 } | 417 } |
| 403 fn decode(decoder: &mut Decoder, context: Context) -> Self { | 418 fn decode(decoder: &mut Decoder, context: Context) -> Result<Self, Validatio
nError> { |
| 404 let skipped = { | 419 let skipped = { |
| 405 let mut state = decoder.get_mut(&context); | 420 let mut state = decoder.get_mut(&context); |
| 406 match T::mojom_type() { | 421 match T::mojom_type() { |
| 407 MojomType::Pointer => state.skip_if_null_pointer(), | 422 MojomType::Pointer => state.skip_if_null_pointer(), |
| 408 MojomType::Union => state.skip_if_null_union(), | 423 MojomType::Union => state.skip_if_null_union(), |
| 409 MojomType::Handle => state.skip_if_null_handle(), | 424 MojomType::Handle => state.skip_if_null_handle(), |
| 410 MojomType::Interface => state.skip_if_null_interface(), | 425 MojomType::Interface => state.skip_if_null_interface(), |
| 411 MojomType::Simple => panic!("Unexpected simple type in Option!")
, | 426 MojomType::Simple => panic!("Unexpected simple type in Option!")
, |
| 412 } | 427 } |
| 413 }; | 428 }; |
| 414 if skipped { | 429 if skipped { |
| 415 None | 430 Ok(None) |
| 416 } else { | 431 } else { |
| 417 Some(T::decode(decoder, context)) | 432 match T::decode(decoder, context) { |
| 433 Ok(value) => Ok(Some(value)), |
| 434 Err(err) => Err(err), |
| 435 } |
| 418 } | 436 } |
| 419 } | 437 } |
| 420 } | 438 } |
| 421 | 439 |
| 422 macro_rules! impl_pointer_for_array { | 440 macro_rules! impl_pointer_for_array { |
| 423 () => { | 441 () => { |
| 424 fn header_data(&self) -> DataHeaderValue { | 442 fn header_data(&self) -> DataHeaderValue { |
| 425 DataHeaderValue::Elements(self.len() as u32) | 443 DataHeaderValue::Elements(self.len() as u32) |
| 426 } | 444 } |
| 427 fn serialized_size(&self, context: &Context) -> usize { | 445 fn serialized_size(&self, context: &Context) -> usize { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 447 } | 465 } |
| 448 } | 466 } |
| 449 | 467 |
| 450 impl<T: MojomEncodable> MojomPointer for Vec<T> { | 468 impl<T: MojomEncodable> MojomPointer for Vec<T> { |
| 451 impl_pointer_for_array!(); | 469 impl_pointer_for_array!(); |
| 452 fn encode_value(self, encoder: &mut Encoder, context: Context) { | 470 fn encode_value(self, encoder: &mut Encoder, context: Context) { |
| 453 for elem in self.into_iter() { | 471 for elem in self.into_iter() { |
| 454 elem.encode(encoder, context.clone()); | 472 elem.encode(encoder, context.clone()); |
| 455 } | 473 } |
| 456 } | 474 } |
| 457 fn decode_value(decoder: &mut Decoder, context: Context) -> Vec<T> { | 475 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Vec<T>, V
alidationError> { |
| 458 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match | 476 let elems = { |
| 459 let (_bytes, elems) = { | |
| 460 let mut state = decoder.get_mut(&context); | 477 let mut state = decoder.get_mut(&context); |
| 461 (state.decode::<u32>(), state.decode::<u32>()) | 478 match state.decode_array_header::<T>() { |
| 479 Ok(header) => header.data(), |
| 480 Err(err) => return Err(err), |
| 481 } |
| 462 }; | 482 }; |
| 463 let mut value = Vec::with_capacity(elems as usize); | 483 let mut value = Vec::with_capacity(elems as usize); |
| 464 // TODO(mknyszek): Don't trust elems blindly | |
| 465 for _ in 0..elems { | 484 for _ in 0..elems { |
| 466 value.push(T::decode(decoder, context.clone())); | 485 match T::decode(decoder, context.clone()) { |
| 486 Ok(elem) => value.push(elem), |
| 487 Err(err) => return Err(err), |
| 488 } |
| 467 } | 489 } |
| 468 value | 490 Ok(value) |
| 469 } | 491 } |
| 470 } | 492 } |
| 471 | 493 |
| 472 impl<T: MojomEncodable> MojomEncodable for Vec<T> { | 494 impl<T: MojomEncodable> MojomEncodable for Vec<T> { |
| 473 impl_encodable_for_array!(); | 495 impl_encodable_for_array!(); |
| 474 } | 496 } |
| 475 | 497 |
| 476 macro_rules! impl_encodable_for_boxed_fixed_array { | 498 macro_rules! impl_encodable_for_boxed_fixed_array { |
| 477 ($($len:expr),*) => { | 499 ($($len:expr),*) => { |
| 478 $( | 500 $( |
| 479 impl<T: MojomEncodable> MojomPointer for Box<[T; $len]> { | 501 impl<T: MojomEncodable> MojomPointer for Box<[T; $len]> { |
| 480 impl_pointer_for_array!(); | 502 impl_pointer_for_array!(); |
| 481 fn encode_value(self, encoder: &mut Encoder, context: Context) { | 503 fn encode_value(self, encoder: &mut Encoder, context: Context) { |
| 482 for elem in (self as Box<[T]>).into_vec().into_iter() { | 504 for elem in (self as Box<[T]>).into_vec().into_iter() { |
| 483 elem.encode(encoder, context.clone()); | 505 elem.encode(encoder, context.clone()); |
| 484 } | 506 } |
| 485 } | 507 } |
| 486 fn decode_value(decoder: &mut Decoder, context: Context) -> Box<[T;
$len]> { | 508 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<B
ox<[T; $len]>, ValidationError> { |
| 487 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match | 509 let elems = { |
| 488 let (_bytes, elems) = { | |
| 489 let mut state = decoder.get_mut(&context); | 510 let mut state = decoder.get_mut(&context); |
| 490 (state.decode::<u32>(), state.decode::<u32>()) | 511 match state.decode_array_header::<T>() { |
| 512 Ok(header) => header.data(), |
| 513 Err(err) => return Err(err), |
| 514 } |
| 491 }; | 515 }; |
| 492 assert_eq!(elems, $len); | 516 if elems != $len { |
| 517 return Err(ValidationError::UnexpectedArrayHeader); |
| 518 } |
| 493 let mut array: [T; $len]; | 519 let mut array: [T; $len]; |
| 520 let mut error = None; |
| 494 unsafe { | 521 unsafe { |
| 495 // Since we don't force Default to be implemented on Mojom t
ypes | 522 // Since we don't force Default to be implemented on Mojom t
ypes |
| 496 // (mainly due to handles) we need to create this array as u
ninitialized | 523 // (mainly due to handles) we need to create this array as u
ninitialized |
| 497 // and initialize it manually. | 524 // and initialize it manually. |
| 498 array = mem::uninitialized(); | 525 array = mem::uninitialized(); |
| 526 let mut inits = 0; |
| 499 for elem in &mut array[..] { | 527 for elem in &mut array[..] { |
| 500 ptr::write(elem, T::decode(decoder, context.clone())); | 528 match T::decode(decoder, context.clone()) { |
| 529 Ok(value) => ptr::write(elem, value), |
| 530 Err(err) => { |
| 531 error = Some(err); |
| 532 break; |
| 533 }, |
| 534 } |
| 535 inits += 1; |
| 536 } |
| 537 // An error occurred, so we need to do some clean-up. |
| 538 if inits != $len { |
| 539 for i in 0..inits { |
| 540 ptr::drop_in_place(&mut array[i] as *mut T); |
| 541 } |
| 542 mem::forget(array); |
| 543 return Err(error.take().expect("Corrupted stack?")); |
| 501 } | 544 } |
| 502 } | 545 } |
| 503 Box::new(array) | 546 Ok(Box::new(array)) |
| 504 } | 547 } |
| 505 } | 548 } |
| 506 impl<T: MojomEncodable> MojomEncodable for Box<[T; $len]> { | 549 impl<T: MojomEncodable> MojomEncodable for Box<[T; $len]> { |
| 507 impl_encodable_for_array!(); | 550 impl_encodable_for_array!(); |
| 508 } | 551 } |
| 509 )* | 552 )* |
| 510 } | 553 } |
| 511 } | 554 } |
| 512 | 555 |
| 513 // Unfortunately, we cannot be generic over the length of a fixed array | 556 // Unfortunately, we cannot be generic over the length of a fixed array |
| 514 // even though its part of the type (this will hopefully be added in the | 557 // even though its part of the type (this will hopefully be added in the |
| 515 // future) so for now we implement encodable for only the first 33 fixed | 558 // future) so for now we implement encodable for only the first 33 fixed |
| 516 // size array types. | 559 // size array types. |
| 517 impl_encodable_for_boxed_fixed_array!( 0, 1, 2, 3, 4, 5, 6, 7, | 560 impl_encodable_for_boxed_fixed_array!( 0, 1, 2, 3, 4, 5, 6, 7, |
| 518 8, 9, 10, 11, 12, 13, 14, 15, | 561 8, 9, 10, 11, 12, 13, 14, 15, |
| 519 16, 17, 18, 19, 20, 21, 22, 23, | 562 16, 17, 18, 19, 20, 21, 22, 23, |
| 520 24, 25, 26, 27, 28, 29, 30, 31, | 563 24, 25, 26, 27, 28, 29, 30, 31, |
| 521 32); | 564 32); |
| 522 | 565 |
| 523 impl<T: MojomEncodable> MojomPointer for Box<[T]> { | 566 impl<T: MojomEncodable> MojomPointer for Box<[T]> { |
| 524 impl_pointer_for_array!(); | 567 impl_pointer_for_array!(); |
| 525 fn encode_value(self, encoder: &mut Encoder, context: Context) { | 568 fn encode_value(self, encoder: &mut Encoder, context: Context) { |
| 526 for elem in self.into_vec().into_iter() { | 569 for elem in self.into_vec().into_iter() { |
| 527 elem.encode(encoder, context.clone()); | 570 elem.encode(encoder, context.clone()); |
| 528 } | 571 } |
| 529 } | 572 } |
| 530 fn decode_value(decoder: &mut Decoder, context: Context) -> Box<[T]> { | 573 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<Box<[T]>,
ValidationError> { |
| 531 Vec::<T>::decode_value(decoder, context).into_boxed_slice() | 574 match Vec::<T>::decode_value(decoder, context) { |
| 575 Ok(vec) => Ok(vec.into_boxed_slice()), |
| 576 Err(err) => Err(err), |
| 577 } |
| 532 } | 578 } |
| 533 } | 579 } |
| 534 | 580 |
| 535 impl<T: MojomEncodable> MojomEncodable for Box<[T]> { | 581 impl<T: MojomEncodable> MojomEncodable for Box<[T]> { |
| 536 impl_encodable_for_array!(); | 582 impl_encodable_for_array!(); |
| 537 } | 583 } |
| 538 | 584 |
| 539 // We can represent a Mojom string as just a Rust String type | 585 // We can represent a Mojom string as just a Rust String type |
| 540 // since both are UTF-8. | 586 // since both are UTF-8. |
| 541 impl MojomPointer for String { | 587 impl MojomPointer for String { |
| 542 fn header_data(&self) -> DataHeaderValue { | 588 fn header_data(&self) -> DataHeaderValue { |
| 543 DataHeaderValue::Elements(self.len() as u32) | 589 DataHeaderValue::Elements(self.len() as u32) |
| 544 } | 590 } |
| 545 fn serialized_size(&self, _context: &Context) -> usize { | 591 fn serialized_size(&self, _context: &Context) -> usize { |
| 546 DATA_HEADER_SIZE + self.len() | 592 DATA_HEADER_SIZE + self.len() |
| 547 } | 593 } |
| 548 fn encode_value(self, encoder: &mut Encoder, context: Context) { | 594 fn encode_value(self, encoder: &mut Encoder, context: Context) { |
| 549 for byte in self.as_bytes() { | 595 for byte in self.as_bytes() { |
| 550 byte.encode(encoder, context.clone()); | 596 byte.encode(encoder, context.clone()); |
| 551 } | 597 } |
| 552 } | 598 } |
| 553 fn decode_value(decoder: &mut Decoder, context: Context) -> String { | 599 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<String, V
alidationError> { |
| 554 let mut state = decoder.get_mut(&context); | 600 let mut state = decoder.get_mut(&context); |
| 555 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match | 601 let elems = match state.decode_array_header::<u8>() { |
| 556 let _bytes = state.decode::<u32>(); | 602 Ok(header) => header.data(), |
| 557 let elems = state.decode::<u32>(); | 603 Err(err) => return Err(err), |
| 604 }; |
| 558 let mut value = Vec::with_capacity(elems as usize); | 605 let mut value = Vec::with_capacity(elems as usize); |
| 559 // TODO(mknyszek): Don't trust elems blindly | |
| 560 for _ in 0..elems { | 606 for _ in 0..elems { |
| 561 value.push(state.decode::<u8>()); | 607 value.push(state.decode::<u8>()); |
| 562 } | 608 } |
| 563 match String::from_utf8(value) { | 609 match String::from_utf8(value) { |
| 564 Ok(string) => string, | 610 Ok(string) => Ok(string), |
| 565 // TODO(mknyszek): Don't panic and return an error | |
| 566 Err(err) => panic!("Error decoding String: {}", err), | 611 Err(err) => panic!("Error decoding String: {}", err), |
| 567 } | 612 } |
| 568 } | 613 } |
| 569 } | 614 } |
| 570 | 615 |
| 571 impl MojomEncodable for String { | 616 impl MojomEncodable for String { |
| 572 impl_encodable_for_pointer!(); | 617 impl_encodable_for_pointer!(); |
| 573 fn compute_size(&self, context: Context) -> usize { | 618 fn compute_size(&self, context: Context) -> usize { |
| 574 encoding::align_default(self.serialized_size(&context)) | 619 encoding::align_default(self.serialized_size(&context)) |
| 575 } | 620 } |
| 576 } | 621 } |
| 577 | 622 |
| 623 /// Helper function to clean up duplicate code in HashMap. |
| 624 fn array_claim_and_decode_header<T: MojomEncodable>(decoder: &mut Decoder, offse
t: usize) -> Result<(Context, usize), ValidationError> { |
| 625 let context = match decoder.claim(offset) { |
| 626 Ok(new_context) => new_context, |
| 627 Err(err) => return Err(err), |
| 628 }; |
| 629 let elems = { |
| 630 let state = decoder.get_mut(&context); |
| 631 match state.decode_array_header::<T>() { |
| 632 Ok(header) => header.data(), |
| 633 Err(err) => return Err(err), |
| 634 } |
| 635 }; |
| 636 Ok((context, elems as usize)) |
| 637 } |
| 638 |
| 578 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomPointer for HashMap<
K, V> { | 639 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomPointer for HashMap<
K, V> { |
| 579 fn header_data(&self) -> DataHeaderValue { | 640 fn header_data(&self) -> DataHeaderValue { |
| 580 DataHeaderValue::Version(0) | 641 DataHeaderValue::Version(0) |
| 581 } | 642 } |
| 582 fn serialized_size(&self, _context: &Context) -> usize { | 643 fn serialized_size(&self, _context: &Context) -> usize { |
| 583 MAP_SIZE | 644 MAP_SIZE |
| 584 } | 645 } |
| 585 fn encode_value(self, encoder: &mut Encoder, context: Context) { | 646 fn encode_value(self, encoder: &mut Encoder, context: Context) { |
| 586 let elems = self.len(); | 647 let elems = self.len(); |
| 587 let meta_value = DataHeaderValue::Elements(elems as u32); | 648 let meta_value = DataHeaderValue::Elements(elems as u32); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 601 // Claim space for the keys array in the encoder | 662 // Claim space for the keys array in the encoder |
| 602 let keys_context = encoder.add(&keys_data_header).unwrap(); | 663 let keys_context = encoder.add(&keys_data_header).unwrap(); |
| 603 // Encode keys, setup vals | 664 // Encode keys, setup vals |
| 604 for (key, value) in self.into_iter() { | 665 for (key, value) in self.into_iter() { |
| 605 key.encode(encoder, keys_context.clone()); | 666 key.encode(encoder, keys_context.clone()); |
| 606 vals_vec.push(value); | 667 vals_vec.push(value); |
| 607 } | 668 } |
| 608 // Encode vals | 669 // Encode vals |
| 609 vals_vec.encode(encoder, context.clone()) | 670 vals_vec.encode(encoder, context.clone()) |
| 610 } | 671 } |
| 611 fn decode_value(decoder: &mut Decoder, context: Context) -> HashMap<K, V> { | 672 fn decode_value(decoder: &mut Decoder, context: Context) -> Result<HashMap<K
, V>, ValidationError> { |
| 612 // TODO(mknyszek): Verify elems, bytes, and T::embed_size match | |
| 613 let (keys_offset, vals_offset) = { | 673 let (keys_offset, vals_offset) = { |
| 614 let mut state = decoder.get_mut(&context); | 674 let state = decoder.get_mut(&context); |
| 615 let _bytes = state.decode::<u32>(); | 675 match state.decode_struct_header(&MAP_VERSIONS) { |
| 616 let _version = state.decode::<u32>(); | 676 Ok(_) => (), |
| 617 let keys_offset = state.decode_pointer() as usize; | 677 Err(err) => return Err(err), |
| 618 let vals_offset = state.decode_pointer() as usize; | 678 }; |
| 619 (keys_offset, vals_offset) | 679 // Decode the keys pointer and check for overflow |
| 680 let keys_offset = match state.decode_pointer() { |
| 681 Some(ptr) => ptr, |
| 682 None => return Err(ValidationError::IllegalPointer), |
| 683 }; |
| 684 // Decode the keys pointer and check for overflow |
| 685 let vals_offset = match state.decode_pointer() { |
| 686 Some(ptr) => ptr, |
| 687 None => return Err(ValidationError::IllegalPointer), |
| 688 }; |
| 689 if keys_offset == MOJOM_NULL_POINTER || vals_offset == MOJOM_NULL_PO
INTER { |
| 690 return Err(ValidationError::UnexpectedNullPointer); |
| 691 } |
| 692 (keys_offset as usize, vals_offset as usize) |
| 620 }; | 693 }; |
| 621 let keys_context = decoder.claim(keys_offset).unwrap(); | 694 let (keys_context, keys_elems) = match array_claim_and_decode_header::<K
>(decoder, keys_offset) { |
| 622 let keys_elems = { | 695 Ok((context, elems)) => (context, elems), |
| 623 let state = decoder.get_mut(&keys_context); | 696 Err(err) => return Err(err), |
| 624 let _size_keys = state.decode::<u32>(); | |
| 625 state.decode::<u32>() | |
| 626 }; | 697 }; |
| 627 let mut keys_vec: Vec<K> = Vec::with_capacity(keys_elems as usize); | 698 let mut keys_vec: Vec<K> = Vec::with_capacity(keys_elems as usize); |
| 628 for _ in 0..keys_elems { | 699 for _ in 0..keys_elems { |
| 629 let key = K::decode(decoder, keys_context.clone()); | 700 let key = match K::decode(decoder, keys_context.clone()) { |
| 701 Ok(value) => value, |
| 702 Err(err) => return Err(err), |
| 703 }; |
| 630 keys_vec.push(key); | 704 keys_vec.push(key); |
| 631 } | 705 } |
| 632 let vals_context = decoder.claim(vals_offset).unwrap(); | 706 let (vals_context, vals_elems) = match array_claim_and_decode_header::<V
>(decoder, vals_offset) { |
| 633 let vals_elems = { | 707 Ok((context, elems)) => (context, elems), |
| 634 let state = decoder.get_mut(&vals_context); | 708 Err(err) => return Err(err), |
| 635 let _size_vals = state.decode::<u32>(); | |
| 636 state.decode::<u32>() | |
| 637 }; | 709 }; |
| 638 // TODO(mknyszek): Do a validation error instead | 710 if keys_elems != vals_elems { |
| 639 assert_eq!(keys_elems, vals_elems); | 711 return Err(ValidationError::DifferentSizedArraysInMap); |
| 640 // TODO(mknyszek): Don't trust elems blindly | 712 } |
| 641 let mut map = HashMap::with_capacity(keys_elems as usize); | 713 let mut map = HashMap::with_capacity(keys_elems as usize); |
| 642 for key in keys_vec.into_iter() { | 714 for key in keys_vec.into_iter() { |
| 643 let val = V::decode(decoder, vals_context.clone()); | 715 let val = match V::decode(decoder, vals_context.clone()) { |
| 716 Ok(value) => value, |
| 717 Err(err) => return Err(err), |
| 718 }; |
| 644 map.insert(key, val); | 719 map.insert(key, val); |
| 645 } | 720 } |
| 646 map | 721 Ok(map) |
| 647 } | 722 } |
| 648 } | 723 } |
| 649 | 724 |
| 650 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomEncodable for HashMa
p<K, V> { | 725 impl<K: MojomEncodable + Eq + Hash, V: MojomEncodable> MojomEncodable for HashMa
p<K, V> { |
| 651 impl_encodable_for_pointer!(); | 726 impl_encodable_for_pointer!(); |
| 652 fn compute_size(&self, context: Context) -> usize { | 727 fn compute_size(&self, context: Context) -> usize { |
| 653 let mut size = encoding::align_default(self.serialized_size(&context)); | 728 let mut size = encoding::align_default(self.serialized_size(&context)); |
| 654 // The size of the one array | 729 // The size of the one array |
| 655 size += DATA_HEADER_SIZE; | 730 size += DATA_HEADER_SIZE; |
| 656 size += (K::embed_size(&context) * self.len()).as_bytes(); | 731 size += (K::embed_size(&context) * self.len()).as_bytes(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 Bits(8 * mem::size_of::<u32>()) | 763 Bits(8 * mem::size_of::<u32>()) |
| 689 } | 764 } |
| 690 fn compute_size(&self, _context: Context) -> usize { | 765 fn compute_size(&self, _context: Context) -> usize { |
| 691 0 | 766 0 |
| 692 } | 767 } |
| 693 fn encode(self, encoder: &mut Encoder, context: Context) { | 768 fn encode(self, encoder: &mut Encoder, context: Context) { |
| 694 let pos = encoder.add_handle(self.as_untyped()); | 769 let pos = encoder.add_handle(self.as_untyped()); |
| 695 let mut state = encoder.get_mut(&context); | 770 let mut state = encoder.get_mut(&context); |
| 696 state.encode(pos as i32); | 771 state.encode(pos as i32); |
| 697 } | 772 } |
| 698 fn decode(decoder: &mut Decoder, context: Context) -> $handle_type { | 773 fn decode(decoder: &mut Decoder, context: Context) -> Result<$handle_typ
e, ValidationError> { |
| 699 // TODO(mknyszek): Verify handle index | |
| 700 let handle_index = { | 774 let handle_index = { |
| 701 let mut state = decoder.get_mut(&context); | 775 let mut state = decoder.get_mut(&context); |
| 702 state.decode::<i32>() | 776 state.decode::<i32>() |
| 703 }; | 777 }; |
| 704 decoder.claim_handle::<$handle_type>(handle_index) | 778 decoder.claim_handle::<$handle_type>(handle_index) |
| 705 } | 779 } |
| 706 } | 780 } |
| 707 } | 781 } |
| 708 | 782 |
| 709 impl MojomEncodable for UntypedHandle { | 783 impl MojomEncodable for UntypedHandle { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 722 impl_encodable_for_handle!(data_pipe::Consumer<T>); | 796 impl_encodable_for_handle!(data_pipe::Consumer<T>); |
| 723 } | 797 } |
| 724 | 798 |
| 725 impl<T> MojomEncodable for data_pipe::Producer<T> { | 799 impl<T> MojomEncodable for data_pipe::Producer<T> { |
| 726 impl_encodable_for_handle!(data_pipe::Producer<T>); | 800 impl_encodable_for_handle!(data_pipe::Producer<T>); |
| 727 } | 801 } |
| 728 | 802 |
| 729 impl MojomEncodable for wait_set::WaitSet { | 803 impl MojomEncodable for wait_set::WaitSet { |
| 730 impl_encodable_for_handle!(wait_set::WaitSet); | 804 impl_encodable_for_handle!(wait_set::WaitSet); |
| 731 } | 805 } |
| OLD | NEW |