mirror of
https://github.com/codedread/bitjs
synced 2025-10-03 09:39:16 +02:00
Add starter file sniffer for detecting file types
This commit is contained in:
parent
c85f5ae2cb
commit
59d677c6bb
2 changed files with 90 additions and 0 deletions
63
file/sniffer.js
Normal file
63
file/sniffer.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* File Sniffer.
|
||||||
|
*
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* Copyright(c) 2020 Google Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fileSignatures = {
|
||||||
|
'image/png': [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A],
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Build a tree of signature bytes that end in a MIME type.
|
||||||
|
class Node {
|
||||||
|
/**
|
||||||
|
* @param {number} value
|
||||||
|
*/
|
||||||
|
constructor(value) {
|
||||||
|
this.value = value;
|
||||||
|
this.children = {};
|
||||||
|
this.mimeType = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top-level node in the tree.
|
||||||
|
const root = new Node();
|
||||||
|
let maxDepth = 0;
|
||||||
|
|
||||||
|
// Construct the tree.
|
||||||
|
(function() {
|
||||||
|
for (const mimeType in fileSignatures) {
|
||||||
|
let curNode = root;
|
||||||
|
let depth = 0;
|
||||||
|
for (const byte of fileSignatures[mimeType]) {
|
||||||
|
if (curNode.children[byte] === undefined) {
|
||||||
|
curNode.children[byte] = new Node(byte);
|
||||||
|
}
|
||||||
|
depth++;
|
||||||
|
curNode = curNode.children[byte];
|
||||||
|
}
|
||||||
|
if (maxDepth < depth) {
|
||||||
|
maxDepth = depth;
|
||||||
|
}
|
||||||
|
curNode.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ArrayBuffer} ab
|
||||||
|
* @return {string} The MIME type of the buffer, or undefined.
|
||||||
|
*/
|
||||||
|
export function findMimeType(ab) {
|
||||||
|
const depth = ab.byteLength < maxDepth ? ab.byteLength : maxDepth;
|
||||||
|
const arr = new Uint8Array(ab).subarray(0, depth);
|
||||||
|
let curNode = root;
|
||||||
|
for (const byte of arr) {
|
||||||
|
if (curNode.children[byte] === undefined) return undefined;
|
||||||
|
curNode = curNode.children[byte];
|
||||||
|
if (curNode.mimeType) return curNode.mimeType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debugger;
|
27
tests/file-sniffer-test.html
Normal file
27
tests/file-sniffer-test.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Unit tests for bitjs.io.ByteStreamBitStream</title>
|
||||||
|
<script src="muther.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="module">
|
||||||
|
debugger;
|
||||||
|
import {findMimeType} from '../file/sniffer.js';
|
||||||
|
const assert = muther.assert;
|
||||||
|
const assertEquals = muther.assertEquals;
|
||||||
|
const assertThrows = muther.assertThrows;
|
||||||
|
|
||||||
|
let array;
|
||||||
|
muther.go({
|
||||||
|
setUp: function() {
|
||||||
|
array = new Uint8Array(16);
|
||||||
|
},
|
||||||
|
tests: {
|
||||||
|
testPNG() {
|
||||||
|
array.set([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0xFF]);
|
||||||
|
assertEquals('image/png', findMimeType(array.buffer));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue