Converting byte[] to ArrayBuffer in Nashorn - javascript

How do I convert an array of bytes into ArrayBuffer in Nashorn? I am trying to insert binary data into a pure JavaScript environment (i.e., it doesn't have access to Java.from or Java.to) and so would like to create an instance out an array of bytes.

Looks like I was going about this the wrong way. It made more sense to convert it into Uint8Array since what I'm sending in is an array of bytes.
I created the following function:
function byteToUint8Array(byteArray) {
var uint8Array = new Uint8Array(byteArray.length);
for(var i = 0; i < uint8Array.length; i++) {
uint8Array[i] = byteArray[i];
}
return uint8Array;
}
This will convert an array of bytes (so byteArray is actually of type byte[]) into a Uint8Array.

I think you're right about using a Uint8Array, but this code might be preferable:
function byteToUint8Array(byteArray) {
var uint8Array = new Uint8Array(byteArray.length);
uint8Array.set(Java.from(byteArray));
return uint8Array;
}
Also, if you really need an ArrayBuffer you can use uint8Array.buffer.

Related

Cannot get the value of an ArrayBuffer Object in Javascript

I have an ArrayBuffer object that I need to be able to convert to String to JSON, but I can't get the value of the [Int8Array] out of the object, even though it is clearly there.
I've tried all variations on this, but they all return undefined
console.log(result);//Returns the array buffer
//Following methods all return undefined?
console.log(result["[[Int8Array]]"]);
console.log(result[[[Int8Array]]]);
console.log(result[[["Int8Array"]]]);
console.log(result[Int8Array]);
console.log(result["Int8Array"]);
How can I get all the Int8Array or UInt8Array values that are clearly available in the object?
You can use the textDecoder that accepts ArrayBuffer (as well as uint8array) without having to deal with Uint8array's:
var str = new TextDecoder().decode(arrayBuffer)
var json = JSON.parse(str)
if you want to get straight to json
var json = await new Response(arrayBuffer).json()
You need to intiantiate a new Uint8Array to get their values, you can't access them directly using your ArrayBuffer instance.
var buf = new ArrayBuffer(8);
var int8view = new Uint8Array(buf);
console.log(int8view)
JSFiddle : https://jsfiddle.net/v8m7pjqb/

ArrayBuffer madness - how to get binary into an arraybuffer

This is doing my head in.
I have a jquery ajax post returning output from a mysql database. One field is binary. I wish to proccess that binary field using Javascript. I have been around and around in circles trying different approaches non of which seem satisfactory and most hit a road block.
I can pass the data up base64 encoded and then decode it in Javascript.
The data is a packet so I wish to decode it using a DataView as it has all the Get... calls for treating the data as a packet ( like a C structure ).
I have tried Blobs and Typed Arrays but everwhere I go it seems to just not be the right thing.
What I am after is something like this:
var ab = new ArrayBuffer ( atob( my_base64_encoded_packet_data )
var dv = new DataView ( ab );
Simple! No. The only way I have managed to get close is to using fileReader, like this ( roughly ):
fileReader.onload = function ( ) {
var newBuf = this.result;
callback( newBuf );
return;
};
fileReader.readAsArrayBuffer( buf );
Where buf is a blob and newBuf is the ArrayBuffer.
Here is another approach which does what I want, but seems labour intensive.
function str2ab(str) {
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for (var i=0, var strLen=str.length; i<strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
Help please. Thanks
The problem is that you are using jQuery's ajax. jQuery can't handle binary since it wants everything to be strings. Browser tries to be smart with it and tries to transform the response if you want to receive it as text
What you want is the raw binary so a responseType that is either arraybuffer or a blob is what you want.
The solution is either stick to doing xhr manually or use the new fetch method
fetch(url, opts).then(res => res.arrayBuffer()).then(buffer => {
// code here
})
Sending and Receiving Binary Data - MDN

Base64 encode a javascript object

I have large Javascript objects which I would like to encode to base-64 for AWS Kinesis`
It turns out that:
let objStr = new Buffer(JSON.stringify(obj), 'ascii');
new Buffer(objStr, 'base64').toString('ascii') !== objStr
I'm trying to keep this as simple as possible.
How can I base-64 encode JSON and safely decode it back to its original value?
From String to Base-64
var obj = {a: 'a', b: 'b'};
var encoded = btoa(JSON.stringify(obj))
To decode back to actual
var actual = JSON.parse(atob(encoded))
For reference look here.
https://developer.mozilla.org/en/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
You misunderstood the Buffer(str, [encoding]) constructor, the encoding tells the constructor what encoding was used to create str, or what encoding the constructor should use to decode str into a byte array.
Basically the Buffer class represents byte streams, it's only when you convert it from/to strings that encoding comes into context.
You should instead use buffer.toString("base64") to get base-64 encoded of the buffer content.
let objJsonStr = JSON.stringify(obj);
let objJsonB64 = Buffer.from(objJsonStr).toString("base64");
When converting object to base64 I was getting out of latin range issues and character invalid error.
I made it work in my project with the below line.
Include the base64 and utf8 node packages and access them like this:
var bytes = base64.encode(utf8.encode(JSON.stringify(getOverviewComments())));
You can easily encode and decode from and to JSON/Base64 using a Buffer:
JSON to Base64:
function jsonToBase64(jsonObj) {
const jsonString = JSON.stringify(jsonObj)
return Buffer.from(jsonString).toString('base64')
}
Base64 to JSON:
function encodeBase64ToJson(base64String: string) {
const jsonString = Buffer.from(base64String,'base64').toString()
return JSON.parse(jsonString)
}
atob() and btoa() are outdated and should no longer be used.

How can I convert a Uint8Array with offset into an Int32Array?

I have a Uint8Array with an offset that I receive from another function. This contains the data I need, but there is a bit of other stuff at the start of the buffer backing this typed array.
The actual data are 32bit integers, and I'd like to have that data in an Int32Array. But converting this doesn't seem to be straightforward, I'm currently doing it manually the following way:
var outputBuffer = new ArrayBuffer(data.length);
var inputByteArray = new Uint8Array(outputBuffer);
for (var i=0; i < data.length; ++i) {
inputByteArray[i] = data[i]
}
var outputInt32Array= new Int32Array(outputBuffer);
The straightforward way of just creating a new Int32Array and passing the source Uint8Array doesn't work:
var outputInt32Array = new Int32Array(data) // data is the Uint8Array with offset
This results in a typed array that still behaves like a Uint8Array and hands out individual bytes, not 32bit integers.
Trying it by passing in the offset also doesn't work, I get the error "RangeError: start offset of Int32Array should be a multiple of 4":
var outputInt32Array = new Int32Array(data.buffer, data.byteOffset, length)
Is manually copying each byte the only way to get an Int32Array out of an Int8Array with an offset?
No, you don't need to manually copy the bytes from one to the other array. Using new Int32Array(data.buffer, …) is the best approach, but if you have a weird offset you will need to use a second buffer that is properly aligned. Still, you don't have to copy it manually, you can just use the slice method:
var outputInt32Array = new Int32Array(data.buffer.slice(data.byteOffset), 0, length);
If you need to access Int32s on the same buffer as data, you can also use a DataView.

Defining byte arrray in javascript

How do I pass a byte array from JavaScript to an ActiveX control.
My JavaScript will call WCF server (method) and that method will return a byte array.
After that I need to pass this byte array to the ActiveX control.
Could anybody provide me a solution for this?
Depending on what binding your WCF service uses (and as you are calling it from javascript I assume webHttpBinding) it is quite possible that the returned byte array will be returned as a base 64 encoded string. So you might need to modify the ActiveX component to accept a base 64 encoded string as parameter instead of a byte array.
From javascript you will have a form of base64_encode string. ActiveX component should have a function to convert string to byte array like this
byte[] string2byte(string s)
{
byte[] b = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2) { b[i / 2] = Convert.ToByte(s.Substring(i, 2), 16); }
return b;
}
I solved the problem by returning base64string rather than a byte array from the WCF Service.
So that i can simply convert the Base64 string usning Convert.FromBase64String() method to byte arrary.

Categories