text: /**************************************************************
   * 
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   * 
   *   http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied.  See the License for the
   * specific language governing permissions and limitations
   * under the License.
   * 
   *************************************************************/
  
  
  
  #ifndef ADC_TKPCHARS_HXX
  #define ADC_TKPCHARS_HXX
  
  // USED SERVICES
  	// BASE CLASSES
  	// COMPONENTS
  	// PARAMETRS
  #include <adc_cl.hxx>
  #include <stack>
  
  
  
  /**	@descr
  
  	dpSource:
  
  	1||||||||||||||||||||||a||||||||||||b|||c||||||||||||||||||||...
  
  
  	1 := first character of Sourcecode.
  	a := nLastTokenStart, there starts the last cut token.
  	b := nLastCut, there is a '\0'-char which marks the end of
  		 the last cut token. The original character at b is stored
  		 in cCharAtLastCut and will replace the '\0'-char, when the
  		 next token is cut.
  	c := The current cursor position.
  
  
  	@needs 	cosv.lib
  
  	@use    This class can be used by any parser to get the chars of a
  			text one by one and separate them to tokens.
  **/
  
  class CharacterSource
  {
  	public:
  		// LIFECYCLE
  						CharacterSource();
  						~CharacterSource();
  
  		// OPERATIONS
  		/** Loads the complete contents of in_rSource into the classes private memory.
  			If in_rSource is a file, it has to be open of course.
              After loading the text, the CurChar() is set on the begin of the text.
  		**/
  		void			LoadText(
  							csv::bstream &		io_rSource);
  
          void            InsertTextAtCurPos(
                              const char *        i_sText2Insert );
  
  		///	@return CurChar() after moving forward one char.
              char            MoveOn();
  		/** @return
  			The token which starts at the char which was CurChar(), when
  			CutToken() was called the last time - or at the beginning of the text.
  			The token ends by the CurChar() being replaced by a '\0'.
  
  			Value is valid until the next call of CutToken() or ~CharacterSource().
  		**/
  		const char *	CutToken();
  
  		// INQUIRY
          char            CurChar() const;
  		/// @return The result of the last CutToken(). Or NULL, if there was none yet.
  		const char *	CurToken() const;
  
  	// INQUIRY
  		/// @return true, if
  		bool			IsFinished() const;
  
  	private:
          struct S_SourceState
          {
      		DYN char *		dpSource;
  		    intt			nSourceSize;
  
  		    intt			nCurPos;
  		    intt			nLastCut;
  		    intt			nLastTokenStart;
  		    char 			cCharAtLastCut;
  
                              S_SourceState(
      		                    DYN char *		dpSource,
  		                        intt			nSourceSize,
  		                        intt			nCurPos,
  		                        intt			nLastCut,
  		                        intt			nLastTokenStart,
  		                        char 			cCharAtLastCut );
          };
  
          void            BeginSource();
  		intt			CurPos() const;
          char            MoveOn_OverStack();
  
          // DATA
          std::stack< S_SourceState >
                          aSourcesStack;
  
  		DYN char *		dpSource;
  		intt			nSourceSize;
  
  		intt			nCurPos;
  		intt			nLastCut;
  		intt			nLastTokenStart;
  		char 			cCharAtLastCut;
  };
  
  
  inline char
  CharacterSource::MoveOn()
  	{
  if (DEBUG_ShowText())
  {
  		Cerr() << char(dpSource[nCurPos+1]) << Flush();
  }
          if ( nCurPos < nSourceSize-1 )
      		return dpSource[++nCurPos];
          else if ( aSourcesStack.size() > 0 )
              return MoveOn_OverStack();
          else
              return dpSource[nCurPos = nSourceSize];
  	}
  inline char
  CharacterSource::CurChar() const
  	{ return nCurPos != nLastCut ? dpSource[nCurPos] : cCharAtLastCut; }
  inline const char *
  CharacterSource::CurToken() const
  	{ return &dpSource[nLastTokenStart]; }
  inline bool
  CharacterSource::IsFinished() const
  	{ return nCurPos >= nSourceSize; }
  inline intt
  CharacterSource::CurPos() const
  	{ return nCurPos; }
  
  
  
  
  #endif
  
  
  