Skip to content

Commit

Permalink
feat(crc32c): Convenient Method For Reading Files (#2095)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
danielbankhead committed Oct 25, 2022
1 parent dc04f19 commit 2145c81
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
16 changes: 16 additions & 0 deletions src/crc32c.ts
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {PathLike, createReadStream} from 'fs';

/**
* Ported from {@link https://github.com/google/crc32c/blob/21fc8ef30415a635e7351ffa0e5d5367943d4a94/src/crc32c_portable.cc#L16-L59 github.com/google/crc32c}
*/
Expand Down Expand Up @@ -252,6 +254,19 @@ class CRC32C implements CRC32CValidator {
return new CRC32C(buffer.readInt32BE());
}

static async fromFile(file: PathLike) {
const crc32c = new CRC32C();

await new Promise((resolve, reject) => {
createReadStream(file)
.on('data', (d: Buffer) => crc32c.update(d))
.on('end', resolve)
.on('error', reject);
});

return crc32c;
}

/**
* Generates a `CRC32C` from 4-byte base64-encoded data (string).
*
Expand Down Expand Up @@ -286,6 +301,7 @@ class CRC32C implements CRC32CValidator {

/**
* Generates a `CRC32C` from a variety of compatable types.
* Note: strings are treated as input, not as file paths to read from.
*
* @param value A number, 4-byte `ArrayBufferView`/`Buffer`/`TypedArray`, or 4-byte base64-encoded data (string)
*/
Expand Down
9 changes: 1 addition & 8 deletions system-test/storage.ts
Expand Up @@ -2698,14 +2698,7 @@ describe('storage', () => {

before(async () => {
// get a CRC32C value from the file
crc32c = await new Promise((resolve, reject) => {
const crc32c = new CRC32C();

fs.createReadStream(filePath)
.on('data', (d: Buffer) => crc32c.update(d))
.on('end', () => resolve(crc32c.toString()))
.on('error', reject);
});
crc32c = (await CRC32C.fromFile(filePath)).toString();
});

async function uploadAndVerify(
Expand Down
28 changes: 28 additions & 0 deletions test/crc32c.ts
Expand Up @@ -20,6 +20,9 @@ import {
CRC32C_EXCEPTION_MESSAGES,
} from '../src';
import * as assert from 'assert';
import {join} from 'path';
import {tmpdir} from 'os';
import * as fs from 'fs';

const KNOWN_INPUT_TO_CRC32C = {
/** empty string (i.e. nothing to 'update') */
Expand Down Expand Up @@ -497,5 +500,30 @@ describe('CRC32C', () => {
});
});
});

describe('.fromFile', () => {
let tempFilePath: string;

beforeEach(async () => {
tempFilePath = join(tmpdir(), 'test.crc32c.fromFile');
});

after(async () => {
try {
await fs.promises.unlink(tempFilePath);
} catch (e) {
// errors are fine
}
});

it('should generate a valid `crc32c` via a file path', async () => {
for (const [key, expected] of Object.entries(KNOWN_INPUT_TO_CRC32C)) {
await fs.promises.writeFile(tempFilePath, key);

const crc32c = await CRC32C.fromFile(tempFilePath);
assert.equal(crc32c.toString(), expected);
}
});
});
});
});

0 comments on commit 2145c81

Please sign in to comment.