Skip to content

Commit

Permalink
Decompression
Browse files Browse the repository at this point in the history
  • Loading branch information
jazz-soft committed Oct 26, 2024
1 parent 1225cfb commit ca850f8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 11 deletions.
71 changes: 60 additions & 11 deletions jazz-mxml.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function MXML(s) {
MXML.prototype.isValid = function() { return !!this.xml; };
MXML.prototype.isPartwise = function() { return this.isValid() && !!this.xml['score-partwise']; };
MXML.prototype.isTimewise = function() { return this.isValid() && !!this.xml['score-timewise']; };
MXML.prototype.isOpus = function() { return this.isValid() && !!this.xml['opus']; };
MXML.prototype.part2time = function() {};
MXML.prototype.time2part = MXML.prototype.part2time;
MXML.prototype.format = function () { return builder.build(this.xml); };
Expand Down Expand Up @@ -43,10 +44,46 @@ function dos2date(n) {
function date2dos(d) {
return (d.getSeconds() >> 1) + (d.getMinutes() << 5) + (d.getHours() << 11) + (d.getDate() << 16) + ((d.getMonth() + 1) << 21) + ((d.getFullYear() - 1980) << 25);
}
const meta_inf = 'META-INF/container.xml';
MXML.zipInfo = function(data) {
const inf = zipInfo(data);
if (inf) {
var a = [];
for (var k of inf.FFF) a.push({ name: k, size: inf.FF[k].size, date: inf.FF[k].date });
return a;
}
}
MXML.unzip = function(data) {
var i, k, m, n, s;
const inf = zipInfo(data);
if (!inf) return;
var FF = inf.FF;
var FFF = inf.FFF;
var a, k, s, s0, s1, s2, x;
if (FF[meta_inf]) {
a = [];
x = parse(decompress(data, FF[meta_inf]));
traverse(x, find('rootfile', function(x) { if (x['@_full-path']) a.push(x['@_full-path']); }));
if (a.length) FFF = a;
}
for (k of FFF) {
if (k == meta_inf) continue;
s = decompress(data, FF[k]);
if (!s) continue;
s = String(s);
if (!s0) s0 = s;
x = parse(s);
if (!x) continue;
if (!s1) s1 = s;
if (x['score-partwise'] || x['score-timewise']) return s;
if (x['opus'] && !s2) s2 = s;
}
return s2 || s1 || s0;
}
function zipInfo(data) {
var i, m, n;
var nrec, fnlen, exlen, cmlen, fname;
var FF = {};
var FFF = [];
i = data.length > 65557 ? data.length - 65557 : 0;
for (n = data.length - 22; n >= i; n--) if (data[n] == 80 && data[n + 1] == 75 && data[n + 2] == 5 && data[n + 3] == 6) break;
if (n < i) return;
Expand All @@ -66,18 +103,11 @@ MXML.unzip = function(data) {
console.log('bad zip file');
return;
}
FF[fname] = { off: m + 30 + n2(data, m + 26) + n2(data, m + 28), len: n4(data, m + 18), comp: n2(data, m + 8) };
FFF.push(fname);
FF[fname] = { off: m + 30 + n2(data, m + 26) + n2(data, m + 28), len: n4(data, m + 18), size: n4(data, m + 22), date: dos2date(n4(data, m + 10)), comp: n2(data, m + 8) };
n += 46 + fnlen + exlen + cmlen;
}
k = Object.keys(FF);
if (FF['META-INF/container.xml']) {
s = decompress(data, FF['META-INF/container.xml']);
//console.log(s);
}
else {
s = k[0];
}
if (FF[s]) return decompress(data, FF[s]);
if (FFF.length) return { FFF: FFF, FF: FF };
}
function decompress(data, x) {
var b = data.subarray(x.off, x.off + x.len);
Expand All @@ -98,5 +128,24 @@ function decompress(data, x) {
console.log('compression method not supported:', x.comp);
}
}
function parse(xml) {
try {
if (FXP.XMLValidator.validate(xml) == true) return parser.parse(xml);
}
catch (e) {/**/}
}
function traverse(x, f) {
if (Array.isArray(x)) for (var y of x) traverse(y, f);
if (typeof x != 'object') return;
f(x);
for (var k of Object.keys(x)) traverse(x[k], f);
}
function find(n, f) {
return function(x) {
x = x[n];
if (Array.isArray(x)) for (var y of x) f(y);
else if (typeof x == 'object') f(x);
};
}

module.exports = MXML;
2 changes: 2 additions & 0 deletions specs.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions specs/specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const {XMLParser, XMLBuilder} = require('fast-xml-parser');

var i;
var body = [];
body.push("const mxlm_xsd = '" + read_xml('musicxml.xsd') + "';");
body.push("const p2t_xsl = '" + read_xml('parttime.xsl') + "';");
body.push("const t2p_xsl = '" + read_xml('timepart.xsl') + "';");

Expand Down
1 change: 1 addition & 0 deletions specs/specs.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<BODY>
module.exports = {
mxml_xsd: mxml_xsd,
p2t_xsl: p2t_xsl,
t2p_xsl: t2p_xsl
};

0 comments on commit ca850f8

Please sign in to comment.