Merge pull request #626 from triska/compact_crypto

ENHANCED: library(crypto): Retain the compact representation of strings.
This commit is contained in:
Mark Thom
2020-07-12 12:17:58 -03:00
committed by GitHub
4 changed files with 119 additions and 85 deletions

View File

@@ -445,10 +445,11 @@ The modules that ship with Scryer Prolog are also called
* [`os`](src/lib/os.pl) * [`os`](src/lib/os.pl)
Predicates for reasoning about environment variables. Predicates for reasoning about environment variables.
* [`crypto`](src/lib/crypto.pl) * [`crypto`](src/lib/crypto.pl)
Cryptographically secure random numbers and hashes, HMAC-based Cryptographically secure random numbers and hashes, HMAC-based key
key derivation (HKDF), password-based key derivation (PBKDF2), derivation (HKDF), password-based key derivation (PBKDF2),
public key signatures and signature verification with Ed25519, public key signatures and signature verification with Ed25519,
authenticated encryption, and reasoning about elliptic curves. authenticated symmetric encryption with ChaCha20-Poly1305, and
reasoning about elliptic curves.
To use predicates provided by the `lists` library, write: To use predicates provided by the `lists` library, write:

View File

@@ -688,16 +688,16 @@ impl SystemClauseType {
("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars), ("$write_term_to_chars", 7) => Some(SystemClauseType::WriteTermToChars),
("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion), ("$scryer_prolog_version", 1) => Some(SystemClauseType::ScryerPrologVersion),
("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte), ("$crypto_random_byte", 1) => Some(SystemClauseType::CryptoRandomByte),
("$crypto_data_hash", 3) => Some(SystemClauseType::CryptoDataHash), ("$crypto_data_hash", 4) => Some(SystemClauseType::CryptoDataHash),
("$crypto_data_hkdf", 6) => Some(SystemClauseType::CryptoDataHKDF), ("$crypto_data_hkdf", 7) => Some(SystemClauseType::CryptoDataHKDF),
("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash), ("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash),
("$crypto_data_encrypt", 5) => Some(SystemClauseType::CryptoDataEncrypt), ("$crypto_data_encrypt", 6) => Some(SystemClauseType::CryptoDataEncrypt),
("$crypto_data_decrypt", 5) => Some(SystemClauseType::CryptoDataDecrypt), ("$crypto_data_decrypt", 6) => Some(SystemClauseType::CryptoDataDecrypt),
("$crypto_curve_scalar_mult", 5) => Some(SystemClauseType::CryptoCurveScalarMult), ("$crypto_curve_scalar_mult", 5) => Some(SystemClauseType::CryptoCurveScalarMult),
("$ed25519_sign", 3) => Some(SystemClauseType::Ed25519Sign), ("$ed25519_sign", 5) => Some(SystemClauseType::Ed25519Sign),
("$ed25519_verify", 3) => Some(SystemClauseType::Ed25519Verify), ("$ed25519_verify", 5) => Some(SystemClauseType::Ed25519Verify),
("$ed25519_new_keypair", 1) => Some(SystemClauseType::Ed25519NewKeyPair), ("$ed25519_new_keypair", 1) => Some(SystemClauseType::Ed25519NewKeyPair),
("$ed25519_keypair_public_key", 2) => Some(SystemClauseType::Ed25519KeyPairPublicKey), ("$ed25519_keypair_public_key", 3) => Some(SystemClauseType::Ed25519KeyPairPublicKey),
("$load_html", 3) => Some(SystemClauseType::LoadHTML), ("$load_html", 3) => Some(SystemClauseType::LoadHTML),
("$load_xml", 3) => Some(SystemClauseType::LoadXML), ("$load_xml", 3) => Some(SystemClauseType::LoadXML),
("$getenv", 2) => Some(SystemClauseType::GetEnv), ("$getenv", 2) => Some(SystemClauseType::GetEnv),

View File

@@ -76,13 +76,13 @@ hex_bytes([]) --> [].
hex_bytes([H1,H2|Hs]) --> [Byte], hex_bytes([H1,H2|Hs]) --> [Byte],
{ char_hexval(H1, High), { char_hexval(H1, High),
char_hexval(H2, Low), char_hexval(H2, Low),
Byte is High*16 + Low }, Byte #= High*16 + Low },
hex_bytes(Hs). hex_bytes(Hs).
bytes_hex([]) --> []. bytes_hex([]) --> [].
bytes_hex([B|Bs]) --> [C0,C1], bytes_hex([B|Bs]) --> [C0,C1],
{ High is B>>4, { High #= B>>4,
Low is B /\ 0xf, Low #= B /\ 0xf,
char_hexval(C0, High), char_hexval(C0, High),
char_hexval(C1, Low) char_hexval(C1, Low)
}, },
@@ -101,6 +101,16 @@ must_be_bytes(Bytes, Context) :-
). ).
must_be_byte_chars(Chars, Context) :-
must_be(list, Chars),
( member(Char, Chars),
char_code(Char, Code),
\+ between(0, 255, Code) ->
domain_error(byte_char, Char, Context)
; true
).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cryptographically secure random numbers Cryptographically secure random numbers
======================================= =======================================
@@ -191,18 +201,18 @@ crypto_random_byte(B) :- '$crypto_random_byte'(B).
crypto_data_hash(Data0, Hash, Options0) :- crypto_data_hash(Data0, Hash, Options0) :-
must_be(list, Options0), must_be(list, Options0),
options_data_bytes(Options0, Data0, Data), options_data_chars(Options0, Data0, Data, Encoding),
functor_hash_options(algorithm, A, Options0, _), functor_hash_options(algorithm, A, Options0, _),
( hash_algorithm(A) -> true ( hash_algorithm(A) -> true
; domain_error(hash_algorithm, A, crypto_data_hash/3) ; domain_error(hash_algorithm, A, crypto_data_hash/3)
), ),
'$crypto_data_hash'(Data, HashBytes, A), '$crypto_data_hash'(Data, Encoding, HashBytes, A),
hex_bytes(Hash, HashBytes). hex_bytes(Hash, HashBytes).
options_data_bytes(Options, Data, Bytes) :- options_data_chars(Options, Data, Chars, Encoding) :-
option(encoding(Encoding), Options, utf8), option(encoding(Encoding), Options, utf8),
must_be(atom, Encoding), must_be(atom, Encoding),
encoding_bytes(Encoding, Data, Bytes). encoding_chars(Encoding, Data, Chars).
default_hash(sha256). default_hash(sha256).
@@ -270,12 +280,12 @@ crypto_data_hkdf(Data0, L, Bytes, Options0) :-
), ),
must_be(integer, L), must_be(integer, L),
L >= 0, L >= 0,
options_data_bytes(Options, Data0, Data), options_data_chars(Options, Data0, Data, Encoding),
option(salt(SaltBytes), Options, []), option(salt(SaltBytes), Options, []),
must_be_bytes(SaltBytes, crypto_data_hkdf/4), must_be_bytes(SaltBytes, crypto_data_hkdf/4),
option(info(Info0), Options, []), option(info(Info0), Options, []),
chars_bytes_(Info0, Info, crypto_data_hkdf/4), chars_bytes_(Info0, Info, crypto_data_hkdf/4),
'$crypto_data_hkdf'(Data, SaltBytes, Info, Algorithm, L, Bytes). '$crypto_data_hkdf'(Data, Encoding, SaltBytes, Info, Algorithm, L, Bytes).
hkdf_algorithm(sha256). hkdf_algorithm(sha256).
hkdf_algorithm(sha384). hkdf_algorithm(sha384).
@@ -558,7 +568,7 @@ bytes_base64_([A,B,C|Ls]) --> [W,X,Y,Z],
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :- crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
options_data_bytes(Options, PlainText0, PlainText), options_data_chars(Options, PlainText0, PlainText, Encoding),
option(tag(Tag), Options, _), option(tag(Tag), Options, _),
( nonvar(Tag) -> ( nonvar(Tag) ->
must_be_bytes(Tag, crypto_data_encrypt/6) must_be_bytes(Tag, crypto_data_encrypt/6)
@@ -570,7 +580,7 @@ crypto_data_encrypt(PlainText0, Algorithm, Key, IV, CipherText, Options) :-
( Algorithm = 'chacha20-poly1305' -> true ( Algorithm = 'chacha20-poly1305' -> true
; domain_error('chacha20-poly1305', Algorithm, crypto_data_encrypt/6) ; domain_error('chacha20-poly1305', Algorithm, crypto_data_encrypt/6)
), ),
'$crypto_data_encrypt'(PlainText, Key, IV, Tag, CipherText). '$crypto_data_encrypt'(PlainText, Encoding, Key, IV, Tag, CipherText).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
crypto_data_decrypt(+CipherText, crypto_data_decrypt(+CipherText,
@@ -610,26 +620,25 @@ crypto_data_decrypt(CipherText0, Algorithm, Key, IV, PlainText, Options) :-
must_be(atom, Encoding), must_be(atom, Encoding),
member(Encoding, [utf8,octet]), member(Encoding, [utf8,octet]),
must_be(list, CipherText0), must_be(list, CipherText0),
encoding_bytes(octet, CipherText0, CipherText1), encoding_chars(octet, CipherText0, CipherText1),
append(CipherText1, Tag, CipherText), maplist(char_code, TagChars, Tag),
append(CipherText1, TagChars, CipherText),
( Algorithm = 'chacha20-poly1305' -> true ( Algorithm = 'chacha20-poly1305' -> true
; domain_error('chacha20-poly1305', Algorithm, crypto_data_decrypt/6) ; domain_error('chacha20-poly1305', Algorithm, crypto_data_decrypt/6)
), ),
'$crypto_data_decrypt'(CipherText, Key, IV, Encoding, PlainText). '$crypto_data_decrypt'(CipherText, octet, Key, IV, Encoding, PlainText).
encoding_bytes(octet, Bs0, Bs) :-
must_be(list, Bs0), encoding_chars(octet, Bs, Cs) :-
( maplist(integer, Bs0) -> must_be(list, Bs),
Bs0 = Bs ( maplist(integer, Bs) ->
; maplist(char_code, Bs0, Bs) maplist(char_code, Cs, Bs)
; Bs = Cs
), ),
must_be_bytes(Bs, crypto_encoding). must_be_byte_chars(Cs, crypto_encoding).
encoding_bytes(utf8, Cs, Bs) :- encoding_chars(utf8, Cs, Cs) :-
must_be(list, Cs), must_be(list, Cs),
( maplist(atom, Cs) -> maplist(must_be(character), Cs).
chars_bytes_(Cs, Bs, crypto_encoding)
; domain_error(encryption_encoding, Cs, crypto)
).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Digital signatures with Ed25519 Digital signatures with Ed25519
@@ -667,21 +676,21 @@ encoding_bytes(utf8, Cs, Bs) :-
ed25519_new_keypair(Pair) :- ed25519_new_keypair(Pair) :-
'$ed25519_new_keypair'(Pair). '$ed25519_new_keypair'(Pair).
ed25519_keypair_public_key(Pair0, PublicKey) :- ed25519_keypair_public_key(Pair, PublicKey) :-
encoding_bytes(octet, Pair0, Pair), must_be_byte_chars(Pair, ed25519_keypair_public_key),
'$ed25519_keypair_public_key'(Pair, PublicKey). '$ed25519_keypair_public_key'(Pair, octet, PublicKey).
ed25519_sign(Key0, Data0, Signature, Options) :- ed25519_sign(Key, Data0, Signature, Options) :-
options_data_bytes(Options, Data0, Data), must_be_byte_chars(Key, ed25519_sign),
encoding_bytes(octet, Key0, Key), options_data_chars(Options, Data0, Data, Encoding),
'$ed25519_sign'(Key, Data, Signature0), '$ed25519_sign'(Key, octet, Data, Encoding, Signature0),
hex_bytes(Signature, Signature0). hex_bytes(Signature, Signature0).
ed25519_verify(Key0, Data0, Signature0, Options) :- ed25519_verify(Key, Data0, Signature0, Options) :-
options_data_bytes(Options, Data0, Data), must_be_byte_chars(Key, ed25519_verify),
encoding_bytes(octet, Key0, Key), options_data_chars(Options, Data0, Data, Encoding),
hex_bytes(Signature0, Signature), hex_bytes(Signature0, Signature),
'$ed25519_verify'(Key, Data, Signature). '$ed25519_verify'(Key, octet, Data, Encoding, Signature).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operations on Elliptic Curves Operations on Elliptic Curves

View File

@@ -5291,11 +5291,9 @@ impl MachineState {
self.unify(arg, byte); self.unify(arg, byte);
} }
&SystemClauseType::CryptoDataHash => { &SystemClauseType::CryptoDataHash => {
let stub = MachineError::functor_stub(clause_name!("crypto_data_hash"), 3); let bytes = self.string_encoding_bytes(1, 2);
let bytes = self.integers_to_bytevec(temp_v!(1), stub);
let algorithm = self[temp_v!(3)]; let algorithm_str = match self.store(self.deref(self[temp_v!(4)])) {
let algorithm_str = match self.store(self.deref(algorithm)) {
Addr::Con(h) if self.heap.atom_at(h) => { Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] { if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str() atom.as_str()
@@ -5344,17 +5342,16 @@ impl MachineState {
} }
}; };
self.unify(self[temp_v!(2)], ints_list); self.unify(self[temp_v!(3)], ints_list);
} }
&SystemClauseType::CryptoDataHKDF => { &SystemClauseType::CryptoDataHKDF => {
let data = self.string_encoding_bytes(1, 2);
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4); let stub1 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
let data = self.integers_to_bytevec(temp_v!(1), stub1); let salt = self.integers_to_bytevec(temp_v!(3), stub1);
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4); let stub2 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
let salt = self.integers_to_bytevec(temp_v!(2), stub2); let info = self.integers_to_bytevec(temp_v!(4), stub2);
let stub3 = MachineError::functor_stub(clause_name!("crypto_data_hkdf"), 4);
let info = self.integers_to_bytevec(temp_v!(3), stub3);
let algorithm = match self.store(self.deref(self[temp_v!(4)])) { let algorithm = match self.store(self.deref(self[temp_v!(5)])) {
Addr::Con(h) if self.heap.atom_at(h) => { Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] { if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str() atom.as_str()
@@ -5368,7 +5365,7 @@ impl MachineState {
}; };
let length = let length =
match Number::try_from((self[temp_v!(5)], &self.heap)) { match Number::try_from((self[temp_v!(6)], &self.heap)) {
Ok(Number::Fixnum(n)) => { Ok(Number::Fixnum(n)) => {
usize::try_from(n).unwrap() usize::try_from(n).unwrap()
} }
@@ -5400,7 +5397,7 @@ impl MachineState {
Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))) Addr::HeapCell(self.heap.to_list(bytes.iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))))
}; };
self.unify(self[temp_v!(6)], ints_list); self.unify(self[temp_v!(7)], ints_list);
} }
&SystemClauseType::CryptoPasswordHash => { &SystemClauseType::CryptoPasswordHash => {
let stub1 = MachineError::functor_stub(clause_name!("crypto_password_hash"), 3); let stub1 = MachineError::functor_stub(clause_name!("crypto_password_hash"), 3);
@@ -5436,12 +5433,11 @@ impl MachineState {
self.unify(self[temp_v!(4)], ints_list); self.unify(self[temp_v!(4)], ints_list);
} }
&SystemClauseType::CryptoDataEncrypt => { &SystemClauseType::CryptoDataEncrypt => {
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6); let data = self.string_encoding_bytes(1, 2);
let data = self.integers_to_bytevec(temp_v!(1), stub1);
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6); let stub2 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
let key = self.integers_to_bytevec(temp_v!(2), stub2); let key = self.integers_to_bytevec(temp_v!(3), stub2);
let stub3 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6); let stub3 = MachineError::functor_stub(clause_name!("crypto_data_encrypt"), 6);
let iv = self.integers_to_bytevec(temp_v!(3), stub3); let iv = self.integers_to_bytevec(temp_v!(4), stub3);
let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &key).unwrap(); let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &key).unwrap();
let nonce = aead::Nonce::try_assume_unique_for_key(&iv).unwrap(); let nonce = aead::Nonce::try_assume_unique_for_key(&iv).unwrap();
@@ -5462,18 +5458,17 @@ impl MachineState {
self.heap.put_complete_string(&buffer) self.heap.put_complete_string(&buffer)
}; };
self.unify(self[temp_v!(4)], tag_list); self.unify(self[temp_v!(5)], tag_list);
self.unify(self[temp_v!(5)], complete_string); self.unify(self[temp_v!(6)], complete_string);
} }
&SystemClauseType::CryptoDataDecrypt => { &SystemClauseType::CryptoDataDecrypt => {
let data = self.string_encoding_bytes(1, 2);
let stub1 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6); let stub1 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
let data = self.integers_to_bytevec(temp_v!(1), stub1); let key = self.integers_to_bytevec(temp_v!(3), stub1);
let stub2 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6); let stub2 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
let key = self.integers_to_bytevec(temp_v!(2), stub2); let iv = self.integers_to_bytevec(temp_v!(4), stub2);
let stub3 = MachineError::functor_stub(clause_name!("crypto_data_decrypt"), 6);
let iv = self.integers_to_bytevec(temp_v!(3), stub3);
let encoding = match self.store(self.deref(self[temp_v!(4)])) { let encoding = match self.store(self.deref(self[temp_v!(5)])) {
Addr::Con(h) if self.heap.atom_at(h) => { Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] { if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str() atom.as_str()
@@ -5512,7 +5507,7 @@ impl MachineState {
self.heap.put_complete_string(&buffer) self.heap.put_complete_string(&buffer)
}; };
self.unify(self[temp_v!(5)], complete_string); self.unify(self[temp_v!(6)], complete_string);
} }
&SystemClauseType::CryptoCurveScalarMult => { &SystemClauseType::CryptoCurveScalarMult => {
let curve = match self.store(self.deref(self[temp_v!(1)])) { let curve = match self.store(self.deref(self[temp_v!(1)])) {
@@ -5573,8 +5568,7 @@ impl MachineState {
self.unify(self[temp_v!(1)], complete_string); self.unify(self[temp_v!(1)], complete_string);
} }
&SystemClauseType::Ed25519KeyPairPublicKey => { &SystemClauseType::Ed25519KeyPairPublicKey => {
let stub1 = MachineError::functor_stub(clause_name!("ed25519_keypair_public_key"), 2); let bytes = self.string_encoding_bytes(1, 2);
let bytes = self.integers_to_bytevec(temp_v!(1), stub1);
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&bytes) { let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&bytes) {
Ok(kp) => { kp } Ok(kp) => { kp }
@@ -5586,13 +5580,11 @@ impl MachineState {
self.heap.put_complete_string(&buffer) self.heap.put_complete_string(&buffer)
}; };
self.unify(self[temp_v!(2)], complete_string); self.unify(self[temp_v!(3)], complete_string);
} }
&SystemClauseType::Ed25519Sign => { &SystemClauseType::Ed25519Sign => {
let stub1 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4); let key = self.string_encoding_bytes(1, 2);
let key = self.integers_to_bytevec(temp_v!(1), stub1); let data = self.string_encoding_bytes(3, 4);
let stub2 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
let data = self.integers_to_bytevec(temp_v!(2), stub2);
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&key) { let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&key) {
Ok(kp) => { kp } Ok(kp) => { kp }
@@ -5604,15 +5596,13 @@ impl MachineState {
let sig_list = let sig_list =
Addr::HeapCell(self.heap.to_list(sig.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize))))); Addr::HeapCell(self.heap.to_list(sig.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))));
self.unify(self[temp_v!(3)], sig_list); self.unify(self[temp_v!(5)], sig_list);
} }
&SystemClauseType::Ed25519Verify => { &SystemClauseType::Ed25519Verify => {
let stub1 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4); let key = self.string_encoding_bytes(1, 2);
let key = self.integers_to_bytevec(temp_v!(1), stub1); let data = self.string_encoding_bytes(3, 4);
let stub2 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4); let stub = MachineError::functor_stub(clause_name!("ed25519_verify"), 5);
let data = self.integers_to_bytevec(temp_v!(2), stub2); let signature = self.integers_to_bytevec(temp_v!(5), stub);
let stub3 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
let signature = self.integers_to_bytevec(temp_v!(3), stub3);
let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key); let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key);
match peer_public_key.verify(&data, &signature) { match peer_public_key.verify(&data, &signature) {
@@ -5665,6 +5655,40 @@ impl MachineState {
return_from_clause!(self.last_call, self) return_from_clause!(self.last_call, self)
} }
pub(super)
fn string_encoding_bytes(
&mut self,
data_arg: usize,
encoding_arg: usize,
) -> Vec<u8> {
let data = self.heap_pstr_iter(self[temp_v!(data_arg)]).to_string();
let encoding_str = match self.store(self.deref(self[temp_v!(encoding_arg)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str()
} else {
unreachable!()
}
}
_ => {
unreachable!()
}
};
match encoding_str {
"utf8" => { data.into_bytes() }
"octet" => {
let mut buf = vec![];
for c in data.chars() {
buf.push(c as u8);
}
buf
}
_ => { unreachable!() }
}
}
pub(super) pub(super)
fn xml_node_to_term( fn xml_node_to_term(
&mut self, &mut self,