OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 package org.chromium.mojo.bindings; | 5 package org.chromium.mojo.bindings; |
6 | 6 |
7 import org.chromium.mojo.bindings.Struct.DataHeader; | 7 import org.chromium.mojo.bindings.Struct.DataHeader; |
8 import org.chromium.mojo.system.Core; | 8 import org.chromium.mojo.system.Core; |
9 import org.chromium.mojo.system.Handle; | 9 import org.chromium.mojo.system.Handle; |
10 import org.chromium.mojo.system.MessagePipeHandle; | 10 import org.chromium.mojo.system.MessagePipeHandle; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 /** | 202 /** |
203 * Encode a double at the given offset. | 203 * Encode a double at the given offset. |
204 */ | 204 */ |
205 public void encode(double v, int offset) { | 205 public void encode(double v, int offset) { |
206 mEncoderState.byteBuffer.putDouble(mBaseOffset + offset, v); | 206 mEncoderState.byteBuffer.putDouble(mBaseOffset + offset, v); |
207 } | 207 } |
208 | 208 |
209 /** | 209 /** |
210 * Encode a {@link Struct} at the given offset. | 210 * Encode a {@link Struct} at the given offset. |
211 */ | 211 */ |
212 public void encode(Struct v, int offset) { | 212 public void encode(Struct v, int offset, boolean nullable) { |
213 if (v == null) { | 213 if (v == null) { |
214 encodeNullPointer(offset); | 214 encodeNullPointer(offset, nullable); |
215 return; | 215 return; |
216 } | 216 } |
217 encodePointerToNextUnclaimedData(offset); | 217 encodePointerToNextUnclaimedData(offset); |
218 v.encode(this); | 218 v.encode(this); |
219 } | 219 } |
220 | 220 |
221 /** | 221 /** |
222 * Encodes a String. | 222 * Encodes a String. |
223 */ | 223 */ |
224 public void encode(String v, int offset) { | 224 public void encode(String v, int offset, boolean nullable) { |
225 if (v == null) { | 225 if (v == null) { |
226 encodeNullPointer(offset); | 226 encodeNullPointer(offset, nullable); |
227 return; | 227 return; |
228 } | 228 } |
229 encode(v.getBytes( | 229 final int arrayNullability = nullable ? BindingsHelper.ARRAY_NULLABLE : 0; |
qsr
2014/09/02 07:41:44
You have a constant instead of this 0 in BindingsH
ppi
2014/09/02 16:50:43
Done.
| |
230 Charset.forName("utf8")), offset, BindingsHelper.UNSPECIFIED_ARR AY_LENGTH); | 230 encode(v.getBytes(Charset.forName("utf8")), offset, arrayNullability, |
231 BindingsHelper.UNSPECIFIED_ARRAY_LENGTH); | |
231 } | 232 } |
232 | 233 |
233 /** | 234 /** |
234 * Encodes a {@link Handle}. | 235 * Encodes a {@link Handle}. |
235 */ | 236 */ |
236 public void encode(Handle v, int offset) { | 237 public void encode(Handle v, int offset, boolean nullable) { |
237 if (v == null || !v.isValid()) { | 238 if (v == null || !v.isValid()) { |
ppi
2014/09/01 19:00:45
What do we do if the field is not nullable, v != n
qsr
2014/09/02 07:41:44
Non nullable for a handle means valid, so this cas
ppi
2014/09/02 16:50:43
Acknowledged.
| |
238 encode(-1, offset); | 239 encodeInvalidHandle(offset, nullable); |
239 } else { | 240 } else { |
240 encode(mEncoderState.handles.size(), offset); | 241 encode(mEncoderState.handles.size(), offset); |
241 mEncoderState.handles.add(v); | 242 mEncoderState.handles.add(v); |
242 } | 243 } |
243 } | 244 } |
244 | 245 |
245 /** | 246 /** |
246 * Encode an {@link Interface}. | 247 * Encode an {@link Interface}. |
247 */ | 248 */ |
248 public <T extends Interface> void encode(T v, int offset, Interface.Manager< T, ?> manager) { | 249 public <T extends Interface> void encode(T v, int offset, boolean nullable, |
250 Interface.Manager<T, ?> manager) { | |
249 if (v == null) { | 251 if (v == null) { |
250 encode(-1, offset); | 252 encodeInvalidHandle(offset, nullable); |
251 return; | 253 return; |
252 } | 254 } |
253 if (mEncoderState.core == null) { | 255 if (mEncoderState.core == null) { |
254 throw new UnsupportedOperationException( | 256 throw new UnsupportedOperationException( |
255 "The encoder has been created without a Core. It can't encod e an interface."); | 257 "The encoder has been created without a Core. It can't encod e an interface."); |
256 } | 258 } |
257 // If the instance is a proxy, pass the proxy's handle instead of creati ng a new stub. | 259 // If the instance is a proxy, pass the proxy's handle instead of creati ng a new stub. |
258 if (v instanceof Interface.AbstractProxy) { | 260 if (v instanceof Interface.AbstractProxy) { |
259 Interface.AbstractProxy proxy = (Interface.AbstractProxy) v; | 261 Interface.AbstractProxy proxy = (Interface.AbstractProxy) v; |
260 if (proxy.getMessageReceiver() instanceof HandleOwner) { | 262 if (proxy.getMessageReceiver() instanceof HandleOwner) { |
261 encode(((HandleOwner<?>) proxy.getMessageReceiver()).passHandle( ), offset); | 263 encode(((HandleOwner<?>) proxy.getMessageReceiver()).passHandle( ), offset, |
264 nullable); | |
262 return; | 265 return; |
263 } | 266 } |
264 // If the proxy is not over a message pipe, the default case applies . | 267 // If the proxy is not over a message pipe, the default case applies . |
265 } | 268 } |
266 Pair<MessagePipeHandle, MessagePipeHandle> handles = | 269 Pair<MessagePipeHandle, MessagePipeHandle> handles = |
267 mEncoderState.core.createMessagePipe(null); | 270 mEncoderState.core.createMessagePipe(null); |
268 manager.bind(v, handles.first); | 271 manager.bind(v, handles.first); |
269 encode(handles.second, offset); | 272 encode(handles.second, offset, nullable); |
270 } | 273 } |
271 | 274 |
272 /** | 275 /** |
273 * Encode an {@link InterfaceRequest}. | 276 * Encode an {@link InterfaceRequest}. |
274 */ | 277 */ |
275 public <I extends Interface> void encode(InterfaceRequest<I> v, int offset) { | 278 public <I extends Interface> void encode(InterfaceRequest<I> v, int offset, boolean nullable) { |
276 if (v == null) { | 279 if (v == null) { |
277 encode(-1, offset); | 280 encodeInvalidHandle(offset, nullable); |
278 return; | 281 return; |
279 } | 282 } |
280 if (mEncoderState.core == null) { | 283 if (mEncoderState.core == null) { |
281 throw new UnsupportedOperationException( | 284 throw new UnsupportedOperationException( |
282 "The encoder has been created without a Core. It can't encod e an interface."); | 285 "The encoder has been created without a Core. It can't encod e an interface."); |
283 } | 286 } |
284 encode(v.passHandle(), offset); | 287 encode(v.passHandle(), offset, nullable); |
285 } | 288 } |
286 | 289 |
287 /** | 290 /** |
288 * Returns an {@link Encoder} suitable for encoding an array of pointer of t he given length. | 291 * Returns an {@link Encoder} suitable for encoding an array of pointer of t he given length. |
289 */ | 292 */ |
290 public Encoder encodePointerArray(int length, int offset, int expectedLength ) { | 293 public Encoder encodePointerArray(int length, int offset, int expectedLength ) { |
291 return encoderForArray(BindingsHelper.POINTER_SIZE, length, offset, expe ctedLength); | 294 return encoderForArray(BindingsHelper.POINTER_SIZE, length, offset, expe ctedLength); |
292 } | 295 } |
293 | 296 |
294 /** | 297 /** |
295 * Encodes an array of booleans. | 298 * Encodes an array of booleans. |
296 */ | 299 */ |
297 public void encode(boolean[] v, int offset, int expectedLength) { | 300 public void encode(boolean[] v, int offset, int arrayNullability, int expect edLength) { |
298 if (v == null) { | 301 if (v == null) { |
299 encodeNullPointer(offset); | 302 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
300 return; | 303 return; |
301 } | 304 } |
302 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && | 305 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && |
303 expectedLength != v.length) { | 306 expectedLength != v.length) { |
304 throw new SerializationException("Trying to encode a fixed array of incorrect length."); | 307 throw new SerializationException("Trying to encode a fixed array of incorrect length."); |
305 } | 308 } |
306 byte[] bytes = new byte[(v.length + 7) / BindingsHelper.ALIGNMENT]; | 309 byte[] bytes = new byte[(v.length + 7) / BindingsHelper.ALIGNMENT]; |
307 for (int i = 0; i < bytes.length; ++i) { | 310 for (int i = 0; i < bytes.length; ++i) { |
308 for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) { | 311 for (int j = 0; j < BindingsHelper.ALIGNMENT; ++j) { |
309 int booleanIndex = BindingsHelper.ALIGNMENT * i + j; | 312 int booleanIndex = BindingsHelper.ALIGNMENT * i + j; |
310 if (booleanIndex < v.length && v[booleanIndex]) { | 313 if (booleanIndex < v.length && v[booleanIndex]) { |
311 bytes[i] |= (1 << j); | 314 bytes[i] |= (1 << j); |
312 } | 315 } |
313 } | 316 } |
314 } | 317 } |
315 encodeByteArray(bytes, v.length, offset); | 318 encodeByteArray(bytes, v.length, offset); |
316 } | 319 } |
317 | 320 |
318 /** | 321 /** |
319 * Encodes an array of bytes. | 322 * Encodes an array of bytes. |
320 */ | 323 */ |
321 public void encode(byte[] v, int offset, int expectedLength) { | 324 public void encode(byte[] v, int offset, int arrayNullability, int expectedL ength) { |
322 if (v == null) { | 325 if (v == null) { |
323 encodeNullPointer(offset); | 326 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
324 return; | 327 return; |
325 } | 328 } |
326 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && | 329 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && |
327 expectedLength != v.length) { | 330 expectedLength != v.length) { |
328 throw new SerializationException("Trying to encode a fixed array of incorrect length."); | 331 throw new SerializationException("Trying to encode a fixed array of incorrect length."); |
329 } | 332 } |
330 encodeByteArray(v, v.length, offset); | 333 encodeByteArray(v, v.length, offset); |
331 } | 334 } |
332 | 335 |
333 /** | 336 /** |
334 * Encodes an array of shorts. | 337 * Encodes an array of shorts. |
335 */ | 338 */ |
336 public void encode(short[] v, int offset, int expectedLength) { | 339 public void encode(short[] v, int offset, int arrayNullability, int expected Length) { |
337 if (v == null) { | 340 if (v == null) { |
338 encodeNullPointer(offset); | 341 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
339 return; | 342 return; |
340 } | 343 } |
341 encoderForArray(2, v.length, offset, expectedLength).append(v); | 344 encoderForArray(2, v.length, offset, expectedLength).append(v); |
342 } | 345 } |
343 | 346 |
344 /** | 347 /** |
345 * Encodes an array of ints. | 348 * Encodes an array of ints. |
346 */ | 349 */ |
347 public void encode(int[] v, int offset, int expectedLength) { | 350 public void encode(int[] v, int offset, int arrayNullability, int expectedLe ngth) { |
348 if (v == null) { | 351 if (v == null) { |
349 encodeNullPointer(offset); | 352 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
350 return; | 353 return; |
351 } | 354 } |
352 encoderForArray(4, v.length, offset, expectedLength).append(v); | 355 encoderForArray(4, v.length, offset, expectedLength).append(v); |
353 } | 356 } |
354 | 357 |
355 /** | 358 /** |
356 * Encodes an array of floats. | 359 * Encodes an array of floats. |
357 */ | 360 */ |
358 public void encode(float[] v, int offset, int expectedLength) { | 361 public void encode(float[] v, int offset, int arrayNullability, int expected Length) { |
359 if (v == null) { | 362 if (v == null) { |
360 encodeNullPointer(offset); | 363 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
361 return; | 364 return; |
362 } | 365 } |
363 encoderForArray(4, v.length, offset, expectedLength).append(v); | 366 encoderForArray(4, v.length, offset, expectedLength).append(v); |
364 } | 367 } |
365 | 368 |
366 /** | 369 /** |
367 * Encodes an array of longs. | 370 * Encodes an array of longs. |
368 */ | 371 */ |
369 public void encode(long[] v, int offset, int expectedLength) { | 372 public void encode(long[] v, int offset, int arrayNullability, int expectedL ength) { |
370 if (v == null) { | 373 if (v == null) { |
371 encodeNullPointer(offset); | 374 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
372 return; | 375 return; |
373 } | 376 } |
374 encoderForArray(8, v.length, offset, expectedLength).append(v); | 377 encoderForArray(8, v.length, offset, expectedLength).append(v); |
375 } | 378 } |
376 | 379 |
377 /** | 380 /** |
378 * Encodes an array of doubles. | 381 * Encodes an array of doubles. |
379 */ | 382 */ |
380 public void encode(double[] v, int offset, int expectedLength) { | 383 public void encode(double[] v, int offset, int arrayNullability, int expecte dLength) { |
381 if (v == null) { | 384 if (v == null) { |
382 encodeNullPointer(offset); | 385 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
383 return; | 386 return; |
384 } | 387 } |
385 encoderForArray(8, v.length, offset, expectedLength).append(v); | 388 encoderForArray(8, v.length, offset, expectedLength).append(v); |
386 } | 389 } |
387 | 390 |
388 /** | 391 /** |
389 * Encodes an array of {@link Handle}. | 392 * Encodes an array of {@link Handle}. |
390 */ | 393 */ |
391 public void encode(Handle[] v, int offset, int expectedLength) { | 394 public void encode(Handle[] v, int offset, int arrayNullability, int expecte dLength) { |
392 if (v == null) { | 395 if (v == null) { |
393 encodeNullPointer(offset); | 396 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
394 return; | 397 return; |
395 } | 398 } |
396 Encoder e = encoderForArray( | 399 Encoder e = encoderForArray( |
397 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); | 400 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); |
398 for (int i = 0; i < v.length; ++i) { | 401 for (int i = 0; i < v.length; ++i) { |
399 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i); | 402 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i, |
403 BindingsHelper.isElementNullable(arrayNullability)); | |
400 } | 404 } |
401 } | 405 } |
402 | 406 |
403 /** | 407 /** |
404 * Encodes an array of {@link Interface}. | 408 * Encodes an array of {@link Interface}. |
405 */ | 409 */ |
406 public <T extends Interface> void encode(T[] v, int offset, int expectedLeng th, | 410 public <T extends Interface> void encode(T[] v, int offset, int arrayNullabi lity, |
407 Interface.Manager<T, ?> manager) { | 411 int expectedLength, Interface.Manager<T, ?> manager) { |
408 if (v == null) { | 412 if (v == null) { |
409 encodeNullPointer(offset); | 413 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
410 return; | 414 return; |
411 } | 415 } |
412 Encoder e = encoderForArray( | 416 Encoder e = encoderForArray( |
413 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); | 417 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); |
414 for (int i = 0; i < v.length; ++i) { | 418 for (int i = 0; i < v.length; ++i) { |
415 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i, | 419 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i, |
416 manager); | 420 BindingsHelper.isElementNullable(arrayNullability), manager) ; |
417 } | 421 } |
418 } | 422 } |
419 | 423 |
420 /** | 424 /** |
421 * Encodes an array of {@link InterfaceRequest}. | 425 * Encodes an array of {@link InterfaceRequest}. |
422 */ | 426 */ |
423 public <I extends Interface> void encode(InterfaceRequest<I>[] v, int offset , | 427 public <I extends Interface> void encode(InterfaceRequest<I>[] v, int offset , |
424 int expectedLength) { | 428 int arrayNullability, int expectedLength) { |
425 if (v == null) { | 429 if (v == null) { |
426 encodeNullPointer(offset); | 430 encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullab ility)); |
427 return; | 431 return; |
428 } | 432 } |
429 Encoder e = encoderForArray( | 433 Encoder e = encoderForArray( |
430 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); | 434 BindingsHelper.SERIALIZED_HANDLE_SIZE, v.length, offset, expecte dLength); |
431 for (int i = 0; i < v.length; ++i) { | 435 for (int i = 0; i < v.length; ++i) { |
432 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i); | 436 e.encode(v[i], DataHeader.HEADER_SIZE + BindingsHelper.SERIALIZED_HA NDLE_SIZE * i, |
437 BindingsHelper.isElementNullable(arrayNullability)); | |
433 } | 438 } |
434 } | 439 } |
435 | 440 |
436 /** | 441 /** |
437 * Encode a <code>null</code> pointer. | 442 * Encodes a <code>null</code> pointer iff the object is nullable, raises an exception |
443 * otherwise. | |
438 */ | 444 */ |
439 public void encodeNullPointer(int offset) { | 445 public void encodeNullPointer(int offset, boolean nullable) { |
446 if (!nullable) { | |
447 throw new SerializationException( | |
448 "Trying to encode a null pointer for a non-nullable type."); | |
449 } | |
440 mEncoderState.byteBuffer.putLong(mBaseOffset + offset, 0); | 450 mEncoderState.byteBuffer.putLong(mBaseOffset + offset, 0); |
441 } | 451 } |
442 | 452 |
453 /** | |
454 * Encodes an invalid handle iff the object is nullable, raises an exception otherwise. | |
455 */ | |
456 public void encodeInvalidHandle(int offset, boolean nullable) { | |
457 if (!nullable) { | |
458 throw new SerializationException( | |
459 "Trying to encode an invalid handle for a non-nullable type. "); | |
460 } | |
461 mEncoderState.byteBuffer.putInt(mBaseOffset + offset, -1); | |
462 } | |
463 | |
443 private void encodePointerToNextUnclaimedData(int offset) { | 464 private void encodePointerToNextUnclaimedData(int offset) { |
444 encode((long) mEncoderState.dataEnd - (mBaseOffset + offset), offset); | 465 encode((long) mEncoderState.dataEnd - (mBaseOffset + offset), offset); |
445 } | 466 } |
446 | 467 |
447 private Encoder encoderForArray( | 468 private Encoder encoderForArray( |
448 int elementSizeInByte, int length, int offset, int expectedLength) { | 469 int elementSizeInByte, int length, int offset, int expectedLength) { |
449 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && | 470 if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH && |
450 expectedLength != length) { | 471 expectedLength != length) { |
451 throw new SerializationException("Trying to encode a fixed array of incorrect length."); | 472 throw new SerializationException("Trying to encode a fixed array of incorrect length."); |
452 } | 473 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
487 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE); | 508 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE); |
488 mEncoderState.byteBuffer.asDoubleBuffer().put(v); | 509 mEncoderState.byteBuffer.asDoubleBuffer().put(v); |
489 } | 510 } |
490 | 511 |
491 private void append(long[] v) { | 512 private void append(long[] v) { |
492 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE); | 513 mEncoderState.byteBuffer.position(mBaseOffset + DataHeader.HEADER_SIZE); |
493 mEncoderState.byteBuffer.asLongBuffer().put(v); | 514 mEncoderState.byteBuffer.asLongBuffer().put(v); |
494 } | 515 } |
495 | 516 |
496 } | 517 } |
OLD | NEW |