protected void EndParse() { var skipping = SkipTypes.Any(); //if we are skipping then we will have some references unresolved foreach (var defRef in _deferredReferences /*.Where(dr => !SkipEntities.Contains(dr.ReferenceId))*/) { if (!TrySetObjectValue(defRef.HostEntity, defRef.ParameterIndex, defRef.ReferenceId, defRef.NestedIndex) && !skipping && !AllowMissingReferences) { Logger?.LogWarning("Entity #{0,-5} is referenced but could not be instantiated", defRef.ReferenceId); } } _deferredReferences.Clear(); if (_errors.Any) { Logger?.LogWarning(_errors.Summary); } _progressStatus?.Invoke(100, "Parsing finished."); }
public XbimP21Scanner(string data, IEnumerable <string> ignoreTypes = null) { Logger = XbimLogging.CreateLogger <XbimP21Scanner>(); _scanner = new Scanner(); _scanner.SetSource(data, 0); _streamSize = data.Length; if (ignoreTypes != null) { SkipTypes = new HashSet <string>(ignoreTypes); } var entityApproxCount = (int)_streamSize / 50; //adjust for skipped entities if (SkipTypes.Any()) { //about a 560 entities double adjustRatio = 1 - ((double)(SkipTypes.Count)) / 560; entityApproxCount = (int)(entityApproxCount * adjustRatio); } Entities = new Dictionary <int, IPersist>(entityApproxCount); _deferredReferences = new List <DeferredReference>(entityApproxCount / 4); //assume 50% deferred }
public XbimP21Scanner(Stream strm, long streamSize, IEnumerable <string> ignoreTypes = null) { Logger = XbimLogging.CreateLogger <XbimP21Scanner>(); _scanner = new Scanner(strm); //_scanner = new Scanner(new XbimScanBuffer(strm)); if (ignoreTypes != null) { SkipTypes = new HashSet <string>(ignoreTypes); } var entityApproxCount = 50000; if (streamSize > 0) { _streamSize = streamSize; entityApproxCount = Convert.ToInt32(_streamSize / 50); //average 50 bytes per entity. } //adjust for skipped entities if (SkipTypes.Any()) { //about a 600 entities double adjustRatio = 1.0 - (SkipTypes.Count / 600d); if (adjustRatio < 0) { adjustRatio = 0; } entityApproxCount = (int)(entityApproxCount * adjustRatio); } // make it 4 at least if (entityApproxCount < 1) { entityApproxCount = 4; } Entities = new Dictionary <int, IPersist>(entityApproxCount); _deferredReferences = new List <DeferredReference>(entityApproxCount / 4); //assume 50% deferred }
public bool Parse(bool onlyHeader = false) { var skipping = SkipTypes.Any(); var eofToken = (int)Tokens.EOF; var tok = _scanner.yylex(); int endEntityToken = ';'; while (tok != eofToken && !Cancel) { try { if (tok >= 63) { Tokens t = (Tokens)tok; switch (t) { case Tokens.HEADER: BeginHeader(); break; case Tokens.ENDSEC: if (_inHeader && onlyHeader) { return(true); } EndSec(); break; case Tokens.DATA: BeginData(); break; case Tokens.ENTITY: NewEntity(_scanner.yylval.strVal /*.AsSpan()*/); break; case Tokens.TYPE: var type = _scanner.yylval.strVal; if (skipping && SkipTypes.Contains(type)) { var current = _processStack.Pop(); //SkipEntities.Add(current.EntityLabel); while (tok != endEntityToken && tok != eofToken) { tok = _scanner.yylex(); } break; } if (!SetType(type)) { // move to the end of entity if we couldn't create it while (tok != endEntityToken && tok != eofToken) { tok = _scanner.yylex(); } } break; case Tokens.INTEGER: SetIntegerValue(_scanner.yylval.strVal); break; case Tokens.FLOAT: SetFloatValue(_scanner.yylval.strVal); break; case Tokens.STRING: SetStringValue(_scanner.yylval.strVal); break; case Tokens.BOOLEAN: SetBooleanValue(_scanner.yylval.strVal); break; case Tokens.IDENTITY: SetObjectValue(_scanner.yylval.strVal /*.AsSpan()*/); break; case Tokens.HEXA: SetHexValue(_scanner.yylval.strVal); break; case Tokens.ENUM: SetEnumValue(_scanner.yylval.strVal); break; case Tokens.NONDEF: SetNonDefinedValue(); break; case Tokens.OVERRIDE: SetOverrideValue(); break; case Tokens.TEXT: case Tokens.error: case Tokens.ILLEGALCHAR: throw new XbimParserException($"Unexpected scanner token {t.ToString()}, line {_scanner.yylloc.StartLine}, column {_scanner.yylloc.StartColumn}"); case Tokens.SCOPE: case Tokens.ENDSCOPE: case Tokens.ISOSTEPSTART: case Tokens.ISOSTEPEND: case Tokens.MISC: case Tokens.EOF: default: break; } } else { char c = (char)tok; switch (c) { case '(': BeginList(); break; case ')': EndList(); break; case ';': EndEntity(); break; case '/': case ',': case '=': default: break; } } // get next token tok = _scanner.yylex(); } //XbimParserException is a reason to terminate execution catch (XbimParserException e) { Logger?.LogError(LogEventIds.ParserFailure, e, e.Message); return(false); } //other exceptions might occure but those should just make the parser to wait for the next start of entity //and start from there catch (Exception e) { Logger?.LogError(LogEventIds.FailedEntity, e, e.Message); ErrorCount++; // clear current entity stack to make sure there are no residuals _processStack.Clear(); // scan until the beginning of next entity var entityToken = (int)Tokens.ENTITY; while (tok != eofToken && tok != entityToken) { tok = _scanner.yylex(); } } } EndParse(); return(ErrorCount == 0); }