refactor(@angular-devkit/core): update stringToFileBuffer and fileBufferToString to use TextDecoder and TextEncoder

`TextDecoder` and `TextEncoder` can now be used on Node.js
This commit is contained in:
Alan Agius 2023-05-10 14:20:06 +00:00 committed by angular-robot[bot]
parent 1333a4e8c0
commit a70e7a42f1
3 changed files with 31 additions and 83 deletions

View File

@ -237,7 +237,7 @@ export class FileAlreadyExistException extends BaseException {
// @public (undocumented)
type FileBuffer = ArrayBuffer;
// @public (undocumented)
// @public @deprecated (undocumented)
const fileBuffer: TemplateTag<FileBuffer>;
// @public (undocumented)

View File

@ -6,75 +6,23 @@
* found in the LICENSE file at https://angular.io/license
*/
import { TextDecoder, TextEncoder } from 'node:util';
import { TemplateTag } from '../../utils/literals';
import { FileBuffer } from './interface';
declare const TextEncoder: {
new (encoding: string): {
encode(str: string): Uint8Array;
};
};
declare const TextDecoder: {
new (encoding: string): {
decode(bytes: Uint8Array): string;
};
};
export function stringToFileBuffer(str: string): FileBuffer {
// If we're in Node...
if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {
const buf = Buffer.from(str);
const ab = new ArrayBuffer(buf.length);
const view = new Uint8Array(ab);
for (let i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
return ab;
} else if (typeof TextEncoder !== 'undefined') {
// Modern browsers implement TextEncode.
return new TextEncoder('utf-8').encode(str).buffer;
} else {
// Slowest method but sure to be compatible with every platform.
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
return new TextEncoder().encode(str).buffer;
}
export function fileBufferToString(fileBuffer: FileBuffer): string {
if (fileBuffer.toString.length === 1) {
return (fileBuffer.toString as (enc: string) => string)('utf-8');
}
return new TextDecoder('utf-8').decode(new Uint8Array(fileBuffer));
}
/** @deprecated use `stringToFileBuffer` instead. */
export const fileBuffer: TemplateTag<FileBuffer> = (strings, ...values) => {
return stringToFileBuffer(String.raw(strings, ...values));
};
export function fileBufferToString(fileBuffer: FileBuffer): string {
if (fileBuffer.toString.length == 1) {
return (fileBuffer.toString as (enc: string) => string)('utf-8');
} else if (typeof Buffer !== 'undefined') {
return Buffer.from(fileBuffer).toString('utf-8');
} else if (typeof TextDecoder !== 'undefined') {
// Modern browsers implement TextEncode.
return new TextDecoder('utf-8').decode(new Uint8Array(fileBuffer));
} else {
// Slowest method but sure to be compatible with every platform.
const bufView = new Uint8Array(fileBuffer);
const bufLength = bufView.length;
let result = '';
let chunkLength = Math.pow(2, 16) - 1;
// We have to chunk it because String.fromCharCode.apply will throw
// `Maximum call stack size exceeded` on big inputs.
for (let i = 0; i < bufLength; i += chunkLength) {
if (i + chunkLength > bufLength) {
chunkLength = bufLength - i;
}
result += String.fromCharCode.apply(null, [...bufView.subarray(i, i + chunkLength)]);
}
return result;
}
}

View File

@ -8,7 +8,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { path } from '../path';
import { fileBuffer } from './buffer';
import { stringToFileBuffer } from './buffer';
import { CordHost } from './record';
import { test } from './test';
@ -22,7 +22,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe(undefined, done.fail);
const target = new TestHost();
host.commit(target).subscribe(undefined, done.fail);
@ -42,8 +42,8 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe(undefined, done.fail);
host.write(path`/blue`, fileBuffer`hi again`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi again`)).subscribe(undefined, done.fail);
const target = new TestHost();
host.commit(target).subscribe(undefined, done.fail);
@ -64,7 +64,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe(undefined, done.fail);
host.delete(path`/blue`).subscribe(undefined, done.fail);
const target = new TestHost();
@ -83,7 +83,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe(undefined, done.fail);
host.rename(path`/blue`, path`/red`).subscribe(undefined, done.fail);
const target = new TestHost();
@ -107,7 +107,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe(undefined, done.fail);
host.rename(path`/blue`, path`/blue`).subscribe(undefined, done.fail);
const target = new TestHost();
@ -130,7 +130,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe(undefined, done.fail);
host.rename(path`/blue`, path`/red`).subscribe(undefined, done.fail);
host.rename(path`/red`, path`/yellow`).subscribe(undefined, done.fail);
@ -203,7 +203,7 @@ describe('CordHost', () => {
const host = new CordHost(base);
host.rename(path`/hello`, path`/blue`).subscribe(undefined, done.fail);
host.write(path`/hello`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
const target = base.clone();
host.commit(target).subscribe(undefined, done.fail);
@ -226,7 +226,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/hello`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
const target = base.clone();
host.commit(target).subscribe(undefined, done.fail);
@ -248,8 +248,8 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/hello`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/hello`, fileBuffer`again`).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`again`)).subscribe(undefined, done.fail);
const target = base.clone();
host.commit(target).subscribe(undefined, done.fail);
@ -271,7 +271,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/hello`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
host.rename(path`/hello`, path`/blue`).subscribe(undefined, done.fail);
const target = base.clone();
@ -295,7 +295,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/hello`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
host.delete(path`/hello`).subscribe(undefined, done.fail);
const target = base.clone();
@ -316,7 +316,7 @@ describe('CordHost', () => {
const host = new CordHost(base);
host.rename(path`/hello`, path`/blue`).subscribe(undefined, done.fail);
host.write(path`/blue`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/blue`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
const target = base.clone();
host.commit(target).subscribe(undefined, done.fail);
@ -359,7 +359,7 @@ describe('CordHost', () => {
const host = new CordHost(base);
host.delete(path`/hello`).subscribe(undefined, done.fail);
host.write(path`/hello`, fileBuffer`beautiful world`).subscribe(undefined, done.fail);
host.write(path`/hello`, stringToFileBuffer(`beautiful world`)).subscribe(undefined, done.fail);
const target = base.clone();
host.commit(target).subscribe(undefined, done.fail);
@ -421,7 +421,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/blue`, fileBuffer`hi`).subscribe();
host.write(path`/blue`, stringToFileBuffer(`hi`)).subscribe();
const target = new TestHost({
'/blue': 'test',
@ -442,7 +442,7 @@ describe('CordHost', () => {
});
const host = new CordHost(base);
host.write(path`/hello`, fileBuffer`hi`).subscribe();
host.write(path`/hello`, stringToFileBuffer(`hi`)).subscribe();
const target = new TestHost({});
@ -502,7 +502,7 @@ describe('CordHost', () => {
const host = new CordHost(base);
let error = false;
host.write(path`/dir`, fileBuffer`beautiful world`).subscribe(
host.write(path`/dir`, stringToFileBuffer(`beautiful world`)).subscribe(
undefined,
() => (error = true),
() => (error = false),