@@ -2,6 +2,9 @@ import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common";
22import { E_INVALIDLENGTH , E_INDEXOUTOFRANGE } from "util/error" ;
33import { Uint8Array } from "typedarray" ;
44import { ArrayBufferView } from "arraybuffer" ;
5+ import { Array } from "array" ;
6+
7+
58
69export class Buffer extends Uint8Array {
710 constructor ( size : i32 ) {
@@ -24,18 +27,85 @@ export class Buffer extends Uint8Array {
2427 return result ;
2528 }
2629
30+ public static fromArrayBuffer ( buffer : ArrayBuffer , byteOffset : i32 = 0 , length : i32 = - 1 ) : Buffer {
31+ length = select ( buffer . byteLength , length , length < 0 ) ;
32+ if ( i32 ( byteOffset < 0 ) | i32 ( byteOffset > buffer . byteLength - length ) ) throw new RangeError ( E_INDEXOUTOFRANGE ) ;
33+ if ( length == 0 ) return new Buffer ( 0 ) ;
34+ let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ;
35+ result . data = buffer ; // retains
36+ result . dataStart = changetype < usize > ( buffer ) + < usize > byteOffset ;
37+ result . dataLength = < usize > length ;
38+ return result ;
39+ }
40+
41+ public static fromString ( value : string , encoding : string = "utf8" ) : Buffer {
42+ let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ; // retains
43+ let buffer : ArrayBuffer ;
44+ if ( encoding == "utf8" || encoding == "utf-8" ) {
45+ buffer = String . UTF8 . encode ( value ) ;
46+ } else if ( encoding == "utf16le" ) {
47+ buffer = String . UTF16 . encode ( value ) ;
48+ } else if ( encoding == "hex" ) {
49+ buffer = Buffer . HEX . encode ( value ) ;
50+ // TODO: add ascii encoding
51+ } else {
52+ throw new TypeError ( "Invalid string encoding." ) ;
53+ }
54+
55+ result . data = buffer ; // retains
56+ result . dataStart = changetype < usize > ( buffer ) ;
57+ result . dataLength = buffer . byteLength ;
58+ return result ;
59+ }
60+
61+ public static fromArray < T extends ArrayBufferView > ( value : T , offset : i32 = 0 , length : i32 = - 1 ) : Buffer {
62+ length = select ( value . length , length , length < 0 ) ;
63+ if ( i32 ( offset < 0 ) | i32 ( offset > value . length ) ) throw new RangeError ( E_INDEXOUTOFRANGE ) ;
64+ if ( length > value . length - offset ) throw new RangeError ( E_INVALIDLENGTH ) ;
65+ if ( length == 0 ) return new Buffer ( 0 ) ;
66+ let abv = __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ;
67+ let buffer = __alloc ( length , idof < ArrayBuffer > ( ) ) ;
68+ if ( value instanceof Array < String > ) {
69+ for ( let i = 0 ; i < length ; i ++ ) {
70+ let index = i + offset ;
71+ let byteValue = parseFloat ( unchecked ( value [ index ] ) ) ;
72+ store < u8 > ( buffer + < usize > i , < u8 > select ( 0 , < u8 > byteValue , isNaN ( byteValue ) ) ) ;
73+ }
74+ } else {
75+ for ( let i = 0 ; i < length ; i ++ ) {
76+ let index = i + offset ;
77+ store < u8 > ( buffer + < usize > i , < u8 > unchecked ( value [ index ] ) ) ;
78+ }
79+ }
80+ let result = changetype < Buffer > ( abv ) ; // retains
81+ result . data = changetype < ArrayBuffer > ( buffer ) ; // retains
82+ result . dataStart = buffer ;
83+ result . dataLength = length ;
84+ return result ;
85+ }
86+
87+ public static fromBuffer ( source : Buffer ) : Buffer {
88+ let length = source . dataLength ;
89+ let data = changetype < ArrayBuffer > ( __alloc ( length , idof < ArrayBuffer > ( ) ) ) ; // retains
90+ memory . copy ( changetype < usize > ( data ) , source . dataStart , length ) ;
91+ let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ; // retains
92+ result . data = data ;
93+ result . dataStart = changetype < usize > ( data ) ;
94+ result . dataLength = length ;
95+ return result ;
96+ }
97+
2798 // @ts -ignore: Buffer returns on all valid branches
28- public static from < T extends ArrayBufferView > ( value : T ) : Buffer {
99+ public static from < T > ( value : T ) : Buffer {
29100 // @ts -ignore: AssemblyScript treats this statement correctly
30- if ( value instanceof String [ ] ) {
101+ if ( value instanceof Array < String > ) {
31102 let length = < usize > value . length ;
32103 let buffer = __alloc ( length , idof < ArrayBuffer > ( ) ) ;
33104 let sourceStart = value . dataStart ;
34105 for ( let i : usize = 0 ; i < length ; i ++ ) {
35106 let str = changetype < string > ( load < usize > ( sourceStart + ( < usize > i << alignof < usize > ( ) ) ) ) ;
36107 let value = parseFloat ( str ) ; // parseFloat is still naive
37- trace ( "float values" , 2 , value , u8 ( value ) ) ;
38- store < u8 > ( buffer + i , isFinite ( value ) ? u8 ( value ) : u8 ( 0 ) ) ;
108+ store < u8 > ( buffer + i , < u8 > select ( value , 0.0 , isFinite ( value ) ) ) ;
39109 }
40110 let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ;
41111 result . data = changetype < ArrayBuffer > ( buffer ) ;
@@ -57,20 +127,20 @@ export class Buffer extends Uint8Array {
57127 result . dataLength = buffer . byteLength ;
58128 return result ;
59129 } else if ( value instanceof Buffer ) {
60- let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ;
130+ let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ; // retains
61131 result . data = value . buffer ;
62132 result . dataStart = value . dataStart ;
63133 result . dataLength = value . dataLength ;
64134 return result ;
65135 } else if ( value instanceof ArrayBufferView ) {
66- let length = value . length ;
136+ let length = < usize > value . length ;
67137 let buffer = __alloc ( length , idof < ArrayBuffer > ( ) ) ;
68- let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ;
138+ let result = changetype < Buffer > ( __alloc ( offsetof < Buffer > ( ) , idof < Buffer > ( ) ) ) ; // retains
69139 // @ts -ignore: value[i] is implied to work
70- for ( let i = 0 ; i < length ; i ++ ) store < u8 > ( buffer + usize ( i ) , u8 ( unchecked ( value [ i ] ) ) ) ;
71- result . data = changetype < ArrayBuffer > ( buffer ) ;
140+ for ( let i = < usize > 0 ; i < length ; i ++ ) store < u8 > ( buffer + i , < u8 > unchecked ( value [ i ] ) ) ;
141+ result . data = changetype < ArrayBuffer > ( buffer ) ; // retains
72142 result . dataStart = buffer ;
73- result . dataLength = u32 ( length ) ;
143+ result . dataLength = < u32 > length ;
74144 return result ;
75145 }
76146 ERROR ( "Cannot call Buffer.from<T>() where T is not a string, Buffer, ArrayBuffer, Array, or Array-like Object." ) ;
0 commit comments