Files
snort/packages/system/src/negentropy/utils.ts
2024-01-25 15:21:42 +00:00

84 lines
1.8 KiB
TypeScript

import { VectorStorageItem } from "./vector-storage";
import { WrappedBuffer } from "./wrapped-buffer";
export const PROTOCOL_VERSION = 0x61; // Version 1
export const FINGERPRINT_SIZE = 16;
export const enum Mode {
Skip = 0,
Fingerprint = 1,
IdList = 2,
}
/**
* Decode variable int, also consumes the bytes from buf
*/
export function decodeVarInt(buf: Uint8Array | WrappedBuffer) {
let res = 0;
while (1) {
if (buf.length === 0) throw Error("parse ends prematurely");
let byte = 0;
if (buf instanceof WrappedBuffer) {
byte = buf.shift();
} else {
byte = buf[0];
buf = buf.subarray(1);
}
res = (res << 7) | (byte & 127);
if ((byte & 128) === 0) break;
}
return res;
}
export function encodeVarInt(n: number) {
if (n === 0) return new Uint8Array([0]);
let o = [];
while (n !== 0) {
o.push(n & 127);
n >>>= 7;
}
o.reverse();
for (let i = 0; i < o.length - 1; i++) o[i] |= 128;
return new Uint8Array(o);
}
export function getByte(buf: WrappedBuffer) {
return getBytes(buf, 1)[0];
}
export function getBytes(buf: WrappedBuffer | Uint8Array, n: number) {
if (buf.length < n) throw Error("parse ends prematurely");
if (buf instanceof WrappedBuffer) {
return buf.shiftN(n);
} else {
const ret = buf.subarray(0, n);
buf = buf.subarray(n);
return ret;
}
}
export function compareUint8Array(a: Uint8Array, b: Uint8Array) {
for (let i = 0; i < a.byteLength; i++) {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
}
if (a.byteLength > b.byteLength) return 1;
if (a.byteLength < b.byteLength) return -1;
return 0;
}
export function itemCompare(a: VectorStorageItem, b: VectorStorageItem) {
if (a.timestamp === b.timestamp) {
return compareUint8Array(a.id, b.id);
}
return a.timestamp - b.timestamp;
}