Skip to content

Commit 392d073

Browse files
upy-fs-builder: Calculate size a file will take in the filesystem.
Replaces the naive method implemented in higher levels of abstraction where they only counted the number of data bytes. Note: That because chunks are not shared the file size calculation will always be a multiple of the chunk size.
1 parent ea51f98 commit 392d073

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed

src/__tests__/micropython-fs-builder.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,9 @@ describe('Reading files from the filesystem.', () => {
558558
expect(failCase).toThrow(Error);
559559
});
560560

561-
// TODO: Create tests with a file that has chunks in non-continuous order
562-
// TODO: Create test with chunks that point to each other in an infinite loop
563-
// TODO: Create test with chunks that point to each other in the Marker/Tail
561+
// TODO: Read tests with a file that has chunks in non-continuous order
562+
// TODO: Read test with chunks that point to each other in an infinite loop
563+
// TODO: Read test with chunks that don't point to each other in Marker/Tail
564+
// TODO: Read test with chunks using the all the start file markers
565+
// TODO: Test calculateFileSize()
564566
});

src/__tests__/micropython-fs-hex.spec.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,15 @@ describe('Tests exists method.', () => {
277277
describe('Test size method.', () => {
278278
it('File size is retrieved correctly.', () => {
279279
const micropythonFs = new MicropythonFsHex(uPyHexFile);
280-
micropythonFs.write(
281-
'five_bytes.txt',
282-
new Uint8Array([30, 31, 32, 33, 34, 35])
283-
);
280+
micropythonFs.write('five_bytes.txt', new Uint8Array([30, 31, 32, 33, 34]));
281+
micropythonFs.write('more_bytes.txt', new Uint8Array(128).fill(0x55));
284282

285-
const fileSize = micropythonFs.size('five_bytes.txt');
283+
const fileSize1 = micropythonFs.size('five_bytes.txt');
284+
const fileSize2 = micropythonFs.size('more_bytes.txt');
286285

287-
expect(fileSize).toEqual(6);
286+
// Real size counts chunks, so always a multiple of 128
287+
expect(fileSize1).toEqual(128);
288+
expect(fileSize2).toEqual(256);
288289
});
289290

290291
it('Throw error with invalid file name.', () => {

src/micropython-fs-builder.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,29 @@ class FsFile {
270270
}
271271
return fileFsBytes;
272272
}
273+
274+
/**
275+
* @returns Size, in bytes, of how much space the file takes in the filesystem
276+
* flash memory.
277+
*/
278+
getFsFileSize(): number {
279+
let chunksUsed = Math.ceil(this._fsDataBytes.length / CHUNK_DATA_LEN);
280+
// When MicroPython uses up to the last byte of the last chunk it will
281+
// still consume the next chunk, even if it doesn't add any data to it
282+
if (!(this._fsDataBytes.length % CHUNK_DATA_LEN)) {
283+
chunksUsed += 1;
284+
}
285+
return chunksUsed * CHUNK_LEN;
286+
}
287+
}
288+
289+
/**
290+
* @returns Size, in bytes, of how much space the file would take in the
291+
* MicroPython filesystem.
292+
*/
293+
function calculateFileSize(filename: string, data: Uint8Array): number {
294+
const file = new FsFile(filename, data);
295+
return file.getFsFileSize();
273296
}
274297

275298
/**
@@ -457,4 +480,9 @@ function getIntelHexFiles(
457480
return files;
458481
}
459482

460-
export { addIntelHexFile, addIntelHexFiles, getIntelHexFiles };
483+
export {
484+
addIntelHexFile,
485+
addIntelHexFiles,
486+
calculateFileSize,
487+
getIntelHexFiles,
488+
};

src/micropython-fs-hex.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
/** Manage files in a MicroPython hex file. */
22
import { FsInterface } from './fs-interface';
3-
import { addIntelHexFiles, getIntelHexFiles } from './micropython-fs-builder';
3+
import {
4+
addIntelHexFiles,
5+
calculateFileSize,
6+
getIntelHexFiles,
7+
} from './micropython-fs-builder';
48
import { SimpleFile } from './simple-file';
59

610
export class MicropythonFsHex implements FsInterface {
@@ -149,7 +153,10 @@ export class MicropythonFsHex implements FsInterface {
149153
if (!this.exists(filename)) {
150154
throw new Error(`File "${filename}" does not exist.`);
151155
}
152-
return this._files[filename].getSize();
156+
return calculateFileSize(
157+
this._files[filename].filename,
158+
this._files[filename].getBytes()
159+
);
153160
}
154161

155162
/**

src/simple-file.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,4 @@ export class SimpleFile {
3737
getBytes(): Uint8Array {
3838
return this._dataBytes;
3939
}
40-
41-
getSize(): number {
42-
return this._dataBytes.length;
43-
}
4440
}

0 commit comments

Comments
 (0)