白岳
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