Skip to content

Commit 002c8d4

Browse files
upy-fs-hex: Add method to configure the available stoagra size.
1 parent 8cdfcab commit 002c8d4

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

docs/quick-guide.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ var fsSize = micropythonFs.getStorageSize();
3838
var fsAvailableSize = micropythonFs.getStorageUsed();
3939
var fsUsedSize = micropythonFs.getStorageRemaining();
4040

41+
// You can also provide an artificial storage size
42+
micropythonFs.setStorageSize(20 * 1024);
43+
4144
// Generate a new hex string or Uint8Array with MicroPython and the files
4245
var intelHexStrWithFs = micropythonFs.getIntelHex();
4346
var intelHexBytesWithFs = micropythonFs.getIntelHexBytes();

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,75 @@ describe('Test size operations.', () => {
122122
expect(microbitFs.getStorageUsed()).toEqual(27648);
123123
expect(microbitFs.getStorageRemaining()).toEqual(0);
124124
});
125+
126+
it('Sets a maximum filesystem size via constructor', () => {
127+
const microbitFs = new MicropythonFsHex(uPyHexFile, { maxFsSize: 1024 });
128+
129+
expect(microbitFs.getStorageUsed()).toEqual(0);
130+
expect(microbitFs.getStorageRemaining()).toEqual(1024);
131+
132+
microbitFs.create('chunk1.py', 'first 128 byte chunk');
133+
microbitFs.create('chunk2.py', 'second 128 byte chunk');
134+
microbitFs.create('chunk3.py', 'thrid 128 byte chunk');
135+
microbitFs.create('chunk4.py', 'fouth 128 byte chunk');
136+
microbitFs.create('chunk5.py', 'fifth 128 byte chunk');
137+
microbitFs.create('chunk6.py', 'sixth 128 byte chunk');
138+
microbitFs.create('chunk7.py', 'seventh 128 byte chunk');
139+
microbitFs.create('chunk8.py', 'eighth 128 byte chunk');
140+
microbitFs.getIntelHex();
141+
142+
expect(microbitFs.getStorageUsed()).toEqual(1024);
143+
expect(microbitFs.getStorageRemaining()).toEqual(0);
144+
145+
microbitFs.create('chunk9.py', 'This file will not fit');
146+
const failCase = () => {
147+
microbitFs.getIntelHex();
148+
};
149+
150+
expect(failCase).toThrow(Error);
151+
});
152+
153+
it('Sets a maximum filesystem size via constructor', () => {
154+
const microbitFs = new MicropythonFsHex(uPyHexFile);
155+
microbitFs.setStorageSize(1024);
156+
157+
expect(microbitFs.getStorageUsed()).toEqual(0);
158+
expect(microbitFs.getStorageRemaining()).toEqual(1024);
159+
160+
microbitFs.create('chunk1.py', 'first 128 byte chunk');
161+
microbitFs.create('chunk2.py', 'second 128 byte chunk');
162+
microbitFs.create('chunk3.py', 'thrid 128 byte chunk');
163+
microbitFs.create('chunk4.py', 'fouth 128 byte chunk');
164+
microbitFs.create('chunk5.py', 'fifth 128 byte chunk');
165+
microbitFs.create('chunk6.py', 'sixth 128 byte chunk');
166+
microbitFs.create('chunk7.py', 'seventh 128 byte chunk');
167+
microbitFs.create('chunk8.py', 'eighth 128 byte chunk');
168+
microbitFs.getIntelHex();
169+
microbitFs.getIntelHexBytes();
170+
171+
expect(microbitFs.getStorageUsed()).toEqual(1024);
172+
expect(microbitFs.getStorageRemaining()).toEqual(0);
173+
174+
microbitFs.create('chunk9.py', 'This file will not fit');
175+
const failCase1 = () => microbitFs.getIntelHex();
176+
const failCase2 = () => microbitFs.getIntelHexBytes();
177+
178+
expect(failCase1).toThrow(Error);
179+
expect(failCase2).toThrow(Error);
180+
});
181+
182+
it('The maximum filesystem size cannot be larger than space available', () => {
183+
const failCase1 = () => {
184+
const microbitFs = new MicropythonFsHex(uPyHexFile, {
185+
maxFsSize: 1024 * 1024,
186+
});
187+
};
188+
const microbitFs = new MicropythonFsHex(uPyHexFile);
189+
const failCase2 = () => microbitFs.setStorageSize(1024 * 1024);
190+
191+
expect(failCase1).toThrow(Error);
192+
expect(failCase2).toThrow(Error);
193+
});
125194
});
126195

127196
describe('Test write method.', () => {

src/micropython-fs-hex.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { SimpleFile } from './simple-file';
1111
export class MicropythonFsHex implements FsInterface {
1212
private _intelHex: string;
1313
private _files: { [id: string]: SimpleFile } = {};
14+
private _storageSize: number = 0;
1415

1516
/**
1617
* File System manager constructor.
@@ -20,14 +21,18 @@ export class MicropythonFsHex implements FsInterface {
2021
*
2122
* @param intelHex - MicroPython Intel Hex string.
2223
*/
23-
constructor(intelHex: string) {
24+
constructor(
25+
intelHex: string,
26+
{ maxFsSize = 0 }: { maxFsSize?: number } = {}
27+
) {
2428
this._intelHex = intelHex;
2529
this.importFilesFromIntelHex(this._intelHex);
2630
if (this.ls().length) {
2731
throw new Error(
2832
'There are files in the MicropythonFsHex constructor hex file input.'
2933
);
3034
}
35+
this.setStorageSize(maxFsSize);
3136
}
3237

3338
/**
@@ -169,13 +174,31 @@ export class MicropythonFsHex implements FsInterface {
169174
return files;
170175
}
171176

177+
/**
178+
* Sets a storage size limit. Must be smaller than available space in
179+
* MicroPython.
180+
*
181+
* @param {number} size - Size in bytes for the filesystem.
182+
*/
183+
setStorageSize(size: number): void {
184+
if (size > getIntelHexFsSize(this._intelHex)) {
185+
throw new Error(
186+
'Storage size limit provided is larger than size available in the MicroPython hex.'
187+
);
188+
}
189+
this._storageSize = size;
190+
}
191+
172192
/**
173193
* Calculate the MicroPython filesystem total size.
194+
* If an max storage size limit has been set, it returns this number.
174195
*
175196
* @returns Size of the filesystem in bytes.
176197
*/
177198
getStorageSize(): number {
178-
return getIntelHexFsSize(this._intelHex);
199+
return this._storageSize
200+
? this._storageSize
201+
: getIntelHexFsSize(this._intelHex);
179202
}
180203

181204
/**
@@ -255,6 +278,9 @@ export class MicropythonFsHex implements FsInterface {
255278
* @returns A new string with MicroPython and the filesystem included.
256279
*/
257280
getIntelHex(intelHex?: string): string {
281+
if (this.getStorageRemaining() < 0) {
282+
throw new Error('There is no storage space left.');
283+
}
258284
const finalHex = intelHex || this._intelHex;
259285
const files: { [filename: string]: Uint8Array } = {};
260286
Object.values(this._files).forEach((file) => {
@@ -275,6 +301,9 @@ export class MicropythonFsHex implements FsInterface {
275301
* @returns A Uint8Array with MicroPython and the filesystem included.
276302
*/
277303
getIntelHexBytes(intelHex?: string): Uint8Array {
304+
if (this.getStorageRemaining() < 0) {
305+
throw new Error('There is no storage space left.');
306+
}
278307
const finalHex = intelHex || this._intelHex;
279308
const files: { [filename: string]: Uint8Array } = {};
280309
Object.values(this._files).forEach((file) => {

0 commit comments

Comments
 (0)