Skip to content

Commit

Permalink
stack based encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
kuhe committed Jun 24, 2024
1 parent 0da4481 commit 0fea87f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
47 changes: 31 additions & 16 deletions packages/core/src/submodules/cbor/cbor-encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,21 @@ function encodeHeader(major: CborMajorType, value: Uint64 | number): void {
}
}

const headerEncode: Symbol = Symbol("headerEncodeCbor");

/**
* @param _input - JS data object.
*/
export function encode(_input: any): void {
const encodeQueue = [_input];
const encodeStack = [_input];

while (encodeStack.length) {
const input = encodeStack.pop();
if (input?.headerEncode === headerEncode) {
encodeHeader(input.major, input.count);
continue;
}

while (encodeQueue.length) {
const input = encodeQueue.shift();
ensureSpace(typeof input === "string" ? input.length * 4 : 64);

if (typeof input === "string") {
Expand Down Expand Up @@ -172,11 +179,14 @@ export function encode(_input: any): void {
// though the CBOR spec includes it.
throw new Error("@smithy/core/cbor: client may not serialize undefined value.");
} else if (Array.isArray(input)) {
encodeHeader(majorList, input.length);
for (let i = 0; i < input.length; ++i) {
// encode(input[i]);
encodeQueue.push(input[i]);
for (let i = input.length - 1; i >= 0; --i) {
encodeStack.push(input[i]);
}
encodeStack.push({
headerEncode,
major: majorList,
count: input.length,
});
continue;
} else if (typeof input.byteLength === "number") {
ensureSpace(input.length * 2);
Expand All @@ -185,20 +195,25 @@ export function encode(_input: any): void {
cursor += input.byteLength;
continue;
} else if (typeof input === "object" && "tag" in input && "value" in input && Object.keys(input).length === 2) {
encodeHeader(majorTag, input.tag);
// encode(input.value);
encodeQueue.push(input.value);
encodeStack.push(input.value);
encodeStack.push({
headerEncode,
major: majorTag,
count: input.tag,
});
continue;
} else if (typeof input === "object") {
const keys = Object.keys(input);
encodeHeader(majorMap, keys.length);
for (let i = 0; i < keys.length; ++i) {
for (let i = keys.length - 1; i >= 0; --i) {
const key = keys[i];
// encode(key);
// encode(input[key]);
encodeQueue.push(key);
encodeQueue.push(input[key]);
encodeStack.push(input[key]);
encodeStack.push(key);
}
encodeStack.push({
headerEncode,
major: majorMap,
count: keys.length,
});
continue;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/submodules/cbor/cbor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,10 @@ describe("cbor", () => {
},
cbor: allocByteArray([
164, 102, 110, 117, 109, 98, 101, 114, 27, 0, 0, 122, 204, 161, 196, 74, 227, 103, 109, 101, 115, 115, 97, 103,
101, 108, 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 100, 108, 105, 115, 116, 131, 99, 109, 97,
112, 163, +0, +244, +161, 97, 97, 97, 97, 97, 98, 97, 98, 101, 105, 116, 101, 109, 115, 136, +97, +97, +97, +98,
0, 32, 245, 244, 246, 96, 100, 116, 101, 115, 116, 130, 109, 110, 101, 115, 116, 101, 100, 32, 105, 116, 101,
109, 32, 65, 109, 110, 101, 115, 116, 101, 100, 32, 105, 116, 101, 109, 32, 66,
101, 108, 104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 100, 108, 105, 115, 116, 131, 0, 244, 161,
97, 97, 97, 98, 99, 109, 97, 112, 163, 97, 97, 97, 97, 97, 98, 97, 98, 101, 105, 116, 101, 109, 115, 136, 0, 32,
245, 244, 246, 96, 100, 116, 101, 115, 116, 130, 109, 110, 101, 115, 116, 101, 100, 32, 105, 116, 101, 109, 32,
65, 109, 110, 101, 115, 116, 101, 100, 32, 105, 116, 101, 109, 32, 66,
]),
},
];
Expand Down

0 comments on commit 0fea87f

Please sign in to comment.