UNPKG

ts-md5

Version:

TypeScript MD5 implementation

111 lines (92 loc) 2.94 kB
import {Md5} from './md5'; declare let FileReaderSync: any; export interface HashingResponse { success: boolean; result?: string | Int32Array; } // Hashes any blob export class Md5FileHasher { private _reader: any; private _md5!: Md5; private _part!: number; // private _length!: number; private _blob: any; constructor( private _callback: (r: HashingResponse) => void, // Callback to return the result private _async: boolean = true, // Async version is not always available in a web worker private _partSize: number = 1048576, // 1mb ) { this._configureReader(); } /** * Hash a blob of data in the worker * @param blob Data to hash */ public hash(blob: any) { const self = this; self._blob = blob; // self._length = Math.ceil(blob.size / self._partSize); self._part = 0; self._md5 = new Md5(); self._processPart(); } private _fail() { this._callback({ success: false, result: 'data read failed' }); } private _hashData(e: any) { let self = this; self._md5.appendByteArray(new Uint8Array(e.target.result)); if (self._part * self._partSize >= self._blob.size) { self._callback({ success: true, result: self._md5.end() }); } else { self._processPart(); } } private _processPart() { const self = this; let endbyte = 0; let current_part: any; self._part += 1; if (self._blob.size > self._partSize) { // If blob bigger then part_size we will slice it up endbyte = self._part * self._partSize; if (endbyte > self._blob.size) { endbyte = self._blob.size; } current_part = self._blob.slice((self._part - 1) * self._partSize, endbyte); } else { current_part = self._blob; } if (self._async) { self._reader.readAsArrayBuffer(current_part); } else { setTimeout(() => { try { self._hashData({ target: { result: self._reader.readAsArrayBuffer(current_part) }, }); } catch (e) { self._fail(); } }, 0); } } private _configureReader() { const self = this; if (self._async) { self._reader = new FileReader(); self._reader.onload = self._hashData.bind(self); self._reader.onerror = self._fail.bind(self); self._reader.onabort = self._fail.bind(self); } else { self._reader = new FileReaderSync(); } } }