// $Revision: 1.1 $ // Copyright (c) 1994 Taligent, Inc. All rights reserved. #ifndef TaligentSamples_SNIPPETDISPLAY #define TaligentSamples_SNIPPETDISPLAY #ifndef IOSTREAMH #include #endif #ifndef Taligent_STANDARDTEXT #include #endif #ifndef Taligent_MEMORY #include #endif #ifndef Taligent_UNICODEGENERAL #include #endif // A reference to char data. class TRepChars { public: TRepChars(const char*); TRepChars(const char*, unsigned long); TRepChars(const unsigned char*); TRepChars(const unsigned char*, unsigned long); TRepChars(const signed char*); TRepChars(const signed char*, unsigned long); const char* GetChars() const; unsigned long GetLength() const; private: const char* fChars; unsigned long fLength; }; // A reference to UniChar data. class TRepUniChars { public: TRepUniChars(const UniChar*); TRepUniChars(const UniChar*, unsigned long); const UniChar* GetUniChars() const; unsigned long GetLength() const; private: const UniChar* fUniChars; unsigned long fLength; }; // A reference to byte data. TSnippetDisplay will use the chunk size as a hint // when formatting data for output: if it not 0, TSnippetDisplay uses it, else // TSnippetDisplay provides its own chunk size. A space is inserted in the output // after every chunksize characters. class TRepData { public: TRepData(const void*, unsigned long length, unsigned long chunkSize = 0); const void* GetData() const; unsigned long GetLength() const; unsigned long GetChunkSize() const; private: const void* fData; unsigned long fLength; unsigned long fChunkSize; }; // Provides 'stream' protocol for accepting chars, unichars, data, and text. Default // behavior 'asciifies' the data and inserts it into the buffer. Flush just resets // the buffer. Defaults: data chunk size is 2 bytes, asciify newline is false, // indent = 0, indent text is four spaces. // // Note that c++ will construct TRepChars for you if you call display << "Some char* text" // since TRepChars provides a constructor that takes a const char*. // // Single chars and UniChars will coerce to double, so to stream them you need to // create a TRepChar or TRepUniChar directly. The promotion to double takes // precedence over indirectly constructing a TRepChar or TRepUniChar, so having // those take char or UniChar parameters for their constructors wouldn't fix this. // Another alternative is to overload all the standard integral types, but UniChar // is simply a short, so there would still be ambiguity. This seemed the best // solution. class TSnippetDisplay { public: TSnippetDisplay(); virtual ~TSnippetDisplay(); typedef TSnippetDisplay& (*SnippetDisplayFn)(TSnippetDisplay&); TSnippetDisplay& operator<<(const TRepChars&); TSnippetDisplay& operator<<(const TRepUniChars&); TSnippetDisplay& operator<<(const TRepData&); TSnippetDisplay& operator<<(const TText&); TSnippetDisplay& operator<<(double); TSnippetDisplay& operator<<(SnippetDisplayFn); virtual void Newline(); virtual void Flush(); virtual void Reset(); virtual int GetDataChunkSize() const; virtual void SetDataChunkSize(int cs); virtual bool GetAsciifyNewline() const; virtual void SetAsciifyNewline(bool); virtual int GetIndent() const; virtual void SetIndent(int); virtual void SetIndentText(const TText&); virtual void GetIndentText(TText&) const; protected: virtual TSnippetDisplay& DisplayChars(const TRepChars&); virtual TSnippetDisplay& DisplayUniChars(const TRepUniChars&); virtual TSnippetDisplay& DisplayData(const TRepData&); virtual TSnippetDisplay& DisplayText(const TText&); virtual TSnippetDisplay& DisplayDouble(double); virtual TSnippetDisplay& DisplayFn(SnippetDisplayFn); virtual void AsciifyChars(const TRepChars&); virtual void AsciifyUniChars(const TRepUniChars&); virtual void AsciifyData(const TRepData&); virtual TStream& GetBuffer(); virtual TMemorySurrogate GetBufferMemory(); virtual void CheckIndent(); virtual void HandleFlush(); private: int fDataChunkSize; int fIndent; TStandardText fIndentText; bool fNewline; bool fAsciifyNewline; TContiguousGrowingStream fBuffer; }; // Overrides HandleFlush to write the contents of the buffer to an ostream. class TSnippetCoutDisplay : public TSnippetDisplay { public: TSnippetCoutDisplay(ostream& os = cout); virtual ~TSnippetCoutDisplay(); virtual void Newline(); protected: virtual void HandleFlush(); private: ostream& fOStream; }; // Overrides HandleFlush to write the contents of the buffer to a TText. Also // overrides DisplayText to copy the text and styles directly to the TText. class TSnippetTextDisplay : public TSnippetDisplay { public: TSnippetTextDisplay(); virtual ~TSnippetTextDisplay(); virtual void Newline(); virtual void Reset(); virtual void GetText(TText&) const; protected: virtual TSnippetDisplay& DisplayText(const TText&); virtual void HandleFlush(); private: TStandardText fText; }; // Overload endl, flush for convenience of folks used to ostream, and add indent/outdent. TSnippetDisplay& endl(TSnippetDisplay&); TSnippetDisplay& flush(TSnippetDisplay&); TSnippetDisplay& indent(TSnippetDisplay&); TSnippetDisplay& outdent(TSnippetDisplay&); // Inline implementation. TSnippetDisplay& TSnippetDisplay::operator<<(const TRepChars& rc) { return DisplayChars(rc); } TSnippetDisplay& TSnippetDisplay::operator<<(const TRepUniChars& ruc) { return DisplayUniChars(ruc); } TSnippetDisplay& TSnippetDisplay::operator<<(const TRepData& rd) { return DisplayData(rd); } TSnippetDisplay& TSnippetDisplay::operator<<(const TText& text) { return DisplayText(text); } TSnippetDisplay& TSnippetDisplay::operator<<(double n) { return DisplayDouble(n); } TSnippetDisplay& TSnippetDisplay::operator<<(SnippetDisplayFn fn) { return DisplayFn(fn); } int TSnippetDisplay::GetDataChunkSize() const { return fDataChunkSize; } void TSnippetDisplay::SetDataChunkSize(int cs) { fDataChunkSize = cs; } int TSnippetDisplay::GetIndent() const { return fIndent; } void TSnippetDisplay::SetIndent(int indent) { fIndent = Max(0, Min(indent, 30)); } void TSnippetDisplay::SetIndentText(const TText& text) { fIndentText = text; } void TSnippetDisplay::GetIndentText(TText& text) const { text = fIndentText; } bool TSnippetDisplay::GetAsciifyNewline() const { return fAsciifyNewline; } void TSnippetDisplay::SetAsciifyNewline(bool tf) { fAsciifyNewline = tf; } TStream& TSnippetDisplay::GetBuffer() { return fBuffer; } TRepChars::TRepChars(const char* s) : fChars(s), fLength(strlen(s)) {} TRepChars::TRepChars(const char* s, unsigned long l) : fChars(s), fLength(l) {} TRepChars::TRepChars(const unsigned char* s) : fChars((char*)s), fLength(strlen((char*)s)) {} TRepChars::TRepChars(const unsigned char* s, unsigned long l) : fChars((char*)s), fLength(l) {} TRepChars::TRepChars(const signed char* s) : fChars((char*)s), fLength(strlen((char*)s)) {} TRepChars::TRepChars(const signed char* s, unsigned long l) : fChars((char*)s), fLength(l) {} const char* TRepChars::GetChars() const { return fChars; } unsigned long TRepChars::GetLength() const { return fLength; } TRepUniChars::TRepUniChars(const UniChar* u) : fUniChars(u), fLength (0) { for (register const UniChar* p = u; *p != TGeneralPunctuation::kNull; p++) {} fLength = p - u; } TRepUniChars::TRepUniChars(const UniChar* u, unsigned long l) : fUniChars(u), fLength(l) {} const UniChar* TRepUniChars::GetUniChars() const { return fUniChars; } unsigned long TRepUniChars::GetLength() const { return fLength; } TRepData::TRepData(const void* d, unsigned long l, unsigned long cs) : fData(d), fLength(l), fChunkSize (cs) {} const void* TRepData::GetData() const { return fData; } unsigned long TRepData::GetLength() const { return fLength; } unsigned long TRepData::GetChunkSize() const { return fChunkSize; } #endif // TaligentSamples_SNIPPETDISPLAY