-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathparser.js
135 lines (107 loc) · 4.43 KB
/
parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* Copyright (c) 2019 Parallax Inc., All Rights Reserved. */
function parseFile(payload) {
/* Parse payload (.elf, .binary, or .eeprom format) for Propeller Application image.
Returns Propeller Application image as an ArrayBuffer if successful, or returns an Error object if failed.*/
// Currently only standard Propeller Application format is supported- No non-zero data beyond vbase (program size)
var progSize = 0;
var output = null;
// Convert payload from base-64 to string (fstr)
var fstr = atob(payload);
// Set up workspace as an array buffer (f) and unsigned byte, word, and long views (fbv, fwv, flv)
// Ensure workspace's length is a multiple of 4 (32-bit longs) for convenient handling
var f = str2ab(fstr, Math.trunc(fstr.length / 4) * 4);
var fbv = new Uint8Array(f);
var fwv = new Uint16Array(f);
var flv = new Uint32Array(f);
// Detect if it's an expected ".elf" file format:
if (fbv[0] === 0x7F && (fstr[1] + fstr[2] + fstr[3]) === 'ELF' && fbv[4] === 1) {
// Found 32-bit class .elf data; check data encoding and version
if (fbv[6] !== 1 || flv[5] !== 1 || fbv[5] !== 1) {return Error("Unexpected ELF version or data encoding")}
// Found version 1 little-endian format; check for executable content
if (fwv[8] !== 2) {return Error("ELF data does not include Propeller Application Executable content")}
// Found executable type; find Program Header metrics
var e_phoff = flv[7] / 4; /*(in longs)*/
var e_phentsize = fwv[21] / 4; /*(in longs)*/
var e_phnum = fwv[22];
//Build Propeller Application Image described by program headers
for (phIdx = 0; phIdx < e_phnum; phIdx++) {
var phEnt = e_phoff+e_phentsize*phIdx;
if (flv[phEnt] === 1) {
//Found load-type program header; find image block's offset (in elf), target address (in output), and data size
var imageOff = flv[phEnt+1]; /*(in bytes)*/
var imageAddr = flv[phEnt+3]; /*(in bytes)*/
var imageDSize = flv[phEnt+4]; /*(in bytes)*/
if (!progSize) {
// First load-type entry? Use image's built-in program size to size output ArrayBuffer
progSize = fwv[imageOff/2+4];
var imageFile = new ArrayBuffer(progSize);
output = new Uint8Array(imageFile);
}
//Place next block of Propeller Application image into output image
output.set(fbv.slice(imageOff, imageOff+imageDSize), imageAddr);
}
}
// Verify image found
if (!progSize) {return Error("Propeller Application image not found")}
// Generate checksum
output[5] = checksumArray(output, output.byteLength);
// Output as ArrayBuffer:
return imageFile;
} else {
// payload must be a ".binary" or ".eeprom" file
progSize = fwv[4];
var imageFile = new ArrayBuffer(progSize);
var binView = new Uint8Array(fbv, 0, progSize);
// Verify checksum, error if not
if (checksumArray(binView, progSize) !== 0) {return Error("Invalid checksum in .binary or .eeprom data");}
// OUTPUT AS ARRAYBUFFER:
return f;
}
}
// ******** SCRATCHPAD ********
// OUTPUT AS A BASE-64 ENCODED STRING:
/*
var outBuf = '';
for (var y = 0; y < progSize; y++) {
outBuf += String.fromCharCode(output[y] || 0);
}
if (outBuf) {
return btoa(outBuf); // returns base64 encoded Propeller image
} else {
return null;
}
*/
/* //Below is a failed attempt to write the data as a binary file
for (var y = 0; y < output.byteLength; y++) {
outBuf += String.fromCharCode(output[y]) || 0;
}
chrome.fileSystem.chooseEntry({type: "openDirectory"},
function(entry, fileEntries) {
// console.log(entry.fullPath);
entry.getFile('log.txt', {create: true, exclusive: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};
// Create a new Blob and write it to log.txt.
var blob = new Blob(outBuf, {type: 'text/plain'});
fileWriter.write(blob);
}, function() {console.log("createWriter error")});
}, function() {console.log("getFile error")});
});
*/
// OUTPUT AS A BASE-64 ENCODED STRING:
/*
// if necessary, trunc the program to the size spec'd in the file header.
for (var z = 0; z < progSize; z++) {
outBuf += String.fromCharCode(fbv[z]) || 0;
}
if (outBuf) {
return btoa(outBuf); // returns base64 encoded Propeller image
} else {
return null;
}
*/