flatbuffers

Форк
0
/
reference-util.ts 
109 строк · 4.0 Кб
1
import { BitWidth } from './bit-width.js'
2
import { toByteWidth, fromByteWidth } from './bit-width-util.js'
3
import { toUTF8Array, fromUTF8Array } from './flexbuffers-util.js'
4

5
export function validateOffset(dataView: DataView, offset: number, width: number): void {
6
  if (dataView.byteLength <= offset + width || (offset & (toByteWidth(width) - 1)) !== 0) {
7
    throw "Bad offset: " + offset + ", width: " + width;
8
  }
9
}
10

11
export function readInt(dataView: DataView, offset: number, width: number): number | bigint {
12
  if (width < 2) {
13
    if (width < 1) {
14
      return dataView.getInt8(offset);
15
    } else {
16
      return dataView.getInt16(offset, true);
17
    }
18
  } else {
19
    if (width < 3) {
20
      return dataView.getInt32(offset, true)
21
    } else {
22
      if (dataView.setBigInt64 === undefined) {
23
        return BigInt(dataView.getUint32(offset, true)) + (BigInt(dataView.getUint32(offset + 4, true)) << BigInt(32));
24
      }
25
      return dataView.getBigInt64(offset, true)
26
    }
27
  }
28
}
29

30
export function readUInt(dataView: DataView, offset: number, width: number): number | bigint {
31
  if (width < 2) {
32
    if (width < 1) {
33
      return dataView.getUint8(offset);
34
    } else {
35
      return dataView.getUint16(offset, true);
36
    }
37
  } else {
38
    if (width < 3) {
39
      return dataView.getUint32(offset, true)
40
    } else {
41
      if (dataView.getBigUint64 === undefined) {
42
        return BigInt(dataView.getUint32(offset, true)) + (BigInt(dataView.getUint32(offset + 4, true)) << BigInt(32));
43
      }
44
      return dataView.getBigUint64(offset, true)
45
    }
46
  }
47
}
48

49
export function readFloat(dataView: DataView, offset: number, width: number): number {
50
  if (width < BitWidth.WIDTH32) {
51
    throw "Bad width: " + width;
52
  }
53
  if (width === BitWidth.WIDTH32) {
54
    return dataView.getFloat32(offset, true);
55
  }
56
  return dataView.getFloat64(offset, true);
57
}
58

59
export function indirect(dataView: DataView, offset: number, width: number): number {
60
  const step = readUInt(dataView, offset, width) as number;
61
  return offset - step;
62
}
63

64
export function keyIndex(key: string, dataView: DataView, offset: number, parentWidth: number, byteWidth: number, length: number): number | null {
65
  const input = toUTF8Array(key);
66
  const keysVectorOffset = indirect(dataView, offset, parentWidth) - byteWidth * 3;
67
  const bitWidth = fromByteWidth(byteWidth);
68
  const indirectOffset = keysVectorOffset - Number(readUInt(dataView, keysVectorOffset, bitWidth));
69
  const _byteWidth = Number(readUInt(dataView, keysVectorOffset + byteWidth, bitWidth));
70
  let low = 0;
71
  let high = length - 1;
72
  while (low <= high) {
73
    const mid = (high + low) >> 1;
74
    const dif = diffKeys(input, mid, dataView, indirectOffset, _byteWidth);
75
    if (dif === 0) return mid;
76
    if (dif < 0) {
77
      high = mid - 1;
78
    } else {
79
      low = mid + 1;
80
    }
81
  }
82
  return null;
83
}
84

85
export function diffKeys(input: Uint8Array, index: number, dataView: DataView, offset: number, width: number): number {
86
  const keyOffset = offset + index * width;
87
  const keyIndirectOffset = keyOffset - Number(readUInt(dataView, keyOffset, fromByteWidth(width)));
88
  for (let i = 0; i < input.length; i++) {
89
    const dif = input[i] - dataView.getUint8(keyIndirectOffset + i);
90
    if (dif !== 0) {
91
      return dif;
92
    }
93
  }
94
  return dataView.getUint8(keyIndirectOffset + input.length) === 0 ? 0 : -1;
95
}
96

97
export function keyForIndex(index: number, dataView: DataView, offset: number, parentWidth: number, byteWidth: number): string {
98
  const keysVectorOffset = indirect(dataView, offset, parentWidth) - byteWidth * 3;
99
  const bitWidth = fromByteWidth(byteWidth);
100
  const indirectOffset = keysVectorOffset - Number(readUInt(dataView, keysVectorOffset, bitWidth));
101
  const _byteWidth = Number(readUInt(dataView, keysVectorOffset + byteWidth, bitWidth));
102
  const keyOffset = indirectOffset + index * _byteWidth;
103
  const keyIndirectOffset = keyOffset - Number(readUInt(dataView, keyOffset, fromByteWidth(_byteWidth)));
104
  let length = 0;
105
  while (dataView.getUint8(keyIndirectOffset + length) !== 0) {
106
    length++;
107
  }
108
  return fromUTF8Array(new Uint8Array(dataView.buffer, keyIndirectOffset, length));
109
}
110

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.