UNPKG

@jsonjoy.com/json-pack

Version:

High-performance JSON serialization library

132 lines 4.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NfsFsDir = void 0; const NfsFsDirent_1 = require("./NfsFsDirent"); const builder_1 = require("../builder"); const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader"); const XdrDecoder_1 = require("../../../xdr/XdrDecoder"); /** * Implements Node.js-like Dir interface for NFS v4 directory iteration. */ class NfsFsDir { constructor(path, nfs, operations) { this.path = path; this.nfs = nfs; this.operations = operations; this.entries = []; this.position = 0; this.closed = false; } async ensureLoaded() { if (this.entries.length > 0 || this.closed) return; const attrNums = [1 /* Nfsv4Attr.FATTR4_TYPE */]; const attrMask = []; for (const attrNum of attrNums) { const wordIndex = Math.floor(attrNum / 32); const bitIndex = attrNum % 32; while (attrMask.length <= wordIndex) attrMask.push(0); attrMask[wordIndex] |= 1 << bitIndex; } const operations = [...this.operations]; operations.push(builder_1.nfs.READDIR(attrMask)); const response = await this.nfs.compound(operations); if (response.status !== 0 /* Nfsv4Stat.NFS4_OK */) throw new Error(`Failed to read directory: ${response.status}`); const readdirRes = response.resarray[response.resarray.length - 1]; if (readdirRes.status !== 0 /* Nfsv4Stat.NFS4_OK */ || !readdirRes.resok) throw new Error(`Failed to read directory: ${readdirRes.status}`); const entryList = readdirRes.resok.entries; for (let i = 0; i < entryList.length; i++) { const entry = entryList[i]; const name = entry.name; const fattr = entry.attrs; const reader = new Reader_1.Reader(); reader.reset(fattr.attrVals); const xdr = new XdrDecoder_1.XdrDecoder(reader); let fileType = 1 /* Nfsv4FType.NF4REG */; const returnedMask = fattr.attrmask.mask; for (let i = 0; i < returnedMask.length; i++) { const word = returnedMask[i]; if (!word) continue; for (let bit = 0; bit < 32; bit++) { if (!(word & (1 << bit))) continue; const attrNum = i * 32 + bit; if (attrNum === 1 /* Nfsv4Attr.FATTR4_TYPE */) { fileType = xdr.readUnsignedInt(); } } } this.entries.push(new NfsFsDirent_1.NfsFsDirent(name, fileType)); } } async close(callback) { this.closed = true; this.entries = []; this.position = 0; if (callback) { try { callback(); } catch (err) { callback(err); } } } closeSync() { this.closed = true; this.entries = []; this.position = 0; } async read(callback) { try { if (this.closed) { const err = new Error('Directory is closed'); if (callback) { callback(err, null); return null; } throw err; } await this.ensureLoaded(); if (this.position >= this.entries.length) { if (callback) { callback(null, null); } return null; } const entry = this.entries[this.position++]; if (callback) { callback(null, entry); } return entry; } catch (err) { if (callback) { callback(err, null); return null; } throw err; } } readSync() { if (this.closed) { throw new Error('Directory is closed'); } if (this.position >= this.entries.length) { return null; } return this.entries[this.position++]; } async *[Symbol.asyncIterator]() { await this.ensureLoaded(); for (const entry of this.entries) { yield entry; } } } exports.NfsFsDir = NfsFsDir; //# sourceMappingURL=NfsFsDir.js.map