Skip to content

Instantly share code, notes, and snippets.

@chemzqm
Last active December 10, 2022 19:18
Show Gist options
  • Save chemzqm/9f2334ca201dc2fbc363fdd757aa2ed4 to your computer and use it in GitHub Desktop.
Save chemzqm/9f2334ca201dc2fbc363fdd757aa2ed4 to your computer and use it in GitHub Desktop.
pack and unpack wxvpkg
const path = require('path')
const fs = require('fs')
const { execSync } = require('child_process')
let file = path.join(process.cwd(), 'core.wxvpkg')
if (fs.existsSync(file)) {
execSync(`rmtrash ${file}`)
}
let fd = fs.openSync(file, 'w')
let dest = path.join(__dirname, 'dest')
function writeSync(buf, start) {
fs.writeSync(fd, buf, 0, buf.length, start)
}
function writeInt32(number, start) {
let buf = Buffer.alloc(4)
buf.writeInt32BE(number, 0)
writeSync(buf, start)
}
let files = fs.readdirSync(dest)
let totalCount = files.length
let buf = Buffer.alloc(4)
buf.writeInt32BE(totalCount, 0)
writeSync(buf, 14)
let start = 18
// 12 + /name.length
let dataOffset = start
for (let file of files) {
let name = `/${file}`
let buf = Buffer.from(name, 'utf8')
dataOffset = dataOffset + 12 + buf.length
}
for (let file of files) {
let nb = Buffer.from(`/${file}`, 'utf8')
// write filename byte length
writeInt32(nb.length, start)
start += 4
// write filename
writeSync(nb, start)
start += nb.length
// write offset
writeInt32(dataOffset, start)
start += 4
// write length
let contentBuf = fs.readFileSync(path.join(dest, file))
writeInt32(contentBuf.length, start)
start += 4
// write content
writeSync(contentBuf, dataOffset)
dataOffset += contentBuf.length
}
fs.closeSync(fd)
// Extract core.wxvpkg of current folder to dest folder
const path = require('path')
const fs = require('fs')
let dest = path.join(__dirname, 'dest')
fs.mkdirSync(dest, {recursive: true})
let file = path.join(process.cwd(), 'core.wxvpkg')
let fd = fs.openSync(file, 'r')
// read buffer
function readSync(start, length) {
const n = Buffer.alloc(length);
fs.readSync(fd, n, 0, length, start)
return n
}
const totalCount = readSync(14, 4).readInt32BE(0)
const map = {};
let n = 18;
for (let i = 0; i < totalCount; i++) {
const e = {};
// byte length of filename
const i = readSync(n, 4).readInt32BE(0);
n += 4;
e.name = readSync(n, i).toString();
n += i;
e.offset = readSync(n, 4).readInt32BE(0);
n += 4;
e.length = readSync(n, 4).readInt32BE(0);
n += 4;
map[e.name] = e
}
let created = []
for (let item of Object.values(map)) {
let dir = path.join(dest, path.dirname(item.name))
if (created.indexOf(dir) == -1) {
fs.mkdirSync(dir, {recursive: true})
created.push(dir)
}
let buf = readSync(item.offset, item.length)
let filepath = path.join(dest, item.name)
fs.writeFileSync(filepath, buf.toString('utf8'), 'utf8')
}
fs.closeSync(fd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment