buffer: add isAscii method

PR-URL: https://github.com/nodejs/node/pull/46046
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
Yagiz Nizipli 2023-01-19 22:24:40 -05:00 committed by GitHub
parent 49413ad8ae
commit babe6d7c84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 0 deletions

View File

@ -5138,6 +5138,20 @@ For code running using Node.js APIs, converting between base64-encoded strings
and binary data should be performed using `Buffer.from(str, 'base64')` and
`buf.toString('base64')`.**
### `buffer.isAscii(input)`
<!-- YAML
added: REPLACEME
-->
* input {Buffer | ArrayBuffer | TypedArray} The input to validate.
* Returns: {boolean}
This function returns `true` if `input` contains only valid ASCII-encoded data,
including the case in which `input` is empty.
Throws if the `input` is a detached array buffer.
### `buffer.isUtf8(input)`
<!-- YAML

View File

@ -56,6 +56,7 @@ const {
compareOffset,
createFromString,
fill: bindingFill,
isAscii: bindingIsAscii,
isUtf8: bindingIsUtf8,
indexOfBuffer,
indexOfNumber,
@ -1320,11 +1321,20 @@ function isUtf8(input) {
throw new ERR_INVALID_ARG_TYPE('input', ['TypedArray', 'Buffer'], input);
}
function isAscii(input) {
if (isTypedArray(input) || isAnyArrayBuffer(input)) {
return bindingIsAscii(input);
}
throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input);
}
module.exports = {
Buffer,
SlowBuffer,
transcode,
isUtf8,
isAscii,
// Legacy
kMaxLength,

View File

@ -1238,6 +1238,21 @@ static void IsUtf8(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(simdutf::validate_utf8(abv.data(), abv.length()));
}
static void IsAscii(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK_EQ(args.Length(), 1);
CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() ||
args[0]->IsSharedArrayBuffer());
ArrayBufferViewContents<char> abv(args[0]);
if (abv.WasDetached()) {
return node::THROW_ERR_INVALID_STATE(
env, "Cannot validate on a detached buffer");
}
args.GetReturnValue().Set(simdutf::validate_ascii(abv.data(), abv.length()));
}
void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
@ -1373,6 +1388,7 @@ void Initialize(Local<Object> target,
SetMethodNoSideEffect(context, target, "encodeUtf8String", EncodeUtf8String);
SetMethodNoSideEffect(context, target, "isUtf8", IsUtf8);
SetMethodNoSideEffect(context, target, "isAscii", IsAscii);
target
->Set(context,
@ -1430,6 +1446,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(EncodeUtf8String);
registry->Register(IsUtf8);
registry->Register(IsAscii);
registry->Register(StringSlice<ASCII>);
registry->Register(StringSlice<BASE64>);

View File

@ -0,0 +1,42 @@
'use strict';
require('../common');
const assert = require('assert');
const { isAscii, Buffer } = require('buffer');
const { TextEncoder } = require('util');
const encoder = new TextEncoder();
assert.strictEqual(isAscii(encoder.encode('hello')), true);
assert.strictEqual(isAscii(encoder.encode('ğ')), false);
assert.strictEqual(isAscii(Buffer.from([])), true);
[
undefined,
'', 'hello',
false, true,
0, 1,
0n, 1n,
Symbol(),
() => {},
{}, [], null,
].forEach((input) => {
assert.throws(
() => { isAscii(input); },
{
code: 'ERR_INVALID_ARG_TYPE',
},
);
});
{
// Test with detached array buffers
const arrayBuffer = new ArrayBuffer(1024);
structuredClone(arrayBuffer, { transfer: [arrayBuffer] });
assert.throws(
() => { isAscii(arrayBuffer); },
{
code: 'ERR_INVALID_STATE'
}
);
}