home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Found / FWString / Sources / FWCharIt.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  15.7 KB  |  530 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWCharIt.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    (c) 1993, 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFound.hpp"
  11.  
  12. #ifndef FWCHARIT_H
  13. #include "FWCharIt.h"
  14. #endif
  15.  
  16. #if FW_LIB_EXPORT_PRAGMAS
  17. #pragma lib_export on
  18. #endif
  19.  
  20. #ifdef FW_BUILD_MAC
  21. #pragma segment FWString
  22. #endif
  23.  
  24. //========================================================================================
  25. //    CLASS FW_CTextReader
  26. //========================================================================================
  27.  
  28. #ifdef FW_DEBUG_TEXT_ITERATORS
  29. //----------------------------------------------------------------------------------------
  30. //    FW_CTextReader::ClassInvariants
  31. //----------------------------------------------------------------------------------------
  32.  
  33. void FW_CTextReader::ClassInvariants() const
  34. {
  35.     if (fNext == 0)
  36.     {
  37.         // Must be in initial state, before first GetNextBuffer
  38.         FW_ASSERT(fStart == 0);
  39.         FW_ASSERT(fLimit == 0);
  40.         FW_ASSERT(fBufferSum == 0);        
  41.     }
  42.     else if (fNext == fLimit)
  43.     {
  44.         // Must be at end of data structure
  45.         FW_ASSERT(fBufferSum == fByteLength);
  46.     }
  47.     else
  48.     {
  49.         FW_ASSERT(fBufferSum < fByteLength);
  50.         if (fNext<fStart)
  51.         {
  52.             // Must be at position -1 (backup past beginning)
  53.             FW_ASSERT(fBufferSum == 0);
  54.             FW_ASSERT(fNext == fStart-1); // may not be correct anymore
  55.         }
  56.         else
  57.         {
  58.             // Must be somewhere in middle of stream
  59.             FW_ASSERT(fStart <= fNext);
  60.             FW_ASSERT(fNext <= fLimit);
  61.         }
  62.     }
  63. }
  64. #endif
  65.  
  66. //----------------------------------------------------------------------------------------
  67. //    FW_CTextReader::FW_CTextReader
  68. //----------------------------------------------------------------------------------------
  69.  
  70. FW_CTextReader::FW_CTextReader(    const FW_Byte *chunk1Start, 
  71.                                 const FW_Byte *chunk1Limit,
  72.                                 FW_ByteCount totalLength) :
  73.     fStart(chunk1Start), 
  74.     fLimit(chunk1Limit), 
  75.     fNext(chunk1Start), 
  76.     fByteLength(totalLength),
  77.     fBufferSum(0),
  78.     fBytesPerChar(sizeof(FW_Char))
  79. {
  80.     ClassInvariants();
  81. }
  82.  
  83. //----------------------------------------------------------------------------------------
  84. //    FW_CTextReader::~FW_CTextReader
  85. //----------------------------------------------------------------------------------------
  86.  
  87. FW_CTextReader::~FW_CTextReader()
  88. {
  89. }
  90.  
  91. //----------------------------------------------------------------------------------------
  92. //    FW_CTextReader::CharactersInBlock
  93. //----------------------------------------------------------------------------------------
  94.  
  95. FW_CharacterCount FW_CTextReader::CharactersInBlock(const FW_Byte* last,
  96.                                                     const FW_Byte* first)
  97. {
  98.     return (last-first)/fBytesPerChar;
  99. }
  100.  
  101. //----------------------------------------------------------------------------------------
  102. //    FW_CTextReader::GetLength
  103. //----------------------------------------------------------------------------------------
  104.  
  105. FW_CharacterCount FW_CTextReader::GetLength()
  106. {
  107.     return fByteLength/fBytesPerChar;
  108. }
  109.  
  110. //----------------------------------------------------------------------------------------
  111. //    FW_CTextReader::GetCharacterAndAdvance
  112. //----------------------------------------------------------------------------------------
  113.  
  114. FW_Char FW_CTextReader::GetCharacterAndAdvance()
  115. {
  116.     ClassInvariants();
  117.     register FW_Char temp = PeekCharacter();
  118.     if (temp != FW_kNulCharacter)
  119.         Advance(1);
  120.     ClassInvariants();
  121.     return temp;
  122. }
  123.  
  124. //----------------------------------------------------------------------------------------
  125. FW_LChar FW_CTextReader::GetCharacterAndAdvance(FW_ByteCount& bytesInChar)
  126. {
  127.     ClassInvariants();
  128.     register FW_LChar temp = PeekCharacter(bytesInChar);
  129.     if (temp != FW_kNulCharacter)
  130.         Advance(bytesInChar);
  131.     ClassInvariants();
  132.     return temp;
  133. }
  134.  
  135. //----------------------------------------------------------------------------------------
  136. //    FW_CTextReader::BackupAndGetCharacter
  137. //----------------------------------------------------------------------------------------
  138.  
  139. FW_Char FW_CTextReader::BackupAndGetCharacter()
  140. {
  141.     ClassInvariants();
  142.     Backup(1);
  143.     ClassInvariants();
  144.     return PeekCharacter();
  145. }
  146.  
  147. //----------------------------------------------------------------------------------------
  148. FW_LChar FW_CTextReader::BackupAndGetCharacter(FW_ByteCount& bytesInChar)
  149. {
  150.     ClassInvariants();
  151.     Backup(fBytesPerChar);
  152.     ClassInvariants();
  153.     return PeekCharacter(bytesInChar);
  154. }
  155.  
  156. //----------------------------------------------------------------------------------------
  157. //    FW_CTextReader::PeekCharacter
  158. //----------------------------------------------------------------------------------------
  159.  
  160. FW_Char FW_CTextReader::PeekCharacter()
  161. {
  162.     ClassInvariants();
  163.  
  164.     if (fNext>=fStart && fNext<fLimit)
  165.         return *((FW_Char*)fNext);    // default to one byte characters
  166.     else
  167.         return FW_kNulCharacter;
  168. }
  169.  
  170. //----------------------------------------------------------------------------------------
  171. FW_LChar FW_CTextReader::PeekCharacter(FW_ByteCount& bytesInChar)
  172. {
  173.     ClassInvariants();
  174.     bytesInChar = fBytesPerChar;
  175.  
  176.     if (fNext>=fStart && fNext<fLimit)
  177.     {
  178.         FW_LChar ch = *((FW_Char*)fNext);    // default to one byte characters
  179.         if (fBytesPerChar == 2)
  180.             ch = *((FW_WChar*)fNext);
  181.         if (fBytesPerChar == 4)
  182.             ch = *((FW_LChar*)fNext);
  183.         return ch;
  184.     }
  185.     else
  186.         return FW_kNulCharacter;
  187. }
  188.  
  189. //----------------------------------------------------------------------------------------
  190. //    FW_CTextReader::Advance
  191. //----------------------------------------------------------------------------------------
  192.  
  193. void FW_CTextReader::Advance(FW_ByteCount delta)
  194. {
  195.     ClassInvariants();
  196.     FW_ASSERT(delta>=0);
  197.     FW_ASSERT(delta+GetPosition() <= fByteLength);
  198.     FW_ByteCount inThisBuf = BytesInBlock(fLimit, fNext);
  199.     while (delta >= inThisBuf)
  200.     {
  201.         delta -= inThisBuf;
  202.         fNext += inThisBuf;
  203.         GetNextBuffer();
  204.         inThisBuf = BytesInBlock(fLimit, fStart);
  205.     }
  206.     fNext += delta;
  207.     ClassInvariants();
  208. }
  209.  
  210. //----------------------------------------------------------------------------------------
  211. //    FW_CTextReader::Backup
  212. //----------------------------------------------------------------------------------------
  213.  
  214. void FW_CTextReader::Backup(FW_ByteCount delta)
  215. {
  216.     ClassInvariants();
  217.     FW_ASSERT(delta>=0);
  218. /*    FW_ASSERT(delta<=GetPosition());    * doesn't allow backup at start */
  219.  
  220.     if (delta > 0)
  221.     {
  222.         if (fNext==fStart)    // at the start of a buffer
  223.         {
  224.             GetPreviousBuffer();
  225.         }
  226.         else if (fNext == fLimit)    // at the end of the last buffer
  227.         {    // subtract bytes that were added by GetNextBuffer
  228.             fBufferSum -= BytesInBlock(fLimit, fStart);
  229.         }
  230.  
  231.         FW_ByteCount inThisBuf = BytesInBlock(fNext, fStart);
  232.         if (inThisBuf > 0)
  233.             while (delta > inThisBuf)
  234.             {
  235.                 delta -= inThisBuf;
  236.                 fNext = fStart;
  237.                 GetPreviousBuffer();
  238.                 inThisBuf = BytesInBlock(fNext, fStart);
  239.             }
  240.         fNext = PreviousByte(fNext, delta);    // may backup before fStart (-1)
  241.         ClassInvariants();
  242.     }
  243. }
  244.  
  245. //----------------------------------------------------------------------------------------
  246. //    FW_CTextReader::GetNextBuffer
  247. //----------------------------------------------------------------------------------------
  248.  
  249. void FW_CTextReader::GetNextBuffer()
  250. {
  251.     // ClassInvariants won't hold here.
  252.     // This function is called to (among other things) restore class invariants.
  253.     FW_ASSERT(fNext == fLimit);    // Must hold, but violates invariants
  254.     fBufferSum += BytesInBlock(fLimit, fStart);
  255.     if (fBufferSum < fByteLength)
  256.     {
  257.         DoGetNextBuffer();
  258.         fNext = fStart;
  259.     }
  260.     else
  261.     {
  262.         FW_ASSERT(fBufferSum == fByteLength);
  263.         fNext = fLimit;
  264.     }
  265.     ClassInvariants();
  266. }
  267.  
  268. //----------------------------------------------------------------------------------------
  269. //    FW_CTextReader::GetPreviousBuffer
  270. //----------------------------------------------------------------------------------------
  271.  
  272. void FW_CTextReader::GetPreviousBuffer()
  273. {
  274.     ClassInvariants();
  275.     if (fBufferSum == 0)
  276.     {
  277.         fNext = fStart;
  278.     }
  279.     else if (fBufferSum == fByteLength)
  280.     {
  281.         FW_ASSERT(fLimit == fNext);
  282.         fBufferSum -= BytesInBlock(fLimit, fStart);
  283.     }
  284.     else
  285.     {
  286.         FW_ASSERT(fStart == fNext);
  287.         DoGetPreviousBuffer();
  288.         FW_ASSERT(fStart < fLimit);
  289.         fBufferSum -= BytesInBlock(fLimit, fStart);
  290.         FW_ASSERT(fBufferSum >= 0);
  291.         fNext = fLimit;
  292.     }
  293.     // Invariants won't hold here
  294.     // The calling function must modify fNext appropriately
  295.     // Note that GetPreviousBuffer is a protected method,
  296.     // so clients are not held responsible to restore invariants.
  297.     // Also, subclasses shouldn't need to call this function directly.
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. //    FW_CTextReader::GetPosition
  302. //----------------------------------------------------------------------------------------
  303.  
  304. FW_ByteCount FW_CTextReader::GetPosition(FW_Boolean inChars)
  305. {
  306.     ClassInvariants();
  307.     FW_ByteCount result;
  308.  
  309.     if (fNext == fLimit)
  310.         result = fBufferSum;
  311.     else
  312.         result = fBufferSum + (fNext - fStart);
  313.  
  314.     if (inChars)
  315.     {
  316.         result = BytesToChars(result);
  317.     }
  318.  
  319.     return result;
  320. }
  321.  
  322. //----------------------------------------------------------------------------------------
  323. //    FW_CTextReader::SetPosition
  324. //----------------------------------------------------------------------------------------
  325.  
  326. void FW_CTextReader::SetPosition(FW_ByteCount position)
  327. {
  328.     ClassInvariants();
  329.     FW_ASSERT(position>=0);
  330.     FW_ASSERT(position<=fByteLength);
  331.     FW_ByteCount curPosition = GetPosition();
  332.     if (position < curPosition)
  333.         Backup(curPosition-position);
  334.     else if (position > curPosition)
  335.         Advance(position-curPosition);
  336.     ClassInvariants();
  337. }
  338.  
  339. //========================================================================================
  340. //    CLASS FW_CTextWriter
  341. //========================================================================================
  342.  
  343. //----------------------------------------------------------------------------------------
  344. //    FW_CTextWriter::FW_CTextWriter
  345. //----------------------------------------------------------------------------------------
  346.  
  347. FW_CTextWriter::FW_CTextWriter(FW_Byte *chunk1Start, 
  348.                                FW_Byte *chunk1Limit) :
  349.     fStart(chunk1Start),
  350.     fNext(chunk1Start),
  351.     fLimit(chunk1Limit),
  352.     fBufferSum(0),
  353.     fBytesPerChar(sizeof(FW_Char))
  354. {
  355. }
  356.  
  357. //----------------------------------------------------------------------------------------
  358. //    FW_CTextWriter::~FW_CTextWriter
  359. //----------------------------------------------------------------------------------------
  360.  
  361. FW_CTextWriter::~FW_CTextWriter()
  362. {
  363. }
  364.  
  365. //----------------------------------------------------------------------------------------
  366. //    FW_CTextWriter::BytesToChars
  367. //----------------------------------------------------------------------------------------
  368.  
  369. FW_CharacterCount FW_CTextWriter::BytesToChars(const FW_ByteCount bytes)
  370. {
  371.     return bytes/fBytesPerChar;
  372. }
  373.  
  374. //----------------------------------------------------------------------------------------
  375. //    FW_CTextWriter::CharactersInBlock
  376. //----------------------------------------------------------------------------------------
  377.  
  378. FW_CharacterCount FW_CTextWriter::CharactersInBlock(const FW_Byte* last,
  379.                                                     const FW_Byte* first)
  380. {
  381.     return (last-first)/fBytesPerChar;
  382. }
  383.  
  384. //----------------------------------------------------------------------------------------
  385. //    FW_CTextWriter::FlushAndUpdateText
  386. //----------------------------------------------------------------------------------------
  387. void FW_CTextWriter::FlushAndUpdateText()
  388. {
  389.     FlushBuffer(FALSE);        // flush only what's left in the buffer
  390. }
  391.  
  392. //----------------------------------------------------------------------------------------
  393. //    FW_CTextWriter::FlushBuffer
  394. //----------------------------------------------------------------------------------------
  395. void FW_CTextWriter::FlushBuffer(FW_Boolean flushAll)
  396. {
  397.     FW_ByteCount bytesToFlush;
  398.     if (flushAll)
  399.         bytesToFlush = fLimit - fStart;
  400.     else
  401.         bytesToFlush = fNext - fStart;
  402.  
  403.     DoFlushBuffer(bytesToFlush);
  404.     fBufferSum += bytesToFlush;
  405. }
  406.  
  407. //----------------------------------------------------------------------------------------
  408. //    FW_CTextWriter::PutCharacterAndAdvance
  409. //----------------------------------------------------------------------------------------
  410.  
  411. void FW_CTextWriter::PutCharacterAndAdvance(FW_LChar character, FW_ByteCount bytesInChar)
  412. {
  413.     if (fNext >= fLimit)
  414.         FlushAndGetNextBuffer();
  415.  
  416.     if (bytesInChar == 0)
  417.         bytesInChar = fBytesPerChar;
  418.  
  419.     if (bytesInChar == 1)
  420.         *((FW_Char*)fNext) = character;
  421.     else if (bytesInChar == 2)
  422.         *((FW_WChar*)fNext) = character;
  423.     else
  424.         *((FW_LChar*)fNext) = character;
  425.  
  426.     fNext += bytesInChar;
  427. }
  428.  
  429. //----------------------------------------------------------------------------------------
  430. void FW_CTextWriter::PutCharacterAndAdvance(FW_Char character)
  431. {
  432.     if (fNext >= fLimit)
  433.         FlushAndGetNextBuffer();
  434.  
  435.     *((FW_Char*)fNext) = character;
  436.     fNext += 1;
  437. }
  438.  
  439. //========================================================================================
  440. //    CLASS FW_CMemoryReader
  441. //========================================================================================
  442.  
  443. //----------------------------------------------------------------------------------------
  444. //    FW_CMemoryReader::FW_CMemoryReader
  445. //----------------------------------------------------------------------------------------
  446.  
  447. FW_CMemoryReader::FW_CMemoryReader( const FW_Byte* buffer,
  448.                                     FW_ByteCount bytes) :
  449.     FW_CTextReader(buffer, buffer+bytes, bytes)
  450. {
  451. }
  452.  
  453. //----------------------------------------------------------------------------------------
  454. //    FW_CMemoryReader::FW_CMemoryReader
  455. //----------------------------------------------------------------------------------------
  456.  
  457. FW_CMemoryReader::FW_CMemoryReader( const FW_Char* buffer,
  458.                                     FW_CharacterCount characters, 
  459.                                     FW_ByteCount bytesPerChar) :
  460.     FW_CTextReader((FW_Byte*) buffer, ((FW_Byte*) buffer)+(characters*bytesPerChar), characters*bytesPerChar)
  461. {
  462. }
  463.  
  464. //----------------------------------------------------------------------------------------
  465. //    FW_CMemoryReader::~FW_CMemoryReader
  466. //----------------------------------------------------------------------------------------
  467.  
  468. FW_CMemoryReader::~FW_CMemoryReader()
  469. {
  470. }
  471.  
  472. //----------------------------------------------------------------------------------------
  473. //    FW_CMemoryReader::DoGetNextBuffer
  474. //----------------------------------------------------------------------------------------
  475.  
  476. void FW_CMemoryReader::DoGetNextBuffer()
  477. {
  478.     FW_ASSERT(FALSE);
  479. }
  480.  
  481. //----------------------------------------------------------------------------------------
  482. //    FW_CMemoryReader::DoGetPreviousBuffer
  483. //----------------------------------------------------------------------------------------
  484.  
  485. void FW_CMemoryReader::DoGetPreviousBuffer()
  486. {
  487.     FW_ASSERT(FALSE);
  488. }
  489.  
  490. //========================================================================================
  491. //    CLASS FW_CMemoryWriter
  492. //========================================================================================
  493.  
  494. //----------------------------------------------------------------------------------------
  495. //    FW_CMemoryWriter::FW_CMemoryWriter
  496. //----------------------------------------------------------------------------------------
  497.  
  498. FW_CMemoryWriter::FW_CMemoryWriter(FW_Byte* buffer, FW_ByteCount capacity) :
  499.     FW_CTextWriter(buffer, buffer+capacity)
  500. {
  501. }
  502.  
  503. //----------------------------------------------------------------------------------------
  504. //    FW_CMemoryWriter::~FW_CMemoryWriter
  505. //----------------------------------------------------------------------------------------
  506.  
  507. FW_CMemoryWriter::~FW_CMemoryWriter()
  508. {
  509. }
  510.  
  511. //----------------------------------------------------------------------------------------
  512. //    FW_CMemoryWriter::DoFlushBuffer
  513. //----------------------------------------------------------------------------------------
  514.  
  515. void FW_CMemoryWriter::DoFlushBuffer(FW_ByteCount bytesToFlush)    // Override
  516. {
  517. FW_UNUSED(bytesToFlush);
  518.     // Do nothing
  519. }
  520.  
  521. //----------------------------------------------------------------------------------------
  522. //    FW_CMemoryWriter::DoGetNextBuffer
  523. //----------------------------------------------------------------------------------------
  524.  
  525. void FW_CMemoryWriter::DoGetNextBuffer()    // Override
  526. {
  527.     FW_ASSERT(FALSE);    // Overfilled capacity of buffer!
  528. }
  529.  
  530.