in src/com/amazon/ion/impl/SharedSymbolTable.java [206:320]
static SymbolTable newSharedSymbolTable(IonReader reader,
boolean isOnStruct)
{
if (! isOnStruct)
{
IonType t = reader.next();
if (t != IonType.STRUCT)
{
throw new IonException("invalid symbol table image passed " +
"into reader, " + t + " encountered when a " +
"struct was expected");
}
}
String name = null;
int version = -1;
List<String> symbolsList = new ArrayList<String>();
reader.stepIn();
IonType fieldType = null;
while ((fieldType = reader.next()) != null)
{
if (reader.isNullValue()) continue;
SymbolToken symTok = reader.getFieldNameSymbol();
int sid = symTok.getSid();
if (sid == SymbolTable.UNKNOWN_SYMBOL_ID)
{
// This is a user-defined IonReader or a pure DOM, fall
// back to text
final String fieldName = reader.getFieldName();
sid = getSidForSymbolTableField(fieldName);
}
// TODO amzn/ion-java/issues/35 If there's more than one 'symbols' or 'imports'
// field, they will be merged together.
// TODO amzn/ion-java/issues/36 Switching over SIDs doesn't cover the case
// where the relevant field names are defined by a prev LST;
// the prev LST could have 'symbols' defined locally with a
// different SID!
switch (sid)
{
case VERSION_SID:
if (fieldType == IonType.INT)
{
version = reader.intValue();
}
break;
case NAME_SID:
if (fieldType == IonType.STRING)
{
name = reader.stringValue();
}
break;
case SYMBOLS_SID:
// As per the Spec, other field types are treated as
// empty lists
if (fieldType == IonType.LIST)
{
reader.stepIn();
{
IonType t;
while ((t = reader.next()) != null)
{
String text = null;
if (t == IonType.STRING
&& ! reader.isNullValue())
{
// As per the Spec, if any element of
// the list is the empty string or any
// other type, treat it as null
text = reader.stringValue();
if (text.length() == 0) text = null;
}
symbolsList.add(text);
}
}
reader.stepOut();
}
break;
default:
break;
}
}
reader.stepOut();
if (name == null || name.length() == 0)
{
String message =
"shared symbol table is malformed: field 'name' " +
"must be a non-empty string.";
throw new IonException(message);
}
// As per the Spec, if 'version' field is missing or not at
// least 1, treat it as 1.
version = (version < 1) ? 1 : version;
Map<String, Integer> symbolsMap = null;
if (! symbolsList.isEmpty())
{
symbolsMap = new HashMap<String, Integer>();
transferNonExistingSymbols(symbolsList, symbolsMap);
}
else
{
// Empty Map is more efficient than an empty HashMap
symbolsMap = Collections.emptyMap();
}
// We have all necessary data, pass it over to the private constructor.
return new SharedSymbolTable(name, version, symbolsList, symbolsMap);
}