encode.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import Long from 'long'
  2. /**
  3. * 将某个订阅商品转为二进制
  4. * @param param SubscribeInfoType
  5. * @returns {Uint8Array}
  6. */
  7. function subscribeInfoToByteArrary(param: Proto.GoodsQuoteReq): Uint8Array {
  8. const { subState, exchangeCode, goodsCode } = param;
  9. const dataArray = new Uint8Array(66);
  10. dataArray[0] = subState;
  11. dataArray[1] = exchangeCode ? exchangeCode : 250;
  12. // 不足64byte需要补足
  13. const a = stringToByteArray(goodsCode, false);
  14. if (a.length <= 64) {
  15. const b = new Uint8Array(64);
  16. b.set(a);
  17. dataArray.set(b, 2);
  18. } else {
  19. // 此处有疑问,超了未做处理,
  20. console.warn(`goodsCode:${goodsCode} 转化为二进制后长度超过了 64位`);
  21. return new Uint8Array();
  22. }
  23. return dataArray;
  24. }
  25. /**
  26. * 将字符串转化为二进制数组的方法
  27. * value 字符串
  28. * islittleEndian 是否小端
  29. * @returns {Uint8Array}
  30. */
  31. function stringToByteArray(value: string, isLittleEndian: boolean): Uint8Array {
  32. const buf = [];
  33. let offset = 0;
  34. for (let i = 0; i < value.length; i++) {
  35. if (value.charCodeAt(i) > 255) {
  36. const tmp = uIntToByteArray(value.charCodeAt(i), isLittleEndian, 2);
  37. buf[i + offset] = tmp[0];
  38. buf[i + offset + 1] = tmp[1];
  39. offset++;
  40. } else {
  41. buf[i + offset] = value.charCodeAt(i);
  42. }
  43. }
  44. return new Uint8Array(buf);
  45. }
  46. /**
  47. * 将无符号整型数值型转化为二进制数组的方法
  48. * value 无符号整型数值
  49. * isLittleEndian 是否小端
  50. * length 长度
  51. * * @returns {Uint8Array}
  52. */
  53. function uIntToByteArray(value: number, isLittleEndian: boolean, length: number): Uint8Array {
  54. const dataView = new DataView(new Uint8Array(length).buffer);
  55. switch (length) {
  56. case 2:
  57. dataView.setUint16(0, value, isLittleEndian);
  58. break;
  59. case 4:
  60. dataView.setUint32(0, value, isLittleEndian);
  61. break;
  62. case 8:
  63. dataView.setFloat64(0, value, isLittleEndian);
  64. break;
  65. default:
  66. // 此处暂时返回空的 Uint8Array , 是否做异常处理,遇到情况再说
  67. console.warn('将无符号整型数值型转化为二进制数组传入的 【length】 不匹配');
  68. return new Uint8Array();
  69. }
  70. const array = new Uint8Array(dataView.buffer);
  71. return array;
  72. }
  73. /**
  74. * 将订阅商品列表转为二进制数组
  75. * @param arr 订阅商品列表
  76. * @param token
  77. * @param loginId 登录id
  78. */
  79. export function subscribeListToByteArrary(arr: Proto.GoodsQuoteReq[], token: string, loginId: Long): Uint8Array {
  80. const count = arr.length;
  81. const dataArray = new Uint8Array(76 + 66 * count);
  82. // 处理登录账号id
  83. let postion = 0;
  84. dataArray.set(loginId.toBytes(false), postion);
  85. // 处理 token
  86. postion += 8;
  87. // Token,不足64byte需要补足
  88. const a = stringToByteArray(token, false);
  89. if (a.length <= 64) {
  90. const b = new Uint8Array(64);
  91. b.set(a);
  92. dataArray.set(b, postion);
  93. } else {
  94. // 此处有疑问,超了未做处理,
  95. console.warn('【token】 转化为二进制后长度超过了 64位');
  96. // return null;
  97. }
  98. // 处理 条数
  99. postion += 64;
  100. const coutTemp = uIntToByteArray(count, false, 4);
  101. dataArray.set(coutTemp, postion);
  102. postion += 4;
  103. // 处理 订阅的商品
  104. for (let i = 0; i < count; i++) {
  105. const item = subscribeInfoToByteArrary(arr[i]);
  106. dataArray.set(item, postion);
  107. postion += 66;
  108. }
  109. return dataArray;
  110. }