| import { btoa, readAsArrayBuffer } from 'pouchdb-binary-utils'; |
| import Md5 from 'spark-md5'; |
| var setImmediateShim = global.setImmediate || global.setTimeout; |
| var MD5_CHUNK_SIZE = 32768; |
| |
| function rawToBase64(raw) { |
| return btoa(raw); |
| } |
| |
| function sliceBlob(blob, start, end) { |
| if (blob.webkitSlice) { |
| return blob.webkitSlice(start, end); |
| } |
| return blob.slice(start, end); |
| } |
| |
| function appendBlob(buffer, blob, start, end, callback) { |
| if (start > 0 || end < blob.size) { |
| // only slice blob if we really need to |
| blob = sliceBlob(blob, start, end); |
| } |
| readAsArrayBuffer(blob, function (arrayBuffer) { |
| buffer.append(arrayBuffer); |
| callback(); |
| }); |
| } |
| |
| function appendString(buffer, string, start, end, callback) { |
| if (start > 0 || end < string.length) { |
| // only create a substring if we really need to |
| string = string.substring(start, end); |
| } |
| buffer.appendBinary(string); |
| callback(); |
| } |
| |
| function binaryMd5(data, callback) { |
| var inputIsString = typeof data === 'string'; |
| var len = inputIsString ? data.length : data.size; |
| var chunkSize = Math.min(MD5_CHUNK_SIZE, len); |
| var chunks = Math.ceil(len / chunkSize); |
| var currentChunk = 0; |
| var buffer = inputIsString ? new Md5() : new Md5.ArrayBuffer(); |
| |
| var append = inputIsString ? appendString : appendBlob; |
| |
| function next() { |
| setImmediateShim(loadNextChunk); |
| } |
| |
| function done() { |
| var raw = buffer.end(true); |
| var base64 = rawToBase64(raw); |
| callback(base64); |
| buffer.destroy(); |
| } |
| |
| function loadNextChunk() { |
| var start = currentChunk * chunkSize; |
| var end = start + chunkSize; |
| currentChunk++; |
| if (currentChunk < chunks) { |
| append(buffer, data, start, end, next); |
| } else { |
| append(buffer, data, start, end, done); |
| } |
| } |
| loadNextChunk(); |
| } |
| |
| export default binaryMd5; |