Fix canonical encoding of Set and Dictionary
This commit is contained in:
parent
4022b76650
commit
a05bf0cb7a
|
@ -60,10 +60,16 @@ export class Dictionary<V, T extends object = DefaultPointer> extends FlexMap<Va
|
|||
|
||||
[PreserveOn](encoder: Encoder<T>) {
|
||||
if (encoder.canonical) {
|
||||
const pieces = Array.from(this).map(([k, v]) =>
|
||||
Bytes.concat([canonicalEncode(k), canonicalEncode(v)]));
|
||||
pieces.sort(Bytes.compare);
|
||||
encoder.encoderawvalues(Tag.Dictionary, pieces);
|
||||
const entries = Array.from(this);
|
||||
const pieces = entries.map<[Bytes, number]>(([k, _v], i) => [canonicalEncode(k), i]);
|
||||
pieces.sort((a, b) => Bytes.compare(a[0], b[0]));
|
||||
encoder.emitbyte(Tag.Dictionary);
|
||||
pieces.forEach(([_encodedKey, i]) => {
|
||||
const [k, v] = entries[i];
|
||||
encoder.push(k);
|
||||
encoder.push(v as unknown as Value<T>); // Suuuuuuuper unsound
|
||||
});
|
||||
encoder.emitbyte(Tag.End);
|
||||
} else {
|
||||
encoder.emitbyte(Tag.Dictionary);
|
||||
this.forEach((v, k) => {
|
||||
|
@ -116,9 +122,9 @@ export class Set<T extends object = DefaultPointer> extends FlexSet<Value<T>> {
|
|||
|
||||
[PreserveOn](encoder: Encoder<T>) {
|
||||
if (encoder.canonical) {
|
||||
const pieces = Array.from(this).map(k => canonicalEncode(k));
|
||||
pieces.sort(Bytes.compare);
|
||||
encoder.encoderawvalues(Tag.Set, pieces);
|
||||
const pieces = Array.from(this).map<[Bytes, Value<T>]>(k => [canonicalEncode(k), k]);
|
||||
pieces.sort((a, b) => Bytes.compare(a[0], b[0]));
|
||||
encoder.encodevalues(Tag.Set, pieces.map(e => e[1]));
|
||||
} else {
|
||||
encoder.encodevalues(Tag.Set, this);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Tag } from "./constants";
|
||||
import { Bytes, BytesLike, underlying } from "./bytes";
|
||||
import { Bytes } from "./bytes";
|
||||
import { Value } from "./values";
|
||||
import { PreserveOn } from "./symbols";
|
||||
import { EncodeError } from "./codec";
|
||||
|
@ -137,12 +137,6 @@ export class Encoder<T extends object> {
|
|||
this.emitbyte(Tag.End);
|
||||
}
|
||||
|
||||
encoderawvalues(tag: Tag, items: BytesLike[]) {
|
||||
this.emitbyte(tag);
|
||||
items.forEach((i) => this.emitbytes(underlying(i)));
|
||||
this.emitbyte(Tag.End);
|
||||
}
|
||||
|
||||
push(v: Encodable<T>) {
|
||||
if (isPreservable<never>(v)) {
|
||||
v[PreserveOn](this as unknown as Encoder<never>);
|
||||
|
|
Loading…
Reference in New Issue