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 3 // found in the LICENSE file. 4 5 package org.chromium.mojo.bindings; 6 7 import org.chromium.mojo.system.AsyncWaiter; 8 import org.chromium.mojo.system.Handle; 9 10 /** 11 * Helper functions. 12 */ 13 public class BindingsHelper { 14 /** 15 * Alignment in bytes for mojo serialization. 16 */ 17 public static final int ALIGNMENT = 8; 18 19 /** 20 * The size, in bytes, of a serialized handle. A handle is serialized as an int representing the 21 * offset of the handle in the list of handles. 22 */ 23 public static final int SERIALIZED_HANDLE_SIZE = 4; 24 25 /** 26 * The size, in bytes, of a serialized pointer. A pointer is serializaed as an unsigned long 27 * representing the offset from its position to the pointed elemnt. 28 */ 29 public static final int POINTER_SIZE = 8; 30 31 /** 32 * The value used for the expected length of a non-fixed size array. 33 */ 34 public static final int UNSPECIFIED_ARRAY_LENGTH = -1; 35 36 /** 37 * Align |size| on {@link BindingsHelper#ALIGNMENT}. 38 */ align(int size)39 public static int align(int size) { 40 return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); 41 } 42 43 /** 44 * Passed as |arrayNullability| when neither the array nor its elements are nullable. 45 */ 46 public static final int NOTHING_NULLABLE = 0; 47 48 /** 49 * "Array bit" of |arrayNullability| is set iff the array itself is nullable. 50 */ 51 public static final int ARRAY_NULLABLE = (1 << 0); 52 53 /** 54 * "Element bit" of |arrayNullability| is set iff the array elements are nullable. 55 */ 56 public static final int ELEMENT_NULLABLE = (1 << 1); 57 isArrayNullable(int arrayNullability)58 public static boolean isArrayNullable(int arrayNullability) { 59 return (arrayNullability & ARRAY_NULLABLE) > 0; 60 } 61 isElementNullable(int arrayNullability)62 public static boolean isElementNullable(int arrayNullability) { 63 return (arrayNullability & ELEMENT_NULLABLE) > 0; 64 } 65 66 /** 67 * Align |size| on {@link BindingsHelper#ALIGNMENT}. 68 */ align(long size)69 public static long align(long size) { 70 return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); 71 } 72 73 /** 74 * Compute the size in bytes of the given string encoded as utf8. 75 */ utf8StringSizeInBytes(String s)76 public static int utf8StringSizeInBytes(String s) { 77 int res = 0; 78 for (int i = 0; i < s.length(); ++i) { 79 char c = s.charAt(i); 80 int codepoint = c; 81 if (isSurrogate(c)) { 82 i++; 83 char c2 = s.charAt(i); 84 codepoint = Character.toCodePoint(c, c2); 85 } 86 res += 1; 87 if (codepoint > 0x7f) { 88 res += 1; 89 if (codepoint > 0x7ff) { 90 res += 1; 91 if (codepoint > 0xffff) { 92 res += 1; 93 if (codepoint > 0x1fffff) { 94 res += 1; 95 if (codepoint > 0x3ffffff) { 96 res += 1; 97 } 98 } 99 } 100 } 101 } 102 } 103 return res; 104 } 105 106 /** 107 * Determines if the given {@code char} value is a Unicode <i>surrogate code unit</i>. See 108 * {@link Character#isSurrogate}. Extracting here because the method only exists at API level 109 * 19. 110 */ isSurrogate(char c)111 private static boolean isSurrogate(char c) { 112 return c >= Character.MIN_SURROGATE && c < (Character.MAX_SURROGATE + 1); 113 } 114 115 /** 116 * Returns an {@link AsyncWaiter} to use with the given handle, or <code>null</code> if none if 117 * available. 118 */ getDefaultAsyncWaiterForHandle(Handle handle)119 static AsyncWaiter getDefaultAsyncWaiterForHandle(Handle handle) { 120 if (handle.getCore() != null) { 121 return handle.getCore().getDefaultAsyncWaiter(); 122 } else { 123 return null; 124 } 125 } 126 127 } 128