BERT.JS

ВСТУП

Модуль bert.js надає JavaScript кодер/декодер для External Term Format, який використовується в Erlang distribution protocol. Це означає, що ваші JavaScript програми надсилають повідомлення в рідному форматі Erlang. Цей модуль застосовує DataView, а також методи getUint8, getUint16, getUint32, які забезпечують найшвидший варіант роботи з бінарними даними в JavaScript. Ця бібліотека використовується в Erlang і Haskell версіях N2O. Розмір bert.js — 4654 байта.

Зауважте, що це низькорівнева бібліотека, швидка версія BERT кодера/декодера. Якщо ви хочете генерувати JavaScript SDK з іменованими полями, як в файлах заголовків Erlang, підключіть BERT — високорівневу бібліотеку-двійника, яка генерує обгортки навколо bert.js та забезпечує більш more slick JavaScript досвід.

Erlang структура, яка компілюється в BERT формат:

#io{ code = login, data = { 'Token', 42 } }

Цільова структура bert.js — швидкий низькорівневий жорстко закодований парсер з BERT формату.

{ t: 104, v: [ { t: 100, v: "io" }, { t: 100, v: "login" }, { t: 104, v: [ { t: 100, v: "Token" }, { t: 97, v: 42 } ] } ] }

Цільова структура згенерованого парсера з BERT parse transform:

{ tup: 'io', code: 'login', data: { tup: '$', 0: 'Token', 1: 42 } },

Підтримується наступна практична підмножина формату BERT:

70

Кодування числа з плаваючою точкою IEEE-754; зберігається у вигляді 8 байтів у big-endian IEEE форматі. Цей вираз використовується в мінорній версії 1 зовнішнього формату.

1 8 70 IEEE-754 float

97

Кодування байтів. Беззнакове 8-бітне ціле число (integer).

1 1 97 Int

98

Кодування цілих чисел (Integer). 32-бітне ціле число зі знаком, в big-endian форматі.

1 4 98 Int

99

Кодування числа з плаваючою точкою POSIX; зберігається у вигляді строки. Формат використовується в sprintf, для форматування чисел з плаваючою точкою, як "%.20e" (виділяється більше байтів, ніж необхідно). Для розпакування числа з плаваючою точкою використовується sscanf з форматом "%lf".

1 31 99 Float POSIX string.

100

Кодування атомів. Атом зберігається у вигляді 2-байтового беззнакового цілого числа в big-endian порядку, яким задається довжина, за ним слідують N чисел — 8-бітних Latin-1 знаків (Characters), які є ім'ям атома. Максимально дозволене значення довжини є 255.

1 2 N 100 N Characters

104

Кодування кортежу. Поле арності (Arity) — беззнакове 1-байте ціле число N, яке визначає, скільки елементів знаходиться в секції Елементи (Elements).

1 1 N 104 N Elements

105

Кодування великого кортежу. Відмінність від 104 — N є беззнаковим 4-байтним цілим числом в big-endian форматі.

1 4 N 105 N Elements

106

Nil.

1 106

107

Кодування строки. Оскільки поле N є беззнаковим 2-байтним числом (big-endian), реалізації повинні гарантувати, що списки, довші за 65535 елементів, кодуються за допомогою 108.

1 2 N 107 N Characters

108

Кодування списків. N — кількість елементів в секції Символи (Characters). Хвіст (Tail) — остаточний хвіст списку; це 106 для правильного списку, але, у випадку неправильного списку, може бути будь-якого типу (наприклад, [a|b]).

1 4 N 108 N Characters Tail

109

Бінарне кодування. Бінарні строки генеруються за допомогою бітового синтаксичного виразу (bit syntax expression) або erlang:list_to_binary/1, erlang:term_to_binary/1, чи як вхідні дані від бінарних портів (binary ports). Поле довжини N є беззнаковим 4-байтним цілим числом (big-endian).

1 4 N 109 N Bytes

110

Кодування малого bignum. Bignum зберігається в унарній формі з байтом знаку, який дорівнює 0, якщо binum позитивний, і 1, якщо негативний. При зберіганні цифр молодший байт зберігаються першим. Для обчислення цілого числа можна використовувати наступну формулу:

1 1 1 n 110 n Sign d(0)...d(n-1)

B = 256,
d0*B0 + d1*B1 + d2*B2 + ... dN-1*B(n-1)

111

Кодування великого bignum. Відмінність від 110 — поле довжини є беззнаковим 4-байтним цілим числом.

1 4 1 n 111 n Sign d(0)...d(n-1)

115

Кодування малого атома. Атом зберігається у вигляді 1-байтового беззнакового цілого числа в big-endian порядку, яким задається довжина, за ним слідують N чисел — 8-бітних Latin-1 знаків (Characters), які є ім'ям атома. Максимально дозволене значення довжини є 16.

1 1 N 115 N Characters

116

Кодування мапи (map). Поле N — беззнакове 4-байтне ціле число в big-endian форматі, означає кількість пар "ключ-значення" в map. Пари "ключ-значення" (Ki => Vi) кодуються у секції Пари (Pairs) в наступному порядку: K1, V1, K2, V2,..., Kn, Vn. Дублікати ключів не дозволені в одній і тій же map. Вимагає OTP 17.

1 4 N 116 N K1,V1,K2,V2,...

118

Кодування UTF8 атома. Атом зберігається у вигляді 2-байтового беззнакового цілого числа в big-endian порядку, яким задається довжина, за ним слідують N байтів — закодовані в UTF-8 символи (Characters), які є ім'ям атома.

1 2 N 118 N Characters

119

Кодування малого UTF8 атома. Атом зберігається у вигляді 1-байтового беззнакового цілого числа, яким задається довжина, за ним слідують N байтів — закодовані в UTF-8 символи (Characters), які є ім'ям атома. Довші атоми, закодовані в UTF-8, можна представити за допомогою 118.

1 1 N 119 N Characters

API

enc(json)

Кодує внутрішній JSON в двійковий буфер.

> enc({t: 119, v: "日本"}) Uint8Array([131,119,6,230,151,165,230,156,172])

dec(buffer)

Декодує двійковий буфер у внутрішній JSON.

> dec((new Uint8Array([131,119,6,230,151,165,230,156,172])).buffer) {t: 119, v: "日本"}

bin(x)

> dec(enc(bin('N2O,')).buffer)) {t: 109, v: "N2O,"} [131,109,0,0,0,4,78,50,79,44]

Створює JSON для двійкового кодування.

atom(x)

Створює JSON для кодування Latin-1 атома.

> dec(enc(atom('ok')).buffer)) {t: 100, v: "ok"} [131,100,0,2,111,107]

string(x)

Створює JSON для кодування строки.

> dec(enc(string('ok')).buffer)) {t: 107, v: "ok"} [131,107,0,2,111,107]

float(x)

Створює JSON для кодування числа з плаваючою точкою IEEE-754.

> dec(enc(float('123.13')).buffer) {t: 70, v: 123.13} [131,70,64,94,200,81,235,133,30,184]

number(x)

Створює JSON для кодування цілих чисел та великих чисел GMP.

> dec(enc(number('1')).buffer) {t: 97, v: 1} [131,97,1] > dec(enc(number('100000000')).buffer) {t: 98, v: 100000000} [131,98,5,245,225,0] > dec(enc(number('10000000000000000000000')).buffer) {t: 110, v: 1e+22} [131,110,10,0,0,0,64,178,186,201,224,25,30,2]

list(x,...)

Створює JSON для кодування списку.

> dec(enc(list(atom('1'),number('1'),bin('1'))).buffer) {t: 108, v: [{t: 100, v: "1"}, {t: 97, v: 1}, {t: 109, v: "1"}]} [131,108,0,0,0,3,100,0,1,49,97,1,109,0,0,0,1,49,106]

tuple(x,...)

Створює JSON для кодування кортежу.

> dec(enc(tuple(atom('1'),number('1'),bin('1'))).buffer) {t: 104, v: [{t: 100, v: "1"}, {t: 97, v: 1}, {t: 109, v: "1"}]} [131,104,3,100,0,1,49,97,1,109,0,0,0,1,49]

map(x,...)

Створює JSON для кодування мапи.

> dec(enc(map( {k:bin('rent'),v:float(1.2)}, {k:atom('ok'), v:list(number(1),float(1.0),bin('1'))})).buffer) {t:116, v:[{k:{t:109,v:"rent"},v:{t:70, v:1.2}}, {k:{t:100,v:"ok"}, v:{t:108,v:[{t:97, v:1}, {t:70, v:1}, {t:109,v:"1"}]}}]} [131,116,0,0,0,2,109,0,0,0,4,114,101,110, 116,70,63,243,51,51,51,51,51,51,100,0,2, 111,107,108,0,0,0,3,97,1,70,63,240,0,0,0, 0,0,0,109,0,0,0,1,49,106]

Можливо, Ви також бажаєте почитати про: utf8.js, ieee754.js, heart.js, nitro.js, mq.js, n2o.js.