加载中…
个人资料
JAROD_姜赫
JAROD_姜赫
  • 博客等级:
  • 博客积分:0
  • 博客访问:3,180
  • 关注人气:11
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

unit8array格式与string之间的相互转化

(2017-12-19 18:43:13)
分类: html5

为了调通这个功能,折腾了一个下午,

失败了不下50次。

最后,终于调通了。

客户端与服务器端,

传递信息,可以用 egret自带的 socket的 writeUTF,

最方便的方式,就是,

将 GPB encode 后的 unit8array 数据,转化为 string ,

之后,用egret提供的writeUTF,

互相之间,用字符串传递信息,

之后,彼此再将这个信息解析成 proto 对应的文件,

我从网上找到一个 将 unit8array 格式转化为 string 的方法,

那篇文章写的是转载,而且里面都是英文,估计是外国友人写的,

之后,又从  npm 上 install 了 fast-text-encoding模块,

提取了里面 string 转化为 unit8array 的函数,

两者结合,完成了这个工作。
下面是代码,(egret 端 typescript )

这个是 string 转化为 unit8array的函数


public stringToUint8Array(string, options={stream: false}) {
  if (options.stream) {
    throw new Error(`Failed to encode: the 'stream' option is unsupported.`);
  }

  let pos = 0;
  const len = string.length;
  const out = [];

  let at = 0;  // output position
  let tlen = Math.max(32, len + (len >> 1) + 7);  // 1.5x size
  let target = new Uint8Array((tlen >> 3) << 3);  // ... but at 8 byte offset

  while (pos < len) {
    let value = string.charCodeAt(pos++);
    if (value >= 0xd800 && value <= 0xdbff) {
      // high surrogate
      if (pos < len) {
        const extra = string.charCodeAt(pos);
        if ((extra & 0xfc00) === 0xdc00) {
          ++pos;
          value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
        }
      }
      if (value >= 0xd800 && value <= 0xdbff) {
        continue;  // drop lone surrogate
      }
    }

    // expand the buffer if we couldn't write 4 bytes
    if (at + 4 > target.length) {
      tlen += 8;  // minimum extra
      tlen *= (1.0 + (pos / string.length) * 2);  // take 2x the remaining
      tlen = (tlen >> 3) << 3;  // 8 byte offset

      const update = new Uint8Array(tlen);
      update.set(target);
      target = update;
    }

    if ((value & 0xffffff80) === 0) {  // 1-byte
      target[at++] = value;  // ASCII
      continue;
    } else if ((value & 0xfffff800) === 0) {  // 2-byte
      target[at++] = ((value >>  6) & 0x1f) | 0xc0;
    } else if ((value & 0xffff0000) === 0) {  // 3-byte
      target[at++] = ((value >> 12) & 0x0f) | 0xe0;
      target[at++] = ((value >>  6) & 0x3f) | 0x80;
    } else if ((value & 0xffe00000) === 0) {  // 4-byte
      target[at++] = ((value >> 18) & 0x07) | 0xf0;
      target[at++] = ((value >> 12) & 0x3f) | 0x80;
      target[at++] = ((value >>  6) & 0x3f) | 0x80;
    } else {
      // FIXME: do we care
      continue;
    }

    target[at++] = (value & 0x3f) | 0x80;
  }

  return target.slice(0, at);
}

接下来,是将 unit8array转化为 string的方法

public Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = array.length;
    i = 0;
    while(i < len) {
    c = array[i++];
    switch(c >> 4)
   
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
        // 0xxxxxxx
        out += String.fromCharCode(c);
        break;
      case 12: case 13:
        // 110x xxxx   10xx xxxx
        char2 = array[i++];
        out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
        break;
      case 14:
        // 1110 xxxx  10xx xxxx  10xx xxxx
        char2 = array[i++];
        char3 = array[i++];
        out += String.fromCharCode(((c & 0x0F) << 12) |
                       ((char2 & 0x3F) << 6) |
                       ((char3 & 0x3F) << 0));
        break;
    }
    }

    return out;
}

public largeuint8ArrToString(uint8arr, callback) {
    var bb = new Blob([uint8arr]);
    var f = new FileReader();
    f.onload = function(e) {
        callback(e.target);
    };
    
    f.readAsText(bb);
}

现在,客户端和服务器端,

就可以比较方便的沟通了。



0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有