Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds support for local symbol table append read #760

Merged
merged 1 commit into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/IonBinaryReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class BinaryReader implements Reader {
if (this._parser.getAnnotation(0) !== ion_symbol_table_sid) {
break;
}
this._symtab = makeSymbolTable(this._cat, this);
this._symtab = makeSymbolTable(this._cat, this, this._symtab);
} else {
break;
}
Expand Down
31 changes: 28 additions & 3 deletions src/IonSymbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Reader } from "./IonReader";
import { SharedSymbolTable } from "./IonSharedSymbolTable";
import { SubstituteSymbolTable } from "./IonSubstituteSymbolTable";
import { getSystemSymbolTableImport } from "./IonSystemSymbolTable";
import { IonTypes } from "./Ion";

export const ion_symbol_table = "$ion_symbol_table";
export const ion_symbol_table_sid = 3;
Expand Down Expand Up @@ -100,15 +101,18 @@ function load_symbols(reader: Reader): (string | null)[] {
*
* @param catalog The catalog to resolve imported shared symbol tables from.
* @param reader The Ion {Reader} over the local symbol table in its serialized form.
* @param currentSymbolTable Current local symbol table for the reader.
*/
export function makeSymbolTable(
catalog: Catalog,
reader: Reader
reader: Reader,
currentSymbolTable: LocalSymbolTable
): LocalSymbolTable {
let import_: Import | null = null;
let symbols: (string | null)[] = [];
let foundSymbols: boolean = false;
let foundImports: boolean = false;
let foundLstAppend: boolean = false;

reader.stepIn();
while (reader.next()) {
Expand All @@ -117,14 +121,35 @@ export function makeSymbolTable(
if (foundImports) {
throw new Error("Multiple import fields found.");
}
import_ = load_imports(reader, catalog);
let ion_type = reader.type();
if (
ion_type === IonTypes.SYMBOL &&
reader.stringValue() === ion_symbol_table
) {
// this is a local symbol table append
import_ = currentSymbolTable.import;
let symbols_ = symbols;
symbols = currentSymbolTable.symbols;
symbols.push(...symbols_);
foundLstAppend = true;
} else if (ion_type === IonTypes.LIST) {
import_ = load_imports(reader, catalog);
} else {
throw new Error(
`Expected import field name to be a list or symbol found ${ion_type}`
);
}
foundImports = true;
break;
case "symbols":
if (foundSymbols) {
throw new Error("Multiple symbol fields found.");
}
symbols = load_symbols(reader);
if (foundLstAppend) {
symbols.push(...load_symbols(reader));
} else {
symbols = load_symbols(reader);
}
foundSymbols = true;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/IonTextReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class TextReader implements Reader {
break;
}
this._type = get_ion_type(this._raw_type);
this._symtab = makeSymbolTable(this._cat, this);
this._symtab = makeSymbolTable(this._cat, this, this._symtab);
this._raw = undefined;
this._raw_type = undefined;
} else {
Expand Down
13 changes: 13 additions & 0 deletions test/IonTextReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ class IonTextReaderTests {
assert.equal(ionReader.stringValue(), 'taco');
}

@test "resolves symbol IDs for symbol table append"() {
let ionToRead = `$ion_symbol_table::{ symbols:[ "foo", "bar" ]} $ion_symbol_table::{ imports: $ion_symbol_table, symbols:[ "baz" ]}[$10, $11, $12]`;
let ionReader = ion.makeReader(ionToRead);
ionReader.next();
ionReader.stepIn();
ionReader.next();
assert.equal(ionReader.stringValue(), "foo");
ionReader.next();
assert.equal(ionReader.stringValue(), "bar");
ionReader.next();
assert.equal(ionReader.stringValue(), "baz");
}

@test "Parse through struct"() {
let ionToRead = "{ key : \"string\" }";
let ionReader = ion.makeReader(ionToRead);
Expand Down
1 change: 0 additions & 1 deletion test/iontests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,6 @@ let equivsSkipList = toSkipList([
"ion-tests/iontestdata/good/equivs/decimalsWithUnderscores.ion",
"ion-tests/iontestdata/good/equivs/floatsWithUnderscores.ion",
"ion-tests/iontestdata/good/equivs/intsWithUnderscores.ion",
"ion-tests/iontestdata/good/equivs/localSymbolTableAppend.ion",
"ion-tests/iontestdata/good/equivs/localSymbolTableNullSlots.ion",
"ion-tests/iontestdata/good/equivs/localSymbolTables.ion",
"ion-tests/iontestdata/good/equivs/nonIVMNoOps.ion",
Expand Down