/// <summary> /// Reads the contents of a PGN file, returning a list of games /// and a list of exceptions for games that have errors. /// </summary> /// <param name="data"></param> /// <param name="skip"></param> /// <param name="gameHandler"></param> /// <param name="errorHandler"></param> /// <returns></returns> public PGNParserResults ParsePGN( string data, int skip = 1, Action<PGNGame> gameHandler = null, Action<PGNParserError> errorHandler = null) { var sb = new StringBuilder(); var output = new PGNParserResults(); // newlines simplify boundary checks and help the parser detect start and end // of game data sb.Append(DataPadding); sb.Append(data); sb.Append(DataPadding); sb.Replace("\r", ""); data = sb.ToString(); var indexes = FindGameIndexes(data); for (int i = 0; i < indexes.Count; i++) output.Games.Add(null); Parallel.For(0, indexes.Count, (i) => { if (i % skip == 0) { try { var idx = indexes[i]; var game = ParseGame(data, idx); output.Games[i] = game; if (gameHandler != null) gameHandler(game); } catch (PGNException e) { var err = new PGNParserError(); err.GameNumber = i + 1; err.Col = GetCol(data, e.Index); err.Line = GetRow(data, e.Index) - DataPadding.Length; err.Exception = e; err.Index = e.Index; err.Message = e.Message + ((e.InnerException != null) ? e.InnerException.Message : ""); err.Source = e.SourceComponent; err.Value = (e.PgnToken != null) ? (e.PgnToken.TokenType.ToString() + ": " + e.PgnToken.Value) : e.Token; output.Errors.Add(err); if (errorHandler != null) errorHandler(err); } catch (Exception ex) { var err = new PGNParserError(); err.GameNumber = i + 1; err.Exception = ex; err.Message = ex.Message; Console.WriteLine(err.ToString()); output.Errors.Add(err); if (errorHandler != null) errorHandler(err); } } }); return output; }
/// <summary> /// Reads the contents of a PGN file, returning a list of games /// and a list of exceptions for games that have errors. /// </summary> /// <param name="data"></param> /// <param name="skip"></param> /// <param name="gameHandler"></param> /// <param name="errorHandler"></param> /// <returns></returns> public PGNParserResults ParsePGN( string data, int skip = 1, Action <PGNGame> gameHandler = null, Action <PGNParserError> errorHandler = null) { var sb = new StringBuilder(); var output = new PGNParserResults(); // newlines simplify boundary checks and help the parser detect start and end // of game data sb.Append(DataPadding); sb.Append(data); sb.Append(DataPadding); sb.Replace("\r", ""); data = sb.ToString(); var indexes = FindGameIndexes(data); for (int i = 0; i < indexes.Count; i++) { output.Games.Add(null); } Parallel.For(0, indexes.Count, (i) => { if (i % skip == 0) { try { var idx = indexes[i]; var game = ParseGame(data, idx); output.Games[i] = game; if (gameHandler != null) { gameHandler(game); } } catch (PGNException e) { var err = new PGNParserError(); err.GameNumber = i + 1; err.Col = GetCol(data, e.Index); err.Line = GetRow(data, e.Index) - DataPadding.Length; err.Exception = e; err.Index = e.Index; err.Message = e.Message + ((e.InnerException != null) ? e.InnerException.Message : ""); err.Source = e.SourceComponent; err.Value = (e.PgnToken != null) ? (e.PgnToken.TokenType.ToString() + ": " + e.PgnToken.Value) : e.Token; output.Errors.Add(err); if (errorHandler != null) { errorHandler(err); } } catch (Exception ex) { var err = new PGNParserError(); err.GameNumber = i + 1; err.Exception = ex; err.Message = ex.Message; Console.WriteLine(err.ToString()); output.Errors.Add(err); if (errorHandler != null) { errorHandler(err); } } } }); return(output); }