home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 9.4 KB | 274 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWCharIt.h
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #ifndef FWCHARIT_H
- #define FWCHARIT_H
-
- #ifndef FWEXCLIB_H
- #include "FWExcLib.h"
- #endif
-
- #ifndef FWPRIDEB_H
- #include "FWPriDeb.h"
- #endif
-
- #ifndef FWCHARAC_H
- #include "FWCharac.h"
- #endif
-
- #ifndef SLLOCALE_H
- #include "SLLocale.h"
- #endif
-
- #ifndef SLCHARIT_H
- #include "SLCharIt.h"
- #endif
-
- //========================================================================================
- // Forward Declarations
- //========================================================================================
-
- class FW_OMemoryRunReader;
- class FW_OMemoryRunWriter;
- class FW_OTextRunReader;
- class FW_OTextRunWriter;
-
- //========================================================================================
- // Design Notes for Text Readers
- //
- // Text readers are designed to be as fast and light-weight as possible. We assume
- // that in over 90% of the usage of Text readers, the reader will be used to make
- // one sequential pass through the data structure, operating on one character at a time.
- // The first design goal is therefore:
- // 1) Make GetCharacterAndAdvance be as efficient as possible.
- // In order to achieve full efficiency, we need to minimize overhead for error checking
- // for reading past the end of the data structure. We therefore set this requirement:
- // 2) Rely on a clear contract to minimize overhead. It is not necessary for
- // iterators to fail gracefully when misused.
- // As stated above, in 90% of the cases, the text is read in one forward pass. However,
- // reading backward through the text is a surprisingly large portion of the remaining
- // 10%, and if not supported, significantly reduces the usefulness of readers. We
- // therefore attempt to achieve this goal:
- // 3) Make "put back" a relatively efficient operation. Make it possible to
- // read backwards through the data structure.
- // Often a client iterating over text will want to note the position of some character
- // or token in the text. We therefore set another goal:
- // 4) Support GetPosition ('tell') and SetPosition ('seek') operations.
- // This last goal implies a specific need to handle the case where a client attempts to
- // seek past the end of the text data structure. In this case, to achieve efficiency,
- // we invoke 2), by setting this requirement:
- // 5) It is acceptable to state in the contract that an attempt to SetPosition to
- // an arbitrary position may fail. However, a client can use GetLength to find
- // the length of the data structure; it is safe to SetPosition to any value greater
- // than or equal to zero, and less than the length of the data structure.
- //========================================================================================
-
- //========================================================================================
- // CLASS FW_CTextReader
- //
- // A base class for iterators that read over a data structure containing characters.
- //
- // It is possible to create a TextReader to read over any text data structure, as long
- // as the following constraints are met:
- //
- // 1) It must be possible to get the total number of characters in the data structure
- // at the time the text reader is constructed.
- // 1a) Of course, we assume that the length and content of the data structure does
- // not change while the iterator is being used!
- // 2) The data members fStart, fLimit, and fNext are updated
- //
- //
- // Invariant:
- // ((fStart<=fNext) && (fNext<fLimit))
- // || ((fStart-1==fNext) && (fBufferSum==0))
- // || ((fNext==fLimit) && (fBufferSum==GetLength())
- //========================================================================================
-
- class FW_CTextReader
- {
- public:
- FW_DECLARE_AUTO(FW_CTextReader)
-
- // ----- General
-
- virtual ~ FW_CTextReader();
- FW_CTextReader(FW_OTextRunReader* adoptedReader);
- FW_CTextReader(FW_HTextReader useReader);
-
- operator FW_HTextReader()
- { return fRep; }
-
- FW_ByteCount GetPosition();
- // Get the current byte position, where 0 is first position in data structure.
-
- void SetPosition(FW_ByteCount position);
- // Set the byte position to position.
- // The result is undefined if position is outside the bounds of the data structure.
-
- FW_ByteCount GetByteLength();
- // Get number of bytes in data structure.
-
- const char* PeekByte() const;
- // Return a pointer to the current byte without advancing. Can be used for lookahead.
-
- void GetLocale(FW_Locale& locale) const;
- // Return the data structure's locale.
-
- // ----- Character-by-character iteration
-
- void Advance();
- // Advance by one character.
-
- void Backup();
- // Backup by one character.
-
- FW_LChar PeekCharacter();
- // Return the current character without advancing.
- // Can be used for lookahead.
-
- FW_LChar GetCharacterAndAdvance();
- // Get the current character and advance.
-
- FW_LChar BackupAndGetCharacter();
- // Backup and get previous character (byte).
-
- FW_LChar GetCharacterAndAdvance(FW_ByteCount& bytesInChar);
- // Get the current character and advance.
-
- FW_LChar PeekCharacter(FW_ByteCount& bytesInChar);
- // Return the current character without advancing.
-
- FW_LChar BackupAndGetCharacter(FW_ByteCount& bytesInChar);
- // Backup and get previous character.
-
- // ----- Run iteration
- // With run iteration, the client is responsible for translating between bytes and characters.
-
- void Advance(FW_ByteCount delta);
- // Advance by delta bytes.
- // It is client's responsiblity to ensure that delta bytes is a whole number of characters!
-
- void Backup(FW_ByteCount delta);
- // Backup by delta bytes.
- // It is client's responsiblity to ensure that delta bytes is a whole number of characters!
-
- void PeekRunAhead(const char*& start, FW_ByteCount& length);
- // Peek ahead into current buffer of bytes without advancing.
-
- void PeekRunBehind(const char*& end, FW_ByteCount& length);
- // Peek behind into current buffer of bytes without backing up.
- // end points one past "current" byte!
-
- private:
-
- #ifdef FW_DEBUG
- void ClassInvariants() const;
- #else
- void ClassInvariants() const {} // Let compiler optimize away the empty inline
- #endif
-
- private:
-
- FW_HTextReader fRep;
- FW_OTextRunReader* fAdoptedReader;
- };
-
- //========================================================================================
- // CLASS FW_CTextWriter
- //
- // TextWriters are (intentionally) kept simpler than TextReaders. We assume that there
- // is no need to allow backing up in order to rewrite. This results in a smaller and
- // simpler interface.
- //========================================================================================
-
- class FW_CTextWriter
- {
- public:
- FW_DECLARE_AUTO(FW_CTextWriter)
-
- // ----- General
-
- virtual ~ FW_CTextWriter();
- // Flush the current buffer.
- // Writer destructors must do whatever may be necessary to restore text structure
- // to valid state, e.g. restore NUL termination, cached length member, etc.
-
- FW_CTextWriter(FW_OTextRunWriter* adoptedWriter);
-
- FW_CTextWriter(FW_HTextWriter rep);
-
- operator FW_HTextWriter()
- { return fRep; }
-
- FW_ByteCount GetPosition();
- // Get the current byte position, where 0 is first position in data structure.
-
- // ----- Character-by-character iteration
-
- void PutCharacterAndAdvance(FW_LChar character, FW_ByteCount bytesInChar=0);
- // Write the character into the data structure and advance to next position.
- // If byte length of character is known, pass it along for efficiency.
- // If byte length is not known, pass 0 and the length will be computed.
-
- // ----- Chunky iteration
-
- void WritePeek(char*& start, FW_ByteCount& length);
- // Returns start address and length of buffer to write into.
-
- void WritePeekAdvance(char* start, FW_ByteCount bytesWritten);
- // Inform iterator of number of bytes written into peek buffer
- // start value must be same as returned by WritePeek
- // No calls to PutCharacterAndAdvance between WritePeek and WritePeekAdvance!
-
- void FlushBuffer();
- // Calls DoFlushBuffer to flush the current buffer, and updates fBufferSum.
- // A subclass may want to call this function in it's destructor if it needs
- // to defer final cleanup until after the buffer has been flushed.
-
- protected:
-
- void SetBufferSum(FW_ByteCount bufferSum);
-
- void FlushAndGetNextBuffer();
- // Calls FlushBuffer and DoGetNextBuffer.
- // Called when the buffer has filled up.
-
- private:
- FW_HTextWriter fRep;
- FW_OTextRunWriter* fAdoptedWriter;
- };
-
- //========================================================================================
- // CLASS FW_CMemoryReader
- //========================================================================================
-
- class FW_CMemoryReader : public FW_CTextReader
- {
- public:
- virtual ~FW_CMemoryReader();
- FW_CMemoryReader(const char * buffer, FW_ByteCount bytes);
- static FW_OMemoryRunReader* MakeReader(char * buffer, FW_ByteCount length, FW_Locale* locale = NULL);
- };
-
- //========================================================================================
- // CLASS FW_CMemoryWriter
- //
- // A class for writing into a buffer of characters.
- //========================================================================================
-
- class FW_CMemoryWriter : public FW_CTextWriter
- {
- public:
- virtual ~FW_CMemoryWriter();
- FW_CMemoryWriter(char * buffer, FW_ByteCount capacity);
- static FW_OMemoryRunWriter* MakeWriter(char * buffer, FW_ByteCount capacity);
- };
-
- #endif
-