mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-10 10:30:57 -06:00
@@ -1,37 +0,0 @@
|
||||
// Copyright 2016 The Noms Authors. All rights reserved.
|
||||
// Licensed under the Apache License, version 2.0:
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// @flow
|
||||
|
||||
import {suite, test} from 'mocha';
|
||||
import {assert} from 'chai';
|
||||
import {encode, decode} from './base64.js';
|
||||
|
||||
function uint8ArrayFromString(s: string): Uint8Array {
|
||||
const ta = new Uint8Array(s.length);
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
ta[i] = s.charCodeAt(i);
|
||||
}
|
||||
return ta;
|
||||
}
|
||||
|
||||
suite('base64', () => {
|
||||
test('encode', () => {
|
||||
assert.deepEqual(encode(uint8ArrayFromString('Hello world')), 'SGVsbG8gd29ybGQ=');
|
||||
assert.deepEqual(encode(uint8ArrayFromString('Man')), 'TWFu');
|
||||
assert.deepEqual(encode(uint8ArrayFromString('Ma')), 'TWE=');
|
||||
assert.deepEqual(encode(uint8ArrayFromString('M')), 'TQ==');
|
||||
assert.deepEqual(encode(uint8ArrayFromString('')), '');
|
||||
assert.deepEqual(encode(uint8ArrayFromString('Hello worlds!')), 'SGVsbG8gd29ybGRzIQ==');
|
||||
});
|
||||
|
||||
test('decode', () => {
|
||||
assert.deepEqual(decode('TWFu'), uint8ArrayFromString('Man'));
|
||||
assert.deepEqual(decode('TWE='), uint8ArrayFromString('Ma'));
|
||||
assert.deepEqual(decode('TQ=='), uint8ArrayFromString('M'));
|
||||
assert.deepEqual(decode(''), uint8ArrayFromString(''));
|
||||
assert.deepEqual(decode('SGVsbG8gd29ybGQ='), uint8ArrayFromString('Hello world'));
|
||||
assert.deepEqual(decode('SGVsbG8gd29ybGRzIQ=='), uint8ArrayFromString('Hello worlds!'));
|
||||
});
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
// Copyright 2016 The Noms Authors. All rights reserved.
|
||||
// Licensed under the Apache License, version 2.0:
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// @flow
|
||||
|
||||
// Based on https://github.com/niklasvh/base64-arraybuffer
|
||||
//
|
||||
// base64-arraybuffer
|
||||
// https://github.com/niklasvh/base64-arraybuffer
|
||||
//
|
||||
// Copyright (c) 2012 Niklas von Hertzen
|
||||
// Licensed under the MIT license.
|
||||
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
// Build charCode -> index
|
||||
const lookup: Uint8Array = new Uint8Array(256);
|
||||
for (let i = 0 ; i < chars.length; i++) {
|
||||
lookup[chars.charCodeAt(i)] = i;
|
||||
}
|
||||
|
||||
export function encode(bytes: Uint8Array): string {
|
||||
const len = bytes.length;
|
||||
let base64 = '';
|
||||
|
||||
for (let i = 0; i < len; i += 3) {
|
||||
base64 += chars[bytes[i] >> 2];
|
||||
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
|
||||
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
|
||||
base64 += chars[bytes[i + 2] & 63];
|
||||
}
|
||||
|
||||
if (len % 3 === 2) {
|
||||
base64 = base64.substring(0, base64.length - 1) + '=';
|
||||
} else if (len % 3 === 1) {
|
||||
base64 = base64.substring(0, base64.length - 2) + '==';
|
||||
}
|
||||
|
||||
return base64;
|
||||
}
|
||||
|
||||
export function decode(s: string): Uint8Array {
|
||||
let bufferLength = s.length * 0.75;
|
||||
const len = s.length;
|
||||
|
||||
if (s[len - 1] === '=') {
|
||||
bufferLength--;
|
||||
if (s[len - 2] === '=') {
|
||||
bufferLength--;
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = new Uint8Array(bufferLength);
|
||||
let p = 0;
|
||||
|
||||
for (let i = 0; i < len; i += 4) {
|
||||
const encoded1 = lookup[s.charCodeAt(i)];
|
||||
const encoded2 = lookup[s.charCodeAt(i + 1)];
|
||||
const encoded3 = lookup[s.charCodeAt(i + 2)];
|
||||
const encoded4 = lookup[s.charCodeAt(i + 3)];
|
||||
|
||||
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
|
||||
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
|
||||
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import {assert} from 'chai';
|
||||
import MemoryStore from './memory-store.js';
|
||||
import BatchStore from './batch-store.js';
|
||||
import {BatchStoreAdaptorDelegate} from './batch-store-adaptor.js';
|
||||
import {encodeNomsValue} from './encode.js';
|
||||
import {encodeValue} from './codec.js';
|
||||
|
||||
suite('BatchStore', () => {
|
||||
test('get after schedulePut works immediately', async () => {
|
||||
@@ -17,7 +17,7 @@ suite('BatchStore', () => {
|
||||
const bs = new BatchStore(3, new BatchStoreAdaptorDelegate(ms));
|
||||
const input = 'abc';
|
||||
|
||||
const c = encodeNomsValue(input);
|
||||
const c = encodeValue(input);
|
||||
bs.schedulePut(c, new Set());
|
||||
|
||||
const chunk = await bs.get(c.hash);
|
||||
@@ -30,7 +30,7 @@ suite('BatchStore', () => {
|
||||
const bs = new BatchStore(3, new BatchStoreAdaptorDelegate(ms));
|
||||
const input = 'abc';
|
||||
|
||||
const c = encodeNomsValue(input);
|
||||
const c = encodeValue(input);
|
||||
bs.schedulePut(c, new Set());
|
||||
|
||||
let chunk = await bs.get(c.hash);
|
||||
|
||||
@@ -4,9 +4,36 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import Chunk from './chunk.js';
|
||||
import Hash, {sha1Size} from './hash.js';
|
||||
import ValueDecoder from './value-decoder.js';
|
||||
import ValueEncoder from './value-encoder.js';
|
||||
import {encode, decode} from './utf8.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {setEncodeValue} from './get-hash.js';
|
||||
import {setHash, ValueBase} from './value.js';
|
||||
|
||||
export function encodeValue(v: Value, vw: ?ValueWriter): Chunk {
|
||||
const w = new BinaryNomsWriter();
|
||||
const enc = new ValueEncoder(w, vw);
|
||||
enc.writeValue(v);
|
||||
return new Chunk(w.data);
|
||||
}
|
||||
|
||||
setEncodeValue(encodeValue);
|
||||
|
||||
export function decodeValue(chunk: Chunk, vr: ValueReader): Value {
|
||||
const data = chunk.data;
|
||||
const dec = new ValueDecoder(new BinaryNomsReader(data), vr);
|
||||
const v = dec.readValue();
|
||||
|
||||
if (v instanceof ValueBase) {
|
||||
setHash(v, chunk.hash);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
const maxUInt32 = Math.pow(2, 32);
|
||||
const littleEndian = true;
|
||||
|
||||
@@ -13,7 +13,7 @@ import Database from './database.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import List from './list.js';
|
||||
import Map from './map.js';
|
||||
import {encodeNomsValue} from './encode.js';
|
||||
import {encodeValue} from './codec.js';
|
||||
import NomsSet from './set.js'; // namespace collision with JS Set
|
||||
import {equals} from './compare.js';
|
||||
|
||||
@@ -23,7 +23,7 @@ suite('Database', () => {
|
||||
const ds = new Database(bs);
|
||||
const input = 'abc';
|
||||
|
||||
const c = encodeNomsValue(input);
|
||||
const c = encodeValue(input);
|
||||
const v1 = await ds.readValue(c.hash);
|
||||
assert.equal(null, v1);
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ import Set, {newSetLeafSequence} from './set.js';
|
||||
import type Value from './value.js';
|
||||
import type {NomsKind} from './noms-kind.js';
|
||||
import {Kind} from './noms-kind.js';
|
||||
import {decodeNomsValue, ValueDecoder} from './decode.js';
|
||||
import {encodeNomsValue, ValueEncoder} from './encode.js';
|
||||
import ValueDecoder from './value-decoder.js';
|
||||
import ValueEncoder from './value-encoder.js';
|
||||
import {encodeValue, decodeValue} from './codec.js';
|
||||
import {equals} from './compare.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {makeTestingBatchStore} from './batch-store-adaptor.js';
|
||||
@@ -45,8 +46,8 @@ import {
|
||||
|
||||
function assertRoundTrips(v: Value) {
|
||||
const db = new Database(makeTestingBatchStore());
|
||||
const c = encodeNomsValue(v, db);
|
||||
const out = decodeNomsValue(c, db);
|
||||
const c = encodeValue(v, db);
|
||||
const out = decodeValue(c, db);
|
||||
assert.isTrue(equals(v, out));
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import {getTypeOfValue} from './type.js';
|
||||
import {ValueBase} from './value.js';
|
||||
|
||||
type encodeFn = (v: Value, vw: ?ValueWriter) => Chunk;
|
||||
let encodeNomsValue: ?encodeFn = null;
|
||||
let encodeValue: ?encodeFn = null;
|
||||
|
||||
export function getHashOfValue(v: Value): Hash {
|
||||
if (v instanceof ValueBase) {
|
||||
@@ -24,7 +24,7 @@ export function getHashOfValue(v: Value): Hash {
|
||||
}
|
||||
|
||||
export function getHash(v: Value): Hash {
|
||||
return notNull(encodeNomsValue)(v, null).hash;
|
||||
return notNull(encodeValue)(v, null).hash;
|
||||
}
|
||||
|
||||
export function ensureHash(h: ?Hash, v: Value): Hash {
|
||||
@@ -35,6 +35,6 @@ export function ensureHash(h: ?Hash, v: Value): Hash {
|
||||
return getHash(v);
|
||||
}
|
||||
|
||||
export function setEncodeNomsValue(encode: encodeFn) {
|
||||
encodeNomsValue = encode;
|
||||
export function setEncodeValue(encode: encodeFn) {
|
||||
encodeValue = encode;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export {default as Commit} from './commit.js';
|
||||
export {default as Database} from './database.js';
|
||||
export {default as Dataset} from './dataset.js';
|
||||
export {default as Blob, BlobReader, BlobWriter} from './blob.js';
|
||||
export {decodeNomsValue} from './decode.js';
|
||||
export {decodeValue} from './codec.js';
|
||||
export {default as Chunk} from './chunk.js';
|
||||
export {default as HttpBatchStore} from './http-batch-store.js';
|
||||
export {default as MemoryStore} from './memory-store.js';
|
||||
@@ -24,7 +24,7 @@ export {
|
||||
createStructClass,
|
||||
escapeStructField,
|
||||
} from './struct.js';
|
||||
export {encodeNomsValue} from './encode.js';
|
||||
export {encodeValue} from './codec.js';
|
||||
export {invariant, notNull} from './assert.js';
|
||||
export {isPrimitiveKind, Kind, kindToString} from './noms-kind.js';
|
||||
export {default as List, ListWriter, ListLeafSequence} from './list.js';
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
// @flow
|
||||
|
||||
import Blob, {BlobLeafSequence} from './blob.js';
|
||||
import Chunk from './chunk.js';
|
||||
import Ref, {constructRef} from './ref.js';
|
||||
import {newStructWithTypeNoValidation} from './struct.js';
|
||||
import type Struct from './struct.js';
|
||||
@@ -28,13 +27,11 @@ import List, {ListLeafSequence} from './list.js';
|
||||
import Map, {MapLeafSequence} from './map.js';
|
||||
import Set, {SetLeafSequence} from './set.js';
|
||||
import {IndexedMetaSequence, OrderedMetaSequence} from './meta-sequence.js';
|
||||
import {ValueBase, setHash} from './value.js';
|
||||
import type Value from './value.js';
|
||||
import type {ValueReader} from './value-store.js';
|
||||
import type {NomsReader} from './codec.js';
|
||||
import {BinaryNomsReader} from './codec.js';
|
||||
|
||||
export class ValueDecoder {
|
||||
export default class ValueDecoder {
|
||||
_r: NomsReader;
|
||||
_ds: ValueReader;
|
||||
|
||||
@@ -53,7 +50,6 @@ export class ValueDecoder {
|
||||
return constructRef(t, hash, height);
|
||||
}
|
||||
|
||||
|
||||
readType(parentStructTypes: Type[]): Type {
|
||||
const k = this.readKind();
|
||||
switch (k) {
|
||||
@@ -234,15 +230,3 @@ export class ValueDecoder {
|
||||
return structType;
|
||||
}
|
||||
}
|
||||
|
||||
export function decodeNomsValue(chunk: Chunk, vr: ValueReader): Value {
|
||||
const data = chunk.data;
|
||||
const dec = new ValueDecoder(new BinaryNomsReader(data), vr);
|
||||
const v = dec.readValue();
|
||||
|
||||
if (v instanceof ValueBase) {
|
||||
setHash(v, chunk.hash);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
@@ -4,30 +4,27 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import Chunk from './chunk.js';
|
||||
import Ref from './ref.js';
|
||||
import Struct, {StructMirror} from './struct.js';
|
||||
import type {NomsKind} from './noms-kind.js';
|
||||
import {StructDesc, Type, getTypeOfValue} from './type.js';
|
||||
import {MetaTuple} from './meta-sequence.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {isPrimitiveKind, kindToString, Kind} from './noms-kind.js';
|
||||
import Blob, {BlobLeafSequence} from './blob.js';
|
||||
import List, {ListLeafSequence} from './list.js';
|
||||
import Map, {MapLeafSequence} from './map.js';
|
||||
import Set, {SetLeafSequence} from './set.js';
|
||||
import Ref from './ref.js';
|
||||
import Sequence from './sequence.js';
|
||||
import {setEncodeNomsValue} from './get-hash.js';
|
||||
import Blob, {BlobLeafSequence} from './blob.js';
|
||||
import {describeTypeOfValue} from './encode-human-readable.js';
|
||||
import type {primitive} from './primitives.js';
|
||||
import Set, {SetLeafSequence} from './set.js';
|
||||
import Struct, {StructMirror} from './struct.js';
|
||||
import type Value from './value.js';
|
||||
import type {ValueWriter} from './value-store.js';
|
||||
import type {NomsKind} from './noms-kind.js';
|
||||
import type {NomsWriter} from './codec.js';
|
||||
import {BinaryNomsWriter} from './codec.js';
|
||||
import type {ValueWriter} from './value-store.js';
|
||||
import type {primitive} from './primitives.js';
|
||||
import {MetaTuple} from './meta-sequence.js';
|
||||
import {StructDesc, Type, getTypeOfValue} from './type.js';
|
||||
import {describeTypeOfValue} from './encode-human-readable.js';
|
||||
import {invariant} from './assert.js';
|
||||
import {isPrimitiveKind, kindToString, Kind} from './noms-kind.js';
|
||||
|
||||
type primitiveOrArray = primitive | Array<primitiveOrArray>;
|
||||
|
||||
export class ValueEncoder {
|
||||
export default class ValueEncoder {
|
||||
_w: NomsWriter;
|
||||
_vw: ?ValueWriter;
|
||||
|
||||
@@ -251,12 +248,3 @@ export class ValueEncoder {
|
||||
parentStructTypes.pop();
|
||||
}
|
||||
}
|
||||
|
||||
export function encodeNomsValue(v: Value, vw: ?ValueWriter): Chunk {
|
||||
const w = new BinaryNomsWriter();
|
||||
const enc = new ValueEncoder(w, vw);
|
||||
enc.writeValue(v);
|
||||
return new Chunk(w.data);
|
||||
}
|
||||
|
||||
setEncodeNomsValue(encodeNomsValue);
|
||||
@@ -12,7 +12,7 @@ import BatchStore from './batch-store.js';
|
||||
import {BatchStoreAdaptorDelegate} from './batch-store-adaptor.js';
|
||||
import ValueStore from './value-store.js';
|
||||
import List from './list.js';
|
||||
import {encodeNomsValue} from './encode.js';
|
||||
import {encodeValue} from './codec.js';
|
||||
import {equals} from './compare.js';
|
||||
|
||||
export class FakeBatchStore extends BatchStore {
|
||||
@@ -27,7 +27,7 @@ suite('ValueStore', () => {
|
||||
const vs = new ValueStore(new FakeBatchStore(ms));
|
||||
const input = 'abc';
|
||||
|
||||
const c = encodeNomsValue(input);
|
||||
const c = encodeValue(input);
|
||||
const v1 = await vs.readValue(c.hash);
|
||||
assert.equal(null, v1);
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ import {
|
||||
} from './type.js';
|
||||
import {Kind} from './noms-kind.js';
|
||||
import {ValueBase} from './value.js';
|
||||
import {decodeNomsValue} from './decode.js';
|
||||
import {decodeValue} from './codec.js';
|
||||
import {invariant, notNull} from './assert.js';
|
||||
import {encodeNomsValue} from './encode.js';
|
||||
import {encodeValue} from './codec.js';
|
||||
import {describeType, describeTypeOfValue} from './encode-human-readable.js';
|
||||
import {equals} from './compare.js';
|
||||
|
||||
@@ -63,7 +63,7 @@ export default class ValueStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
const v = decodeNomsValue(chunk, this);
|
||||
const v = decodeValue(chunk, this);
|
||||
this._valueCache.add(hash, chunk.data.length, v);
|
||||
this._knownHashes.cacheChunks(v, hash);
|
||||
// hash is trivially a hint for v, so consider putting that in the cache.
|
||||
@@ -78,7 +78,7 @@ export default class ValueStore {
|
||||
|
||||
writeValue<T: Value>(v: T): Ref<T> {
|
||||
const t = getTypeOfValue(v);
|
||||
const chunk = encodeNomsValue(v, this);
|
||||
const chunk = encodeValue(v, this);
|
||||
invariant(!chunk.isEmpty());
|
||||
const {hash} = chunk;
|
||||
const height = maxChunkHeight(v) + 1;
|
||||
|
||||
Reference in New Issue
Block a user