From: <ag...@us...> - 2009-04-17 02:31:24
|
Revision: 547 http://zoolib.svn.sourceforge.net/zoolib/?rev=547&view=rev Author: agreen Date: 2009-04-17 02:31:06 +0000 (Fri, 17 Apr 2009) Log Message: ----------- Extend ZStrimR protocol with an Imp_ReadCP method. The default implementation does what ReadCP always used to do, but subclasses can override it if they're able to return a single code point more efficiently than an arbitrary count. Modified Paths: -------------- trunk/zoolib/source/cxx/zoolib/ZStrim.cpp trunk/zoolib/source/cxx/zoolib/ZStrim.h trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.cpp trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.h Modified: trunk/zoolib/source/cxx/zoolib/ZStrim.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZStrim.cpp 2009-04-17 02:29:39 UTC (rev 546) +++ trunk/zoolib/source/cxx/zoolib/ZStrim.cpp 2009-04-17 02:31:06 UTC (rev 547) @@ -214,26 +214,14 @@ and the value of \a oCP is undefined. */ bool ZStrimR::ReadCP(UTF32& oCP) const - { - for (;;) - { - size_t countRead; - this->Read(&oCP, 1, &countRead); - if (countRead == 0) - return false; - if (ZUnicode::sIsValid(oCP)) - return true; - } - } + { return const_cast<ZStrimR*>(this)->Imp_ReadCP(oCP); } /// Read a single CP and return it, throwing end of strim if necessary. UTF32 ZStrimR::ReadCP() const { UTF32 theCP; - size_t countRead; - this->Read(&theCP, 1, &countRead); - if (countRead == 0) - sThrowEndOfStrim(); + if (!this->ReadCP(theCP)) + sThrowEndOfStrim(); return theCP; } @@ -568,6 +556,19 @@ { sCopyReadToWrite(*this, iStrimW, iCountCP, oCountCPRead, oCountCPWritten); } +bool ZStrimR::Imp_ReadCP(UTF32& oCP) + { + for (;;) + { + size_t countRead; + this->Read(&oCP, 1, &countRead); + if (countRead == 0) + return false; + if (ZUnicode::sIsValid(oCP)) + return true; + } + } + /// Read and discard iCountCP code points. /** Override this method if your strim implementation can skip past code points without actually @@ -1668,6 +1669,26 @@ } } +bool ZStrimU_Unreader::Imp_ReadCP(UTF32& oCP) + { + if (fState == eStateUnread) + { + fState = eStateNormal; + oCP = fCP; + return true; + } + + if (fStrimSource.ReadCP(fCP)) + { + oCP = fCP; + fState = eStateNormal; + return true; + } + + fState = eStateHitEnd; + return false; + } + void ZStrimU_Unreader::Imp_Unread() { switch (fState) @@ -1777,6 +1798,18 @@ } } +bool ZStrimU_String32::Imp_ReadCP(UTF32& oCP) + { + const size_t theLength = fString.length(); + while (fPosition < theLength) + { + oCP = fString[fPosition++]; + if (ZUnicode::sIsValidCP(oCP)) + return true; + } + return false; + } + void ZStrimU_String32::Imp_Unread() { ZAssert(fPosition); Modified: trunk/zoolib/source/cxx/zoolib/ZStrim.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZStrim.h 2009-04-17 02:29:39 UTC (rev 546) +++ trunk/zoolib/source/cxx/zoolib/ZStrim.h 2009-04-17 02:31:06 UTC (rev 547) @@ -146,6 +146,8 @@ virtual void Imp_CopyTo(const ZStrimW& iStrimW, size_t iCountCP, size_t* oCountCPRead, size_t* oCountCPWritten); + virtual bool Imp_ReadCP(UTF32& oCP); + virtual void Imp_Skip(size_t iCountCP, size_t* oCountCPSkipped); //@} }; @@ -562,6 +564,8 @@ virtual void Imp_ReadUTF8(UTF8* iDest, size_t iCountCU, size_t* oCountCU, size_t iCountCP, size_t* oCountCP); + virtual bool Imp_ReadCP(UTF32& oCP); + // From ZStrimU virtual void Imp_Unread(); @@ -592,6 +596,8 @@ virtual void Imp_ReadUTF8(UTF8* iDest, size_t iCountCU, size_t* oCountCU, size_t iCountCP, size_t* oCountCP); + virtual bool Imp_ReadCP(UTF32& oCP); + // From ZStrimU virtual void Imp_Unread(); Modified: trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.cpp =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.cpp 2009-04-17 02:29:39 UTC (rev 546) +++ trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.cpp 2009-04-17 02:31:06 UTC (rev 547) @@ -158,6 +158,55 @@ } } +bool ZStrimR_CFString::Imp_ReadCP(UTF32& oCP) + { + using namespace ZUnicode; + const CFIndex length = ::CFStringGetLength(fStringRef); + for (;;) + { + if (fPosition >= length) + { + // We've run off the end. + return false; + } + + const UniChar theCU = ::CFStringGetCharacterAtIndex(fStringRef, fPosition++); + if (sIsSmallNormal(theCU)) + { + oCP = theCU; + return true; + } + else if (sIsSmallNormalOrHighSurrogate(theCU)) + { + // Must be a high surrogate as it's not a small normal. + if (fPosition >= length) + { + // But we'd run off the end. Restore the value of ioCurrent to indicate this. + --fPosition; + return false; + } + + const UniChar theCU2 = ::CFStringGetCharacterAtIndex(fStringRef, fPosition++); + if (sIsLowSurrogate(theCU2)) + { + oCP = sUTF32FromSurrogates(theCU, theCU2); + return true; + } + --fPosition; + } + else if (sIsBigNormalOrBeyond(theCU)) + { + oCP = theCU; + return true; + } + else + { + // Must be an out of order low surrogate. + } + } + return false; + } + // ================================================================================================= #pragma mark - #pragma mark * ZStrimW_CFString Modified: trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.h =================================================================== --- trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.h 2009-04-17 02:29:39 UTC (rev 546) +++ trunk/zoolib/source/cxx/zoolib/ZStrim_CFString.h 2009-04-17 02:31:06 UTC (rev 547) @@ -52,6 +52,8 @@ virtual void Imp_ReadUTF8(UTF8* iDest, size_t iCountCU, size_t* oCountCU, size_t iCountCP, size_t* oCountCP); + virtual bool Imp_ReadCP(UTF32& oCP); + private: ZRef<CFStringRef> fStringRef; size_t fPosition; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |