Skip to content

Commit

Permalink
s
Browse files Browse the repository at this point in the history
  • Loading branch information
nonzzz committed Jul 30, 2024
1 parent dfd0e27 commit b639d4a
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 64 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"module": "dist/index.mjs",
"scripts": {
"dev": "rescript -w",
"prebuild": "rescript",
"build": "tsx scripts/gen-entry.ts && rollup --config rollup.config.mts --configPlugin swc3",
"build": "rollup --config rollup.config.mts --configPlugin swc3",
"pretest": "sh -c '[ -d ./dist ] && echo \"Directory exists. Skipping build.\" || (echo \"Directory does not exist. Running build...\" && pnpm run build)'",
"test": "vitest"
},
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve'
import { swc } from 'rollup-plugin-swc3'
import dts from 'rollup-plugin-dts'

export default defineConfig([{ input: 'lib/es6/internal/index.mjs',
export default defineConfig([{ input: 'src/index.ts',
output: [
{ file: 'dist/index.mjs', format: 'esm', exports: 'named' },
{ file: 'dist/index.js', format: 'cjs', exports: 'named' }
Expand Down
11 changes: 8 additions & 3 deletions src/head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,15 @@ const dec =/* @__PURE__ */ new TextDecoder()
function encodeString(s: string) {
return enc.encode(s)
}
/* @__NO_SIDE_EFFECTS__ */
function indexOf(b: Uint8Array, c: number, start: number) {
//
}

/* @__NO_SIDE_EFFECTS__ */
function decodeString(b: Uint8Array) {
return dec.decode(b)
function decodeString(b: Uint8Array, offset: number, length: number, encoding = 'utf-8') {
// return dec.decode(b)
b.subarray(offset, offset + length)
}

/* @__NO_SIDE_EFFECTS__ */
Expand Down Expand Up @@ -210,6 +215,6 @@ const defaultDecodeOptions = {
export function decode(b: Uint8Array, options?: DecodingHeadOptions) {
const opts = options = { ...defaultDecodeOptions, ...options }
const { filenameEncoding, allowUnknownFormat } = opts
const name = decodeString(b.slice(0, 100))
// const name = decodeString(b.slice(0, 100))
// const mode = parseInt(decodeString(b.slice(100, 108)), 8)
}
118 changes: 60 additions & 58 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,72 @@
const typeFlag = {
reg_type: '0',
areg_type: '\0',
link_type: '1',
sym_type: '2',
chr_type: '3',
blk_type: '4',
dir_type: '5',
fifo_type: '6',
cont_type: '7'
} as const
// const typeFlag = {
// reg_type: '0',
// areg_type: '\0',
// link_type: '1',
// sym_type: '2',
// chr_type: '3',
// blk_type: '4',
// dir_type: '5',
// fifo_type: '6',
// cont_type: '7'
// } as const

const mod = {
ts_uid: 0o4000,
ts_gid: 0o2000,
ts_vtx: 0o1000,
tu_read: 0o0400,
tu_write: 0o0200,
tu_exec: 0o0100,
tg_read: 0o0040,
tg_write: 0o0020,
tg_exec: 0o0010,
to_read: 0o0004,
to_write: 0o0002,
to_exec: 0o0001
}
// const mod = {
// ts_uid: 0o4000,
// ts_gid: 0o2000,
// ts_vtx: 0o1000,
// tu_read: 0o0400,
// tu_write: 0o0200,
// tu_exec: 0o0100,
// tg_read: 0o0040,
// tg_write: 0o0020,
// tg_exec: 0o0010,
// to_read: 0o0004,
// to_write: 0o0002,
// to_exec: 0o0001
// }

export type TypeFlag = typeof typeFlag[keyof typeof typeFlag]
// export type TypeFlag = typeof typeFlag[keyof typeof typeFlag]

export type Mod = typeof mod[keyof typeof mod]
// export type Mod = typeof mod[keyof typeof mod]

// export const f_mod = mod.
// // export const f_mod = mod.

export declare const f_mod: number
// export declare const f_mod: number

export declare const d_mod: number
// export declare const d_mod: number

export interface HeadOptions {
name: string
mode: number
uid: number
gid: number
size: number
typeflag: TypeFlag
linkname: string
magic: string
version: string
uname: string
gname: string
devmajor: number
devminor: number
mtime: number
prefix: string
}
// export interface HeadOptions {
// name: string
// mode: number
// uid: number
// gid: number
// size: number
// typeflag: TypeFlag
// linkname: string
// magic: string
// version: string
// uname: string
// gname: string
// devmajor: number
// devminor: number
// mtime: number
// prefix: string
// }

export interface DecodeOptions {
filenameEncoding: string
allowunknowFormat: boolean
}
// export interface DecodeOptions {
// filenameEncoding: string
// allowunknowFormat: boolean
// }

export declare function encode(options: HeadOptions): Uint8Array
// export declare function encode(options: HeadOptions): Uint8Array

export declare function decode(b: Uint8Array, options: DecodeOptions): Partial<HeadOptions>
// export declare function decode(b: Uint8Array, options: DecodeOptions): Partial<HeadOptions>

export interface PackInstance {
add: (binary: Uint8Array, options: HeadOptions) => void
done: () => void
}
// export interface PackInstance {
// add: (binary: Uint8Array, options: HeadOptions) => void
// done: () => void
// }

export declare function pack(): PackInstance
// export declare function pack(): PackInstance

export * from './head'
88 changes: 88 additions & 0 deletions src/stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Readable, Writable } from 'stream'
import type { ReadableOptions, WritableOptions } from 'stream'
import { F_MODE, TypeFlag, encode } from './head'
import type { EncodingHeadOptions } from './head'

export type PackOptions = Partial<Omit<EncodingHeadOptions, 'name' | 'size' | 'mtime'>> & {
filename: string
}

function createReadbleStream(options?: ReadableOptions) {
return new Readable(options)
}

function createWriteableStream(options?: WritableOptions) {
return new Writable(options)
}

// New archives should be created using REGTYPE.
const defaultPackOptions = {
mode: F_MODE,
uid: 0,
gid: 0,
typeflag: TypeFlag.REG_TYPE,
devmajor: 0,
devminor: 0
} satisfies Partial<EncodingHeadOptions>

export class Pack {
private reader: Readable
private finished: boolean
constructor() {
this.reader = createReadbleStream()
this.finished = false
}

private resolveHeadOptions(size: number, options: PackOptions): EncodingHeadOptions {
const { filename, ...rest } = options

return { ...defaultPackOptions, ...rest, name: filename, mtime: Math.floor(Date.now() / 1000), size }
}

add(binary: Uint8Array, options: PackOptions) {
const resolved = this.resolveHeadOptions(binary.length, options)
this.transport(binary, resolved)
}

done() {
if (this.finished) return
this.finished = true
// The end of tar is two 512 byte blocks of zeros
// For performance reasone, we should call push as less as possible
this.reader.push(new Uint8Array(1024))
this.reader.push(null)
}

private transport(binary: Uint8Array, resolvedOptions: EncodingHeadOptions) {
const writer = createWriteableStream({
write: (chunk, encoding, callback) => {
this.reader.push(encode(resolvedOptions))
this.reader.push(chunk)
callback()
},
final: (callback) => {
this.reader.push(null)
callback()
}
})
writer.write(binary)
}

receiver() {
return this.reader
}
}

export function createPack() {
return new Pack()
}

export class Extract {}

export function createExtract() {
return new Extract()
}

const pack = createPack()

pack.add(new Uint8Array(), { filename: 'test.txt' })

0 comments on commit b639d4a

Please sign in to comment.