mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 10:51:07 +00:00
v3 js: varint routines [#41]
This commit is contained in:
@@ -11,7 +11,13 @@ import {
|
|||||||
createDirectory,
|
createDirectory,
|
||||||
} from "./index";
|
} from "./index";
|
||||||
|
|
||||||
import { Entry as EntryV3, zxyToTileId, tileIdToZxy, findTile } from "./v3";
|
import {
|
||||||
|
Entry as EntryV3,
|
||||||
|
zxyToTileId,
|
||||||
|
tileIdToZxy,
|
||||||
|
findTile,
|
||||||
|
readVarint,
|
||||||
|
} from "./v3";
|
||||||
|
|
||||||
test("stub data", (assertion) => {
|
test("stub data", (assertion) => {
|
||||||
let dataview = createDirectory([
|
let dataview = createDirectory([
|
||||||
@@ -148,6 +154,22 @@ test("convert spec v1 directory to spec v2 directory", (assertion) => {
|
|||||||
assertion.ok(entry!.offset === 3);
|
assertion.ok(entry!.offset === 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("varint", (assertion) => {
|
||||||
|
let b: BufferPosition = {
|
||||||
|
buf: new Uint8Array([0, 1, 127, 0xe5, 0x8e, 0x26]),
|
||||||
|
pos: 0,
|
||||||
|
};
|
||||||
|
assertion.eq(readVarint(b), 0);
|
||||||
|
assertion.eq(readVarint(b), 1);
|
||||||
|
assertion.eq(readVarint(b), 127);
|
||||||
|
assertion.eq(readVarint(b), 624485);
|
||||||
|
b = {
|
||||||
|
buf: new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f]),
|
||||||
|
pos: 0,
|
||||||
|
};
|
||||||
|
assertion.eq(readVarint(b), 9007199254740991);
|
||||||
|
});
|
||||||
|
|
||||||
test("zxy to tile id", (assertion) => {
|
test("zxy to tile id", (assertion) => {
|
||||||
assertion.eq(zxyToTileId(0, 0, 0), 0);
|
assertion.eq(zxyToTileId(0, 0, 0), 0);
|
||||||
assertion.eq(zxyToTileId(1, 0, 0), 1);
|
assertion.eq(zxyToTileId(1, 0, 0), 1);
|
||||||
@@ -185,7 +207,9 @@ test("tile search for first entry == id", (assertion) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("tile search for first entry == id", (assertion) => {
|
test("tile search for first entry == id", (assertion) => {
|
||||||
let entries: EntryV3[] = [{ tileId: 100, offset: 1, length: 1, runLength: 1 }];
|
let entries: EntryV3[] = [
|
||||||
|
{ tileId: 100, offset: 1, length: 1, runLength: 1 },
|
||||||
|
];
|
||||||
let entry = findTile(entries, 100)!;
|
let entry = findTile(entries, 100)!;
|
||||||
assertion.eq(entry.offset, 1);
|
assertion.eq(entry.offset, 1);
|
||||||
assertion.eq(entry.length, 1);
|
assertion.eq(entry.length, 1);
|
||||||
@@ -193,7 +217,9 @@ test("tile search for first entry == id", (assertion) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("tile search for first entry == id", (assertion) => {
|
test("tile search for first entry == id", (assertion) => {
|
||||||
let entries: EntryV3[] = [{ tileId: 100, offset: 1, length: 1, runLength: 2 }];
|
let entries: EntryV3[] = [
|
||||||
|
{ tileId: 100, offset: 1, length: 1, runLength: 2 },
|
||||||
|
];
|
||||||
let entry = findTile(entries, 101)!;
|
let entry = findTile(entries, 101)!;
|
||||||
assertion.eq(entry.offset, 1);
|
assertion.eq(entry.offset, 1);
|
||||||
assertion.eq(entry.length, 1);
|
assertion.eq(entry.length, 1);
|
||||||
@@ -217,7 +243,9 @@ test("tile search for first entry == id", (assertion) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("leaf search", (assertion) => {
|
test("leaf search", (assertion) => {
|
||||||
let entries: EntryV3[] = [{ tileId: 100, offset: 1, length: 1, runLength: 0 }];
|
let entries: EntryV3[] = [
|
||||||
|
{ tileId: 100, offset: 1, length: 1, runLength: 0 },
|
||||||
|
];
|
||||||
let entry = findTile(entries, 150);
|
let entry = findTile(entries, 150);
|
||||||
assertion.eq(entry!.offset, 1);
|
assertion.eq(entry!.offset, 1);
|
||||||
assertion.eq(entry!.length, 1);
|
assertion.eq(entry!.length, 1);
|
||||||
|
|||||||
58
js/v3.ts
58
js/v3.ts
@@ -1,3 +1,60 @@
|
|||||||
|
interface BufferPosition {
|
||||||
|
buf: Uint8Array;
|
||||||
|
pos: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toNum(low: number, high: number): number {
|
||||||
|
return (high >>> 0) * 0x100000000 + (low >>> 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readVarintRemainder(l: number, p: BufferPosition): number {
|
||||||
|
var buf = p.buf,
|
||||||
|
h,
|
||||||
|
b;
|
||||||
|
b = buf[p.pos++];
|
||||||
|
h = (b & 0x70) >> 4;
|
||||||
|
if (b < 0x80) return toNum(l, h);
|
||||||
|
b = buf[p.pos++];
|
||||||
|
h |= (b & 0x7f) << 3;
|
||||||
|
if (b < 0x80) return toNum(l, h);
|
||||||
|
b = buf[p.pos++];
|
||||||
|
h |= (b & 0x7f) << 10;
|
||||||
|
if (b < 0x80) return toNum(l, h);
|
||||||
|
b = buf[p.pos++];
|
||||||
|
h |= (b & 0x7f) << 17;
|
||||||
|
if (b < 0x80) return toNum(l, h);
|
||||||
|
b = buf[p.pos++];
|
||||||
|
h |= (b & 0x7f) << 24;
|
||||||
|
if (b < 0x80) return toNum(l, h);
|
||||||
|
b = buf[p.pos++];
|
||||||
|
h |= (b & 0x01) << 31;
|
||||||
|
if (b < 0x80) return toNum(l, h);
|
||||||
|
throw new Error("Expected varint not more than 10 bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readVarint(p: BufferPosition): number {
|
||||||
|
var buf = p.buf,
|
||||||
|
val,
|
||||||
|
b;
|
||||||
|
|
||||||
|
b = buf[p.pos++];
|
||||||
|
val = b & 0x7f;
|
||||||
|
if (b < 0x80) return val;
|
||||||
|
b = buf[p.pos++];
|
||||||
|
val |= (b & 0x7f) << 7;
|
||||||
|
if (b < 0x80) return val;
|
||||||
|
b = buf[p.pos++];
|
||||||
|
val |= (b & 0x7f) << 14;
|
||||||
|
if (b < 0x80) return val;
|
||||||
|
b = buf[p.pos++];
|
||||||
|
val |= (b & 0x7f) << 21;
|
||||||
|
if (b < 0x80) return val;
|
||||||
|
b = buf[p.pos];
|
||||||
|
val |= (b & 0x0f) << 28;
|
||||||
|
|
||||||
|
return readVarintRemainder(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
function rotate(n: number, xy: number[], rx: number, ry: number): void {
|
function rotate(n: number, xy: number[], rx: number, ry: number): void {
|
||||||
if (ry == 0) {
|
if (ry == 0) {
|
||||||
if (rx == 1) {
|
if (rx == 1) {
|
||||||
@@ -98,4 +155,3 @@ export function findTile(entries: Entry[], tileId: number): Entry | null {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user