2020-11-07 23:49:05 +00:00
|
|
|
import { memory } from './types';
|
Typescript conversion of several files, including js/cpu6502 (#38)
* Convert `js/util.js` to Typescript and add tests
Besides converting `js/util.js` to Typescript, this change also adds
`js/types.ts` that defines common types used in apple2js. Some of
these types, like `byte` and `word` are for information only.
* Convert `js/base64.js` to Typescript
This also adds a new type, `memory`, that is either an array of
numbers, or a Uint8Array.
* Convert `js/ram.js` to Typescript
This change does not convert `RAM` to a class; it just introduces types.
* Basic typing of cpu6502
This is a really rough first pass. There are some problems that can't
be fixed until this is turned into a real class, but at least all of
the function arguments are now typed. This caught a few cases where
extra arguments were being passed in.
* Convert `js/cpu6502` to a class
In theory, idiomatic classes should be better than the previous
closure-based classes. However, this conversion shows that the
instruction table does not fit well with idiomatic classes as method
referenced in the table need to be called with the correct `this`
everywhere.
This should, at best, be considered a first attempt.
2020-11-01 16:43:48 +00:00
|
|
|
|
|
|
|
const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
|
|
|
|
|
|
/** Encode an array of bytes in base64. */
|
2020-12-29 14:40:58 +00:00
|
|
|
export function base64_encode(data: null | undefined): undefined;
|
|
|
|
export function base64_encode(data: memory): string;
|
|
|
|
export function base64_encode(data: memory | null | undefined): string | undefined {
|
2020-11-07 23:49:05 +00:00
|
|
|
// Twacked by Will Scullin to handle arrays of 'bytes'
|
2016-11-22 05:17:34 +00:00
|
|
|
|
2013-10-10 18:03:07 +00:00
|
|
|
// http://kevin.vanzonneveld.net
|
|
|
|
// + original by: Tyler Akins (http://rumkin.com)
|
|
|
|
// + improved by: Bayron Guevara
|
|
|
|
// + improved by: Thunder.m
|
|
|
|
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
|
// + bugfixed by: Pellentesque Malesuada
|
|
|
|
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
|
// - depends on: utf8_encode
|
|
|
|
// * example 1: base64_encode('Kevin van Zonneveld');
|
|
|
|
// * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
|
|
|
|
|
|
|
|
// mozilla has this native
|
|
|
|
// - but breaks in 2.0.0.12!
|
|
|
|
//if (typeof this.window['atob'] == 'function') {
|
|
|
|
// return atob(data);
|
|
|
|
//}
|
2016-11-22 05:17:34 +00:00
|
|
|
|
2020-11-07 23:49:05 +00:00
|
|
|
|
|
|
|
let o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc='';
|
|
|
|
const tmp_arr = [];
|
2013-10-10 18:03:07 +00:00
|
|
|
|
|
|
|
if (!data) {
|
2020-12-29 14:40:58 +00:00
|
|
|
return undefined;
|
2013-10-10 18:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
do { // pack three octets into four hexets
|
|
|
|
o1 = data[i++];
|
|
|
|
o2 = data[i++];
|
|
|
|
o3 = data[i++];
|
|
|
|
|
|
|
|
bits = o1<<16 | o2<<8 | o3;
|
|
|
|
|
|
|
|
h1 = bits>>18 & 0x3f;
|
|
|
|
h2 = bits>>12 & 0x3f;
|
|
|
|
h3 = bits>>6 & 0x3f;
|
|
|
|
h4 = bits & 0x3f;
|
|
|
|
|
|
|
|
// use hexets to index into b64, and append result to encoded string
|
Typescript conversion of several files, including js/cpu6502 (#38)
* Convert `js/util.js` to Typescript and add tests
Besides converting `js/util.js` to Typescript, this change also adds
`js/types.ts` that defines common types used in apple2js. Some of
these types, like `byte` and `word` are for information only.
* Convert `js/base64.js` to Typescript
This also adds a new type, `memory`, that is either an array of
numbers, or a Uint8Array.
* Convert `js/ram.js` to Typescript
This change does not convert `RAM` to a class; it just introduces types.
* Basic typing of cpu6502
This is a really rough first pass. There are some problems that can't
be fixed until this is turned into a real class, but at least all of
the function arguments are now typed. This caught a few cases where
extra arguments were being passed in.
* Convert `js/cpu6502` to a class
In theory, idiomatic classes should be better than the previous
closure-based classes. However, this conversion shows that the
instruction table does not fit well with idiomatic classes as method
referenced in the table need to be called with the correct `this`
everywhere.
This should, at best, be considered a first attempt.
2020-11-01 16:43:48 +00:00
|
|
|
tmp_arr[ac++] = B64.charAt(h1) + B64.charAt(h2) + B64.charAt(h3) + B64.charAt(h4);
|
2013-10-10 18:03:07 +00:00
|
|
|
} while (i < data.length);
|
2016-11-22 05:17:34 +00:00
|
|
|
|
2013-10-10 18:03:07 +00:00
|
|
|
enc = tmp_arr.join('');
|
2016-11-22 05:17:34 +00:00
|
|
|
|
2013-10-10 18:03:07 +00:00
|
|
|
switch (data.length % 3) {
|
2020-11-26 01:28:37 +00:00
|
|
|
case 1:
|
|
|
|
enc = enc.slice(0, -2) + '==';
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
enc = enc.slice(0, -1) + '=';
|
|
|
|
break;
|
2013-10-10 18:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return enc;
|
|
|
|
}
|
|
|
|
|
Typescript conversion of several files, including js/cpu6502 (#38)
* Convert `js/util.js` to Typescript and add tests
Besides converting `js/util.js` to Typescript, this change also adds
`js/types.ts` that defines common types used in apple2js. Some of
these types, like `byte` and `word` are for information only.
* Convert `js/base64.js` to Typescript
This also adds a new type, `memory`, that is either an array of
numbers, or a Uint8Array.
* Convert `js/ram.js` to Typescript
This change does not convert `RAM` to a class; it just introduces types.
* Basic typing of cpu6502
This is a really rough first pass. There are some problems that can't
be fixed until this is turned into a real class, but at least all of
the function arguments are now typed. This caught a few cases where
extra arguments were being passed in.
* Convert `js/cpu6502` to a class
In theory, idiomatic classes should be better than the previous
closure-based classes. However, this conversion shows that the
instruction table does not fit well with idiomatic classes as method
referenced in the table need to be called with the correct `this`
everywhere.
This should, at best, be considered a first attempt.
2020-11-01 16:43:48 +00:00
|
|
|
/** Returns undefined if the input is null or undefined. */
|
|
|
|
export function base64_decode(data: null | undefined): undefined;
|
|
|
|
/** Returns an array of bytes from the given base64-encoded string. */
|
|
|
|
export function base64_decode(data: string): memory;
|
|
|
|
/** Returns an array of bytes from the given base64-encoded string. */
|
|
|
|
export function base64_decode(data: string | null | undefined): memory | undefined {
|
2020-11-07 23:49:05 +00:00
|
|
|
// Twacked by Will Scullin to handle arrays of 'bytes'
|
2016-11-22 05:17:34 +00:00
|
|
|
|
2013-10-10 18:03:07 +00:00
|
|
|
// http://kevin.vanzonneveld.net
|
|
|
|
// + original by: Tyler Akins (http://rumkin.com)
|
|
|
|
// + improved by: Thunder.m
|
|
|
|
// + input by: Aman Gupta
|
|
|
|
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
|
// + bugfixed by: Onno Marsman
|
|
|
|
// + bugfixed by: Pellentesque Malesuada
|
|
|
|
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
|
// + input by: Brett Zamir (http://brett-zamir.me)
|
|
|
|
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
|
// - depends on: utf8_decode
|
|
|
|
// * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
|
|
|
|
// * returns 1: 'Kevin van Zonneveld'
|
|
|
|
|
|
|
|
// mozilla has this native
|
|
|
|
// - but breaks in 2.0.0.12!
|
|
|
|
//if (typeof this.window['btoa'] == 'function') {
|
|
|
|
// return btoa(data);
|
|
|
|
//}
|
|
|
|
|
2020-11-07 23:49:05 +00:00
|
|
|
let o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0;
|
|
|
|
const tmp_arr = [];
|
2013-10-10 18:03:07 +00:00
|
|
|
|
|
|
|
if (!data) {
|
Typescript conversion of several files, including js/cpu6502 (#38)
* Convert `js/util.js` to Typescript and add tests
Besides converting `js/util.js` to Typescript, this change also adds
`js/types.ts` that defines common types used in apple2js. Some of
these types, like `byte` and `word` are for information only.
* Convert `js/base64.js` to Typescript
This also adds a new type, `memory`, that is either an array of
numbers, or a Uint8Array.
* Convert `js/ram.js` to Typescript
This change does not convert `RAM` to a class; it just introduces types.
* Basic typing of cpu6502
This is a really rough first pass. There are some problems that can't
be fixed until this is turned into a real class, but at least all of
the function arguments are now typed. This caught a few cases where
extra arguments were being passed in.
* Convert `js/cpu6502` to a class
In theory, idiomatic classes should be better than the previous
closure-based classes. However, this conversion shows that the
instruction table does not fit well with idiomatic classes as method
referenced in the table need to be called with the correct `this`
everywhere.
This should, at best, be considered a first attempt.
2020-11-01 16:43:48 +00:00
|
|
|
return undefined;
|
2013-10-10 18:03:07 +00:00
|
|
|
}
|
|
|
|
|
Typescript conversion of several files, including js/cpu6502 (#38)
* Convert `js/util.js` to Typescript and add tests
Besides converting `js/util.js` to Typescript, this change also adds
`js/types.ts` that defines common types used in apple2js. Some of
these types, like `byte` and `word` are for information only.
* Convert `js/base64.js` to Typescript
This also adds a new type, `memory`, that is either an array of
numbers, or a Uint8Array.
* Convert `js/ram.js` to Typescript
This change does not convert `RAM` to a class; it just introduces types.
* Basic typing of cpu6502
This is a really rough first pass. There are some problems that can't
be fixed until this is turned into a real class, but at least all of
the function arguments are now typed. This caught a few cases where
extra arguments were being passed in.
* Convert `js/cpu6502` to a class
In theory, idiomatic classes should be better than the previous
closure-based classes. However, this conversion shows that the
instruction table does not fit well with idiomatic classes as method
referenced in the table need to be called with the correct `this`
everywhere.
This should, at best, be considered a first attempt.
2020-11-01 16:43:48 +00:00
|
|
|
do { // unpack four hexets into three octets using index points in B64
|
|
|
|
h1 = B64.indexOf(data.charAt(i++));
|
|
|
|
h2 = B64.indexOf(data.charAt(i++));
|
|
|
|
h3 = B64.indexOf(data.charAt(i++));
|
|
|
|
h4 = B64.indexOf(data.charAt(i++));
|
2013-10-10 18:03:07 +00:00
|
|
|
|
|
|
|
bits = h1<<18 | h2<<12 | h3<<6 | h4;
|
|
|
|
|
|
|
|
o1 = bits>>16 & 0xff;
|
|
|
|
o2 = bits>>8 & 0xff;
|
|
|
|
o3 = bits & 0xff;
|
|
|
|
|
2016-11-22 05:17:34 +00:00
|
|
|
tmp_arr[ac++] = o1;
|
2013-10-10 18:03:07 +00:00
|
|
|
if (h3 != 64) {
|
|
|
|
tmp_arr[ac++] = o2;
|
2016-11-22 05:17:34 +00:00
|
|
|
}
|
2013-10-10 18:03:07 +00:00
|
|
|
if (h4 != 64) {
|
|
|
|
tmp_arr[ac++] = o3;
|
|
|
|
}
|
|
|
|
} while (i < data.length);
|
|
|
|
|
2021-02-08 04:50:50 +00:00
|
|
|
return new Uint8Array(tmp_arr);
|
2013-10-10 18:03:07 +00:00
|
|
|
}
|
2021-02-28 03:17:36 +00:00
|
|
|
|
|
|
|
const DATA_URL_PREFIX = 'data:application/octet-stream;base64,';
|
|
|
|
|
|
|
|
export function base64_json_parse(json: string) {
|
|
|
|
const reviver = (_key: string, value: any) => {
|
|
|
|
if (typeof value ==='string' && value.startsWith(DATA_URL_PREFIX)) {
|
|
|
|
return base64_decode(value.slice(DATA_URL_PREFIX.length));
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
};
|
|
|
|
|
|
|
|
return JSON.parse(json, reviver);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function base64_json_stringify(json: any) {
|
|
|
|
const replacer = (_key: string, value: any) => {
|
|
|
|
if (value instanceof Uint8Array) {
|
|
|
|
return DATA_URL_PREFIX + base64_encode(value);
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
};
|
|
|
|
|
|
|
|
return JSON.stringify(json, replacer);
|
|
|
|
}
|