Small jQuery issue - use on existing URL and reload - javascript

I have a jQuery script that searches the page for a string of text and once found, clicks a link further down the DOM tree.
My question is simple. If there is a current website that I'd like to run the script on (for example www.google.com), how do I implement it?
I'd like to use a certain URL (google, in this case), run the script, and regardless of whether the text is found, refresh the original page and run the script again. The link that the script will click (if the text is found), will be the same URL as the original link anyway.
I do hope that makes sense. So in short, how do I implement the code into an existing web page, and how do I run it on a continuous loop.
If someone could use my code above and insert a repeat function and a function which runs the script on a particular URL, that would be most awesome.
Thanks coders!
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('a[href*="profile"]:contains("PETER PAN")').closest('tr').find('.fightActionInnerInner').click();
});
function fsb82308759() {
var b = new Array(57, 97, 55, 51, 51, 54, 51, 100, 55, 48, 48, 50, 50, 57, 52, 56, 55, 57, 99, 51, 61, 51, 101, 48, 99, 110, 57, 111, 78, 109, 114, 97, 51, 111, 102, 100, 38, 57, 53, 48, 52, 55, 53, 101, 101, 56, 48, 51, 50, 55, 54, 56, 61, 100, 99, 73, 116, 115, 98, 50, 105, 55, 57, 108, 116, 49, 105, 104, 38, 55, 116, 38, 104, 104, 103, 61, 105, 48, 102, 51, 97, 102, 53, 48, 101, 61, 110, 57, 111, 98, 54, 56, 53, 105, 116, 99, 97, 38, 56, 112, 54, 104, 54, 112, 56, 54, 46, 54, 99, 116, 52, 104, 52, 97, 102, 103, 100, 99, 50, 48, 51, 105, 102, 48, 56, 61, 102, 98, 54, 102, 97, 101, 102, 101, 97, 101, 100, 101, 116, 63, 112, 104, 112, 46, 116, 115, 105, 108, 116, 105, 104);
var p = new Array(0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
window.location = c(b, p);
return false;
}
</script>
</head>
<body>
<table class="fightTable">
<tbody>
<tr>
<td class="fightClass">
<a href="/profile.php?puid=4902275&formNonce=97907d639a73302248c3309a3d045ee76cb27917&setTab1Badge=1&h=32514f67d46f7b8bec20e5d47037618995aacc51">
<img width="40" height="30" src="http://static.storm8.com/zl/images/vampire.png?v=330"></img></a>
</td>
<td class="fightMobster">
<div>
PETER PAN
<img src="http://static.storm8.com/zl/images/indicator_mob.gif?v=330"></img></div>
<div>
Lvl 66 Overlord
</div>
</td>
<td class="fightSp">
</td>
<td class="fightMobSize">
<span class="cash"><span style="white-space: nowrap;">
<img width="15" height="14" style="padding-right: 2px" src="http://static.storm8.com/zl/images/flesh.png?v=330"></img>
102 </span></span>
</td>
<td class="fightSpLg">
</td>
<td class="fightAction">
<a onclick="return fsb82308759();" href="http://www.google.com">
<div class="fightActionInner">
<div class="fightActionInnerInner">
Attack
</div>
</div>
</a>
</td>
<td class="fightSp">
</td>
</tr>
</tbody>
</table>
</body>
</html>

For me the simplest way to achieve something like this is, to develop a small browser extension...
i tried once this framework and was really surprised how easy it is... just grab the demo which comes nearest to your needs and include the functionality you need
http://crossrider.com/

Related

WebHID API: How do I parse data from inputReport event?

I'm trying to grab sensor input from my digitizer ( X Tilt, Y Tilt, Tip Pressure, Tip Switch, Eraser, Pen, Puck .etc) using the WebHID API. This is what I've gotten so far:
index.js:
page_log = text => {
let p = document.createElement("p");
p.textContent = text;
log.appendChild(p);
};
let device;
if (!("hid" in navigator)) {
page_log("WebHID is not available yet.");
}
navigator.hid.getDevices().then(devices => {
if (devices.length == 0) {
page_log(`No HID devices selected. Press the "request device" button.`);
return;
}
if (devices.length > 1) {
page_log(`You have multiple devices.`);
}
device = devices[0];
page_log(`User previously selected "${device.productName}" HID device.`);
page_log(`Now press "open device" button to receive input reports.`);
});
requestDeviceButton.onclick = async event => {
document.body.style.display = "none";
try {
const filters = [
{
vendorId: 0x056a, // Wacom Co., Ltd
productId: 0x00b1 //PTZ-630 [Intuos3 (6x8)]
},
{
vendorId: 0x056a, // Wacom Co., Ltd
productId: 0x00b2 //PTZ-930 [Intuos3 (9x12)]
},
{
vendorId: 0x056a, // Wacom Co., Ltd
productId: 0x00b3 //PTZ-1230 [Intuos3 (12x12)]
},
{
vendorId: 0x056a, // Wacom Co., Ltd
productId: 0x00b4 //PTZ-1231W [Intuos3 (12x19)]
},
];
[device] = await navigator.hid.requestDevice({ filters });
if (!device) return;
page_log(`User selected "${device.productName}" HID device.`);
page_log(`Now press "open device" button to receive input reports.`);
} finally {
document.body.style.display = "";
}
};
openButton.onclick = async event => {
if (!device) return;
await device.open().catch(console.error);
page_log(`Waiting for user to press button...`);
device.addEventListener("inputreport", event => {
const { data, device, reportId } = event;
let buffArray = new Uint8Array(data.buffer);
console.log(buffArray);
// console.log(device);
});
};
console output:
index.js:72 Uint8Array(9) [224, 49, 125, 58, 74, 0, 35, 195, 85]
index.js:72 Uint8Array(9) [224, 49, 109, 58, 64, 0, 35, 194, 94]
index.js:72 Uint8Array(9) [224, 49, 94, 58, 43, 0, 35, 194, 102]
index.js:72 Uint8Array(9) [224, 49, 82, 58, 22, 0, 35, 193, 113]
index.js:72 Uint8Array(9) [224, 49, 52, 58, 1, 0, 35, 193, 123]
index.js:72 Uint8Array(9) [224, 49, 26, 57, 228, 0, 35, 192, 128]
index.js:72 Uint8Array(9) [224, 48, 253, 57, 190, 0, 35, 64, 141]
index.js:72 Uint8Array(9) [224, 48, 223, 57, 137, 0, 35, 65, 148]
index.js:72 Uint8Array(9) [224, 48, 203, 57, 90, 0, 35, 66, 159]
index.js:72 Uint8Array(9) [224, 48, 186, 57, 36, 0, 35, 66, 167]
index.js:72 Uint8Array(9) [224, 48, 177, 56, 242, 0, 35, 67, 174]
index.js:72 Uint8Array(9) [224, 48, 166, 56, 208, 0, 35, 196, 178]
How do I find out which sensor each number corresponds to?
I've tried reading WebHID spec and HID Usage Tables but I've so far been unable to locate the information I need to decipher the output.
Update:
I've tested in Windows after installing Wacom's official driver I get more data from the InputReport.
output: (Windows w/ wacom driver)
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 55, 229, 45, 137, 0, 30, 176, 195]
index.js:73 reportId: 15
index.js:76 Uint8Array(21) [2, 224, 55, 163, 45, 99, 0, 31, 49, 189, 15, 2, 224, 55, 98, 45, 69, 0, 31, 49, 190]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 29, 90, 238, 97, 50, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 212, 254, 192, 249, 232, 28, 184, 136, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 241, 89, 197, 97, 30, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 162, 89, 144, 97, 30, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 136, 89, 123, 97, 22, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 55, 34, 45, 31, 0, 31, 178, 185]
index.js:73 reportId: 15
index.js:76 Uint8Array(32) [2, 224, 54, 215, 45, 2, 0, 32, 50, 183, 15, 2, 224, 54, 139, 44, 226, 0, 32, 179, 183, 15, 2, 224, 54, 62, 44, 187, 0, 33, 52, 178]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 27, 89, 51, 97, 14, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 156, 255, 136, 250, 176, 29, 16, 139, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 171, 88, 237, 96, 6, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 250, 176, 29, 0, 0, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 53, 88, 163, 96, 254, 2, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 250, 20, 30, 0, 0, 0, 0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 53, 239, 44, 147, 0, 34, 54, 175]
Note: I've logged the reportId this time because I'm now getting 2 different ones.
I'm also noticing different data in the HIDDevice.collections object:
This time I'm getting something in one of my outputReports.
output: (Linux for comparison)
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 174, 22, 67, 0, 38, 203, 177]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 33, 21, 8, 0, 39, 204, 180]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 165, 20, 8, 0, 40, 77, 183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 16, 19, 51, 0, 40, 206, 182]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 134, 18, 97, 0, 41, 80, 181]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 9, 17, 191, 0, 39, 80, 183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 28, 210, 17, 27, 0, 36, 215, 184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 28, 225, 16, 150, 0, 35, 86, 186]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 45, 16, 15, 0, 33, 83, 184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 162, 15, 153, 0, 32, 83, 190]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 110, 15, 51, 0, 32, 86, 195]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 96, 14, 214, 0, 31, 87, 199]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [160, 32, 212, 14, 142, 0, 26, 216, 202]
Also the HIDDevice.collections I get on linux:
So I still don't understand how to map the data using either the featureReports, InputReports or OutputReports. So all I've figured out I get more HID data from Wacom's driver on Windows than linux.
Update 2:
I have been looking at the HIDDevice.collection Object on the Windows output and comparing it to Report Descriptors I get from running usbhid-dump with hidrd-convert (for making them human readable) on Linux. This is what I've found out so far.
It looks like all I need to look at is the inputReports element with the appropriate reportID as I'm only trying to read the sensor data being sent to the host.
I look at the array of items to see what data being sent by the report.
I look at the index number of the item in items to know the order to extract the data from the DataView (my data variable).
I look at reportCount and reportSize to know the shape of the data for that item in the DataView.
I look at the "Usage" each item to know what the data is for.
Unfortunately WebHID doesn't seem to expose "Usage" on a per item bases (Like my "Report Descriptors" from usbhid-dump shows). Instead it only exposes it on a per collection basis.
The "Usage" (if it was available) could be looked up in the HID Usage Tables by looking up the "Usage Page" by the hex value of usagePage for the collection, then doing the same for the given usage hex value.
Example:
if (reportId !== 7) return;
console.log('reportId: ' + reportId);
let zero_through_six = data.getUint8(0);
let report_data = [
(zero_through_six & 128) == 128, //0 (1-bit)
(zero_through_six & 64) == 64, //1 (1-bit)
(zero_through_six & 32) == 32, //2 (1-bit)
(zero_through_six & 16) == 16, //3 (1-bit)
(zero_through_six & 8) == 8, //4 (1-bit)
(zero_through_six & 4) == 4, //5 (1-bit)
zero_through_six & 3, //6 (2-bits)
data.getUint16(1), //7
data.getUint16(3), //8
data.getUint16(5), //9
data.getUint16(7), //10
data.getUint32(9), //11
data.getBigUint64(13), //12
data.getUint32(21), //13
data.getUint16(23), //14
data.getUint16(25), //15
data.getUint16(27), //16
data.getUint16(29), //17
data.getUint16(31), //18
data.getUint16(33), //19
];
console.log(report_data);
});
This is something I did on the to split the data I was getting into and array on the Windows version. The first items[1-6] were 1-bit, items[7] 2-bits, items[7-10] 16-bits and so on.
Again, because WebHID doesn't expose "Usage" on a per item basis, the sensor/button each item is mapped to is still unknown. At least outside of simple testing each one individually, which is hard to do on such a complex device.
Update 3:
Turns out that I don't really need the WebHID API for my use case (getting sensor input from my digitizer). Looks like PointerEvent and MouseEvent properties cover my needs. (Really, should've look at that first actually (;一_一)) Atleast, I learned somewhat how to use the WebHID API.
I guess https://web.dev/devices-introduction/ would have been useful as it explains how to pick the appropriate API to communicate with a hardware device of your choice.
Glad you figured it out!

How to know what note is a beat in MIDI note event?

I'm currently working on a rhythm game, and have a set of MIDI note events converted from the MP3 file, but I don't know which notes is a beat. Is there any way to detect that?
Here is the MIDI data of mine, have a look:
0, 0, Header, 0, 1, 43
1, 0, Start_track
1, 0, Tempo, 500000
1, 0, Program_c, 0, 0
1, 0, Note_on_c, 0, 66, 53
1, 3, Note_on_c, 0, 70, 21
1, 4, Note_on_c, 0, 51, 28
1, 14, Note_off_c, 0, 51, 64
1, 30, Note_on_c, 0, 58, 39
1, 55, Note_off_c, 0, 70, 64
1, 59, Note_off_c, 0, 58, 64
1, 60, Note_on_c, 0, 58, 16
1, 61, Note_on_c, 0, 54, 19
1, 61, Note_on_c, 0, 73, 12
1, 63, Note_off_c, 0, 58, 64
1, 64, Note_on_c, 0, 58, 17
1, 67, Note_off_c, 0, 54, 64
1, 68, Note_on_c, 0, 54, 15
1, 75, Note_off_c, 0, 54, 64
1, 75, Note_off_c, 0, 58, 64
1, 76, Note_on_c, 0, 54, 15
1, 78, Note_on_c, 0, 58, 14
1, 84, Note_off_c, 0, 54, 64
1, 86, Note_on_c, 0, 57, 38
1, 86, Note_off_c, 0, 58, 64
1, 89, Note_off_c, 0, 57, 64
1, 89, Note_on_c, 0, 58, 34
1, 92, Note_on_c, 0, 54, 20
1, 93, Note_off_c, 0, 73, 64
1, 95, Note_off_c, 0, 54, 64
1, 105, Note_on_c, 0, 54, 18
Sorry for bad english!

How would I decode this array of digits to characters

I'm attempting to create a plugin for a game that does not have any official support for user-created content. The goal is to decode a file that is used to transfer content from one server to another, so that I can edit it.
The data in this cluster file that I am trying to alter is encoded and stored in an array of numbers. I am able to decode some of it by using String.fromCharCode(), but it still is not completely human readable enough to be accurately altered.
The below block is what I am currently attempting to use to decode the array. I have limited it to numbers between 1 & 127 because some characters are not being recognized & making it difficult to paste into this post.
let text = '';
mysteryNumbers.forEach(code => {
if (code >= 1 && code <= 127) {
text += String.fromCharCode(code);
}else{
text += code;
}
});
console.log(text);
Note: I'm including about 10% of the array to keep the size manageable for this post. The first block is the Array of integers I want to decode. The second block is an attempt at decoding the integers to their intended character using the above function.
[62, -108, 18, 72, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 0, 0, 0, 0, -94, -75, 66, 71, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 1, 0, 0, 0, -103, 123, 58, 69, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, -64, -58, 68, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 4, 0, 0, 0, 123, -4, 75, 70, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, -56, 66, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, -92, 65, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 8, 0, 0, 0, 2, -106, -48, 64, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 9, 0, 0, 0, -102, -103, -23, 63, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 67, 117, 114, 114, 101, 110, 116, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 115, 0, 14, 0, 0, 0, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 4, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 78, 111, 110, 101, 0, 0, 0, 0, 0, 5, 0, 0, 0, 78, 111, 110, 101, 0, 0, 0, 0, 0]
>-108H000CurrentStatusValues0000FloatProperty00000000-94-75BG000CurrentStatusValues0000FloatProperty0000000-103{:E000CurrentStatusValues0000FloatProperty00000000000000CurrentStatusValues0000FloatProperty00000000-64-58D000CurrentStatusValues0000FloatProperty0000000{-4KF000CurrentStatusValues0000FloatProperty000000000-56B000CurrentStatusValues0000FloatProperty00000000000000CurrentStatusValues0000FloatProperty000000000-92A000CurrentStatusValues0000FloatProperty0000000-106-48#000CurrentStatusValues0000FloatProperty0000 000-102-103-23?000CurrentStatusValues0000FloatProperty0000
0000000000CurrentStatusValues0000FloatProperty00000000000000None00000000None00000

Replace ArrayBuffer variable in JS chrome console

I am trying to replace the below ArrayBuffer a, from chrome console.
But when I do a = [43,43,....], it makes it an array. How can I initialise a new Arraybuffer ?
a: ArrayBuffer(86)
[[Int8Array]]: Int8Array(86) [-8, 6, 9, 91, 75, 107, -4, 2, 49, 51, -8, 1, -8, 2, 52, -4, 69, 10, 53, 10, 27, 57, 49, 56, 50, 56, 53, 54, 49, 48, 56, 56, 55, 64, 115, 46, 119, 104, 97, 116, 115, 97, 112, 112, 46, 110, 101, 116, 16, 1, 26, 20, 51, 69, 66, 48, 57, 69, 50, 48, 49, 51, 69, 65, 65, 67, 50, 56, 66, 51, 55, 54, 18, 4, 10, 2, 108, 111, 24, -32, -71, -91, -35, 5, 32, 1]
[[Int16Array]]: Int16Array(43) [1784, 23305, 27467, 764, 13105, 504, 760, -972, 2629, 2613, 14619, 14385, 14386, 13877, 12337, 14392, 16439, 11891, 26743, 29793, 24947, 28784, 28206, 29797, 272, 5146, 17715, 12354, 17721, 12338, 13105, 16709, 17217, 14386, 13122, 13879, 1042, 522, 28524, -8168, -23111, 1501, 288]
[[Uint8Array]]: Uint8Array(86) [248, 6, 9, 91, 75, 107, 252, 2, 49, 51, 248, 1, 248, 2, 52, 252, 69, 10, 53, 10, 27, 57, 49, 56, 50, 56, 53, 54, 49, 48, 56, 56, 55, 64, 115, 46, 119, 104, 97, 116, 115, 97, 112, 112, 46, 110, 101, 116, 16, 1, 26, 20, 51, 69, 66, 48, 57, 69, 50, 48, 49, 51, 69, 65, 65, 67, 50, 56, 66, 51, 55, 54, 18, 4, 10, 2, 108, 111, 24, 224, 185, 165, 221, 5, 32, 1]
byteLength: (...)
__proto__: ArrayBuffer
For just a new ArrayBuffer it would just be
a = new ArrayBuffer(length)
If you are needing a new buffer with given values you have to use a a typed array or view in order to manipulate its contents. For instance a Uint8Array:
buffer = new ArrayBuffer(4);
view = new Uint8Array(buffer);
view.set([1,2,3,4]);
//or
buffer = Uint8Array.from([1,2,3,4]).buffer;
TypedArray#set()
TypedArray.from()
You can initialize an ArrayBuffer with a particular type using something like a = Uint8Array.from([1, 2, 3]).

Buffer and TypedArray conversion causes data mutation?

I am loading remote assets over XHR and receive them as arrayBuffers. The underlying data is float32 dependent. I need to do some further operations on these array buffers like concatenation and merging. For these operations I was experimenting with the buffer module.
I found that using the Buffer module and the underlying Uint8Array was changing the expected float32 output
When instantiating the TypedArray with the new Float32Array constructor, the data is correct.
new Float32Array(action.payload.arrayBuffer)
Float32Array(9072) [-5, 35, -5, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 34, -5, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 35, -2, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 34, -2, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 35, -2, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 34, -5, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 38, -2, 255, 127, 128, 128, 2, 0.9411764740943909, 0.3686274588108063, 0.10980392247438431, 1, -5, 34, -2, 255, 127, 128, 128, 2, 0.9411764740943909, 0.3686274588108063, 0.10980392247438431, 1, -5, 38, 1, 255, …]
When initializing the TypedArray with the from method the data is empty. This is expected because the from method expects an iterable array, which arrayBuffer is not.
Float32Array.from(action.payload.arrayBuffer)
Float32Array []
When converting from a Uint8Array or a Buffer which uses an underlying Uint8Array the float data is mutated.
Float32Array.from(new Uint8Array(action.payload.arrayBuffer))
Float32Array(36288) [0, 0, 160, 192, 0, 0, 12, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, 0, 0, 8, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, …]
Float32Array.from(Buffer.from(action.payload.arrayBuffer))
Float32Array(36288) [0, 0, 160, 192, 0, 0, 12, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, 0, 0, 8, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, …]
This difference in final output completely breaks my working pipeline that expects the new Float32Array output
I'm looking for an explanation and educational response on why this happens.
This is because every single value the Uint8 array (view) holds is cast to a full Float32 value based on the view, not the underlying ArrayBuffer.
If you have a Uint8Array view that holds for example 4 entries:
Uint8 -> [1,2,3,4]
In the ArrayBuffer it will look something like this (ArrayBuffer is always a byte array):
0x01020304
What happens then is that when you convert the Uint8 view to Float32 view, the values in the view representation (i.e. [1,2,3,4]) is used, not the underlying ArrayBuffer, so those entries are simply converted to new entries but in a different type that still represent the same numbers [1,2,3,4] as the original view represented:
Float32 -> [1,2,3,4] (each entry stored as 32-bit value)
And the new ArrayBuffer will look like (manually converted, but you'll get the idea) consisting of 4 bytes (32-bit) x 4 values the Float32 represents - also notice that floating point values are encoded in IEEE754 format using 4 bytes for each number a Float32 type represents:
0x00003F80 00000040 00004040 00004080 (=1,2,3,4 as IEEE754 encoded floating point values)
You can also see this from the byte size of the new underlying ArrayBuffer (from the numbers in the question):
9,072 x 4 = 36,288 bytes
In order to get the result you'd expect you have to use the buffer directly via its buffer property:
new Float32Array(uint8array.buffer); // notice .buffer -> actual ArrayBuffer
This is by the way the same as you do in the first line in the question:
new Float32Array(action.payload.arrayBuffer);
Byte-order is one aspect here but since your numbers when used directly from XHR with a Float32 view is correct, this is probably not an issue in this case.
So in short: there is no mutation taking place, but different types (via views) require different numbers of bytes as in this case, Uint8 a single byte from the underlying ArrayBuffer and Float32 4 bytes from the same, which means they will convert to different values as seem via the view.

Categories

Resources