This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/surfaces/icd-test-runner/js/crud/_helpers.js
2026-03-14 19:36:33 +00:00

111 lines
4.8 KiB
JavaScript

/**
* ICD Test Runner — CRUD Helpers
* Shared utilities for CRUD tier tests (ZIP builder, etc.).
*/
(function () {
'use strict';
var T = window.ICD;
if (!T) return;
if (!T.crud) T.crud = {};
// ── Minimal ZIP builder (no dependencies) ──
// Builds a valid ZIP archive from { filename: content } pairs.
// Content is UTF-8 strings. Returns a Blob suitable for FormData upload.
var crc32Table = null;
function crc32(bytes) {
if (!crc32Table) {
crc32Table = new Uint32Array(256);
for (var i = 0; i < 256; i++) {
var c = i;
for (var j = 0; j < 8; j++) {
c = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);
}
crc32Table[i] = c;
}
}
var crc = 0xFFFFFFFF;
for (var k = 0; k < bytes.length; k++) {
crc = crc32Table[(crc ^ bytes[k]) & 0xFF] ^ (crc >>> 8);
}
return (crc ^ 0xFFFFFFFF) >>> 0;
}
T.crud.buildTestZip = function (files) {
var encoder = new TextEncoder();
var entries = [];
var offset = 0;
// Build file entries
Object.keys(files).forEach(function (name) {
var nameBytes = encoder.encode(name);
var dataBytes = encoder.encode(files[name]);
var c = crc32(dataBytes);
entries.push({ name: nameBytes, data: dataBytes, crc: c, offset: offset });
// Local file header (30) + name + data
offset += 30 + nameBytes.length + dataBytes.length;
});
// Calculate central directory
var cdOffset = offset;
var cdSize = 0;
entries.forEach(function (e) { cdSize += 46 + e.name.length; });
var totalSize = cdOffset + cdSize + 22; // + EOCD
var buf = new ArrayBuffer(totalSize);
var view = new DataView(buf);
var pos = 0;
// Write local file headers + data
entries.forEach(function (e) {
view.setUint32(pos, 0x04034b50, true); pos += 4; // signature
view.setUint16(pos, 20, true); pos += 2; // version needed
view.setUint16(pos, 0, true); pos += 2; // flags
view.setUint16(pos, 0, true); pos += 2; // compression (store)
view.setUint16(pos, 0, true); pos += 2; // mod time
view.setUint16(pos, 0, true); pos += 2; // mod date
view.setUint32(pos, e.crc, true); pos += 4; // crc32
view.setUint32(pos, e.data.length, true); pos += 4; // compressed size
view.setUint32(pos, e.data.length, true); pos += 4; // uncompressed size
view.setUint16(pos, e.name.length, true); pos += 2; // name length
view.setUint16(pos, 0, true); pos += 2; // extra length
new Uint8Array(buf, pos, e.name.length).set(e.name); pos += e.name.length;
new Uint8Array(buf, pos, e.data.length).set(e.data); pos += e.data.length;
});
// Write central directory
entries.forEach(function (e) {
view.setUint32(pos, 0x02014b50, true); pos += 4; // signature
view.setUint16(pos, 20, true); pos += 2; // version made by
view.setUint16(pos, 20, true); pos += 2; // version needed
view.setUint16(pos, 0, true); pos += 2; // flags
view.setUint16(pos, 0, true); pos += 2; // compression
view.setUint16(pos, 0, true); pos += 2; // mod time
view.setUint16(pos, 0, true); pos += 2; // mod date
view.setUint32(pos, e.crc, true); pos += 4; // crc32
view.setUint32(pos, e.data.length, true); pos += 4; // compressed size
view.setUint32(pos, e.data.length, true); pos += 4; // uncompressed size
view.setUint16(pos, e.name.length, true); pos += 2; // name length
view.setUint16(pos, 0, true); pos += 2; // extra length
view.setUint16(pos, 0, true); pos += 2; // comment length
view.setUint16(pos, 0, true); pos += 2; // disk number
view.setUint16(pos, 0, true); pos += 2; // internal attrs
view.setUint32(pos, 0, true); pos += 4; // external attrs
view.setUint32(pos, e.offset, true); pos += 4; // local header offset
new Uint8Array(buf, pos, e.name.length).set(e.name); pos += e.name.length;
});
// Write EOCD
view.setUint32(pos, 0x06054b50, true); pos += 4; // signature
view.setUint16(pos, 0, true); pos += 2; // disk number
view.setUint16(pos, 0, true); pos += 2; // cd start disk
view.setUint16(pos, entries.length, true); pos += 2; // entries on disk
view.setUint16(pos, entries.length, true); pos += 2; // total entries
view.setUint32(pos, cdSize, true); pos += 4; // cd size
view.setUint32(pos, cdOffset, true); pos += 4; // cd offset
view.setUint16(pos, 0, true); // comment length
return new Blob([buf], { type: 'application/zip' });
};
})();