Skip to content

Commit d4e7e74

Browse files
d-googddelgrosso1
authored andcommitted
feat(crc32c): Convenient Method For Reading Files (googleapis#2095)
* feat(crc32c): Convenient Method For Reading Files * fix: `fs/promises` for Node 12 * fix: Use `unlink`, `rm` isn't available on Node 12 * fix: Use `unlink`, `rm` isn't available on Node 12
1 parent 7d7f4ca commit d4e7e74

3 files changed

Lines changed: 45 additions & 8 deletions

File tree

src/crc32c.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import {PathLike, createReadStream} from 'fs';
16+
1517
/**
1618
* Ported from {@link https://github.com/google/crc32c/blob/21fc8ef30415a635e7351ffa0e5d5367943d4a94/src/crc32c_portable.cc#L16-L59 github.com/google/crc32c}
1719
*/
@@ -252,6 +254,19 @@ class CRC32C implements CRC32CValidator {
252254
return new CRC32C(buffer.readInt32BE());
253255
}
254256

257+
static async fromFile(file: PathLike) {
258+
const crc32c = new CRC32C();
259+
260+
await new Promise((resolve, reject) => {
261+
createReadStream(file)
262+
.on('data', (d: Buffer) => crc32c.update(d))
263+
.on('end', resolve)
264+
.on('error', reject);
265+
});
266+
267+
return crc32c;
268+
}
269+
255270
/**
256271
* Generates a `CRC32C` from 4-byte base64-encoded data (string).
257272
*
@@ -286,6 +301,7 @@ class CRC32C implements CRC32CValidator {
286301

287302
/**
288303
* Generates a `CRC32C` from a variety of compatable types.
304+
* Note: strings are treated as input, not as file paths to read from.
289305
*
290306
* @param value A number, 4-byte `ArrayBufferView`/`Buffer`/`TypedArray`, or 4-byte base64-encoded data (string)
291307
*/

system-test/storage.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2698,14 +2698,7 @@ describe('storage', () => {
26982698

26992699
before(async () => {
27002700
// get a CRC32C value from the file
2701-
crc32c = await new Promise((resolve, reject) => {
2702-
const crc32c = new CRC32C();
2703-
2704-
fs.createReadStream(filePath)
2705-
.on('data', (d: Buffer) => crc32c.update(d))
2706-
.on('end', () => resolve(crc32c.toString()))
2707-
.on('error', reject);
2708-
});
2701+
crc32c = (await CRC32C.fromFile(filePath)).toString();
27092702
});
27102703

27112704
async function uploadAndVerify(

test/crc32c.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import {
2020
CRC32C_EXCEPTION_MESSAGES,
2121
} from '../src';
2222
import * as assert from 'assert';
23+
import {join} from 'path';
24+
import {tmpdir} from 'os';
25+
import * as fs from 'fs';
2326

2427
const KNOWN_INPUT_TO_CRC32C = {
2528
/** empty string (i.e. nothing to 'update') */
@@ -497,5 +500,30 @@ describe('CRC32C', () => {
497500
});
498501
});
499502
});
503+
504+
describe('.fromFile', () => {
505+
let tempFilePath: string;
506+
507+
beforeEach(async () => {
508+
tempFilePath = join(tmpdir(), 'test.crc32c.fromFile');
509+
});
510+
511+
after(async () => {
512+
try {
513+
await fs.promises.unlink(tempFilePath);
514+
} catch (e) {
515+
// errors are fine
516+
}
517+
});
518+
519+
it('should generate a valid `crc32c` via a file path', async () => {
520+
for (const [key, expected] of Object.entries(KNOWN_INPUT_TO_CRC32C)) {
521+
await fs.promises.writeFile(tempFilePath, key);
522+
523+
const crc32c = await CRC32C.fromFile(tempFilePath);
524+
assert.equal(crc32c.toString(), expected);
525+
}
526+
});
527+
});
500528
});
501529
});

0 commit comments

Comments
 (0)