Example #1
0
 /// <summary>
 /// Constructor the initializes our parser.
 /// </summary>
 public PGNReader()
 {
     _Regex       = new Regex("^\\[([A-Za-z]*) \"(.*)\"", RegexOptions.Compiled);
     _Value       = new StringBuilder();
     _State       = Enums.PGNReaderState.Header;
     _SaveState   = new Stack();
     _PeriodCount = 0;
 }
Example #2
0
 /// <summary>
 /// Constructor the initializes our parser.
 /// </summary>
 public PGNReader()
 {
     _Regex = new Regex("^\\[([A-Za-z]*) \"(.*)\"", RegexOptions.Compiled);
     _Value = new StringBuilder();
     _State = Enums.PGNReaderState.Header;
     _SaveState = new Stack();
     _PeriodCount = 0;
 }
Example #3
0
        /// <summary>
        ///     Calls the correct event based on the parsers state.
        /// </summary>
        /// <param name="state"></param>
        private void CallEvent(Enums.PGNReaderState state)
        {
            if (_Value.Length > 0)
            {
                switch (state)
                {
                case Enums.PGNReaderState.Comment:
                    if (EventCommentParsed != null)
                    {
                        EventCommentParsed(this);
                    }
                    State = _PrevState;
                    break;

                case Enums.PGNReaderState.Nags:
                    if (EventNagParsed != null)
                    {
                        EventNagParsed(this);
                    }
                    State = _PrevState;
                    break;

                case Enums.PGNReaderState.ConvertNag:
                    string nag = _Value.ToString();
                    _Value.Length = 0;
                    if (nag.Equals("!"))
                    {
                        _Value.Append('1');
                    }
                    else if (nag.Equals("?"))
                    {
                        _Value.Append('2');
                    }
                    else if (nag.Equals("!!"))
                    {
                        _Value.Append('3');
                    }
                    else if (nag.Equals("??"))
                    {
                        _Value.Append('4');
                    }
                    else if (nag.Equals("!?"))
                    {
                        _Value.Append('5');
                    }
                    else if (nag.Equals("?!"))
                    {
                        _Value.Append('6');
                    }
                    else
                    {
                        _Value.Append('0');
                    }
                    if (EventNagParsed != null)
                    {
                        EventNagParsed(this);
                    }
                    State = _PrevState;
                    break;

                case Enums.PGNReaderState.Number:
                    if (EventMoveParsed != null)
                    {
                        EventMoveParsed(this);
                    }
                    State = Enums.PGNReaderState.Color;
                    break;

                case Enums.PGNReaderState.White:
                    if (EventMoveParsed != null)
                    {
                        EventMoveParsed(this);
                    }
                    State = Enums.PGNReaderState.Black;
                    break;

                case Enums.PGNReaderState.Black:
                    if (EventMoveParsed != null)
                    {
                        EventMoveParsed(this);
                    }
                    State = Enums.PGNReaderState.Number;
                    break;

                case Enums.PGNReaderState.EndMarker:
                    if (EventendMarkerParsed != null)
                    {
                        EventendMarkerParsed(this);
                    }
                    State = Enums.PGNReaderState.Header;
                    break;
                }
            }
            // Always clear out our data as the handler should have used this value during the event.
            _Value.Length = 0;
        }
Example #4
0
        /// <summary>
        ///     Handles individual charaters which may signal a change in the
        ///     parser's state.
        /// </summary>
        /// <param name="aChar"></param>
        private void HandleChar(char aChar)
        {
            switch (aChar)
            {
            case '{':
                CallEvent(State);
                _PrevState = State;
                State      = Enums.PGNReaderState.Comment;
                break;

            case '(':
                if (EventEnterVariation != null)
                {
                    EventEnterVariation(this);
                }
                _Value.Length = 0;
                _SaveState.Push(State);
                break;

            case ')':
                if (EventExitVariation != null)
                {
                    EventExitVariation(this);
                }
                _Value.Length = 0;
                State         = (Enums.PGNReaderState)_SaveState.Pop();
                break;

            case ' ':
                // Only if we have some data do we want to fire an event.
                CallEvent(State);
                break;

            case '.':
                // We may have come across 6. e4 6... d5 as in our example data.
                State = Enums.PGNReaderState.Number;
                CallEvent(State);
                _PeriodCount = 1;
                break;

            case '$':
                CallEvent(State);
                _PrevState = State;
                State      = Enums.PGNReaderState.Nags;
                break;

            case '!':
            case '?':
                if (State != Enums.PGNReaderState.ConvertNag)
                {
                    CallEvent(State);
                    _PrevState = State;
                    State      = Enums.PGNReaderState.ConvertNag;
                }
                _Value.Append(aChar);
                break;

            case '-':
                if (State != Enums.PGNReaderState.EndMarker && _Value.Length >= 1)
                {
                    if ("012".IndexOf(_Value[_Value.Length - 1]) >= 0)
                    {
                        State = Enums.PGNReaderState.EndMarker;
                    }
                }
                _Value.Append(aChar);
                break;

            case '*':
                State = Enums.PGNReaderState.EndMarker;
                _Value.Append(aChar);
                break;

            case '\t':
                break;

            default:
                _Value.Append(aChar);
                break;
            }
        }
Example #5
0
        /// <summary>
        /// Handles the parsing of the actual game notation of the PGN file.
        /// </summary>
        /// <param name="line"></param>
        public void ParseDetail(string line)
        {
            foreach (char aChar in line)
            {
                // Handle any special processing of our text.
                switch (_State)
                {
                case Enums.PGNReaderState.Comment:
                    if (aChar == '}')
                    {
                        CallEvent(_State);
                    }
                    else
                    {
                        _Value.Append(aChar);
                    }
                    break;

                case Enums.PGNReaderState.Nags:
                    if (aChar >= '0' && aChar <= '9')
                    {
                        _Value.Append(aChar);
                    }
                    else
                    {
                        CallEvent(_State);
                        HandleChar(aChar);
                    }
                    break;

                case Enums.PGNReaderState.Color:
                    if (aChar == '.')
                    {
                        _PeriodCount++;
                    }
                    else
                    {
                        _Value.Length = 0;
                        if (_PeriodCount == 1)
                        {
                            _State = Enums.PGNReaderState.White;
                        }
                        else if (_PeriodCount > 1)
                        {
                            _State = Enums.PGNReaderState.Black;
                        }
                        HandleChar(aChar);
                        _PeriodCount = 0;
                    }
                    break;

                default:
                    HandleChar(aChar);
                    break;
                }
            }
            // Ensure we add a space between comment lines that are broken appart.
            if (_State == Enums.PGNReaderState.Comment)
            {
                _Value.Append(' ');
            }
            else
            {
                CallEvent(_State);
            }
        }
Example #6
0
        /// <summary>
        /// Responsible for the main driver loop of the parser.  Here we read
        /// in the PGN file and produce events for the listening parties.
        /// </summary>
        public void Parse()
        {
            StringBuilder builder = new StringBuilder(1024);
            StreamReader  reader  = null;

            if (EventStarting != null)
            {
                EventStarting(this);
            }
            try
            {
                Encoding fileEncoding = TextFileEncoding.GetEncoding(_filename);
                reader = new StreamReader(_filename, fileEncoding);

                while (!reader.EndOfStream)
                {
                    #region while
                    char aChar = (char)reader.Read();
                    switch (aChar)
                    {
                        #region case
                    case '\n':
                        _Data          = builder.ToString();
                        builder.Length = 0;
                        if (_Data.Length > 0)
                        {
                            if (_State != Enums.PGNReaderState.Comment && Regex.IsMatch(_Data, "^\\["))
                            {
                                if (_NextGame == false)
                                {
                                    CallEvent(_State);

                                    _NextGame = true;
                                    if (EventNewGame != null)
                                    {
                                        EventNewGame(this);
                                    }
                                }
                                _State = Enums.PGNReaderState.Header;
                                ParseTag(_Data);
                                _Value.Length = 0;
                            }
                            else
                            {
                                if (_NextGame)
                                {
                                    _NextGame = false;
                                    if (EventExitHeader != null)
                                    {
                                        EventExitHeader(this);
                                    }
                                }
                                ParseDetail(_Data);
                            }
                        }
                        break;

                    case '\r':
                        break;

                    default:
                        builder.Append(aChar);
                        if (reader.EndOfStream)
                        {
                            goto case '\n';
                        }
                        break;
                        #endregion
                    }
                    #endregion
                }//while

                CallEvent(_State);
            }
            catch (ApplicationException)
            {
                throw;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader = null;
                }
            }
            if (EventFinished != null)
            {
                EventFinished(this);
            }
        }
Example #7
0
 /// <summary>
 /// Handles individual charaters which may signal a change in the
 /// parser's state.
 /// </summary>
 /// <param name="aChar"></param>
 private void HandleChar(char aChar)
 {
     switch (aChar)
     {
         case '{':
             CallEvent(_State);
             _PrevState = _State;
             _State = Enums.PGNReaderState.Comment;
             break;
         case '(':
             if (EventEnterVariation != null)
                 EventEnterVariation(this);
             _Value.Length = 0;
             _SaveState.Push(_State);
             break;
         case ')':
             if (EventExitVariation != null)
                 EventExitVariation(this);
             _Value.Length = 0;
             _State = (Enums.PGNReaderState)_SaveState.Pop();
             break;
         case ' ':
             // Only if we have some data do we want to fire an event.
             CallEvent(_State);
             break;
         case '.':
             // We may have come across 6. e4 6... d5 as in our example data.
             _State = Enums.PGNReaderState.Number;
             CallEvent(_State);
             _PeriodCount = 1;
             break;
         case '$':
             CallEvent(_State);
             _PrevState = _State;
             _State = Enums.PGNReaderState.Nags;
             break;
         case '!':
         case '?':
             if (_State != Enums.PGNReaderState.ConvertNag)
             {
                 CallEvent(_State);
                 _PrevState = _State;
                 _State = Enums.PGNReaderState.ConvertNag;
             }
             _Value.Append(aChar);
             break;
         case '-':
             if (_State != Enums.PGNReaderState.EndMarker && _Value.Length >= 1)
             {
                 if ("012".IndexOf(_Value[_Value.Length - 1]) >= 0)
                     _State = Enums.PGNReaderState.EndMarker;
             }
             _Value.Append(aChar);
             break;
         case '*':
             _State = Enums.PGNReaderState.EndMarker;
             _Value.Append(aChar);
             break;
         case '\t':
             break;
         default:
             _Value.Append(aChar);
             break;
     }
 }
Example #8
0
 /// <summary>
 /// Calls the correct event based on the parsers state.
 /// </summary>
 /// <param name="state"></param>
 private void CallEvent(Enums.PGNReaderState state)
 {
     if (_Value.Length > 0)
     {
         switch (state)
         {
             case Enums.PGNReaderState.Comment:
                 if (EventCommentParsed != null)
                     EventCommentParsed(this);
                 _State = _PrevState;
                 break;
             case Enums.PGNReaderState.Nags:
                 if (EventNagParsed != null)
                     EventNagParsed(this);
                 _State = _PrevState;
                 break;
             case Enums.PGNReaderState.ConvertNag:
                 string nag = _Value.ToString();
                 _Value.Length = 0;
                 if (nag.Equals("!"))
                     _Value.Append('1');
                 else if (nag.Equals("?"))
                     _Value.Append('2');
                 else if (nag.Equals("!!"))
                     _Value.Append('3');
                 else if (nag.Equals("??"))
                     _Value.Append('4');
                 else if (nag.Equals("!?"))
                     _Value.Append('5');
                 else if (nag.Equals("?!"))
                     _Value.Append('6');
                 else
                     _Value.Append('0');
                 if (EventNagParsed != null)
                     EventNagParsed(this);
                 _State = _PrevState;
                 break;
             case Enums.PGNReaderState.Number:
                 if (EventMoveParsed != null)
                     EventMoveParsed(this);
                 _State = Enums.PGNReaderState.Color;
                 break;
             case Enums.PGNReaderState.White:
                 if (EventMoveParsed != null)
                     EventMoveParsed(this);
                 _State = Enums.PGNReaderState.Black;
                 break;
             case Enums.PGNReaderState.Black:
                 if (EventMoveParsed != null)
                     EventMoveParsed(this);
                 _State = Enums.PGNReaderState.Number;
                 break;
             case Enums.PGNReaderState.EndMarker:
                 if (EventendMarkerParsed != null)
                     EventendMarkerParsed(this);
                 _State = Enums.PGNReaderState.Header;
                 break;
         }
     }
     // Always clear out our data as the handler should have used this value during the event.
     _Value.Length = 0;
 }
Example #9
0
        /// <summary>
        /// Handles the parsing of the actual game notation of the PGN file.
        /// </summary>
        /// <param name="line"></param>
        public void ParseDetail(string line)
        {
            foreach (char aChar in line)
            {
                // Handle any special processing of our text.
                switch (_State)
                {
                    case Enums.PGNReaderState.Comment:
                        if (aChar == '}')
                        {
                            CallEvent(_State);
                        }
                        else
                            _Value.Append(aChar);
                        break;

                    case Enums.PGNReaderState.Nags:
                        if (aChar >= '0' && aChar <= '9')
                            _Value.Append(aChar);
                        else
                        {
                            CallEvent(_State);
                            HandleChar(aChar);
                        }
                        break;
                    case Enums.PGNReaderState.Color:
                        if (aChar == '.')
                        {
                            _PeriodCount++;
                        }
                        else
                        {
                            _Value.Length = 0;
                            if (_PeriodCount == 1)
                            {
                                _State = Enums.PGNReaderState.White;
                            }
                            else if (_PeriodCount > 1)
                            {
                                _State = Enums.PGNReaderState.Black;
                            }
                            HandleChar(aChar);
                            _PeriodCount = 0;
                        }
                        break;

                    default:
                        HandleChar(aChar);
                        break;
                }
            }
            // Ensure we add a space between comment lines that are broken appart.
            if (_State == Enums.PGNReaderState.Comment)
                _Value.Append(' ');
            else
                CallEvent(_State);
        }
Example #10
0
        /// <summary>
        /// Responsible for the main driver loop of the parser.  Here we read
        /// in the PGN file and produce events for the listening parties.
        /// </summary>
        public void Parse()
        {
            StringBuilder builder = new StringBuilder(1024);
            StreamReader reader = null;

            if (EventStarting != null)
                EventStarting(this);
            try
            {
                Encoding fileEncoding = TextFileEncoding.GetEncoding(_filename);
                reader = new StreamReader(_filename, fileEncoding);

                while (!reader.EndOfStream)
                {
                    #region while
                    char aChar = (char)reader.Read();
                    switch (aChar)
                    {
                        #region case
                        case '\n':
                            _Data = builder.ToString();
                            builder.Length = 0;
                            if (_Data.Length > 0)
                            {
                                if (_State != Enums.PGNReaderState.Comment && Regex.IsMatch(_Data, "^\\["))
                                {
                                    if (_NextGame == false)
                                    {
                                        CallEvent(_State);

                                        _NextGame = true;
                                        if (EventNewGame != null)
                                        {
                                            EventNewGame(this);
                                        }
                                    }
                                    _State = Enums.PGNReaderState.Header;
                                    ParseTag(_Data);
                                    _Value.Length = 0;
                                }
                                else
                                {
                                    if (_NextGame)
                                    {
                                        _NextGame = false;
                                        if (EventExitHeader != null)
                                        {
                                            EventExitHeader(this);
                                        }
                                    }
                                    ParseDetail(_Data);
                                }
                            }
                            break;
                        case '\r':
                            break;
                        default:
                            builder.Append(aChar);
                            if (reader.EndOfStream)
                            {
                                goto case '\n';
                            }
                            break;
                        #endregion
                    }
                    #endregion

                }//while

                CallEvent(_State);
            }
            catch (ApplicationException)
            {
                throw;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader = null;
                }
            }
            if (EventFinished != null)
                EventFinished(this);
        }