etcher-sdk
Version:
89 lines • 3.46 kB
JavaScript
"use strict";
/*
* Copyright 2019 balena.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SparseFilterStream = void 0;
const stream_1 = require("stream");
const shared_1 = require("./shared");
class SparseFilterStream extends stream_1.Transform {
constructor({ blocks, verify, generateChecksums, }) {
super({ objectMode: true });
this.position = 0;
this.blocks = blocks;
this.stateIterator = (0, shared_1.createSparseReaderStateIterator)(blocks, verify, generateChecksums);
this.nextBlock();
}
nextBlock() {
this.state = this.stateIterator.next().value;
}
_transform(chunk, _encoding, callback) {
let error;
try {
this.__transform(chunk);
}
catch (err) {
error = err;
}
callback(error);
}
__transform(buffer) {
// eslint-disable-next-line no-constant-condition
while (true) {
if (this.state === undefined) {
// No current block means we're done reading
this.position += buffer.length;
return;
}
if (this.position >=
this.state.subBlock.offset + this.state.subBlock.length) {
// The current position is after the current block: go to the next block
this.nextBlock();
continue;
}
if (buffer.length === 0) {
return;
}
if (this.position < this.state.subBlock.offset) {
// Skip bytes before the current block
const toSkip = Math.min(this.state.subBlock.offset - this.position, buffer.length);
this.position += toSkip;
if (toSkip >= buffer.length) {
// There would be no data remaining after the slice
return;
}
buffer = buffer.slice(toSkip);
}
// The position is now inside the current block
// Cut until the end of the block or the end of the buffer to transform
const bytesLeftInBlock = this.state.subBlock.offset + this.state.subBlock.length - this.position;
const length = Math.min(bytesLeftInBlock, buffer.length);
const bufferToPush = buffer.slice(0, length);
if (this.state.hasher !== undefined) {
this.state.hasher.update(bufferToPush);
}
this.push({
buffer: bufferToPush,
position: this.position,
});
// Move position
this.position += length;
// Start over with the remaining data (if any)
buffer = buffer.slice(length);
}
}
}
exports.SparseFilterStream = SparseFilterStream;
//# sourceMappingURL=sparse-filter-stream.js.map