/** * @return the set of clusterIds that have consumed the mutation */ public List<UUID> getClusterIds() { List<UUID> clusterIds = new ArrayList<>(); byte[] bytes = getAttribute(CONSUMED_CLUSTER_IDS); if(bytes != null) { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); int numClusters = in.readInt(); for(int i=0; i<numClusters; i++){ clusterIds.add(new UUID(in.readLong(), in.readLong())); } } return clusterIds; }
/** * @return the set of clusterIds that have consumed the mutation */ public List<UUID> getClusterIds() { List<UUID> clusterIds = new ArrayList<>(); byte[] bytes = getAttribute(CONSUMED_CLUSTER_IDS); if(bytes != null) { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); int numClusters = in.readInt(); for(int i=0; i<numClusters; i++){ clusterIds.add(new UUID(in.readLong(), in.readLong())); } } return clusterIds; }
/** * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array from the * beginning. */ public static ByteArrayDataInput newDataInput(byte[] bytes) { return newDataInput(new ByteArrayInputStream(bytes)); }
/** * Returns a new {@link ByteArrayDataInput} instance to read from the {@code bytes} array, * starting at the given position. * * @throws IndexOutOfBoundsException if {@code start} is negative or greater than the length of * the array */ public static ByteArrayDataInput newDataInput(byte[] bytes, int start) { checkPositionIndex(start, bytes.length); return newDataInput(new ByteArrayInputStream(bytes, start, bytes.length - start)); }
/** * @return the set of clusterIds that have consumed the mutation */ public List<UUID> getClusterIds() { List<UUID> clusterIds = new ArrayList<>(); byte[] bytes = getAttribute(CONSUMED_CLUSTER_IDS); if(bytes != null) { ByteArrayDataInput in = ByteStreams.newDataInput(bytes); int numClusters = in.readInt(); for(int i=0; i<numClusters; i++){ clusterIds.add(new UUID(in.readLong(), in.readLong())); } } return clusterIds; }
/** * Returns an integer representing an IPv4 address regardless of whether the supplied argument is * an IPv4 address or not. * * <p>IPv6 addresses are <b>coerced</b> to IPv4 addresses before being converted to integers. * * <p>As long as there are applications that assume that all IP addresses are IPv4 addresses and * can therefore be converted safely to integers (for whatever purpose) this function can be used * to handle IPv6 addresses as well until the application is suitably fixed. * * <p>NOTE: an IPv6 address coerced to an IPv4 address can only be used for such purposes as * rudimentary identification or indexing into a collection of real {@link InetAddress}es. They * cannot be used as real addresses for the purposes of network communication. * * @param ip {@link InetAddress} to convert * @return {@code int}, "coerced" if ip is not an IPv4 address * @since 7.0 */ public static int coerceToInteger(InetAddress ip) { return ByteStreams.newDataInput(getCoercedIPv4Address(ip).getAddress()).readInt(); }
/** * Returns the Teredo information embedded in a Teredo address. * * @param ip {@link Inet6Address} to be examined for embedded Teredo information * @return extracted {@code TeredoInfo} * @throws IllegalArgumentException if the argument is not a valid IPv6 Teredo address */ public static TeredoInfo getTeredoInfo(Inet6Address ip) { checkArgument(isTeredoAddress(ip), "Address '%s' is not a Teredo address.", toAddrString(ip)); byte[] bytes = ip.getAddress(); Inet4Address server = getInet4Address(Arrays.copyOfRange(bytes, 4, 8)); int flags = ByteStreams.newDataInput(bytes, 8).readShort() & 0xffff; // Teredo obfuscates the mapped client port, per section 4 of the RFC. int port = ~ByteStreams.newDataInput(bytes, 10).readShort() & 0xffff; byte[] clientBytes = Arrays.copyOfRange(bytes, 12, 16); for (int i = 0; i < clientBytes.length; i++) { // Teredo obfuscates the mapped client IP, per section 4 of the RFC. clientBytes[i] = (byte) ~clientBytes[i]; } Inet4Address client = getInet4Address(clientBytes); return new TeredoInfo(server, client, port, flags); }