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