home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / base / bytarray.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  12KB  |  554 lines

  1.  
  2.  
  3.  
  4.  
  5. /*
  6.  *
  7.  *          Copyright (C) 1994, M. A. Sridhar
  8.  *  
  9.  *
  10.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  11.  *     to copy, modify or distribute this software  as you see fit,
  12.  *     and to use  it  for  any  purpose, provided   this copyright
  13.  *     notice and the following   disclaimer are included  with all
  14.  *     copies.
  15.  *
  16.  *                        DISCLAIMER
  17.  *
  18.  *     The author makes no warranties, either expressed or implied,
  19.  *     with respect  to  this  software, its  quality, performance,
  20.  *     merchantability, or fitness for any particular purpose. This
  21.  *     software is distributed  AS IS.  The  user of this  software
  22.  *     assumes all risks  as to its quality  and performance. In no
  23.  *     event shall the author be liable for any direct, indirect or
  24.  *     consequential damages, even if the  author has been  advised
  25.  *     as to the possibility of such damages.
  26.  *
  27.  */
  28.  
  29.  
  30.  
  31.  
  32. #if defined(__GNUC__)
  33. #pragma implementation
  34. #endif
  35.  
  36.  
  37.  
  38. #include "base/defs.h"
  39. #include "base/bytarray.h"
  40. #include "base/bytstrng.h"
  41. #include "base/stream.h"
  42.  
  43.  
  44. // #define NEW_OP new (__LINE__, __FILE__)
  45. #define NEW_OP new
  46.  
  47.  
  48.  
  49.  
  50. #ifdef __BORLANDC__
  51. #include <mem.h>
  52. #ifndef __OS2__
  53. #define MEMCMP _fmemcmp
  54. #else
  55. #define MEMCMP memcmp
  56. #endif
  57. #else
  58. #include <string.h>
  59. #define MEMCMP memcmp
  60. #endif
  61.  
  62.  
  63. CL_DEFINE_CLASS(CL_ByteArray, _CL_ByteArray_CLASSID);
  64.  
  65.  
  66. CL_ByteArray::CL_ByteArray(CL_Object* client)
  67. {
  68.     _array = 0L;
  69.     _size = 0L;
  70.     _client = client;
  71. }
  72.  
  73.  
  74. //
  75. // Constructor: assume that the array of bytes in question begins
  76. // at the given address, and is of the given size
  77. //
  78. CL_ByteArray::CL_ByteArray (uchar *buf, long size, CL_Object* client)
  79. {
  80.     _array  = buf;
  81.     _size = size;
  82.     _client = client;
  83. }
  84.  
  85.  
  86.  
  87.  
  88. CL_ByteArray::CL_ByteArray (const CL_ByteArray& b)
  89. {
  90.     _array  = b._array;
  91.     _size = b._size;
  92.     _client = b._client;
  93. }
  94.  
  95.  
  96.  
  97. CL_ByteArray::~CL_ByteArray ()
  98. {
  99. }
  100.  
  101.     
  102.  
  103.  
  104. void CL_ByteArray::SetAllBytesTo (uchar b)
  105. {
  106.     if (!PrepareToChange() || (_client && !_client->PrepareToChange()))
  107.         return;
  108.     if (_size > 0 && _array != NULL) {
  109.         memset (_array, b, _size);
  110.         Notify ();
  111.         if (_client)
  112.             _client->Notify();
  113.     }
  114. }
  115.  
  116.  
  117. //
  118. // Retrieve the byte at the given index. As usual, 
  119. // zero-origin indexing is assumed. It is an error to specify an
  120. // index outside the legal range.
  121. uchar CL_ByteArray::operator[] (long index)
  122. {
  123.     assert ((index >= 0 && index < _size),
  124.             ("CL_ByteArray::operator[]: Bad "
  125.              "index %ld size %ld\n", index, _size));
  126.     if (!_array) { // Because of memory problems?
  127.         uchar c = 0;
  128.         return c;
  129.     }
  130.     return _array[index];
  131. }
  132.  
  133.  
  134.  
  135. //
  136. // Comparison methods
  137. // For the methods taking character pointer arguments, it is
  138. // assumed that the size of the byte array is the same as our
  139. // size.
  140. //
  141.  
  142. bool CL_ByteArray::operator== (const uchar* b) const
  143. {
  144.     return MEMCMP (_array, (uchar*) b, _size) == 0;
  145. }
  146.  
  147.  
  148. bool CL_ByteArray::operator== (const CL_Object& b) const
  149. {
  150.     if (!IsA (b))
  151.         return FALSE;
  152.     register const CL_ByteArray& o = (const CL_ByteArray&) b;
  153.     return o._size == _size && MEMCMP (_array, o._array, _size) == 0;
  154. }
  155.  
  156.  
  157. bool CL_ByteArray::operator== (const CL_ByteArray& o) const
  158. {
  159.     return o._size == _size && MEMCMP (_array, o._array, _size) == 0;
  160. }
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169. bool CL_ByteArray::operator!= (const CL_Object& b) const
  170. {
  171.     if (!IsA (b))
  172.         return TRUE;
  173.     return MEMCMP (_array, ((const CL_ByteArray&) b).AsPtr(),
  174.                    _size) != 0; 
  175. }
  176.  
  177.  
  178. bool CL_ByteArray::operator!= (const CL_ByteArray& o) const
  179. {
  180.     return o._size != _size || MEMCMP (_array, o._array, _size) != 0;
  181. }
  182.  
  183.  
  184. bool CL_ByteArray::operator!= (const uchar* b) const
  185. {
  186.     return MEMCMP (_array, b, _size) != 0;
  187. }
  188.  
  189.  
  190.  
  191.  
  192.  
  193. bool CL_ByteArray::operator>= (const CL_Object& b) const
  194. {
  195.     if (!IsA (b))
  196.         return this >= (CL_ByteArray*) &b;
  197.     return (MEMCMP (_array, ((const CL_ByteArray&) b).AsPtr(),
  198.                     _size) >= 0);
  199. }
  200.  
  201. bool CL_ByteArray::operator>= (const CL_ByteArray& o) const
  202. {
  203.     register long sz = minl (_size, o._size);
  204.     return MEMCMP (_array, o._array, sz) >= 0;
  205. }
  206.  
  207.  
  208. bool CL_ByteArray::operator>= (const uchar* b) const
  209. {
  210.     return MEMCMP (_array, b, _size) >= 0;
  211. }
  212.  
  213.  
  214.  
  215.  
  216.  
  217. bool CL_ByteArray::operator<= (const CL_Object& b) const
  218. {
  219.     if (!IsA (b))
  220.         return this <= (CL_ByteArray*) &b;
  221.     return MEMCMP (_array, ((const CL_ByteArray&) b).AsPtr(),
  222.                    _size) <= 0; 
  223. }
  224.  
  225. bool CL_ByteArray::operator<= (const CL_ByteArray& o) const
  226. {
  227.     register long sz = minl (_size, o._size);
  228.     return MEMCMP (_array, o._array, sz) <= 0;
  229. }
  230.  
  231.  
  232. bool CL_ByteArray::operator<= (const uchar* b) const
  233. {
  234.     return MEMCMP (_array, b, _size) <= 0;
  235. }
  236.  
  237.  
  238.  
  239.  
  240.  
  241. bool CL_ByteArray::operator> (const CL_Object& b) const
  242. {
  243.     if (!IsA (b))
  244.         return this > (CL_ByteArray*) &b;
  245.     short result = MEMCMP (_array, ((const CL_ByteArray&) b).AsPtr(),
  246.                            _size);
  247.     return  result > 0 || result == 0 &&
  248.             _size > ((const CL_ByteArray&) b).Size();
  249. }
  250.  
  251. bool CL_ByteArray::operator> (const CL_ByteArray& o) const
  252. {
  253.     register long sz = minl (_size, o._size);
  254.     return MEMCMP (_array, o._array, sz) > 0;
  255. }
  256.  
  257.  
  258. bool CL_ByteArray::operator> (const uchar* b) const
  259. {
  260.     return MEMCMP (_array, b, _size) > 0;
  261. }
  262.  
  263.  
  264.  
  265.  
  266.  
  267. bool CL_ByteArray::operator< (const CL_Object& b) const
  268. {
  269.     if (!IsA (b))
  270.         return this < (CL_ByteArray*) &b;
  271.     short result = MEMCMP (_array, ((const CL_ByteArray&) b).AsPtr(),
  272.                    _size);
  273.     return result < 0 || result == 0 &&
  274.             _size < ((const CL_ByteArray&) b).Size();
  275. }
  276.  
  277. bool CL_ByteArray::operator< (const CL_ByteArray& o) const
  278. {
  279.     register long sz = minl (_size, o._size);
  280.     return MEMCMP (_array, o._array, sz) < 0;
  281. }
  282.  
  283.  
  284. bool CL_ByteArray::operator< (const uchar* b) const
  285. {
  286.     return MEMCMP (_array, b, _size) < 0;
  287. }
  288.  
  289.  
  290.  
  291.  
  292.  
  293. short CL_ByteArray::Compare (const CL_Object& o) const
  294. {
  295.     if (!IsA (o))
  296.         return this < (CL_ByteArray*) &o ? -1 : 1;
  297.     return MEMCMP (_array, ((const CL_ByteArray&) o)._array, _size);
  298. }
  299.  
  300.  
  301.  
  302. short CL_ByteArray::Compare (const CL_ByteArray& o) const
  303. {
  304.     return MEMCMP (_array, o._array, _size);
  305. }
  306.  
  307.  
  308.  
  309.  
  310. //
  311. // Sub-array extraction
  312. //
  313. // Return the sub-array beginning at the given index (using
  314. // 0-origin indexing) and of the given size. Note that the
  315. // returned CL_ByteArray uses (part of) the same memory as we do.
  316. //
  317. CL_ByteArray CL_ByteArray::operator() (long start, long size) const
  318. {
  319.     CL_ByteArray p (_array+start, size, _client);
  320.     return p;
  321. }
  322.  
  323.  
  324.  
  325.         
  326. CL_ByteString CL_ByteArray::operator+ (const CL_ByteArray& b) const
  327. {
  328.     CL_ByteString b1 (_size + b.Size());
  329.     b1(0, _size) = _array;
  330.     b1.Suffix (_size) = b;
  331.     return b1;
  332. }
  333.  
  334.  
  335.  
  336.  
  337.  
  338. //
  339. // Return the length of the longest common prefix with the
  340. // parameter.
  341. long CL_ByteArray::CommonPrefixLength (const CL_ByteArray& b)
  342. {
  343.     if (!_array)
  344.         return 0; // No memory
  345.     long i;
  346.     uchar* p = b.AsPtr();
  347.     for (i = 0; i < _size; i++) 
  348.         if (_array[i] != p[i]) return i;
  349.     return _size;
  350. }
  351.  
  352.  
  353. long CL_ByteArray::CommonPrefixLength (const uchar* p)
  354. {
  355.     if (!_array)
  356.         return 0; // No memory
  357.     long i;
  358.     for (i = 0; i < _size; i++) 
  359.         if (_array[i] != p[i]) return i;
  360.     return _size;
  361. }
  362.  
  363.  
  364.  
  365. CL_ByteArray CL_ByteArray::Suffix (long index) const
  366. {
  367.     return CL_ByteArray ( (*this) (index, (_size > index) ?
  368.                                    (_size - index) : 0L));
  369. }
  370.  
  371.  
  372.  
  373.  
  374.  
  375. long CL_ByteArray::LongValueAt (long index) const
  376. {
  377.     if (!_array)
  378.         return 0; // No memory
  379.     long value;
  380.     
  381.     memcpy ((uchar*) &value, &_array[index], sizeof (long));
  382.     return value;
  383. }
  384.  
  385.     
  386.     
  387.  
  388.  
  389. short CL_ByteArray::ShortValueAt (long index) const
  390. {
  391.     if (!_array)
  392.         return 0; // No memory
  393.     short value  = 0;
  394.     
  395.     if (_array)
  396.         memcpy ((uchar*) &value, &_array[index], sizeof (short));
  397.     return value;
  398. }
  399.  
  400.  
  401. long CL_ByteArray::CopyTo (uchar* buffer, long count, long pos)
  402. {
  403.     if (count > 0 && _array && pos >= 0 && pos < _size) {
  404.         long n = minl (_size - pos, count);
  405.         memcpy (buffer, _array + pos, n);
  406.         return n;
  407.     }
  408.     return 0;
  409. }
  410.  
  411.  
  412.     
  413. long CL_ByteArray::CopyFrom (uchar* buffer, long count, long pos) const
  414. {
  415.     if (count > 0 && _array && pos >= 0 && pos < _size) {
  416.         long n = minl (_size - pos, count);
  417.         memcpy (_array + pos, buffer, n);
  418.         return n;
  419.     }
  420.     return 0;
  421. }
  422.  
  423.  
  424.     
  425. CL_String CL_ByteArray::AsString () const
  426. {
  427.     if (!_array)
  428.         return ""; // No memory
  429.     if (_size <= 0)
  430.         return "";
  431.     uchar* p = NEW_OP uchar [_size+1];
  432.     if (!p)
  433.         return "";
  434.     memcpy (p, _array, _size);
  435.     p[_size] = '\0';
  436.     CL_String s ((char*) p);
  437.     delete [] p;
  438.     return s;
  439. }
  440.  
  441.  
  442.  
  443.  
  444.  
  445. //
  446. // Assignment
  447. //
  448. void CL_ByteArray::operator= (const CL_ByteArray& b)
  449. {
  450.     if (this == &b)
  451.         return;
  452.     if (!PrepareToChange() || (_client && !_client->PrepareToChange()))
  453.         return;
  454.     if (!_array)
  455.         return; // No memory
  456.     if (!b._array)
  457.         return; // Null second array
  458.     if (_array != b._array)  {
  459.         memcpy (_array, b.AsPtr(), minl (_size, b.Size()));
  460.         Notify ();
  461.         if (_client)
  462.             _client->Notify();
  463.     }
  464. }
  465.  
  466. void CL_ByteArray::operator= (const uchar* p)
  467. {
  468.     if (!PrepareToChange() || (_client && !_client->PrepareToChange()))
  469.         return;
  470.     if (!_array)
  471.         return; // No memory
  472.     if (!p) return;
  473.     if (_array != p)  {
  474.         memcpy (_array, p, _size);
  475.         Notify ();
  476.         if (_client)
  477.             _client->Notify();
  478.     }
  479. }
  480.  
  481.  
  482. void CL_ByteArray::operator= (const CL_String& p)
  483. {
  484.     if (!PrepareToChange() || (_client && !_client->PrepareToChange()))
  485.         return;
  486.     if (!_array)
  487.         return; // No memory
  488.     if (_array != (uchar*) p.AsPtr())  {
  489.         memcpy (_array, p.AsPtr(), minl (_size, p.Size()+1));
  490.         Notify ();
  491.         if (_client)
  492.             _client->Notify();
  493.     }
  494. }
  495.  
  496.  
  497. CL_ByteArray& CL_ByteArray::operator= (short value)
  498. {
  499.     if (!PrepareToChange() || (_client && !_client->PrepareToChange()))
  500.         return *this;
  501.     if (!_array)
  502.         return *this; // No memory
  503.     memcpy (_array, &value, minl (_size, sizeof value));
  504.     Notify ();
  505.     if (_client)
  506.         _client->Notify();
  507.     return *this;
  508. }
  509.  
  510.  
  511.  
  512. CL_ByteArray& CL_ByteArray::operator= (long value)
  513. {
  514.     if (!PrepareToChange() || (_client && !_client->PrepareToChange()))
  515.         return *this;
  516.     if (!_array)
  517.         return *this; // No memory
  518.     memcpy (_array, &value, minl (_size, sizeof value));
  519.     Notify ();
  520.     if (_client)
  521.         _client->Notify();
  522.     return *this;
  523. }
  524.  
  525.  
  526.  
  527.  
  528.  
  529. long CL_ByteArray::StorableFormWidth() const
  530. {
  531.     return sizeof (CL_ClassId) + _size;
  532. }
  533.  
  534. bool CL_ByteArray::ReadFrom (const CL_Stream& s)
  535. {
  536.     if (!PrepareToChange() || !ReadClassId(s)
  537.         || !s.Read (_array, _size))
  538.         return FALSE;
  539.     Notify();
  540.     if (_client)
  541.         _client->Notify();
  542.     return TRUE;
  543. }
  544.  
  545.  
  546. bool CL_ByteArray::WriteTo (CL_Stream& s) const
  547. {
  548.     return s.Write (ClassId())  && s.Write (_array, _size);
  549. }
  550.  
  551.  
  552.  
  553.  
  554.