* [jsfm] support to pass buffer between js and native
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/5b7aae05 Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/5b7aae05 Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/5b7aae05 Branch: refs/heads/0.16-dev Commit: 5b7aae05760943ebeb549861f2641ddea12d28e0 Parents: 85e32df Author: Hanks <zhanghan...@gmail.com> Authored: Wed Aug 2 15:55:05 2017 +0800 Committer: Hanks <zhanghan...@gmail.com> Committed: Wed Aug 2 15:55:05 2017 +0800 ---------------------------------------------------------------------- html5/runtime/callback-manager.js | 4 ++- html5/runtime/normalize.js | 54 ++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/5b7aae05/html5/runtime/callback-manager.js ---------------------------------------------------------------------- diff --git a/html5/runtime/callback-manager.js b/html5/runtime/callback-manager.js index 84a40f2..058fcc0 100644 --- a/html5/runtime/callback-manager.js +++ b/html5/runtime/callback-manager.js @@ -17,6 +17,8 @@ * under the License. */ +import { decodePrimitive } from './normalize' + /** * For general callback management of a certain Weex instance. * Because function can not passed into native, so we create callback @@ -46,7 +48,7 @@ export default class CallbackManager { delete this.callbacks[callbackId] } if (typeof callback === 'function') { - return callback(data) + return callback(decodePrimitive(data)) } return new Error(`invalid callback id "${callbackId}"`) } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/5b7aae05/html5/runtime/normalize.js ---------------------------------------------------------------------- diff --git a/html5/runtime/normalize.js b/html5/runtime/normalize.js index 3d9ad0b..f1e93b8 100644 --- a/html5/runtime/normalize.js +++ b/html5/runtime/normalize.js @@ -3,6 +3,29 @@ export function typof (v) { return s.substring(8, s.length - 1) } +export function bufferToBase64 (buffer) { + if (typeof btoa !== 'function') { + return '' + } + const string = Array.prototype.map.call( + new Uint8Array(buffer), + code => String.fromCharCode(code) + ).join('') + return btoa(string) // eslint-disable-line no-undef +} + +export function base64ToBuffer (base64) { + if (typeof atob !== 'function') { + return new ArrayBuffer(0) + } + const string = atob(base64) // eslint-disable-line no-undef + const array = new Uint8Array(string.length) + Array.prototype.forEach.call(string, (ch, i) => { + array[i] = ch.charCodeAt(0) + }) + return array.buffer +} + /** * Normalize a primitive value. * @param {any} v @@ -29,7 +52,11 @@ export function normalizePrimitive (v) { return v case 'ArrayBuffer': - return { type, buffer: v } + return { + '@type': 'binary', + dataType: type, + base64: bufferToBase64(v) + } case 'Int8Array': case 'Uint8Array': @@ -40,9 +67,32 @@ export function normalizePrimitive (v) { case 'Uint32Array': case 'Float32Array': case 'Float64Array': - return { type, buffer: v.buffer } + return { + '@type': 'binary', + dataType: type, + base64: bufferToBase64(v.buffer) + } default: return JSON.stringify(v) } } + +export function decodePrimitive (data) { + if (typof(data) === 'Object') { + // decode base64 into binary + if (data['@type'] && data['@type'] === 'binary') { + return base64ToBuffer(data.base64 || '') + } + + const realData = {} + for (const key in data) { + realData[key] = decodePrimitive(data[key]) + } + return realData + } + if (typof(data) === 'Array') { + return data.map(decodePrimitive) + } + return data +}