Merge branch 'base64' into canvas2d+base64

This commit is contained in:
0JARVIS0 2020-11-30 14:10:09 +08:00
commit 06f92d2d1a
3 changed files with 252 additions and 35 deletions

View File

@ -3,6 +3,7 @@
* 详细设计文档可查看 https://juejin.im/post/5b42d3ede51d4519277b6ce3
*/
const util = require('./util');
const sha1 = require('./sha1');
const SAVED_FILES_KEY = 'savedFiles';
const KEY_TOTAL_SIZE = 'totalSize';
@ -40,53 +41,139 @@ export default class Dowloader {
resolve(url);
return;
}
const fileName = getFileName(url);
if (!lru) {
// 无 lru 情况下直接判断 临时文件是否存在,不存在重新下载
wx.getFileInfo({
filePath: url,
filePath: fileName,
success: () => {
resolve(url);
},
fail: () => {
downloadFile(url, lru).then((path) => {
resolve(path);
}, () => {
reject();
});
if (util.isOnlineUrl(url)) {
downloadFile(url, lru).then((path) => {
resolve(path);
}, () => {
reject();
});
} else if (util.isDataUrl(url)) {
transformBase64File(url, lru).then(path => {
resolve(path);
}, () => {
reject();
});
}
},
})
return
}
const file = getFile(url);
const file = getFile(fileName);
if (file) {
// 检查文件是否正常,不正常需要重新下载
wx.getSavedFileInfo({
filePath: file[KEY_PATH],
success: (res) => {
resolve(file[KEY_PATH]);
},
fail: (error) => {
console.error(`the file is broken, redownload it, ${JSON.stringify(error)}`);
downloadFile(url, lru).then((path) => {
resolve(path);
}, () => {
reject();
});
},
});
if (file[KEY_PATH].indexOf('//usr/') !== -1) {
wx.getFileInfo({
filePath: file[KEY_PATH],
success() {
resolve(file[KEY_PATH]);
},
fail(error) {
console.error(`base64 file broken, ${JSON.stringify(error)}`);
transformBase64File(url, lru).then(path => {
resolve(path);
}, () => {
reject();
});
}
})
} else {
// 检查文件是否正常,不正常需要重新下载
wx.getSavedFileInfo({
filePath: file[KEY_PATH],
success: (res) => {
resolve(file[KEY_PATH]);
},
fail: (error) => {
console.error(`the file is broken, redownload it, ${JSON.stringify(error)}`);
downloadFile(url, lru).then((path) => {
resolve(path);
}, () => {
reject();
});
},
});
}
} else {
downloadFile(url, lru).then((path) => {
resolve(path);
}, () => {
reject();
});
if (util.isOnlineUrl(url)) {
downloadFile(url, lru).then((path) => {
resolve(path);
}, () => {
reject();
});
} else if (util.isDataUrl(url)) {
transformBase64File(url, lru).then(path => {
resolve(path);
}, () => {
reject();
});
}
}
});
}
}
function getFileName(url) {
if (util.isDataUrl(url)) {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(url) || [];
const fileName = `${sha1.hex_sha1(bodyData)}.${format}`;
return fileName;
} else {
return url;
}
}
function transformBase64File(base64data, lru) {
return new Promise((resolve, reject) => {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
console.error('base parse failed');
reject();
return;
}
const fileName = `${sha1.hex_sha1(bodyData)}.${format}`;
const path = `${wx.env.USER_DATA_PATH}/${fileName}`;
const buffer = wx.base64ToArrayBuffer(bodyData.replace(/[\r\n]/g, ""));
wx.getFileSystemManager().writeFile({
filePath: path,
data: buffer,
encoding: 'binary',
success() {
wx.getFileInfo({
filePath: path,
success: (tmpRes) => {
const newFileSize = tmpRes.size;
lru ? doLru(newFileSize).then(() => {
saveFile(fileName, newFileSize, path, true).then((filePath) => {
resolve(filePath);
});
}, () => {
resolve(path);
}) : resolve(path);
},
fail: (error) => {
// 文件大小信息获取失败,则此文件也不要进行存储
console.error(`getFileInfo ${path} failed, ${JSON.stringify(error)}`);
resolve(path);
},
});
},
fail(err) {
console.log(err)
}
})
});
}
function downloadFile(url, lru) {
return new Promise((resolve, reject) => {
wx.downloadFile({
@ -127,8 +214,22 @@ function downloadFile(url, lru) {
});
}
function saveFile(key, newFileSize, tempFilePath) {
function saveFile(key, newFileSize, tempFilePath, isDataUrl = false) {
return new Promise((resolve, reject) => {
if (isDataUrl) {
const totalSize = savedFiles[KEY_TOTAL_SIZE] ? savedFiles[KEY_TOTAL_SIZE] : 0;
savedFiles[key] = {};
savedFiles[key][KEY_PATH] = tempFilePath;
savedFiles[key][KEY_TIME] = new Date().getTime();
savedFiles[key][KEY_SIZE] = newFileSize;
savedFiles['totalSize'] = newFileSize + totalSize;
wx.setStorage({
key: SAVED_FILES_KEY,
data: savedFiles,
});
resolve(tempFilePath);
return;
}
wx.saveFile({
tempFilePath: tempFilePath,
success: (fileRes) => {
@ -229,12 +330,21 @@ function removeFiles(pathsShouldDelete) {
if (typeof pathDel === 'object') {
delPath = pathDel.filePath;
}
wx.removeSavedFile({
filePath: delPath,
fail: (error) => {
console.error(`removeSavedFile ${pathDel} failed, ${JSON.stringify(error)}`);
},
});
if (delPath.indexOf('//usr/') !== -1) {
wx.getFileSystemManager().unlink({
filePath: delPath,
fail(error) {
console.error(`removeSavedFile ${pathDel} failed, ${JSON.stringify(error)}`);
}
})
} else {
wx.removeSavedFile({
filePath: delPath,
fail: (error) => {
console.error(`removeSavedFile ${pathDel} failed, ${JSON.stringify(error)}`);
},
});
}
}
}

97
lib/sha1.js Normal file
View File

@ -0,0 +1,97 @@
var hexcase = 0;
var chrsz = 8;
function hex_sha1(s) {
return binb2hex(core_sha1(str2binb(s), s.length * chrsz));
}
function core_sha1(x, len) {
x[len >> 5] |= 0x80 << (24 - (len % 32));
x[(((len + 64) >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = x[i + j];
else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
var t = safe_add(
safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j))
);
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
function sha1_ft(t, b, c, d) {
if (t < 20) return (b & c) | (~b & d);
if (t < 40) return b ^ c ^ d;
if (t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
function sha1_kt(t) {
return t < 20
? 1518500249
: t < 40
? 1859775393
: t < 60
? -1894007588
: -899497514;
}
function safe_add(x, y) {
var lsw = (x & 0xffff) + (y & 0xffff);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
function rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - (i % 32));
return bin;
}
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str +=
hex_tab.charAt((binarray[i >> 2] >> ((3 - (i % 4)) * 8 + 4)) & 0xf) +
hex_tab.charAt((binarray[i >> 2] >> ((3 - (i % 4)) * 8)) & 0xf);
}
return str;
}
module.exports = {
hex_sha1,
}

View File

@ -1,6 +1,14 @@
function isValidUrl(url) {
return /(ht|f)tp(s?):\/\/([^ \\/]*\.)+[^ \\/]*(:[0-9]+)?\/?/.test(url);
return isOnlineUrl(url) || isDataUrl(url);
}
function isOnlineUrl(url) {
return /(ht|f)tp(s?):\/\/([^ \\/]*\.)+[^ \\/]*(:[0-9]+)?\/?/.test(url)
}
function isDataUrl(url) {
return /data:image\/(\w+);base64,(.*)/.test(url);
}
/**
@ -63,6 +71,8 @@ function equal(a, b) {
module.exports = {
isValidUrl,
isOnlineUrl,
isDataUrl,
equal
};