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 interface, which consists of a serialized handle (4 27 * bytes) and a version number (4 bytes). 28 */ 29 public static final int SERIALIZED_INTERFACE_SIZE = 8; 30 31 /** 32 * The size, in bytes, of a serialized pointer. A pointer is serializaed as an unsigned long 33 * representing the offset from its position to the pointed elemnt. 34 */ 35 public static final int POINTER_SIZE = 8; 36 37 /** 38 * The size, in bytes, of a serialized union. 39 */ 40 public static final int UNION_SIZE = 16; 41 42 /** 43 * The header for a serialized map element. 44 */ 45 public static final DataHeader MAP_STRUCT_HEADER = new DataHeader(24, 0); 46 47 /** 48 * The value used for the expected length of a non-fixed size array. 49 */ 50 public static final int UNSPECIFIED_ARRAY_LENGTH = -1; 51 52 /** 53 * Passed as |arrayNullability| when neither the array nor its elements are nullable. 54 */ 55 public static final int NOTHING_NULLABLE = 0; 56 57 /** 58 * "Array bit" of |arrayNullability| is set iff the array itself is nullable. 59 */ 60 public static final int ARRAY_NULLABLE = (1 << 0); 61 62 /** 63 * "Element bit" of |arrayNullability| is set iff the array elements are nullable. 64 */ 65 public static final int ELEMENT_NULLABLE = (1 << 1); 66 isArrayNullable(int arrayNullability)67 public static boolean isArrayNullable(int arrayNullability) { 68 return (arrayNullability & ARRAY_NULLABLE) > 0; 69 } 70 isElementNullable(int arrayNullability)71 public static boolean isElementNullable(int arrayNullability) { 72 return (arrayNullability & ELEMENT_NULLABLE) > 0; 73 } 74 75 /** 76 * Align |size| on {@link BindingsHelper#ALIGNMENT}. 77 */ align(int size)78 public static int align(int size) { 79 return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); 80 } 81 82 /** 83 * Align |size| on {@link BindingsHelper#ALIGNMENT}. 84 */ align(long size)85 public static long align(long size) { 86 return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); 87 } 88 89 /** 90 * Compute the size in bytes of the given string encoded as utf8. 91 */ utf8StringSizeInBytes(String s)92 public static int utf8StringSizeInBytes(String s) { 93 int res = 0; 94 for (int i = 0; i < s.length(); ++i) { 95 char c = s.charAt(i); 96 int codepoint = c; 97 if (isSurrogate(c)) { 98 i++; 99 char c2 = s.charAt(i); 100 codepoint = Character.toCodePoint(c, c2); 101 } 102 res += 1; 103 if (codepoint > 0x7f) { 104 res += 1; 105 if (codepoint > 0x7ff) { 106 res += 1; 107 if (codepoint > 0xffff) { 108 res += 1; 109 if (codepoint > 0x1fffff) { 110 res += 1; 111 if (codepoint > 0x3ffffff) { 112 res += 1; 113 } 114 } 115 } 116 } 117 } 118 } 119 return res; 120 } 121 122 /** 123 * Returns |true| if and only if the two objects are equals, handling |null|. 124 */ equals(Object o1, Object o2)125 public static boolean equals(Object o1, Object o2) { 126 if (o1 == o2) { 127 return true; 128 } 129 if (o1 == null) { 130 return false; 131 } 132 return o1.equals(o2); 133 } 134 135 /** 136 * Returns the hash code of the object, handling |null|. 137 */ hashCode(Object o)138 public static int hashCode(Object o) { 139 if (o == null) { 140 return 0; 141 } 142 return o.hashCode(); 143 } 144 145 /** 146 * Returns the hash code of the value. 147 */ hashCode(boolean o)148 public static int hashCode(boolean o) { 149 return o ? 1231 : 1237; 150 } 151 152 /** 153 * Returns the hash code of the value. 154 */ hashCode(long o)155 public static int hashCode(long o) { 156 return (int) (o ^ (o >>> 32)); 157 } 158 159 /** 160 * Returns the hash code of the value. 161 */ hashCode(float o)162 public static int hashCode(float o) { 163 return Float.floatToIntBits(o); 164 } 165 166 /** 167 * Returns the hash code of the value. 168 */ hashCode(double o)169 public static int hashCode(double o) { 170 return hashCode(Double.doubleToLongBits(o)); 171 } 172 173 /** 174 * Returns the hash code of the value. 175 */ hashCode(int o)176 public static int hashCode(int o) { 177 return o; 178 } 179 180 /** 181 * Determines if the given {@code char} value is a Unicode <i>surrogate code unit</i>. See 182 * {@link Character#isSurrogate}. Extracting here because the method only exists at API level 183 * 19. 184 */ isSurrogate(char c)185 private static boolean isSurrogate(char c) { 186 return c >= Character.MIN_SURROGATE && c < (Character.MAX_SURROGATE + 1); 187 } 188 189 /** 190 * Returns an {@link AsyncWaiter} to use with the given handle, or |null| if none if available. 191 */ getDefaultAsyncWaiterForHandle(Handle handle)192 static AsyncWaiter getDefaultAsyncWaiterForHandle(Handle handle) { 193 if (handle.getCore() != null) { 194 return handle.getCore().getDefaultAsyncWaiter(); 195 } else { 196 return null; 197 } 198 } 199 } 200