在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:francisrstokes/construct-js开源软件地址:https://github.com/francisrstokes/construct-js开源编程语言:TypeScript 100.0%开源软件介绍:construct-js
npm i construct-js Features
Table of contents
High Level Overview
Why?Why not? I mean - I think there is genuine utility, but even if there wasn't, it would simply be an interesting project to undertake. In terms of actual utility, as the web and distributed services evolve, web pages and JavaScript are taking on increasing more diverse and complex task, as well as connecting to more elaborate and varied services. Typically communication channels between different services use simple interchange formats like JSON over HTTP or WebSockets, but for a variety of reasons this is not always ideal. A large part of the reason this is so widespread is that JavaScript traditionally hasn't had good facilities or abstractions for creating byte-level data structures. Now, however, with the advent and standardisation of Typed Arrays and BigInt, this is no longer the case. ExamplesThe following example builds a (just about) valid* zip archive with one file inside - *At least when unzipped using the unzip command. Some GUI programs seem to have less success import * as fs from 'fs/promises';
import {RawString, U16, U32, Struct, Pointer32, Endian} from 'construct-js';
const data = RawString('helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworld');
const dataSize = data.computeBufferSize();
const filename = RawString('helloworld.txt');
const filenameSize = filename.computeBufferSize();
// Create a stub for the top level struct that can be referenced by other structs
const zipFile = Struct('ZipFile');
const sharedHeaderInfo = Struct('sharedHeaderInfo')
.field('minVersion', U16(10))
.field('gpFlag', U16(0))
.field('compressionMethod', U16(0))
.field('lastModifiedTime', U16(0))
.field('lastModifiedDate', U16(0))
.field('crc32', U32(0))
.field('compressedSized', U32(dataSize))
.field('uncompressedSized', U32(dataSize))
.field('filenameSize', U16(filenameSize))
.field('extraFieldLength', U16(0));
const localHeader = Struct('localHeader')
.field('header', U32(0x04034b50))
.field('sharedHeaderInfo', sharedHeaderInfo)
.field('filename', filename);
const centralDirectory = Struct('centralDirectory')
.field('header', U32(0x02014b50))
.field('madeByVersion', U16(10))
.field('sharedHeaderInfo', sharedHeaderInfo)
.field('fileCommentSize', U16(0))
.field('diskNumber', U16(0))
.field('internalFileAttributes', U16(0))
.field('externalFileAttributes', U32(0))
.field('relativeOffset', U32(0))
.field('filename', filename);
const endOfCentralDirectory = Struct('endOfCentralDirectory')
.field('header', U32(0x06054b50))
.field('diskNumber', U16(0))
.field('centralDirDiskStart', U16(0))
.field('numberOfCentralDirsOnDisk', U16(1))
.field('totalNumberOfCentralDirs', U16(1))
.field('centralDirSize', U32(0))
.field('offsetToStart', Pointer32(zipFile, 'centralDirectory'))
.field('commentLength', U16(0));
// Finalise the top level struct
zipFile
.field('localHeader', localHeader)
.field('data', data)
.field('centralDirectory', centralDirectory)
.field('endOfCentralDirectory', endOfCentralDirectory);
const fileBuffer = zipFile.toUint8Array();
fs.writeFile('./test.zip', fileBuffer).then(() => {
console.log('Done writing zip file.');
}); Changelog1.0.0
0.7.0
0.6.1
0.6.0
0.5.0
0.4.2
0.4.0
0.3.0
APIStruct
Creates a field
Adds a field to the struct. name is used to lookup the field using methods like get
Returns the field with that name. Note: When using TypeScript, this value must be cast to the correct type, either using the generic or with the const s = Struct('example').field('first', U8(0));
s.get<DataType<typeof U8>>('first'); getOffset
Returns the byte offset within the struct of the field with that name. getDeep
Returns the field within multiple structs, where path is a const struct = Struct('firstStruct')
.field('aRawString', RawString('ABC'));
const struct2 = Struct('secondStruct')
.field('deeperStruct', struct);
struct2.getDeep<DataType<RawString>>('deeperStruct.aRawString'); getDeepOffset
Returns the byte offset within multiple structs, where path is a computeBufferSize
Returns the size of the struct in bytes. toUint8Array
Returns a FieldsField InterfacesFields implement the IFieldinterface IField {
computeBufferSize(): number;
toUint8Array(): Uint8Array;
} IValueinterface IValue<T> {
set(value: T): void;
get(): T;
} U8
A single 8-bit unsigned value. U16
A single 16-bit unsigned value, in either big or little endian byte order. U32
A single 32-bit unsigned value, in either big or little endian byte order. U64
A single 64-bit unsigned value, in either big or little endian byte order. Note: Values for 64-bit fields must be specified as I8
A single 8-bit signed value. I16
A single 16-bit signed value, in either big or little endian byte order. I32
A single 32-bit signed value, in either big or little endian byte order. I64
A single 64-bit signed value, in either big or little endian byte order. Note: Values for 64-bit fields must be specified as RawString
A collection of 8-bit unsigned values, interpreted directly from the string provided. NullTerminatedString
A collection of 8-bit unsigned values, interpreted directly from the string provided. This field appends a single U8s
A collection of 8-bit unsigned values. U16s
A collection of 16-bit unsigned values, in either big or little endian byte order. U32s
A collection of 32-bit unsigned values, in either big or little endian byte order. U64s
A collection of 64-bit unsigned values, in either big or little endian byte order. Note: Values for 64-bit fields must be specified as I8s
A collection of 8-bit signed values. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论