[client-backup] implement C++ functions for encoding/decoding string in utf-8
Summary:
ENG-4503.
To encrypt/decrypt UserData we need to have it in bytes (Uint8Array in JS or uint8_t[] in C++). From JS level it's not that easy because standard TextEncoder from JS is not available in react-native, so we're using JSI capabilities to convert this.
Encoding can be done always - any UTF-8 string can be represented as ArrayBuffer.
Decoding can be done only if ArrayBuffer has valid code points, to make this check we use this fact: link.
Depends on D8887
Test Plan:
const str = '!ABC+** /==🤬'; const bytes = commUtilsModule.encodeStringToUTF8ArrayBuffer(str); const str2 = commUtilsModule.decodeUTF8ArrayBufferToString( new Uint8Array(bytes).buffer, ); console.log(str === str2); try { console.log( commUtilsModule.decodeUTF8ArrayBufferToString( new Uint8Array([72, 101, 108, 108, 111, 0x80]).buffer, ), ); } catch (e) { // should fail console.log(e); } try { console.log( commUtilsModule.decodeUTF8ArrayBufferToString( new Uint8Array([72, 101, 108, 0x80, 111, 111]).buffer, ), ); } catch (e) { // should fail console.log(e); } try { console.log( commUtilsModule.decodeUTF8ArrayBufferToString( new Uint8Array([0x80, 101, 108, 108, 111]).buffer, ), ); } catch (e) { // should fail console.log(e); } try { console.log( commUtilsModule.decodeUTF8ArrayBufferToString( new Uint8Array([72, 101, 108, 108, 111]).buffer, ), ); } catch (e) { // should work console.log(e); }
Reviewers: michal, marcin, bartek
Reviewed By: michal, marcin, bartek
Subscribers: ashoat, tomek
Differential Revision: https://phab.comm.dev/D8888