-
-
Notifications
You must be signed in to change notification settings - Fork 5
Implemented support for caseFold parameter on Archives File Systems
#17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8c93b08
6679bbb
50b8d04
d3791b8
cf06405
8910c3f
4de1e36
a2e1828
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,4 +5,5 @@ docs | |
| *.log | ||
| tmp | ||
| build | ||
| .coverage | ||
| .coverage | ||
| .DS_Store | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,19 +1,20 @@ | ||||||
| // SPDX-License-Identifier: LGPL-3.0-or-later | ||||||
| import { FileSystem, Inode, type UsageInfo } from '@zenfs/core'; | ||||||
| import type { Backend } from '@zenfs/core/backends/backend.js'; | ||||||
| import type { Backend, SharedConfig } from '@zenfs/core/backends/backend.js'; | ||||||
| import { S_IFDIR, S_IFREG } from '@zenfs/core/constants'; | ||||||
| import { Readonly, Sync } from '@zenfs/core/mixins/index.js'; | ||||||
| import { resolve } from '@zenfs/core/path'; | ||||||
| import { log, withErrno } from 'kerium'; | ||||||
| import { decodeASCII } from 'utilium'; | ||||||
| import type { Directory } from './Directory.js'; | ||||||
| import type { DirectoryRecord } from './DirectoryRecord.js'; | ||||||
| import { PrimaryVolumeDescriptor, VolumeDescriptorType } from './VolumeDescriptor.js'; | ||||||
| import { PXEntry, TFEntry, TFFlag } from './entries.js'; | ||||||
|
|
||||||
| /** | ||||||
| * Options for IsoFS file system instances. | ||||||
| */ | ||||||
| export interface IsoOptions { | ||||||
| export interface IsoOptions extends SharedConfig { | ||||||
| /** | ||||||
| * The ISO file in a buffer. | ||||||
| */ | ||||||
|
|
@@ -33,17 +34,24 @@ export interface IsoOptions { | |||||
| * * Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard | ||||||
| */ | ||||||
| export class IsoFS extends Readonly(Sync(FileSystem)) { | ||||||
| protected data: Uint8Array; | ||||||
| protected readonly options: IsoOptions; | ||||||
| protected pvd: PrimaryVolumeDescriptor; | ||||||
|
|
||||||
| /** | ||||||
| * Constructs a read-only file system from the given ISO. | ||||||
| * @param data The ISO file in a buffer. | ||||||
| * @param name The name of the ISO (optional; used for debug messages / identification). | ||||||
| */ | ||||||
| public constructor(protected data: Uint8Array) { | ||||||
| public constructor(options: IsoOptions) { | ||||||
| super(0x2069736f, 'iso9660'); | ||||||
|
|
||||||
| this.options = options; | ||||||
| this.data = options.data; | ||||||
| this.label = options.name; | ||||||
|
|
||||||
| let candidate: PrimaryVolumeDescriptor | undefined; | ||||||
| const data = this.data; | ||||||
|
|
||||||
| for (let i = 16 * 2048, terminatorFound = false; i < data.length && !terminatorFound; i += 2048) { | ||||||
| switch (data[i] as VolumeDescriptorType) { | ||||||
|
|
@@ -127,13 +135,33 @@ export class IsoFS extends Readonly(Sync(FileSystem)) { | |||||
|
|
||||||
| for (const part of path.split('/').slice(1)) { | ||||||
| if (!dir.isDirectory()) return; | ||||||
| dir = dir.directory.get(part); | ||||||
| const directory: Directory = dir.directory; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| let next: DirectoryRecord | undefined = directory.get(part); | ||||||
| if (!next && this.options.caseFold) { | ||||||
| const foldedPart = this._caseFold(part); | ||||||
| for (const [name, record] of directory) { | ||||||
| if (this._caseFold(name) === foldedPart) { | ||||||
| next = record; | ||||||
| break; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| dir = next; | ||||||
| if (!dir) return; | ||||||
|
Comment on lines
+140
to
151
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is kind of difficult to read... if there is a way to make it more readable & reduce indentation that would be great— perhaps using a gaurd clause? |
||||||
| } | ||||||
|
|
||||||
| return dir; | ||||||
| } | ||||||
|
|
||||||
| private _caseFold(original: string): string { | ||||||
| if (!this.options.caseFold) { | ||||||
| return original; | ||||||
| } | ||||||
|
|
||||||
| return this.options.caseFold === 'upper' ? original.toUpperCase() : original.toLowerCase(); | ||||||
| } | ||||||
|
Comment on lines
+157
to
+163
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is duplicated with ZipFS as well. To reduce duplcation, I'm thinking:
|
||||||
|
|
||||||
| private _get(path: string, record: DirectoryRecord): Inode | undefined { | ||||||
| if (record.isSymlink) { | ||||||
| const target = resolve(path, record.symlinkPath); | ||||||
|
|
@@ -183,9 +211,7 @@ const _Iso = { | |||||
| }, | ||||||
|
|
||||||
| create(options: IsoOptions) { | ||||||
| const fs = new IsoFS(options.data); | ||||||
| fs.label = options.name; | ||||||
| return fs; | ||||||
| return new IsoFS(options); | ||||||
| }, | ||||||
| } as const satisfies Backend<IsoFS, IsoOptions>; | ||||||
| type _Iso = typeof _Iso; | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.