CopyOnWriteData.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:24k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const CopyOnWriteData_cxx_Version =
  51.     "$Id: CopyOnWriteData.cxx,v 1.23 2001/05/28 21:28:34 bko Exp $";
  52. //Authors: Sunitha Kumar, Cullen Jennings
  53. #include "CopyOnWriteData.hxx"
  54. #include <cstdio>
  55. #include <ctype.h>
  56. //PURIFYSTART
  57. #include <strings.h>
  58. //PURIFYSTOP
  59. #include "cpLog.h"
  60. #if USE_HASH_MAP
  61. #include <hash_map>
  62. #endif
  63. #define INLINE_ inline
  64. static const int baseMultiple = 32;
  65. INLINE_
  66. CopyOnWriteData::CopyOnWriteData()
  67.         :
  68.     data_(),
  69.     myCdata(),
  70.     changed(true)
  71. {
  72. }
  73. INLINE_
  74. CopyOnWriteData::CopyOnWriteData( const char* str, int length )
  75.     :
  76.     data_(str, length),
  77.     myCdata(),
  78.     changed(true)
  79. {
  80. }
  81. INLINE_
  82. CopyOnWriteData::CopyOnWriteData( const char* str )
  83.     :
  84.     data_(str, mystrlen(str)),
  85.     myCdata(),
  86.     changed(true)
  87. {
  88.     changed = true;
  89. }
  90. INLINE_
  91. CopyOnWriteData::CopyOnWriteData( const string& str )
  92.     :
  93.     data_(str.c_str(), str.length()),
  94.     myCdata(),
  95.     changed(true)
  96. {
  97. }
  98. INLINE_
  99. CopyOnWriteData::CopyOnWriteData( const mstring& mstr )
  100.     :
  101.     data_(mstr.c_str(), mstr.length()),
  102.     myCdata(),
  103.     changed(true)
  104. {
  105. }
  106. INLINE_
  107. CopyOnWriteData::CopyOnWriteData( int value )
  108.     :
  109.     data_(8),
  110.     myCdata(),
  111.     changed(true)
  112. {
  113.     char str[256];
  114.     sprintf(str, "%d", value);
  115.     int tmp = mystrlen(str);
  116.     data_.makeWritable(tmp);
  117.     mmemcpy(data_.bitsPtr, str, tmp);
  118.     data_.size = tmp;
  119. }
  120. INLINE_
  121. CopyOnWriteData::CopyOnWriteData( const CopyOnWriteData& data )
  122.     :
  123.     data_(data.data_),
  124.     myCdata(),
  125.     changed(true)
  126. {
  127. }
  128. INLINE_
  129. CopyOnWriteData&
  130. CopyOnWriteData::operator=( const char* str )
  131. {
  132.     ASSERT_WRITE(t1, myAssertable);
  133. //    Vocal::Threads::WriteLock
  134.     int tmp = mystrlen(str);
  135.     data_.clear();
  136.     data_.makeWritable(tmp);
  137.     mmemcpy(data_.bitsPtr, str, tmp);
  138.     data_.size = tmp;
  139.     changed = true;
  140.     return *this;
  141. }
  142. INLINE_
  143. CopyOnWriteData&
  144. CopyOnWriteData::operator=( const CopyOnWriteData& data )
  145. {
  146.     ASSERT_WRITE(t1, myAssertable);
  147.     ASSERT_READ(t2, data.myAssertable);
  148.     if (this != &data)
  149.     {
  150.         data_.clear();
  151.         data_ = data.data_;
  152.     }
  153.     changed = true;
  154.     return *this;
  155. }
  156. INLINE_
  157. const char*
  158. CopyOnWriteData::getData() const
  159. {
  160.     ASSERT_READ(t1, myAssertable);
  161.     if(changed)
  162.     {
  163.         changed = false;
  164.         return myCdata.c_str(data_.bitsPtr, data_.size);
  165.     }
  166.     else
  167.     {
  168.         return myCdata.get_c_str();
  169.     }
  170. }
  171. INLINE_
  172. const char*
  173. CopyOnWriteData::getDataBuf() const
  174. {
  175.     ASSERT_READ(t1, myAssertable);
  176.     return data_.bitsPtr;
  177. }
  178. INLINE_
  179. char
  180. CopyOnWriteData::getChar(int i) const
  181. {
  182.     ASSERT_READ(t1, myAssertable);
  183.     assert(i < data_.size);
  184.     return data_.bitsPtr[i];
  185. }
  186. // this version does not check for assert_read, so it is internal only
  187. INLINE_
  188. char
  189. CopyOnWriteData::getCharInternal(int i) const
  190. {
  191.     assert(i < data_.size);
  192.     return data_.bitsPtr[i];
  193. }
  194. INLINE_
  195. void
  196. CopyOnWriteData::setchar(int i, char c)
  197. {
  198.     ASSERT_WRITE(t1, myAssertable);
  199.     data_.makeWritable(i + 1);
  200.     if (i >= data_.size)
  201.     {
  202.         // do something now
  203.         data_.size = i + 1;
  204.     }
  205.     data_.bitsPtr[i] = c;
  206.     changed = true;
  207. }
  208. INLINE_
  209. char
  210. CopyOnWriteData::operator[](int i) const
  211. {
  212.     ASSERT_READ(t1, myAssertable);
  213.     return getCharInternal(i);
  214. }
  215. INLINE_
  216. int
  217. CopyOnWriteData::length() const
  218. {
  219.     ASSERT_READ(t1, myAssertable);
  220.     return data_.size;
  221. }
  222. INLINE_
  223. void
  224. CopyOnWriteData::setBufferSize(int size)
  225. {
  226.     ASSERT_WRITE(t1, myAssertable);
  227.     data_.makeWritable(size);
  228.     changed = true;
  229. }
  230. INLINE_
  231. int
  232. CopyOnWriteData::compare(const char* str, int length) const
  233. {
  234.     ASSERT_READ(t1, myAssertable);
  235.     return data_.compare(str, length);
  236. }
  237. INLINE_
  238. int
  239. CopyOnWriteData::compare(const CopyOnWriteData& data) const
  240. {
  241.     ASSERT_READ(t1, myAssertable);
  242.     ASSERT_READ(t2, data.myAssertable);
  243.     return data_.compare(data.data_.bitsPtr, data.data_.size);
  244. }
  245. INLINE_
  246. int
  247. CopyOnWriteData::compareNoCase(const char* str, int length) const
  248. {
  249.     ASSERT_READ(t1, myAssertable);
  250.     return data_.compareNoCase(str, length);
  251. }
  252. INLINE_
  253. int
  254. CopyOnWriteData::compareNoCase(const CopyOnWriteData& data) const
  255. {
  256.     ASSERT_READ(t1, myAssertable);
  257.     ASSERT_READ(t2, data.myAssertable);
  258.     return data_.compareNoCase(data.data_.bitsPtr, data.data_.size);
  259. }
  260. INLINE_
  261. bool
  262. CopyOnWriteData::operator==(const char* str) const
  263. {
  264. //    return ( data_.compare(str, mystrlen(str)) == 0 );
  265.     ASSERT_READ(t1, myAssertable);
  266.     return ( data_.compareCstr(str) == 0 );
  267. }
  268. INLINE_
  269. bool
  270. CopyOnWriteData::operator==( const CopyOnWriteData& data) const
  271. {
  272.     ASSERT_READ(t1, myAssertable);
  273.     ASSERT_READ(t2, data.myAssertable);
  274.     return ( data_.compare(data.data_.bitsPtr, data.data_.size) == 0 );
  275. }
  276. INLINE_
  277. bool
  278. CopyOnWriteData::operator!=(const char* str) const
  279. {
  280.     ASSERT_READ(t1, myAssertable);
  281.     return !operator==(str);
  282. }
  283. INLINE_
  284. bool
  285. CopyOnWriteData::operator!=(const CopyOnWriteData& data) const
  286. {
  287.     ASSERT_READ(t1, myAssertable);
  288.     ASSERT_READ(t2, data.myAssertable);
  289.     return !operator==(data);
  290. }
  291. INLINE_
  292. bool
  293. CopyOnWriteData::operator>(const CopyOnWriteData& data) const
  294. {
  295.     ASSERT_READ(t1, myAssertable);
  296.     ASSERT_READ(t2, data.myAssertable);
  297.     return ( data_.compare(data.data_.bitsPtr, data.data_.size) > 0 );
  298. }
  299. INLINE_
  300. bool
  301. CopyOnWriteData::operator<(const CopyOnWriteData& data) const
  302. {
  303.     ASSERT_READ(t1, myAssertable);
  304.     ASSERT_READ(t2, data.myAssertable);
  305.     return ( data_.compare(data.data_.bitsPtr, data.data_.size) < 0 );
  306. }
  307. INLINE_
  308. bool
  309. CopyOnWriteData::operator>(const char* data) const
  310. {
  311.     ASSERT_READ(t1, myAssertable);
  312.     return ( data_.compareCstr(data) > 0 );
  313. }
  314. INLINE_
  315. bool
  316. CopyOnWriteData::operator<(const char* data) const
  317. {
  318.     ASSERT_READ(t1, myAssertable);
  319.     return ( data_.compareCstr(data) < 0 );
  320. }
  321. INLINE_
  322. CopyOnWriteData
  323. CopyOnWriteData::operator+(const CopyOnWriteData& data) const
  324. {
  325.     ASSERT_READ(t1, myAssertable);
  326.     ASSERT_READ(t2, data.myAssertable);
  327.     CopyOnWriteData tmp(*this);
  328.     tmp += data;
  329.     return tmp;
  330. }
  331. INLINE_
  332. CopyOnWriteData
  333. CopyOnWriteData::operator+(const char* str) const
  334. {
  335.     ASSERT_READ(t1, myAssertable);
  336.     CopyOnWriteData tmp(*this);
  337.     tmp += str;
  338.     return tmp;
  339. }
  340. INLINE_
  341. void
  342. CopyOnWriteData::operator+=(const CopyOnWriteData& data)
  343. {
  344.     ASSERT_WRITE(t1, myAssertable);
  345.     ASSERT_READ(t2, data.myAssertable);
  346.     if (data.data_.size)
  347.     {
  348.         data_.makeWritable(data_.size + data.data_.size);
  349.         mmemcpy(data_.bitsPtr + data_.size,
  350.                data.data_.bitsPtr, data.data_.size);
  351.         data_.size += data.data_.size;
  352.     }
  353.     changed = true;
  354. }
  355. INLINE_
  356. void
  357. CopyOnWriteData::operator+=(const char* str)
  358. {
  359.     ASSERT_WRITE(t1, myAssertable);
  360.     int len = mystrlen(str);
  361.     if (len)
  362.     {
  363.         data_.makeWritable(data_.size + len);
  364.         mmemcpy(data_.bitsPtr + data_.size, str, len);
  365.         data_.size += len;
  366.     }
  367.     changed = true;
  368. }
  369. INLINE_
  370. CopyOnWriteData::~CopyOnWriteData()
  371. {
  372. }
  373. INLINE_
  374. void
  375. CopyOnWriteData::erase()
  376. {
  377.     ASSERT_WRITE(t1, myAssertable);
  378.     data_.clear();
  379.     changed = true;
  380. }
  381. INLINE_
  382. CopyOnWriteData::operator string() const
  383. {
  384.     ASSERT_READ(t1, myAssertable);
  385.     return string(data_.bitsPtr, static_cast < unsigned int > (data_.size));
  386. }
  387. INLINE_
  388. CopyOnWriteData::operator const char*() const
  389. {
  390.     return getData();
  391. }
  392. INLINE_
  393. CopyOnWriteData::operator mstring() const
  394. {
  395.     return mstring(getData());
  396. }
  397. INLINE_
  398. CopyOnWriteData::operator int() const
  399. {
  400.     ASSERT_READ(t1, myAssertable);
  401.     int l = data_.size;
  402.     int val = 0;
  403.     char* p = data_.bitsPtr;
  404.     while (l--)
  405.     {
  406.         char c = *p++;
  407.         if ((c >= '0') && (c <= '9'))
  408.         {
  409.             val *= 10;
  410.             val += c - '0';
  411.         }
  412.         else
  413.         {
  414.             return val;
  415.         }
  416.     }
  417.     return val;
  418. }
  419. INLINE_
  420. void CopyOnWriteData::lowercase()
  421. {
  422.     ASSERT_WRITE(t1, myAssertable);
  423.     int len = data_.size;
  424.     data_.makeWritable(len);
  425.     int i = 0;
  426.     while(i < len)
  427.     {
  428. data_.bitsPtr[i] = std::tolower(data_.bitsPtr[i]);
  429. i++;
  430.     }
  431.     changed = true;
  432. }
  433. INLINE_
  434. void CopyOnWriteData::uppercase()
  435. {
  436.     ASSERT_WRITE(t1, myAssertable);
  437.     int len = data_.size;
  438.     data_.makeWritable(len);
  439.     int i = 0;
  440.     while(i < len)
  441.     {
  442. data_.bitsPtr[i] = std::toupper(data_.bitsPtr[i]);
  443. i++;
  444.     }
  445.     changed = true;
  446. }
  447. INLINE_
  448. string CopyOnWriteData::getstring() const
  449. {
  450.     ASSERT_READ(t1, myAssertable);
  451.     return string(data_.bitsPtr, static_cast < unsigned int > (data_.size));
  452. }
  453. INLINE_
  454. int
  455. CopyOnWriteData::find( const CopyOnWriteData& match, int start )
  456. {
  457.     ASSERT_WRITE(t1, myAssertable);
  458.     changed = true;
  459.     int pos = 0;
  460.     if ( start != npos )
  461.     {
  462.         pos = start;
  463.     }
  464.     const char* ptr = data_.bitsPtr + pos;
  465.     while ((pos + match.data_.size) <= data_.size)
  466.     {
  467.         if ( (*(ptr) == *match.data_.bitsPtr ) &&
  468.                 (strncmp(ptr,
  469.                          match.data_.bitsPtr,
  470.                          match.data_.size)
  471.                  == 0))
  472.         {
  473.             // a match has been found
  474.             return pos;
  475.         }
  476.         ++ptr;
  477.         ++pos;  // or not
  478.     }
  479.     return npos;
  480. }
  481. INLINE_
  482. int
  483. CopyOnWriteData::find( const char* match, int start )
  484. {
  485.     ASSERT_WRITE(t1, myAssertable);
  486.     changed = true;
  487.     int matchLength = mystrlen(match);
  488.     int pos = 0;
  489.     if ( start != npos )
  490.     {
  491.         pos = start;
  492.     }
  493.     int compares = data_.size - matchLength - pos;
  494.     const char* ptr = data_.bitsPtr + pos;
  495.     while ((pos + matchLength) <= data_.size)
  496.         //    while((pos + matchLength) <= data_.size)
  497.         while (compares-- >= 0)
  498.         {
  499.             if (
  500.                 (*match == *(ptr)) &&
  501.                 ( strncmp(ptr,
  502.                           match,
  503.                           matchLength)
  504.                   == 0))
  505.             {
  506.                 // a match has been found
  507.                 return pos;
  508.             }
  509.             ++ptr;
  510.             ++pos;  // or not
  511.         }
  512.     return npos;
  513. }
  514. INLINE_
  515. int
  516. CopyOnWriteData::match( const char* match,
  517.                         CopyOnWriteData* retModifiedCopyOnWriteData,
  518.                         bool doReplace,
  519.                         CopyOnWriteData replaceWith)
  520. {
  521.     ASSERT_WRITE(t1, myAssertable);
  522.     changed = true;
  523.     if (replaceWith != "")
  524.     {
  525.         int retVal;
  526.         string::size_type pos = getstring().find(match);
  527.         if (pos == string::npos)
  528.         {
  529.             return NOT_FOUND;
  530.         }
  531.         int matchLength = mystrlen(match);
  532.         string::size_type replacePos = pos + matchLength;
  533.         retVal = FIRST;
  534.         if (retModifiedCopyOnWriteData)
  535.         {
  536. //            (*retModifiedCopyOnWriteData) = getstring().substr(0, pos);
  537.             ASSERT_UNLOCK(myAssertable);
  538.             (*retModifiedCopyOnWriteData) = *this;
  539.             ASSERT_WRITELOCK(myAssertable);
  540.             (*retModifiedCopyOnWriteData).data_.substr(0, pos);
  541.             if (retModifiedCopyOnWriteData->data_.size)
  542.             {
  543.                 retVal = FOUND;
  544.             }
  545.         }
  546.         if (doReplace)
  547.         {
  548.             if (replacePos <= static_cast < unsigned int > (data_.size) )
  549.             {
  550.                 replace(0, replacePos, replaceWith);
  551.             }
  552.             else
  553.             {
  554.                 printf("pos=%d  match.len=%d replacePos=%d  buf.size()= %dn",
  555.                        pos,
  556.                        matchLength,
  557.                        replacePos,
  558.                        data_.size );
  559.             }
  560.         }
  561.         return retVal;
  562.     }
  563.     else
  564.     {
  565.         int retVal;
  566.         ASSERT_UNLOCK(myAssertable);
  567.         int pos = find(match);
  568.         ASSERT_WRITELOCK(myAssertable);
  569.         if (pos == npos)
  570.         {
  571.             return NOT_FOUND;
  572.         }
  573.         int matchLength = mystrlen(match);
  574.         int replacePos = pos + matchLength;
  575.         retVal = FIRST;
  576.         if (retModifiedCopyOnWriteData)
  577.         {
  578. //            (*retModifiedCopyOnWriteData) = getstring().substr(0, pos);
  579.             ASSERT_UNLOCK(myAssertable);
  580.             (*retModifiedCopyOnWriteData) = *this;
  581.             ASSERT_WRITELOCK(myAssertable);
  582.             (*retModifiedCopyOnWriteData).data_.substr(0, pos);
  583.             if (retModifiedCopyOnWriteData->data_.size)
  584.             {
  585.                 retVal = FOUND;
  586.             }
  587.         }
  588.         if (doReplace)
  589.         {
  590.             if (replacePos <= data_.size )
  591.             {
  592.                 data_.truncate(replacePos, 0);
  593.             }
  594.             else
  595.             {
  596.                 printf("pos=%d  match.len=%d replacePos=%d  buf.size()= %dn",
  597.                        pos,
  598.                        matchLength,
  599.                        replacePos,
  600.                        data_.size );
  601.             }
  602.         }
  603.         return retVal;
  604.     }
  605. }
  606. static INLINE_
  607. bool isIn(char c, const char* match)
  608. {
  609.     char p;
  610.     while((p = *match++))
  611.     {
  612. if(p == c)
  613. {
  614.     return true;
  615. }
  616.     }
  617.     return false;
  618. }
  619. class CharSet
  620. {
  621.     public:
  622.         CharSet(const char* matchString);
  623.         bool isIn(char c);
  624.     private:
  625.         bool myArray[256];
  626. };
  627. INLINE_
  628. CharSet::CharSet(const char* matchString)
  629. {
  630.     bzero(myArray, 256 * sizeof(bool));
  631.     while(*matchString != '')
  632.     {
  633.         myArray[*matchString] = true;
  634.     }
  635. }
  636. INLINE_ bool 
  637. CharSet::isIn(char c)
  638. {
  639.     return myArray[c];
  640. }
  641. INLINE_
  642. CopyOnWriteData
  643. CopyOnWriteData::parseOutsideQuotes( const char* match, 
  644.                                      bool useQuote,
  645.                                      bool useAngle,
  646.                                      bool* matchFail )
  647. {
  648.     ASSERT_WRITE(t1, myAssertable);
  649.     changed = true;
  650.     int pos = 0;
  651.     bool inDoubleQuotes = false;
  652.     bool inAngleBrackets = false;
  653.     bool foundAny = false;
  654.     while(!foundAny && (pos < data_.size))
  655.     {
  656. char p = *(data_.bitsPtr + pos);
  657.         switch (p)
  658.         {
  659.         case '"':
  660.             if(!inAngleBrackets && useQuote)
  661.             {
  662.                 inDoubleQuotes = !inDoubleQuotes;
  663.             }
  664.             break;
  665.         case '<':
  666.             if(!inDoubleQuotes && useAngle)
  667.             {
  668.                 inAngleBrackets = true;
  669.             }
  670.             break;
  671.         case '>':
  672.             if(!inDoubleQuotes && useAngle)
  673.             {
  674.                 inAngleBrackets = false;
  675.             }
  676.             break;
  677.         default:
  678.             break;
  679.         }
  680. if(!inDoubleQuotes && !inAngleBrackets && isIn(p, match))
  681. {
  682.     foundAny = true;
  683. }
  684. pos++;
  685.     }
  686.     int pos2 = pos;
  687.     while(
  688. foundAny && 
  689. (pos2 < data_.size) && 
  690. isIn(*(data_.bitsPtr + pos2), match)
  691. )
  692.     {
  693. pos2++;
  694.     }
  695.     CopyOnWriteData result;
  696.     if(foundAny)
  697.     {
  698.         ASSERT_UNLOCK(myAssertable);
  699. result = *this;
  700.         ASSERT_WRITELOCK(myAssertable);
  701. result.data_.substr(0, pos - 1);
  702. data_.substr(pos2, data_.size);
  703. if(matchFail)
  704. {
  705.     *matchFail = false;
  706. }
  707.     }
  708.     else
  709.     {
  710. if(matchFail)
  711. {
  712.     *matchFail = true;
  713. }
  714.     }
  715.     return result;
  716. }
  717. INLINE_
  718. CopyOnWriteData
  719. CopyOnWriteData::parse( const char* match, bool* matchFail )
  720. {
  721.     ASSERT_WRITE(t1, myAssertable);
  722.     changed = true;
  723.     int pos = 0;
  724.     bool foundAny = false;
  725.     while(!foundAny && (pos < data_.size))
  726.     {
  727. char p = *(data_.bitsPtr + pos);
  728. if(isIn(p, match))
  729. {
  730.     foundAny = true;
  731. }
  732. pos++;
  733.     }
  734.     int pos2 = pos;
  735.     while(
  736. foundAny && 
  737. (pos2 < data_.size) && 
  738. isIn(*(data_.bitsPtr + pos2), match)
  739. )
  740.     {
  741. pos2++;
  742.     }
  743.     CopyOnWriteData result;
  744.     if(foundAny)
  745.     {
  746.         ASSERT_UNLOCK(myAssertable);
  747. result = *this;
  748.         ASSERT_WRITELOCK(myAssertable);
  749. result.data_.substr(0, pos - 1);
  750. data_.substr(pos2, data_.size);
  751. if(matchFail)
  752. {
  753.     *matchFail = false;
  754. }
  755.     }
  756.     else
  757.     {
  758. if(matchFail)
  759. {
  760.     *matchFail = true;
  761. }
  762.     }
  763.     return result;
  764. }
  765. INLINE_
  766. CopyOnWriteData
  767. CopyOnWriteData::matchChar( const char* match, char* matchedChar )
  768. {
  769.     ASSERT_WRITE(t1, myAssertable);
  770.     changed = true;
  771.     int pos = 0;
  772.     bool foundAny = false;
  773.     while(!foundAny && (pos < data_.size))
  774.     {
  775. char p = *(data_.bitsPtr + pos);
  776. if(isIn(p, match))
  777. {
  778.     foundAny = true;
  779.     if(matchedChar)
  780.     {
  781. *matchedChar = p;
  782.     }
  783. }
  784. pos++;
  785.     }
  786.     CopyOnWriteData result;
  787.     if(foundAny)
  788.     {
  789.         ASSERT_UNLOCK(myAssertable);
  790. result = *this;
  791.         ASSERT_WRITELOCK(myAssertable);
  792. result.data_.substr(0, pos - 1);
  793. data_.substr(pos, data_.size);
  794.     }
  795.     else if(matchedChar)
  796.     {
  797. *matchedChar = '';
  798.     }
  799.     return result;
  800. }
  801. INLINE_
  802. CopyOnWriteData
  803. CopyOnWriteData::getLine( bool* matchFail )
  804. {
  805.     ASSERT_WRITE(t1, myAssertable);
  806.     changed = true;
  807.     const int STARTING = 0;
  808.     const int HAS_CR = 1;
  809.     const int HAS_LF = 2;
  810.     const int HAS_CRLF = 3;
  811.     int state = STARTING;
  812.     int pos = 0;
  813.     bool foundAny = false;
  814.     while(!foundAny && (pos < data_.size))
  815.     {
  816. char p = *(data_.bitsPtr + pos);
  817. switch(p)
  818.         {
  819.         case 'r':
  820.             state = HAS_CR;
  821.             break;
  822.         case 'n':
  823.     if(state == HAS_CR)
  824.     {
  825. state = HAS_CRLF;
  826.     }
  827.     else
  828.     {
  829. state = HAS_LF;
  830.     }
  831.     foundAny = true;
  832.             break;
  833.         default:
  834.     state = STARTING;
  835.         }
  836. pos++;
  837.     }
  838.     int pos2 = pos;
  839.     if(state == HAS_CRLF)
  840.     {
  841. pos--;
  842.     }
  843.     CopyOnWriteData result;
  844.     if(foundAny)
  845.     {
  846.         ASSERT_UNLOCK(myAssertable);
  847. result = *this;
  848.         ASSERT_WRITELOCK(myAssertable);
  849. result.data_.substr(0, pos - 1);
  850. data_.substr(pos2, data_.size);
  851. if(matchFail)
  852. {
  853.     *matchFail = false;
  854. }
  855.     }
  856.     else
  857.     {
  858. if(matchFail)
  859. {
  860.     *matchFail = true;
  861. }
  862.     }
  863.     return result;
  864. }
  865. INLINE_
  866. bool isEqualNoCase(const CopyOnWriteData& left, const CopyOnWriteData& right)
  867. {
  868.     ASSERT_READ(t1, left.myAssertable);
  869.     ASSERT_READ(t2, right.myAssertable);
  870.     return (left.compareNoCase(right) == 0);
  871. }
  872. INLINE_
  873. bool isEqualNoCase(const char* left, const CopyOnWriteData& right)
  874. {
  875.     ASSERT_READ(t1, right.myAssertable);
  876.     return (right.compareNoCase(left, mystrlen(left)) == 0);
  877. }
  878. INLINE_
  879. void
  880. CopyOnWriteData::replace(int startpos, int endpos,
  881.                          const CopyOnWriteData& replaceStr)
  882. {
  883.     ASSERT_WRITE(t1, myAssertable);
  884.     changed = true;
  885.     if (data_.size)
  886.     {
  887.         string str = getstring();
  888.         str.replace(startpos, endpos, replaceStr.getstring());
  889.         *this = CopyOnWriteData(str);
  890.     }
  891. }
  892. INLINE_
  893. void CopyOnWriteData::removeSpaces()
  894. {
  895.     ASSERT_WRITE(t1, myAssertable);
  896.     changed = true;
  897.     if (data_.size == 0)
  898.     {
  899.         return ;
  900.     }
  901.  
  902.     int firstChar = 0;
  903.  
  904.     while ((firstChar < data_.size) && (getCharInternal(firstChar) == ' '))
  905.     {
  906.         firstChar++;
  907.     }
  908.  
  909.     int lastChar = data_.size;
  910.     while ((lastChar > 0) && (getCharInternal(lastChar - 1) == ' '))
  911.     {
  912.         lastChar--;
  913.     }
  914.     if (firstChar > lastChar)
  915.     {
  916.         firstChar = lastChar;
  917.     }                      
  918.     data_.substr(firstChar, lastChar);       
  919. }
  920. INLINE_
  921. void CopyOnWriteData::removeLWS()
  922. {
  923.     ASSERT_WRITE(t1, myAssertable);
  924.     changed = true;
  925.     int replaceTo;
  926.     int pos = -1;
  927.     ASSERT_UNLOCK(myAssertable);
  928.     pos = find ("rn");
  929.     ASSERT_WRITELOCK(myAssertable);
  930.     if (pos > data_.size)
  931.     {
  932.         ASSERT_UNLOCK(myAssertable);
  933.         pos = find("n");
  934.         ASSERT_WRITELOCK(myAssertable);
  935.     }
  936.     else
  937.     {
  938.       replaceTo = pos+1; //should end after rn
  939.     }
  940.     if (pos > data_.size)
  941.     {
  942. return;
  943.     }
  944.     else
  945.     {
  946.       replaceTo = pos; //should end after n
  947.     }
  948.     bool replaceFlag = false;
  949.     do
  950.     {
  951.         while ( (replaceTo+1 < data_.size) && 
  952.                 ( (getCharInternal(replaceTo+1) == 't') ||
  953.                   (getCharInternal(replaceTo+1) == ' ')
  954.                 ) 
  955.               )
  956.         {
  957.     char temp = getCharInternal(replaceTo);
  958.             replaceTo++;
  959.     temp = getCharInternal(replaceTo);
  960.             replaceFlag = true;
  961.         }
  962.         if (replaceFlag)
  963.         {
  964.             int replaceFrom = pos;
  965.             while ( (replaceFrom-1 > 0) &&
  966.                     ( (getCharInternal(replaceFrom-1) == 't') ||
  967.                       (getCharInternal(replaceFrom-1) == ' ')
  968.                     )
  969.                   )
  970.             {
  971.         char temp = getCharInternal(replaceFrom);
  972.                 replaceFrom--;
  973. temp = getCharInternal(replaceFrom);
  974.             }
  975.             int replaceNum = replaceTo-replaceFrom;
  976.             replace(replaceFrom, replaceNum, ""); //replace with nothing
  977.    
  978.         }
  979.         //remember pos.
  980.         int initpos = pos;
  981.         ASSERT_UNLOCK(myAssertable);
  982.         pos = find("rn", initpos+2);
  983.         ASSERT_WRITELOCK(myAssertable);
  984. if (pos > data_.size)
  985. {
  986.             ASSERT_UNLOCK(myAssertable);
  987.     pos = find("n", initpos+2);
  988.             ASSERT_WRITELOCK(myAssertable);
  989.     replaceTo = pos;
  990.         }
  991. else
  992.         {
  993.     replaceTo = pos+1;
  994.         }
  995.     }
  996.     while (pos < data_.size);
  997. }
  998. INLINE_
  999. void
  1000. CopyOnWriteData::expand(CopyOnWriteData startFrom,
  1001.                         CopyOnWriteData findstr,
  1002.                         CopyOnWriteData replstr,
  1003.                         CopyOnWriteData delimiter)
  1004. {
  1005.     ASSERT_WRITE(t1,myAssertable);
  1006.     ASSERT_READ(t2,startFrom.myAssertable);
  1007.     ASSERT_READ(t3,findstr.myAssertable);
  1008.     ASSERT_READ(t4,replstr.myAssertable);
  1009.     ASSERT_READ(t5, delimiter.myAssertable);
  1010.     changed = true;
  1011.     ASSERT_UNLOCK(myAssertable);
  1012.     int startPos = find(startFrom);
  1013.     ASSERT_WRITELOCK(myAssertable);
  1014.     if (startPos < npos)
  1015.     {
  1016.         ASSERT_UNLOCK(myAssertable);
  1017.         int delimPos
  1018.         = find(delimiter, startPos);
  1019.         int findPos
  1020.         = find(findstr, startPos);
  1021.         ASSERT_WRITELOCK(myAssertable);
  1022.         while (findPos < delimPos)
  1023.         {
  1024.             //found replstr, replace
  1025.             replace( findPos, findstr.data_.size, replstr.getstring());
  1026.             //find next.
  1027.             ASSERT_UNLOCK(myAssertable);
  1028.             delimPos
  1029. = find( delimiter,
  1030. findPos + replstr.data_.size);
  1031.             findPos
  1032. = find( findstr, findPos);
  1033.             ASSERT_WRITELOCK(myAssertable);
  1034.         }
  1035.     }
  1036. }
  1037. INLINE_
  1038. ostream&
  1039. operator<<(ostream& s, const CopyOnWriteData& data)
  1040. {
  1041.     ASSERT_READ(t1, data.myAssertable);
  1042.     s.write(data.data_.bitsPtr, data.data_.size);
  1043.     return s;
  1044. }
  1045. INLINE_
  1046. bool
  1047. operator==(const char* str, const CopyOnWriteData& d)
  1048. {
  1049.     ASSERT_READ(t1, d.myAssertable);
  1050.     return ( d.data_.compare(str, mystrlen(str)) == 0 );
  1051. }
  1052. #if 0
  1053. INLINE_
  1054. bool
  1055. operator!=(const char* str, CopyOnWriteData& d)
  1056. {
  1057.     return (d.data_.compare(str, mystrlen(str)) != 0 );
  1058. }
  1059. #endif
  1060. /* Local Variables: */
  1061. /* c-file-style: "stroustrup" */
  1062. /* indent-tabs-mode: nil */
  1063. /* c-file-offsets: ((access-label . -) (inclass . ++)) */
  1064. /* c-basic-offset: 4 */
  1065. /* End: */