Harrison
5 years ago
51 changed files with 2790 additions and 1358 deletions
@ -0,0 +1,12 @@ |
|||||||
|
package com.eclipsesource.v8; |
||||||
|
|
||||||
|
public class Platform { |
||||||
|
public static final String ANDROID = "android"; |
||||||
|
public static final String LINUX = "linux"; |
||||||
|
public static final String MACOSX = "macosx"; |
||||||
|
public static final String WINDOWS = "windows"; |
||||||
|
|
||||||
|
public static final String NATIVE_CLIENT = "nacl"; |
||||||
|
|
||||||
|
public static final String UNKNOWN = "unknown"; |
||||||
|
} |
@ -0,0 +1,316 @@ |
|||||||
|
/******************************************************************************* |
||||||
|
* Copyright (c) 2017 EclipseSource and others. |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* Trustin Lee - original OS/Arch/Vendor detection code (see: https://github.com/trustin/os-maven-plugin)
|
||||||
|
* Wolfgang Steiner - initial API and implementation |
||||||
|
* |
||||||
|
* Copyright 2014 Trustin Heuiseung Lee. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
******************************************************************************/ |
||||||
|
package com.eclipsesource.v8; |
||||||
|
|
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.Closeable; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileInputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
import java.util.Locale; |
||||||
|
|
||||||
|
public class PlatformDetector { |
||||||
|
public static class Arch { |
||||||
|
public static String getName() { |
||||||
|
final String archProperty = System.getProperty("os.arch"); |
||||||
|
final String archName = normalizeArch(archProperty); |
||||||
|
|
||||||
|
if (archName.equals(Platform.UNKNOWN)) { |
||||||
|
throw new UnsatisfiedLinkError("Unsupported arch: " + archProperty); |
||||||
|
} |
||||||
|
|
||||||
|
return archName; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class OS { |
||||||
|
public static String getName() { |
||||||
|
final String osProperty = System.getProperty("os.name"); |
||||||
|
final String osName = normalizeOs(osProperty); |
||||||
|
|
||||||
|
final String vendorProperty = System.getProperty("java.specification.vendor"); |
||||||
|
final String vendorName = normalize(vendorProperty); |
||||||
|
|
||||||
|
// special handling for android
|
||||||
|
if (vendorName.contains("android") || osName.contains("android")) { |
||||||
|
return Platform.ANDROID; |
||||||
|
} |
||||||
|
|
||||||
|
if (osName.equals(Platform.UNKNOWN)) { |
||||||
|
throw new UnsatisfiedLinkError("Unsupported platform/vendor: " + osProperty + " / " + vendorProperty); |
||||||
|
} |
||||||
|
|
||||||
|
return osName; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isWindows() { |
||||||
|
return getName().equals(Platform.WINDOWS); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isMac() { |
||||||
|
return getName().equals(Platform.MACOSX); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isLinux() { |
||||||
|
return getName().equals(Platform.LINUX); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isNativeClient() { |
||||||
|
return getName().equals(Platform.NATIVE_CLIENT); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isAndroid() { |
||||||
|
return getName().equals(Platform.ANDROID); |
||||||
|
} |
||||||
|
|
||||||
|
public static String getLibFileExtension() { |
||||||
|
if (isWindows()) { |
||||||
|
return "dll"; |
||||||
|
} |
||||||
|
|
||||||
|
if (isMac()) { |
||||||
|
return "dylib"; |
||||||
|
} |
||||||
|
|
||||||
|
if (isLinux() |
||||||
|
|| isAndroid() |
||||||
|
|| isNativeClient()) { |
||||||
|
return "so"; |
||||||
|
} |
||||||
|
|
||||||
|
throw new UnsatisfiedLinkError("Unsupported platform library-extension for: " + getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class Vendor { |
||||||
|
private static final String[] LINUX_OS_RELEASE_FILES = {"/etc/os-release", "/usr/lib/os-release"}; |
||||||
|
private static final String REDHAT_RELEASE_FILE = "/etc/redhat-release"; |
||||||
|
private static final String LINUX_ID_PREFIX = "ID="; |
||||||
|
|
||||||
|
public static String getName() { |
||||||
|
if (OS.isWindows()) { |
||||||
|
return "microsoft"; |
||||||
|
} |
||||||
|
if (OS.isMac()) { |
||||||
|
return "apple"; |
||||||
|
} |
||||||
|
if (OS.isLinux()) { |
||||||
|
return getLinuxOsReleaseId(); |
||||||
|
} |
||||||
|
if (OS.isAndroid()) { |
||||||
|
return "google"; |
||||||
|
} |
||||||
|
|
||||||
|
throw new UnsatisfiedLinkError("Unsupported vendor: " + getName()); |
||||||
|
} |
||||||
|
|
||||||
|
private static String getLinuxOsReleaseId() { |
||||||
|
// First, look for the os-release file.
|
||||||
|
for (String osReleaseFileName : LINUX_OS_RELEASE_FILES) { |
||||||
|
File file = new File(osReleaseFileName); |
||||||
|
if (file.exists()) { |
||||||
|
return parseLinuxOsReleaseFile(file); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Older versions of redhat don't have /etc/os-release. In this case, try
|
||||||
|
// parsing this file.
|
||||||
|
File file = new File(REDHAT_RELEASE_FILE); |
||||||
|
if (file.exists()) { |
||||||
|
return parseLinuxRedhatReleaseFile(file); |
||||||
|
} |
||||||
|
|
||||||
|
throw new UnsatisfiedLinkError("Unsupported linux vendor: " + getName()); |
||||||
|
} |
||||||
|
|
||||||
|
private static String parseLinuxOsReleaseFile(final File file) { |
||||||
|
BufferedReader reader = null; |
||||||
|
try { |
||||||
|
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8")); |
||||||
|
|
||||||
|
String id = null; |
||||||
|
String line; |
||||||
|
while((line = reader.readLine()) != null) { |
||||||
|
// Parse the ID line.
|
||||||
|
if (line.startsWith(LINUX_ID_PREFIX)) { |
||||||
|
// Set the ID for this version.
|
||||||
|
id = normalizeOsReleaseValue(line.substring(LINUX_ID_PREFIX.length())); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return id; |
||||||
|
} catch (IOException ignored) { |
||||||
|
// Just absorb. Don't treat failure to read /etc/os-release as an error.
|
||||||
|
} finally { |
||||||
|
closeQuietly(reader); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private static String parseLinuxRedhatReleaseFile(final File file) { |
||||||
|
BufferedReader reader = null; |
||||||
|
try { |
||||||
|
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8")); |
||||||
|
|
||||||
|
// There is only a single line in this file.
|
||||||
|
String line = reader.readLine(); |
||||||
|
if (line != null) { |
||||||
|
line = line.toLowerCase(Locale.US); |
||||||
|
|
||||||
|
String id; |
||||||
|
if (line.contains("centos")) { |
||||||
|
id = "centos"; |
||||||
|
} else if (line.contains("fedora")) { |
||||||
|
id = "fedora"; |
||||||
|
} else if (line.contains("red hat enterprise linux")) { |
||||||
|
id = "rhel"; |
||||||
|
} else { |
||||||
|
// Other variants are not currently supported.
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return id; |
||||||
|
} |
||||||
|
} catch (IOException ignored) { |
||||||
|
// Just absorb. Don't treat failure to read /etc/os-release as an error.
|
||||||
|
} finally { |
||||||
|
closeQuietly(reader); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private static void closeQuietly(final Closeable obj) { |
||||||
|
try { |
||||||
|
if (obj != null) { |
||||||
|
obj.close(); |
||||||
|
} |
||||||
|
} catch (IOException ignored) { |
||||||
|
// Ignore.
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static String normalizeOsReleaseValue(final String value) { |
||||||
|
// Remove any quotes from the string.
|
||||||
|
return value.trim().replace("\"", ""); |
||||||
|
} |
||||||
|
|
||||||
|
private static String normalizeOs(String value) { |
||||||
|
value = normalize(value); |
||||||
|
if (value.startsWith("aix")) { |
||||||
|
return "aix"; |
||||||
|
} |
||||||
|
if (value.startsWith("hpux")) { |
||||||
|
return "hpux"; |
||||||
|
} |
||||||
|
if (value.startsWith("os400")) { |
||||||
|
// Avoid the names such as os4000
|
||||||
|
if ((value.length() <= 5) || !Character.isDigit(value.charAt(5))) { |
||||||
|
return "os400"; |
||||||
|
} |
||||||
|
} |
||||||
|
if (value.startsWith("android")) { |
||||||
|
return Platform.ANDROID; |
||||||
|
} |
||||||
|
if (value.startsWith("linux")) { |
||||||
|
return Platform.LINUX; |
||||||
|
} |
||||||
|
if (value.startsWith("nacl")) { |
||||||
|
return Platform.NATIVE_CLIENT; |
||||||
|
} |
||||||
|
if (value.startsWith("macosx") || value.startsWith("osx")) { |
||||||
|
return Platform.MACOSX; |
||||||
|
} |
||||||
|
if (value.startsWith("freebsd")) { |
||||||
|
return "freebsd"; |
||||||
|
} |
||||||
|
if (value.startsWith("openbsd")) { |
||||||
|
return "openbsd"; |
||||||
|
} |
||||||
|
if (value.startsWith("netbsd")) { |
||||||
|
return "netbsd"; |
||||||
|
} |
||||||
|
if (value.startsWith("solaris") || value.startsWith("sunos")) { |
||||||
|
return "sunos"; |
||||||
|
} |
||||||
|
if (value.startsWith("windows")) { |
||||||
|
return Platform.WINDOWS; |
||||||
|
} |
||||||
|
|
||||||
|
return Platform.UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
private static String normalizeArch(String value) { |
||||||
|
value = normalize(value); |
||||||
|
if (value.matches("^(x8664|amd64|ia32e|em64t|x64)$")) { |
||||||
|
return "x86_64"; |
||||||
|
} |
||||||
|
if (value.matches("^(x8632|x86|i[3-6]86|ia32|x32)$")) { |
||||||
|
return "x86_32"; |
||||||
|
} |
||||||
|
if (value.matches("^(ia64|itanium64)$")) { |
||||||
|
return "itanium_64"; |
||||||
|
} |
||||||
|
if (value.matches("^(sparc|sparc32)$")) { |
||||||
|
return "sparc_32"; |
||||||
|
} |
||||||
|
if (value.matches("^(sparcv9|sparc64)$")) { |
||||||
|
return "sparc_64"; |
||||||
|
} |
||||||
|
if (value.matches("^(arm|arm32)$")) { |
||||||
|
return "arm_32"; |
||||||
|
} |
||||||
|
if ("aarch64".equals(value)) { |
||||||
|
return "aarch_64"; |
||||||
|
} |
||||||
|
if (value.matches("^(ppc|ppc32)$")) { |
||||||
|
return "ppc_32"; |
||||||
|
} |
||||||
|
if ("ppc64".equals(value)) { |
||||||
|
return "ppc_64"; |
||||||
|
} |
||||||
|
if ("ppc64le".equals(value)) { |
||||||
|
return "ppcle_64"; |
||||||
|
} |
||||||
|
if ("s390".equals(value)) { |
||||||
|
return "s390_32"; |
||||||
|
} |
||||||
|
if ("s390x".equals(value)) { |
||||||
|
return "s390_64"; |
||||||
|
} |
||||||
|
|
||||||
|
return Platform.UNKNOWN; |
||||||
|
} |
||||||
|
|
||||||
|
private static String normalize(final String value) { |
||||||
|
if (value == null) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
return value.toLowerCase(Locale.US).replaceAll("[^a-z0-9]+", ""); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,693 @@ |
|||||||
|
/** |
||||||
|
* Copyright 2016, Genuitec, LLC |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* Genuitec LLC - initial API and implementation |
||||||
|
******************************************************************************/ |
||||||
|
package com.eclipsesource.v8.debug; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.net.ServerSocket; |
||||||
|
import java.net.Socket; |
||||||
|
import java.nio.charset.Charset; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import com.eclipsesource.v8.JavaVoidCallback; |
||||||
|
import com.eclipsesource.v8.Releasable; |
||||||
|
import com.eclipsesource.v8.V8; |
||||||
|
import com.eclipsesource.v8.V8Array; |
||||||
|
import com.eclipsesource.v8.V8Function; |
||||||
|
import com.eclipsesource.v8.V8Object; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>V8DebugServer enables debuggers to connect to J2V8 via V8 server sockets debug protocol. |
||||||
|
* Server has to be created in the same thread as the provided V8 runtime has been created (the V8 thread). |
||||||
|
* You can specify port and whether the {@link #start()} method should |
||||||
|
* block until a client connects. {@link #setTraceCommunication(boolean)} allows to output |
||||||
|
* communication details for debugging purposes. Before creating V8 runtime you need to set V8 flag to expose |
||||||
|
* debug object. If you do not intend to set other flags, than you can use {@link #configureV8ForDebugging()} |
||||||
|
* method, otherwise set {@code -expose-debug-as=__j2v8_Debug} flag through {@link V8#setFlags(String)}. |
||||||
|
* |
||||||
|
* <p>Client connection is handled in a separate thread, however, commands are processed in the V8 thread. |
||||||
|
* Therefore it is vital to provide an opportunity to process requests by calling |
||||||
|
* {@link #processRequests(long)} method from the V8 thread. This will for instance |
||||||
|
* allow to install breakpoints before the JavaScript code starts to execute. It is also good to call that |
||||||
|
* method when V8 thread is idle to promptly provide responses to the debugger to avoid timeouts. |
||||||
|
* |
||||||
|
* <p>Example code: |
||||||
|
* |
||||||
|
* <code><br> |
||||||
|
* //configure for debugging before creating runtime<br>
|
||||||
|
* V8DebugServer.configureV8ForDebugging();<br> |
||||||
|
* <br> |
||||||
|
* //create V8 runtime<br>
|
||||||
|
* V8 runtime = V8.createV8Runtime();<br> |
||||||
|
* <br> |
||||||
|
* //create and start debug server<br>
|
||||||
|
* int port = 0;<br> |
||||||
|
* boolean waitForConnection = true;<br> |
||||||
|
* server = new V8DebugServer(runtime, port, waitForConnection);<br> |
||||||
|
* System.out.println("V8 Debug Server listening on port "<br> |
||||||
|
* + server.getPort());<br> |
||||||
|
* server.start();<br> |
||||||
|
* <br> |
||||||
|
* //execute script and provide name for it<br>
|
||||||
|
* runtime.executeVoidScript("var i = 15", "myscript.js", 0);<br> |
||||||
|
* |
||||||
|
* </code> |
||||||
|
* |
||||||
|
* @author piotr@genuitec.com |
||||||
|
*/ |
||||||
|
@SuppressWarnings("nls") |
||||||
|
public class V8DebugServer { |
||||||
|
|
||||||
|
/** |
||||||
|
* Name under which internal V8 debug object is going to be exposed in the runtime. |
||||||
|
* You can change the name if you are passing a different one through {@code -expose-debug-as} |
||||||
|
* flag. |
||||||
|
*/ |
||||||
|
public static String DEBUG_OBJECT_NAME = "__j2v8_Debug"; |
||||||
|
|
||||||
|
private static final String DEBUG_BREAK_HANDLER = "__j2v8_debug_handler"; |
||||||
|
private static final String MAKE_BREAK_EVENT = "__j2v8_MakeBreakEvent"; |
||||||
|
private static final String MAKE_COMPILE_EVENT = "__j2v8_MakeCompileEvent"; |
||||||
|
private static final String SET_LISTENER = "setListener"; |
||||||
|
private static final String V8_DEBUG_OBJECT = "Debug"; |
||||||
|
|
||||||
|
//Headers
|
||||||
|
private static final String HEADER_TYPE = "Type: "; |
||||||
|
private static final String HEADER_V8_VERSION = "V8-Version: "; |
||||||
|
private static final String HEADER_PROTOCOL_VERSION = "Protocol-Version: "; |
||||||
|
private static final String HEADER_EMBEDDING_HOST = "Embedding-Host: "; |
||||||
|
|
||||||
|
private static final String V8_VERSION = "4.10.253"; |
||||||
|
private static final String J2V8_VERSION = "4.0.0"; |
||||||
|
private static final String PROTOCOL_VERSION = "1"; |
||||||
|
|
||||||
|
//Protocol consts
|
||||||
|
private static final Charset PROTOCOL_CHARSET = Charset.forName("UTF-8"); |
||||||
|
private static final String PROTOCOL_EOL = "\r\n"; |
||||||
|
private static final byte[] PROTOCOL_EOL_BYTES = PROTOCOL_EOL.getBytes(PROTOCOL_CHARSET); |
||||||
|
private static final String PROTOCOL_CONTENT_LENGTH_HEADER = "Content-Length:"; |
||||||
|
private static final byte[] PROTOCOL_CONTENT_LENGTH_BYTES = PROTOCOL_CONTENT_LENGTH_HEADER.getBytes(PROTOCOL_CHARSET); |
||||||
|
private static final int PROTOCOL_BUFFER_SIZE = 4096; |
||||||
|
|
||||||
|
/** |
||||||
|
* Utility method for simplification of configuring V8 for debugging support. |
||||||
|
*/ |
||||||
|
public static void configureV8ForDebugging() { |
||||||
|
try { |
||||||
|
V8.setFlags("-expose-debug-as=" + DEBUG_OBJECT_NAME); |
||||||
|
} catch (Throwable t) { |
||||||
|
t.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ServerSocket server; |
||||||
|
private Socket client; |
||||||
|
private Object clientLock = new Object(); |
||||||
|
|
||||||
|
private V8 runtime; |
||||||
|
private V8Object debugObject; |
||||||
|
private V8Object runningStateDcp; |
||||||
|
private V8Object stoppedStateDcp; |
||||||
|
private boolean waitForConnection; |
||||||
|
private boolean traceCommunication = false; |
||||||
|
|
||||||
|
private List<String> requests = new LinkedList<String>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates V8DebugServer. |
||||||
|
* |
||||||
|
* @param runtime |
||||||
|
* @param port |
||||||
|
* @param waitForConnection |
||||||
|
*/ |
||||||
|
public V8DebugServer(final V8 runtime, final int port, final boolean waitForConnection) { |
||||||
|
this.runtime = runtime; |
||||||
|
this.waitForConnection = waitForConnection; |
||||||
|
|
||||||
|
V8Object debugScope = runtime.getObject(DEBUG_OBJECT_NAME); |
||||||
|
if (debugScope == null) { |
||||||
|
System.err.println("Cannot initialize debugger server - global debug object not found."); |
||||||
|
return; |
||||||
|
} |
||||||
|
try { |
||||||
|
debugObject = debugScope.getObject(V8_DEBUG_OBJECT); |
||||||
|
} finally { |
||||||
|
debugScope.close(); |
||||||
|
} |
||||||
|
|
||||||
|
runtime.executeVoidScript("(function() {\n" |
||||||
|
+ " " + DEBUG_OBJECT_NAME + ".Debug. " + MAKE_BREAK_EVENT + " = function (break_id,breakpoints_hit) {\n" |
||||||
|
+ " return new " + DEBUG_OBJECT_NAME + ".BreakEvent(break_id,breakpoints_hit);\n" |
||||||
|
+ " }\n" |
||||||
|
+ " " + DEBUG_OBJECT_NAME + ".Debug. " + MAKE_COMPILE_EVENT + " = function(script,type) {\n" |
||||||
|
+ " var scripts = " + DEBUG_OBJECT_NAME + ".Debug.scripts()\n" |
||||||
|
+ " for (var i in scripts) {\n" |
||||||
|
+ " if (scripts[i].id == script.id()) {\n" |
||||||
|
+ " return new " + DEBUG_OBJECT_NAME + ".CompileEvent(scripts[i], type);\n" |
||||||
|
+ " }\n" |
||||||
|
+ " }\n" |
||||||
|
+ " return {toJSONProtocol: function() {return ''}}\n" |
||||||
|
+ " }\n" |
||||||
|
+ "})()"); |
||||||
|
try { |
||||||
|
server = new ServerSocket(port); |
||||||
|
} catch (Exception e) { |
||||||
|
logError(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns port on which server is listening or -1 if server failed to bound to a port. |
||||||
|
* @return port or -1 if server failed to bound to a port |
||||||
|
*/ |
||||||
|
public int getPort() { |
||||||
|
return (server != null) && server.isBound() ? server.getLocalPort() : -1; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Output all communication to the console. For purpose of debugging V8DebugServer itself. |
||||||
|
* @param value |
||||||
|
*/ |
||||||
|
public void setTraceCommunication(final boolean value) { |
||||||
|
traceCommunication = value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Starts accepting client connections and blocks until a client connects |
||||||
|
* if {@code waitForConnection} has been passed to V8DebugServer constructor. |
||||||
|
*/ |
||||||
|
public void start() { |
||||||
|
if (server == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
boolean waitForConnection = this.waitForConnection; |
||||||
|
Thread clientThread = new Thread(new ClientLoop(), "J2V8 Debugger Server"); |
||||||
|
clientThread.setDaemon(true); |
||||||
|
clientThread.start(); |
||||||
|
|
||||||
|
setupEventHandler(); |
||||||
|
|
||||||
|
runningStateDcp = runtime.executeObjectScript("(function() {return new " + DEBUG_OBJECT_NAME + ".DebugCommandProcessor(null, true)})()"); |
||||||
|
|
||||||
|
if (waitForConnection) { |
||||||
|
synchronized (clientLock) { |
||||||
|
while (this.waitForConnection) { |
||||||
|
try { |
||||||
|
clientLock.wait(); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
//ignore
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//Process initial requests
|
||||||
|
//Give 100ms for initial debugger connection setup
|
||||||
|
try { |
||||||
|
processRequests(100); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
//ignore
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void stop() { |
||||||
|
try { |
||||||
|
server.close(); |
||||||
|
|
||||||
|
synchronized (clientLock) { |
||||||
|
if (client != null) { |
||||||
|
client.close(); |
||||||
|
client = null; |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
logError(e); |
||||||
|
} |
||||||
|
|
||||||
|
//release resources
|
||||||
|
if (runningStateDcp != null) { |
||||||
|
runningStateDcp.close(); |
||||||
|
runningStateDcp = null; |
||||||
|
} |
||||||
|
if (debugObject != null) { |
||||||
|
debugObject.close(); |
||||||
|
debugObject = null; |
||||||
|
} |
||||||
|
if (stoppedStateDcp != null) { |
||||||
|
stoppedStateDcp.close(); |
||||||
|
stoppedStateDcp = null; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private void sendJson(String json) throws IOException { |
||||||
|
json = json.replace("\\/", "/"); // Unescape slashes.
|
||||||
|
sendMessage("", json); |
||||||
|
} |
||||||
|
|
||||||
|
protected void logError(final Throwable t) { |
||||||
|
t.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
private void sendMessage(final String header, final String contents) throws IOException { |
||||||
|
synchronized (clientLock) { |
||||||
|
if (!isConnected()) { |
||||||
|
throw new IOException("There is no connected client."); |
||||||
|
} |
||||||
|
|
||||||
|
byte[] contentBytes = contents.getBytes(PROTOCOL_CHARSET); |
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
|
||||||
|
//append custom headers
|
||||||
|
sb.append(header); |
||||||
|
|
||||||
|
//append content length header
|
||||||
|
sb.append(PROTOCOL_CONTENT_LENGTH_HEADER); |
||||||
|
sb.append(Integer.toString(contentBytes.length)); |
||||||
|
sb.append(PROTOCOL_EOL); |
||||||
|
|
||||||
|
//skip tools info
|
||||||
|
sb.append(PROTOCOL_EOL); |
||||||
|
|
||||||
|
//send headers to the client
|
||||||
|
client.getOutputStream().write(sb.toString().getBytes( |
||||||
|
PROTOCOL_CHARSET)); |
||||||
|
|
||||||
|
//send contents to the client
|
||||||
|
if (contentBytes.length > 0) { |
||||||
|
client.getOutputStream().write(contentBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isConnected() { |
||||||
|
synchronized (clientLock) { |
||||||
|
return (server != null) && (client != null) && client.isConnected(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void processRequests(final long timeout) throws InterruptedException { |
||||||
|
if (server == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
long start = System.currentTimeMillis(); |
||||||
|
do { |
||||||
|
String[] reqs; |
||||||
|
do { |
||||||
|
synchronized (requests) { |
||||||
|
reqs = requests.toArray(new String[requests.size()]); |
||||||
|
requests.clear(); |
||||||
|
} |
||||||
|
for (String req : reqs) { |
||||||
|
try { |
||||||
|
processRequest(req); |
||||||
|
} catch (Exception e) { |
||||||
|
logError(e); |
||||||
|
} |
||||||
|
} |
||||||
|
} while (reqs.length > 0); |
||||||
|
if (timeout > 0) { |
||||||
|
Thread.sleep(10); |
||||||
|
} |
||||||
|
} while ((timeout > 0) && ((start + timeout) > System.currentTimeMillis())); |
||||||
|
} |
||||||
|
|
||||||
|
private void processRequest(final String message) throws IOException { |
||||||
|
if (traceCommunication) { |
||||||
|
System.out.println("Got message: \n" + message.substring(0, Math.min(message.length(), 1000))); |
||||||
|
} |
||||||
|
V8Array params = new V8Array(runtime); |
||||||
|
params.push(message); |
||||||
|
|
||||||
|
@SuppressWarnings("resource") |
||||||
|
V8Object dcp = stoppedStateDcp != null ? stoppedStateDcp : runningStateDcp; |
||||||
|
Object result = dcp.executeFunction("processDebugJSONRequest", params); |
||||||
|
|
||||||
|
String json = result.toString(); |
||||||
|
|
||||||
|
if ((stoppedStateDcp == null) && json.contains("\"running\":false")) { |
||||||
|
//XXX Need to implement functionality by adding to V8 class
|
||||||
|
// breakpoints before initial script or function execution
|
||||||
|
json = json.replace("\"running\":false", "\"running\":true") |
||||||
|
.replace("\"success\":true", "\"success\":false") |
||||||
|
.replace("{\"", "{\"message\":\"Client requested suspension is not supported on J2V8.\",\""); |
||||||
|
dcp.add("running_", true); |
||||||
|
} |
||||||
|
|
||||||
|
if (traceCommunication) { |
||||||
|
System.out.println("Returning response: \n" + json.substring(0, Math.min(json.length(), 1000))); |
||||||
|
} |
||||||
|
sendJson(json); |
||||||
|
} |
||||||
|
|
||||||
|
private void setupEventHandler() { |
||||||
|
EventHandler handler = new EventHandler(); |
||||||
|
debugObject.registerJavaMethod(handler, DEBUG_BREAK_HANDLER); |
||||||
|
V8Function debugHandler = null; |
||||||
|
V8Array parameters = null; |
||||||
|
try { |
||||||
|
debugHandler = (V8Function) debugObject.getObject(DEBUG_BREAK_HANDLER); |
||||||
|
parameters = new V8Array(runtime); |
||||||
|
parameters.push(debugHandler); |
||||||
|
debugObject.executeFunction(SET_LISTENER, parameters); |
||||||
|
} finally { |
||||||
|
if ((debugHandler != null) && !debugHandler.isReleased()) { |
||||||
|
debugHandler.close(); |
||||||
|
} |
||||||
|
if ((parameters != null) && !parameters.isReleased()) { |
||||||
|
parameters.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void enterBreakLoop(final V8Object execState, final V8Object eventData) throws IOException { |
||||||
|
try { |
||||||
|
V8Array params = new V8Array(runtime); |
||||||
|
try { |
||||||
|
params.push(false); |
||||||
|
stoppedStateDcp = execState.executeObjectFunction("debugCommandProcessor", params); |
||||||
|
} finally { |
||||||
|
params.close(); |
||||||
|
} |
||||||
|
|
||||||
|
//send event to debugger
|
||||||
|
int breakId = execState.getInteger("break_id"); |
||||||
|
V8Array breakpointsHit = eventData.getArray("break_points_hit_"); |
||||||
|
V8Object event = null; |
||||||
|
|
||||||
|
params = new V8Array(runtime); |
||||||
|
try { |
||||||
|
params.push(breakId); |
||||||
|
params.push(breakpointsHit); |
||||||
|
event = debugObject.executeObjectFunction(MAKE_BREAK_EVENT, params); |
||||||
|
String json = event.executeStringFunction("toJSONProtocol", null); |
||||||
|
if (traceCommunication) { |
||||||
|
System.out.println("Sending event (Break):\n" + json); |
||||||
|
} |
||||||
|
sendJson(json); |
||||||
|
} finally { |
||||||
|
params.close(); |
||||||
|
breakpointsHit.close(); |
||||||
|
if (event != null) { |
||||||
|
event.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//process requests until one of the resumes execution
|
||||||
|
while (isConnected() && !stoppedStateDcp.executeBooleanFunction("isRunning", null)) { |
||||||
|
try { |
||||||
|
processRequests(10); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
//ignore
|
||||||
|
} |
||||||
|
} |
||||||
|
} finally { |
||||||
|
stoppedStateDcp.close(); |
||||||
|
stoppedStateDcp = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void sendCompileEvent(final V8Object eventData) throws IOException { |
||||||
|
if (!isConnected()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
//send event to debugger
|
||||||
|
int type = eventData.getInteger("type_"); |
||||||
|
V8Object script = eventData.getObject("script_"); |
||||||
|
V8Object event = null; |
||||||
|
|
||||||
|
V8Array params = new V8Array(runtime); |
||||||
|
try { |
||||||
|
params.push(script); |
||||||
|
params.push(type); |
||||||
|
event = debugObject.executeObjectFunction(MAKE_COMPILE_EVENT, params); |
||||||
|
String json = event.executeStringFunction("toJSONProtocol", null); |
||||||
|
if (traceCommunication) { |
||||||
|
System.out.println("Sending event (CompileEvent):\n" + json.substring(0, Math.min(json.length(), 1000))); |
||||||
|
} |
||||||
|
if (json.length() > 0) { |
||||||
|
sendJson(json); |
||||||
|
} |
||||||
|
} finally { |
||||||
|
params.close(); |
||||||
|
script.close(); |
||||||
|
if (event != null) { |
||||||
|
event.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class EventHandler implements JavaVoidCallback { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void invoke(final V8Object receiver, final V8Array parameters) { |
||||||
|
if ((parameters == null) || parameters.isUndefined()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
V8Object execState = null; |
||||||
|
V8Object eventData = null; |
||||||
|
try { |
||||||
|
int event = parameters.getInteger(0); |
||||||
|
execState = parameters.getObject(1); |
||||||
|
eventData = parameters.getObject(2); |
||||||
|
|
||||||
|
if (traceCommunication) { |
||||||
|
String type = "unknown"; |
||||||
|
switch (event) { |
||||||
|
case 1: |
||||||
|
type = "Break"; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
type = "Exception"; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
type = "NewFunction"; |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
type = "BeforeCompile"; |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
type = "AfterCompile"; |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
type = "CompileError"; |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
type = "PromiseEvent"; |
||||||
|
break; |
||||||
|
case 8: |
||||||
|
type = "AsyncTaskEvent"; |
||||||
|
break; |
||||||
|
} |
||||||
|
System.out.println("V8 has emmitted an event of type " + type); |
||||||
|
} |
||||||
|
|
||||||
|
if (!isConnected()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
switch (event) { |
||||||
|
case 1: //Break
|
||||||
|
enterBreakLoop(execState, eventData); |
||||||
|
break; |
||||||
|
case 5: //afterCompile
|
||||||
|
case 6: //compileError
|
||||||
|
sendCompileEvent(eventData); |
||||||
|
break; |
||||||
|
case 2: //exception
|
||||||
|
default: |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
logError(e); |
||||||
|
} finally { |
||||||
|
safeRelease(execState); |
||||||
|
safeRelease(eventData); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void safeRelease(final Releasable object) { |
||||||
|
if ((object != null)) { |
||||||
|
object.release(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private class ClientLoop implements Runnable { |
||||||
|
|
||||||
|
private int from; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
while (true) { |
||||||
|
try { |
||||||
|
Socket socket = server.accept(); |
||||||
|
socket.setTcpNoDelay(true); |
||||||
|
synchronized (clientLock) { |
||||||
|
client = socket; |
||||||
|
waitForConnection = false; |
||||||
|
clientLock.notifyAll(); |
||||||
|
} |
||||||
|
startHandshake(); |
||||||
|
processClientRequests(); |
||||||
|
} catch (Exception e) { |
||||||
|
synchronized (clientLock) { |
||||||
|
if (client != null) { |
||||||
|
try { |
||||||
|
client.close(); |
||||||
|
} catch (IOException ex) { |
||||||
|
//ignore
|
||||||
|
} |
||||||
|
client = null; |
||||||
|
} |
||||||
|
} |
||||||
|
logError(e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void startHandshake() throws IOException { |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
|
||||||
|
sb.append(HEADER_V8_VERSION); |
||||||
|
sb.append(V8_VERSION); |
||||||
|
sb.append(PROTOCOL_EOL); |
||||||
|
|
||||||
|
sb.append(HEADER_PROTOCOL_VERSION); |
||||||
|
sb.append(PROTOCOL_VERSION); |
||||||
|
sb.append(PROTOCOL_EOL); |
||||||
|
|
||||||
|
sb.append(HEADER_EMBEDDING_HOST); |
||||||
|
sb.append("j2v8 "); |
||||||
|
sb.append(J2V8_VERSION); |
||||||
|
sb.append(PROTOCOL_EOL); |
||||||
|
|
||||||
|
sb.append(HEADER_TYPE); |
||||||
|
sb.append("connect"); |
||||||
|
sb.append(PROTOCOL_EOL); |
||||||
|
|
||||||
|
sendMessage(sb.toString(), ""); |
||||||
|
} |
||||||
|
|
||||||
|
private void processClientRequests() throws IOException { |
||||||
|
final byte[] EMPTY_ARR = new byte[] {}; |
||||||
|
|
||||||
|
byte[] buf = new byte[PROTOCOL_BUFFER_SIZE]; |
||||||
|
int bytesRead; |
||||||
|
int offset = 0; |
||||||
|
|
||||||
|
//Message data
|
||||||
|
boolean toolInfoSkipped = false; |
||||||
|
byte[] messageBytes = EMPTY_ARR; |
||||||
|
int contentLength = -1; |
||||||
|
|
||||||
|
InputStream cIn; |
||||||
|
synchronized (clientLock) { |
||||||
|
cIn = client.getInputStream(); |
||||||
|
} |
||||||
|
|
||||||
|
while ((bytesRead = cIn.read(buf, offset, PROTOCOL_BUFFER_SIZE - offset)) > 0) { |
||||||
|
bytesRead += offset; |
||||||
|
from = 0; |
||||||
|
do { |
||||||
|
if (contentLength < 0) { |
||||||
|
contentLength = readContentLength(buf, bytesRead); |
||||||
|
if (contentLength < 0) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (!toolInfoSkipped) { |
||||||
|
toolInfoSkipped = skipToolInfo(buf, bytesRead); |
||||||
|
if (!toolInfoSkipped) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
int length = Math.min(contentLength - messageBytes.length, bytesRead - from); |
||||||
|
messageBytes = join(messageBytes, buf, from, length); |
||||||
|
from += length; |
||||||
|
if (messageBytes.length == contentLength) { |
||||||
|
String message = new String(messageBytes, PROTOCOL_CHARSET); |
||||||
|
synchronized (requests) { |
||||||
|
requests.add(message); |
||||||
|
} |
||||||
|
contentLength = -1; |
||||||
|
toolInfoSkipped = false; |
||||||
|
messageBytes = EMPTY_ARR; |
||||||
|
} |
||||||
|
} while (from < bytesRead); |
||||||
|
if (from < bytesRead) { |
||||||
|
System.arraycopy(buf, from, buf, 0, bytesRead - from); |
||||||
|
offset = bytesRead - from; |
||||||
|
} else { |
||||||
|
offset = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private int readContentLength(final byte[] bytes, final int to) throws IOException { |
||||||
|
int pos = indexOf(PROTOCOL_CONTENT_LENGTH_BYTES, bytes, from, to); |
||||||
|
if (pos < 0) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
pos += PROTOCOL_CONTENT_LENGTH_BYTES.length; |
||||||
|
int end = indexOf(PROTOCOL_EOL_BYTES, bytes, pos, to); |
||||||
|
if (end < 0) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
String str = new String(bytes, pos, end - pos, PROTOCOL_CHARSET); |
||||||
|
int contentLength; |
||||||
|
try { |
||||||
|
contentLength = Integer.parseInt(str.trim()); |
||||||
|
} catch (Exception ex) { |
||||||
|
throw new IOException("Invalid content length header: '" + str + "' in message" + |
||||||
|
new String(bytes, PROTOCOL_CHARSET)); |
||||||
|
} |
||||||
|
from = end + PROTOCOL_EOL_BYTES.length; |
||||||
|
return contentLength; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean skipToolInfo(final byte[] bytes, final int n) { |
||||||
|
int end = indexOf(PROTOCOL_EOL_BYTES, bytes, from, n); |
||||||
|
if (end < 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
from = end + PROTOCOL_EOL_BYTES.length; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private int indexOf(final byte[] pattern, final byte[] array, final int start, final int end) { |
||||||
|
int len = pattern.length; |
||||||
|
for (int i = start; i < end; i++) { |
||||||
|
for (int j = 0; j <= len; j++) { |
||||||
|
if (j == len) { |
||||||
|
//pattern matches at i
|
||||||
|
return i; |
||||||
|
} |
||||||
|
if (((i + j) >= end) || (array[i + j] != pattern[j])) { |
||||||
|
//pattern does not match at i
|
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
private byte[] join(final byte[] arr1, final byte[] arr2, final int startPos, final int length) { |
||||||
|
byte[] res = new byte[arr1.length + length]; |
||||||
|
System.arraycopy(arr1, 0, res, 0, arr1.length); |
||||||
|
System.arraycopy(arr2, startPos, res, arr1.length, length); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package com.eclipsesource.v8.utils; |
||||||
|
/******************************************************************************* |
||||||
|
* Copyright (c) 2019 EclipseSource and others. |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* EclipseSource - initial API and implementation |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
import java.nio.ByteBuffer; |
||||||
|
|
||||||
|
import com.eclipsesource.v8.V8; |
||||||
|
import com.eclipsesource.v8.V8ArrayBuffer; |
||||||
|
|
||||||
|
/** |
||||||
|
* A lightweight handle to a V8TypedArray. This handle provides |
||||||
|
* access to a V8TypedArray. This handle does not need to be |
||||||
|
* closed, but if the type array is accessed using getV8TypedArray |
||||||
|
* then the result must be closed. |
||||||
|
* |
||||||
|
* The underlying V8TypedArray may be reclaimed by the JavaScript |
||||||
|
* garbage collector. To check if it's still available, use |
||||||
|
* isAvailable. |
||||||
|
*/ |
||||||
|
public class ArrayBuffer { |
||||||
|
|
||||||
|
private V8ArrayBuffer arrayBuffer; |
||||||
|
|
||||||
|
ArrayBuffer(final V8ArrayBuffer arrayBuffer) { |
||||||
|
this.arrayBuffer = (V8ArrayBuffer) arrayBuffer.twin().setWeak(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new ArrayBuffer from a java.nio.ByteBuffer |
||||||
|
* |
||||||
|
* @param v8 the Runtime on which to create the ArrayBuffer |
||||||
|
* @param byteBuffer the ByteBuffer to use to back the ArrayBuffer |
||||||
|
*/ |
||||||
|
public ArrayBuffer(final V8 v8, final ByteBuffer byteBuffer) { |
||||||
|
V8ArrayBuffer v8ArrayBuffer = new V8ArrayBuffer(v8, byteBuffer); |
||||||
|
try { |
||||||
|
arrayBuffer = (V8ArrayBuffer) v8ArrayBuffer.twin().setWeak(); |
||||||
|
} finally { |
||||||
|
v8ArrayBuffer.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Determine if the underlying V8ArrayBuffer is still available, or if it's been cleaned up by the JavaScript |
||||||
|
* garbage collector. |
||||||
|
* |
||||||
|
* @return true if the underlying V8ArrayBuffer is still available, false otherwise. |
||||||
|
*/ |
||||||
|
public boolean isAvailable() { |
||||||
|
return !arrayBuffer.isReleased(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the underlying V8ArrayBuffer. |
||||||
|
* @return the underlying V8ArrayBuffer. |
||||||
|
*/ |
||||||
|
public V8ArrayBuffer getV8ArrayBuffer() { |
||||||
|
return arrayBuffer.twin(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
/******************************************************************************* |
||||||
|
* Copyright (c) 2016 Brandon Sanders |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* Brandon Sanders - initial API and implementation and/or initial documentation |
||||||
|
******************************************************************************/ |
||||||
|
package com.eclipsesource.v8.utils; |
||||||
|
|
||||||
|
import com.eclipsesource.v8.V8; |
||||||
|
|
||||||
|
/** |
||||||
|
* Wrapper class for an {@link com.eclipsesource.v8.V8} instance that allows |
||||||
|
* a V8 instance to be invoked from across threads without explicitly acquiring |
||||||
|
* or releasing locks. |
||||||
|
* |
||||||
|
* This class does not guarantee the safety of any objects stored in or accessed |
||||||
|
* from the wrapped V8 instance; it only enables callers to interact with a V8 |
||||||
|
* instance from any thread. The V8 instance represented by this class should |
||||||
|
* still be treated with thread safety in mind |
||||||
|
* |
||||||
|
* @author Brandon Sanders [brandon@alicorn.io] |
||||||
|
* @author R. Ian Bull - Additional API |
||||||
|
*/ |
||||||
|
public final class ConcurrentV8 { |
||||||
|
private V8 v8 = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new ConcurrentV8. A ConcurrentV8 allows multiple |
||||||
|
* threads to work with the same V8 engine by releasing |
||||||
|
* the locks between calls. |
||||||
|
*/ |
||||||
|
public ConcurrentV8() { |
||||||
|
v8 = V8.createV8Runtime(); |
||||||
|
v8.getLocker().release(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the V8 runtime backing by this ConcurrentV8 |
||||||
|
* |
||||||
|
* @return The V8 runtime backing this ConcurrentV8 |
||||||
|
*/ |
||||||
|
public V8 getV8() { |
||||||
|
return v8; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Runs an {@link V8Runnable} on the V8 thread. |
||||||
|
* |
||||||
|
* <b>Note: </b> This method executes synchronously, not asynchronously; |
||||||
|
* it will not return until the passed {@link V8Runnable} is done |
||||||
|
* executing. The method is also synchronized, so it will block until it |
||||||
|
* gets a chance to run. |
||||||
|
* |
||||||
|
* @param runnable {@link V8Runnable} to run. |
||||||
|
*/ |
||||||
|
public synchronized void run(final V8Runnable runnable) { |
||||||
|
try { |
||||||
|
v8.getLocker().acquire(); |
||||||
|
runnable.run(v8); |
||||||
|
} finally { |
||||||
|
if ((v8 != null) && (v8.getLocker() != null) && v8.getLocker().hasLock()) { |
||||||
|
v8.getLocker().release(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Releases the underlying {@link V8} instance. |
||||||
|
* |
||||||
|
* This method should be invoked once you're done using this object, |
||||||
|
* otherwise a large amount of garbage could be left on the JVM due to |
||||||
|
* native resources. |
||||||
|
* |
||||||
|
* <b>Note:</b> If this method has already been called once, it |
||||||
|
* will do nothing. |
||||||
|
*/ |
||||||
|
public void release() { |
||||||
|
if ((v8 != null) && !v8.isReleased()) { |
||||||
|
// Release the V8 instance from the V8 thread context.
|
||||||
|
run(new V8Runnable() { |
||||||
|
@Override |
||||||
|
public void run(final V8 v8) { |
||||||
|
if ((v8 != null) && !v8.isReleased()) { |
||||||
|
v8.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
/******************************************************************************* |
||||||
|
* Copyright (c) 2017 EclipseSource and others. |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* EclipseSource - initial API and implementation |
||||||
|
******************************************************************************/ |
||||||
|
package com.eclipsesource.v8.utils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Adapt all instances of a single type from JavaScript to Java. |
||||||
|
* The TypeAdapter can be used with the V8ObjectUtils to allow users to customize |
||||||
|
* the conversion. |
||||||
|
*/ |
||||||
|
public abstract class SingleTypeAdapter implements TypeAdapter { |
||||||
|
|
||||||
|
private int typeToAdapt; |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a SingleTypeAdapter |
||||||
|
* |
||||||
|
* @param typeToAdapt The V8 Type this TypeAdapter should be applied to. |
||||||
|
*/ |
||||||
|
public SingleTypeAdapter(final int typeToAdapt) { |
||||||
|
this.typeToAdapt = typeToAdapt; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* @see com.eclipsesource.v8.utils.TypeAdapter#adapt(int, java.lang.Object) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Object adapt(final int type, final Object value) { |
||||||
|
if (type == typeToAdapt) { |
||||||
|
return adapt(value); |
||||||
|
} |
||||||
|
return TypeAdapter.DEFAULT; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Adapt an object from V8 to Java. |
||||||
|
* |
||||||
|
* If the value is a V8Value (V8Object) then it will be released after |
||||||
|
* this method is called. If you wish to retain the object, call |
||||||
|
* ((V8Value)value).twin(); |
||||||
|
* |
||||||
|
* @param value The V8 Object to be converted. |
||||||
|
* @return The adapted Java Object or {@link TypeAdapter#DEFAULT} for the default conversion. |
||||||
|
*/ |
||||||
|
public abstract Object adapt(final Object value); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
/******************************************************************************* |
||||||
|
* Copyright (c) 2017 EclipseSource and others. |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* EclipseSource - initial API and implementation |
||||||
|
******************************************************************************/ |
||||||
|
package com.eclipsesource.v8.utils; |
||||||
|
|
||||||
|
/** |
||||||
|
* An interface which allows a plug-able conversion from V8Value types to Java objects. |
||||||
|
* The TypeAdapter can be used with the V8ObjectUtils to allow users to customize |
||||||
|
* the conversion. |
||||||
|
*/ |
||||||
|
public interface TypeAdapter { |
||||||
|
|
||||||
|
/** |
||||||
|
* A default adapter that if returned in {@link TypeAdapter#adapt(int, Object)}, will result |
||||||
|
* in the default type adaption. |
||||||
|
*/ |
||||||
|
public static final Object DEFAULT = new Object(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Adapt an object from V8 to Java. |
||||||
|
* |
||||||
|
* If the value is a V8Value (V8Object) then it will be released after |
||||||
|
* this method is called. If you wish to retain the object, call |
||||||
|
* ((V8Value)value).twin(); |
||||||
|
* |
||||||
|
* @param type The Type of the object to be adapted. |
||||||
|
* @param value The V8 Object to be converted. |
||||||
|
* @return The adapted Java Object or {@link TypeAdapter#DEFAULT} for the default conversion. |
||||||
|
*/ |
||||||
|
public Object adapt(int type, Object value); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,73 @@ |
|||||||
|
package com.eclipsesource.v8.utils; |
||||||
|
/******************************************************************************* |
||||||
|
* Copyright (c) 2019 EclipseSource and others. |
||||||
|
* All rights reserved. This program and the accompanying materials |
||||||
|
* are made available under the terms of the Eclipse Public License v1.0 |
||||||
|
* which accompanies this distribution, and is available at |
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
* |
||||||
|
* Contributors: |
||||||
|
* EclipseSource - initial API and implementation |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
import com.eclipsesource.v8.V8; |
||||||
|
import com.eclipsesource.v8.V8ArrayBuffer; |
||||||
|
import com.eclipsesource.v8.V8TypedArray; |
||||||
|
|
||||||
|
/** |
||||||
|
* A lightweight handle to a V8TypedArray. This handle provides |
||||||
|
* access to a V8TypedArray. This handle does not need to be |
||||||
|
* closed, but if the type array is accessed using getV8TypedArray |
||||||
|
* then the result must be closed. |
||||||
|
* |
||||||
|
* The underlying V8TypedArray may be reclaimed by the JavaScript |
||||||
|
* garbage collector. To check if it's still available, use |
||||||
|
* isAvailable. |
||||||
|
*/ |
||||||
|
public class TypedArray { |
||||||
|
|
||||||
|
private V8TypedArray typedArray; |
||||||
|
|
||||||
|
TypedArray(final V8TypedArray typedArray) { |
||||||
|
this.typedArray = (V8TypedArray) typedArray.twin().setWeak(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new TypedArray from an ArrayBuffer. |
||||||
|
* |
||||||
|
* @param v8 the V8Runtime on which to create the TypedArray |
||||||
|
* @param buffer the ArrayBuffer to use to back the TypedArray |
||||||
|
* @param type the Type of Array to create |
||||||
|
* @param offset the Offset into the ArrayBuffer in which to map the TyepdArray |
||||||
|
* @param size the Size of the TypedArray |
||||||
|
*/ |
||||||
|
public TypedArray(final V8 v8, final ArrayBuffer buffer, final int type, final int offset, final int size) { |
||||||
|
V8ArrayBuffer v8ArrayBuffer = buffer.getV8ArrayBuffer(); |
||||||
|
V8TypedArray v8typedArray = new V8TypedArray(v8, v8ArrayBuffer, type, offset, size); |
||||||
|
try { |
||||||
|
typedArray = (V8TypedArray) v8typedArray.twin().setWeak(); |
||||||
|
} finally { |
||||||
|
v8ArrayBuffer.close(); |
||||||
|
v8typedArray.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Determine if the underlying V8TypedArray is still available, or if it's been cleaned up by the JavaScript |
||||||
|
* garbage collector. |
||||||
|
* |
||||||
|
* @return true if the underlying V8TypedArray is still available, false otherwise. |
||||||
|
*/ |
||||||
|
public boolean isAvailable() { |
||||||
|
return !typedArray.isReleased(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the underlying V8TypedArray. |
||||||
|
* @return the underlying V8TypedArray. |
||||||
|
*/ |
||||||
|
public V8TypedArray getV8TypedArray() { |
||||||
|
return (V8TypedArray) typedArray.twin(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,109 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
/** |
|
||||||
* A wrapper class for java.nio.ByteBuffer. This class provides some convenience methods |
|
||||||
* for working with the ByteBuffer. Furthermore, this class can be converted to a |
|
||||||
* V8ByteBuffer using V8ObjectUtils. |
|
||||||
*/ |
|
||||||
public class ArrayBuffer { |
|
||||||
|
|
||||||
private ByteBuffer byteBuffer; |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a new ArrayBuffer with an initial capacity. |
|
||||||
* |
|
||||||
* @param capacity The capacity of this ByteBuffer. |
|
||||||
*/ |
|
||||||
public ArrayBuffer(final int capacity) { |
|
||||||
byteBuffer = ByteBuffer.allocateDirect(capacity); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a new ArrayBuffer from a byte array. The array buffer will be allocated with the same |
|
||||||
* size as the byte array, and the contents of the byte array will be copied to the ArrayBuffer. |
|
||||||
* |
|
||||||
* @param src The byte array from which the ArrayBuffer will be initialized. |
|
||||||
*/ |
|
||||||
public ArrayBuffer(final byte[] src) { |
|
||||||
byteBuffer = ByteBuffer.allocateDirect(src.length); |
|
||||||
byteBuffer.put(src, 0, src.length); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a new ArrayBuffer with the given ByteBuffer as the backing store. The ByteBuffer must |
|
||||||
* be created as a DirectBuffer. |
|
||||||
* |
|
||||||
* @param byteBuffer The ByteBuffer to back this ArrayBuffer. |
|
||||||
*/ |
|
||||||
public ArrayBuffer(final ByteBuffer byteBuffer) { |
|
||||||
this.byteBuffer = validateByteBuffer(byteBuffer); |
|
||||||
} |
|
||||||
|
|
||||||
private ByteBuffer validateByteBuffer(final ByteBuffer byteBuffer) { |
|
||||||
if (!byteBuffer.isDirect()) { |
|
||||||
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer"); |
|
||||||
} |
|
||||||
return byteBuffer; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the ByteBuffer backing this ArrayBuffer. |
|
||||||
* |
|
||||||
* @return The ByteBuffer backing this ArrayBuffer. |
|
||||||
*/ |
|
||||||
public ByteBuffer getByteBuffer() { |
|
||||||
return byteBuffer; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the byte at a given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the byte. |
|
||||||
* @return The byte at the given index. |
|
||||||
*/ |
|
||||||
public byte getByte(final int index) { |
|
||||||
return byteBuffer.get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the byte at a given index as an unsigned integer. |
|
||||||
* |
|
||||||
* @param index The index at which to return the byte. |
|
||||||
* @return The unsigned byte at the given index. |
|
||||||
*/ |
|
||||||
public short getUnsignedByte(final int index) { |
|
||||||
return (short) (0xFF & byteBuffer.get(index)); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a byte into the ByteBuffer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to put the byte. |
|
||||||
* @param value The value to put at the index. |
|
||||||
*/ |
|
||||||
public void put(final int index, final byte value) { |
|
||||||
byteBuffer.put(index, value); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns this ArrayBuffers limit. |
|
||||||
* |
|
||||||
* @return This ArrayBuffers limit. |
|
||||||
*/ |
|
||||||
public int limit() { |
|
||||||
return byteBuffer.limit(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Float32Array typed array represents an array of 32-bit floating |
|
||||||
* point numbers. |
|
||||||
*/ |
|
||||||
public class Float32Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Float32Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Float32Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Float32Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Float32Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the floating point (Float32) value at a given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The Float32 value at the given index. |
|
||||||
*/ |
|
||||||
public float get(final int index) { |
|
||||||
return buffer.asFloatBuffer().get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.asFloatBuffer().limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a Float32 value at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The Float32 value to place into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final float value) { |
|
||||||
buffer.asFloatBuffer().put(index, value); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.FLOAT_32_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Float64Array typed array represents an array of 64-bit floating |
|
||||||
* point numbers. |
|
||||||
*/ |
|
||||||
public class Float64Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Float64Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Float64Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Float64Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Float64Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the floating point (Float64) value at a given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The Double (Float64) value at the given index. |
|
||||||
*/ |
|
||||||
public double get(final int index) { |
|
||||||
return buffer.asDoubleBuffer().get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.asDoubleBuffer().limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a Double (Float64) value at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The Double to put into the buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final double value) { |
|
||||||
buffer.asDoubleBuffer().put(index, value); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.FLOAT_64_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Int16Array typed array represents an array of twos-complement |
|
||||||
* 16-bit signed integers in the platform byte order. |
|
||||||
*/ |
|
||||||
public class Int16Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an Int16Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Int16Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Int16Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Int16Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 16-bit signed integer at the given index |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 16-bit integer at the index. |
|
||||||
*/ |
|
||||||
public short get(final int index) { |
|
||||||
return buffer.asShortBuffer().get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.asShortBuffer().limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a 16-bit integer at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 16-bit integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final short value) { |
|
||||||
buffer.asShortBuffer().put(index, value); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.INT_16_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,75 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Int32Array typed array represents an array of twos-complement 32-bit signed |
|
||||||
* integers in the platform byte order. |
|
||||||
*/ |
|
||||||
public class Int32Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an Int32Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Int32Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Int32Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Int32Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 32-bit signed integer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 32-bit integer at the index. |
|
||||||
*/ |
|
||||||
public int get(final int index) { |
|
||||||
return buffer.asIntBuffer().get(index); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.asIntBuffer().limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a 32-bit integer at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 32-bit integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final int value) { |
|
||||||
buffer.asIntBuffer().put(index, value); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.INT_32_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,78 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Int8Array typed array represents an array of twos-complement |
|
||||||
* 8-bit signed integers. |
|
||||||
*/ |
|
||||||
public class Int8Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an Int8Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Int8Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a Int8Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public Int8Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 8-bit signed integer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 8-bit integer at the index. |
|
||||||
*/ |
|
||||||
public byte get(final int index) { |
|
||||||
return buffer.get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts an 8-bit integer at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 8-bit integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final byte value) { |
|
||||||
buffer.put(index, value); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.INT_8_ARRAY; |
|
||||||
} |
|
||||||
} |
|
@ -1,58 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8TypedArray; |
|
||||||
|
|
||||||
/** |
|
||||||
* An abstract class that represents TypedArrays |
|
||||||
*/ |
|
||||||
public abstract class TypedArray { |
|
||||||
|
|
||||||
protected ByteBuffer buffer; |
|
||||||
|
|
||||||
protected TypedArray(final ByteBuffer buffer) { |
|
||||||
if (!buffer.isDirect()) { |
|
||||||
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer"); |
|
||||||
} |
|
||||||
if ((buffer.limit() % V8TypedArray.getStructureSize(getType())) != 0) { |
|
||||||
throw new IllegalArgumentException("ByteBuffer must be a allocated as a direct ByteBuffer"); |
|
||||||
} |
|
||||||
this.buffer = buffer; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return the underlying ByteBuffer. |
|
||||||
* |
|
||||||
* @return The underlying ByteBuffer behind this view |
|
||||||
*/ |
|
||||||
public ByteBuffer getByteBuffer() { |
|
||||||
return buffer; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return the size of this view. The size of the view is determined by the size |
|
||||||
* of the buffer, and the size of the data projected onto it. For example, for a |
|
||||||
* buffer size of 8, and a view representing 16bit integers, the size would be 4. |
|
||||||
* |
|
||||||
* @return The size of this view |
|
||||||
*/ |
|
||||||
public abstract int length(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 'Type' of this TypedArray using one of the constants defined in V8Value. |
|
||||||
* |
|
||||||
* @return The 'Type' of this typed array. |
|
||||||
*/ |
|
||||||
public abstract int getType(); |
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Uint16Array typed array represents an array of 16-bit unsigned |
|
||||||
* integers in the platform byte order. |
|
||||||
*/ |
|
||||||
public class UInt16Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an UInt16Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt16Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a UInt16Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt16Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 16-bit unsigned integer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 16-bit unsigned integer at the index. |
|
||||||
*/ |
|
||||||
public int get(final int index) { |
|
||||||
return 0xFFFF & buffer.asShortBuffer().get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.asShortBuffer().limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a 16-bit unsigned integer at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 16-bit unsigned integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final int value) { |
|
||||||
buffer.asShortBuffer().put(index, (short) (0x0000FFFF & value)); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.UNSIGNED_INT_16_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Uint32Array typed array represents an array of 32-bit unsigned |
|
||||||
* integers in the platform byte order. |
|
||||||
*/ |
|
||||||
public class UInt32Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an UInt32Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt32Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a UInt32Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt32Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 32-bit unsigned integer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 32-bit unsigned integer at the index. |
|
||||||
*/ |
|
||||||
public long get(final int index) { |
|
||||||
return 0x00000000FFFFFFFF & buffer.asIntBuffer().get(index); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.asIntBuffer().limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a 32-bit unsigned integer at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 32-bit unsigned integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final long value) { |
|
||||||
buffer.asIntBuffer().put(index, (int) (0x00000000FFFFFFFF & value)); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.UNSIGNED_INT_32_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,78 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Uint8Array typed array represents an array of 8-bit unsigned integers |
|
||||||
*/ |
|
||||||
public class UInt8Array extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an UInt8Array projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt8Array(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a UInt8Array projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt8Array(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 8-bit unsigned integer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 8-bit unsigned integer at the index. |
|
||||||
*/ |
|
||||||
public short get(final int index) { |
|
||||||
return (short) (0xFF & buffer.get(index)); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a 8-bit unsigned integer at a particular index. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 8-bit unsigned integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final short value) { |
|
||||||
buffer.put(index, (byte) (0x00FF & value)); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.UNSIGNED_INT_8_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,87 +0,0 @@ |
|||||||
/******************************************************************************* |
|
||||||
* Copyright (c) 2016 EclipseSource and others. |
|
||||||
* All rights reserved. This program and the accompanying materials |
|
||||||
* are made available under the terms of the Eclipse Public License v1.0 |
|
||||||
* which accompanies this distribution, and is available at |
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
* |
|
||||||
* Contributors: |
|
||||||
* EclipseSource - initial API and implementation |
|
||||||
******************************************************************************/ |
|
||||||
package com.eclipsesource.v8.utils.typedarrays; |
|
||||||
|
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
import com.eclipsesource.v8.V8Value; |
|
||||||
|
|
||||||
/** |
|
||||||
* The Uint8ClampedArray typed array represents an array of 8-bit unsigned |
|
||||||
* integers clamped to 0-255; if you specified a value that is out of the |
|
||||||
* range of [0,255], 0 or 255 will be set instead. |
|
||||||
*/ |
|
||||||
public class UInt8ClampedArray extends TypedArray { |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates an UInt8ClampedArray projected onto the given ByteBuffer. |
|
||||||
* |
|
||||||
* @param buffer The ByteBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt8ClampedArray(final ByteBuffer buffer) { |
|
||||||
super(buffer); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates a UInt8ClampedArray projected onto the given ArrayBuffer. |
|
||||||
* |
|
||||||
* @param arrayBuffer The ArrayBuffer on which the array is projected on. |
|
||||||
*/ |
|
||||||
public UInt8ClampedArray(final ArrayBuffer arrayBuffer) { |
|
||||||
this(arrayBuffer.getByteBuffer()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the 8-bit unsigned integer at the given index. |
|
||||||
* |
|
||||||
* @param index The index at which to return the value. |
|
||||||
* @return The 8-bit unsigned integer at the index. |
|
||||||
*/ |
|
||||||
public short get(final int index) { |
|
||||||
return (short) (0xFF & buffer.get(index)); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#length() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int length() { |
|
||||||
return buffer.limit(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Puts a 8-bit unsigned integer at a particular index. If the unsigned |
|
||||||
* integer is outside the range [0,255], 0 or 255 will be used instead. |
|
||||||
* |
|
||||||
* @param index The index at which to place the value. |
|
||||||
* @param value The 8-bit unsigned integer to put into buffer. |
|
||||||
*/ |
|
||||||
public void put(final int index, final short value) { |
|
||||||
if (value > 255) { |
|
||||||
buffer.put(index, (byte) (255)); |
|
||||||
} else if (value < 0) { |
|
||||||
buffer.put(index, (byte) (0)); |
|
||||||
} else { |
|
||||||
buffer.put(index, (byte) (value)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* (non-Javadoc) |
|
||||||
* @see com.eclipsesource.v8.utils.typedarrays.TypedArray#getType() |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public int getType() { |
|
||||||
return V8Value.UNSIGNED_INT_8_CLAMPED_ARRAY; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue