home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 27 / IOPROG_27.ISO / SOFT / CALCPLUS.ZIP / CALCTYPE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-02  |  9.0 KB  |  430 lines

  1. /*******************************************************
  2.  
  3.     The CalcPlus Class Library Version 1.0,
  4.     Author: Vladimir Schipunov, Copyright (C) 1996
  5.  
  6.     This library is free software. Permission to use,
  7.     copy, modify and redistribute the CalcPlus library
  8.     for any purpose is hereby granted without fee,
  9.     provided that the above copyright notice appear
  10.     in all copies.
  11.  
  12. *******************************************************/
  13.  
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <time.h>
  17. #if !defined(_MSC_VER) && !defined(__WIN32__) // for MSVC 1.5 & BCC32 4.5
  18.     #include <strstream.h>
  19. #else
  20.     #include <strstrea.h>
  21. #endif
  22. #include "calctype.h"
  23.  
  24. ostream& operator << ( ostream& o, const CType& t )
  25. {
  26.     t.print( o );
  27.     return o;
  28. }
  29.  
  30. istream& operator >> ( istream& i, CType& t )
  31. {
  32.     t.get( i );
  33.     return i;
  34. }
  35.  
  36. CType& CType::operator=( const CType& t )
  37. {
  38.     int n = size();
  39.     if( type()!=t.type() || n!=t.size())
  40.         cerr << "Types or sizes of objects are not the same" << endl;
  41.     else
  42.         memcpy( ptr(), t.data(), n );
  43.     return *this;
  44. }
  45.  
  46. void CType::read( char* s )
  47. {
  48.     istrstream in( s, strlen(s) );
  49.     get( in );
  50. }
  51.  
  52. static char buf[512];
  53. const char* CType::s( char* p ) const
  54. {
  55.     if( !p )
  56.         p = buf;
  57.     ostrstream o( p, sizeof( buf ));
  58.     o << *this << '\0';
  59.     return p;
  60. }
  61.  
  62. CType::empty() const
  63. {
  64.     const char* p = (const char*)data();
  65.     long n = size();
  66.     for( int i = 0; i < n; i++ )
  67.         if( p[i] )
  68.             return 0;
  69.     return 1;
  70. }
  71.  
  72. CType::compare( const CType& t ) const
  73. {
  74.     return (type()==t.type() && size()==t.size()) ?
  75.         memcmp( data(), t.data(), size() ) : -1;
  76. }
  77.  
  78. #define BOOL_TRUE  "TRUE"
  79. #define BOOL_FALSE "FALSE"
  80.  
  81. void CLong::get( istream& in ){ long x; in >> x; n = x; } // for ZTC 3.1
  82. void CLong::print( ostream& out ) const { out << n; }
  83. void CDouble::get( istream& in ){ double x; in >> x; n = x; }
  84. void CDouble::print( ostream& out ) const { out << n; }
  85. void CBool::print( ostream& out ) const { out << (n ? BOOL_TRUE:BOOL_FALSE); }
  86.  
  87. void CBool::get( istream& in )
  88. {
  89.     in >> buf;
  90.     for( int i = 0; i < sizeof( buf ); i++ )
  91.         buf[i] = (char)toupper( buf[i] );
  92.     n = !strcmp( buf, BOOL_FALSE ) ? 0 :
  93.         !strcmp( buf, BOOL_TRUE  ) ? 1 : 2;
  94.     if( n==2 )
  95.         cerr << "Bad initializer for boolean" << endl;
  96. }
  97.  
  98. CString::CString( const char* s, int len ) :
  99.     CType( idString ), zero( len ? 0 : 1 )
  100. {
  101.     n = len ? len : strlen( s )+1;
  102.     p = new char[n];
  103.     if( len )   memcpy( p, s, n );
  104.     else        strcpy( p, s );
  105. }
  106.  
  107. CString::CString( const CString& s ) :
  108.     CType( idString ), n( s.n ),
  109.     p( new char[s.n] ), zero( s.zero )
  110. {
  111.     if( zero )
  112.         strcpy( p, s.p );
  113.     else
  114.         memcpy( p, s.p, n );
  115. }
  116.  
  117. CString::CString( int len ) :
  118.     CType( idString ), n( len ),
  119.     p( new char[len] ), zero( 1 )
  120. {
  121. }
  122.  
  123. const char *CString::s( char *p ) const
  124. {
  125.     if( !p && zero )
  126.         return *this;
  127.     if( !p )
  128.         p = buf;
  129.     memcpy( p, CString::p, n );
  130.     if( !zero )
  131.         p[n] = 0;
  132.     return p;
  133. }
  134.  
  135. void CString::print( ostream& out ) const { out << p; }
  136. void CString::get( istream& in ) { in.read( p, n ); }
  137. void CNil::print( ostream& out ) const { out << "NIL"; }
  138.  
  139. CType& CLong::operator=( const CType& t )
  140. {
  141.     if( t.type()!=idLong )
  142.         return CType::operator=(t);
  143.     n = ((CLong&)t).n;
  144.     return *this;
  145. }
  146.  
  147. CType& CString::operator=( const CType& t )
  148. {
  149.     if( type()!=t.type() || size()==t.size())
  150.         return CType::operator=(t);
  151.     const CString& s = (const CString&)t;
  152.     delete[] p;
  153.     p = new char[s.n];
  154.     memcpy( p, s.p, n );
  155.     return *this;
  156. }
  157.  
  158. CType& CString::operator=( const char* s )
  159. {
  160.     int len = strlen( s )+1;
  161.     if( size()+zero!=len )
  162.     {
  163.         delete[] p;
  164.         p = new char[ n = len ];
  165.     }
  166.     memcpy( p, s, n );
  167.     return *this;
  168. }
  169.  
  170. char& CString::operator[]( int i ) const
  171. {
  172.     static char err;
  173.     if( i<0 || i>=n || !p )
  174.     {
  175.         cerr << "Error in string index" << endl;
  176.         return err;
  177.     }
  178.     return p[i];
  179. }
  180.  
  181. CString& CString::right( char c )
  182. {
  183.     int i;
  184.     for( i = 0; i < n; i++ )
  185.         if( p[n-i-1] != ' ' )
  186.             break;
  187.     if( i < n )
  188.         for( int j = n-1; j >= 0; j-- )
  189.             p[j] = j-i >= 0 ? p[j-i] : c;
  190.     return *this;
  191. }
  192.  
  193. CString& CString::left( char c )
  194. {
  195.     int i;
  196.     for( i = 0; i < n; i++ )
  197.         if( p[i] != ' ' )
  198.             break;
  199.     int j;
  200.     if( i < n )
  201.         for( j = 0; j < n; j++ )
  202.             p[j] = j+i < n ? p[j+i] : c;
  203.     for( j = n-1; j >= 0; j-- )
  204.         if( p[j] != ' ' && p[j] != 0 )
  205.             break;
  206.         else
  207.             p[j] = c;
  208.     return *this;
  209. }
  210.  
  211. CString::operator==( const char* s ) const
  212. {
  213.     return size()==strlen( s ) && !memcmp(s,p,size());
  214. }
  215.  
  216. CArray::CArray( const CArray& t ) :
  217.     CType( t ), array( new CType*[ t.n ]),
  218.     n( t.n ), structure( t.structure ?
  219.         (CArray*)(t.structure->copy()) : 0 )
  220. {
  221.     for( int i = 0; i < n; i++ )
  222.         array[i] = t.array[i]->copy();
  223. }
  224.  
  225. CArray::~CArray()
  226. {
  227.     clear();
  228.     delete structure;
  229. }
  230.  
  231. void CArray::add( CType *t )
  232. {
  233.     CType **q = new CType*[ n+1 ];
  234.     for( int i = 0; i < n; i++ )
  235.         q[i] = array[i];
  236.     q[ n++ ] = t;
  237.     delete[] array;
  238.     array = q;
  239. }
  240.  
  241. void CArray::clear()
  242. {
  243.     for( int i = 0; i < n; i++ )
  244.         delete array[i];
  245.     delete[] array;
  246.     array = 0;
  247.     n = 0;
  248. }
  249.  
  250. CArray::compare( const CType& t ) const
  251. {
  252.     if( t.type() != idArray )
  253.         return 1;
  254.     CArray &a = (CArray&) t;
  255.     if( n != a.n )
  256.         return 1;
  257.     for( int i = 0; i < n; i++ )
  258.         if( array[i]->compare( *a.array[i] ))
  259.             return 1;
  260.     return 0;
  261. }
  262.  
  263. void CArray::print( ostream& o ) const
  264. {
  265.     o << '{';
  266.     for( int i = 0; i < n; i++ )
  267.     {
  268.         o << *array[i];
  269.         if( i!=n-1 )
  270.             o << ',';
  271.     }
  272.     o << '}';
  273. }
  274.  
  275. CType& CArray::operator = ( const CType& t )
  276. {
  277.     if( t.type()==idArray )
  278.         return operator=( (CArray&)t );
  279.     return CType::operator=( t );
  280. }
  281.  
  282. CArray& CArray::operator = ( const CArray&t )
  283. {
  284.     clear();
  285.     for( int i = 0; i < t.n; i++ )
  286.         add( t.array[i]->copy());
  287.     return *this;
  288. }
  289.  
  290. CType& CArray::operator[]( int i )
  291. {
  292.     if( i<0 || i>=n )
  293.     {
  294.         cerr << "Wrong index in array "
  295.              << "[" << i << "]" << endl;
  296.         return *this;
  297.     }
  298.     if( !array[i] )
  299.     {
  300.         cerr << "Element not defined "
  301.              << "[ << i << ]" << endl;
  302.         return *this;
  303.     }
  304.     return *array[i];
  305. }
  306.  
  307. CType& CArray::operator[]( const char* s )
  308. {
  309.     return operator[]( index( s ));
  310. }
  311.  
  312. CArray::index( const char* s ) const
  313. {
  314.     if( !structure )
  315.     {
  316.         cerr << "No structure in array "
  317.              << "[" << s << "]" << endl;
  318.         return -1;
  319.     }
  320.     for( int i = 0; i < structure->n; i++ )
  321.         if( structure->array[i] &&
  322.             structure->array[i]->type()==idString &&
  323.                 ((CString&)(*structure->array[i]))==s )
  324.             return i;
  325.     cerr << "Field not found " << s << endl;
  326.     return -1;
  327. }
  328.  
  329. CArray::remove( int i )
  330. {
  331.     if( !n || i<0 || i>=n )
  332.     {
  333.         cerr << "Wrong index in array "
  334.              << "[" << i << "]" << endl;
  335.         return 1;
  336.     }
  337.     CType** t = new CType*[n-1];
  338.     for( int j = 0; j < n-1; j++ )
  339.         t[j] = j<i ? array[j] : array[j+1];
  340.     delete array[i];
  341.     delete[] array;
  342.     array = t;
  343.     n--;
  344.     return 0;
  345. }
  346.  
  347. int CDate::MonthIsFirst = 0;
  348.  
  349. inline void dateOut( ostream& o, int n )
  350. {
  351.     if( !n )          o << "  ";
  352.     else if( n < 10 ) o << '0' << n;
  353.     else              o << n;
  354. }
  355.  
  356. void CDate::print( ostream& o ) const
  357. {
  358.     dateOut( o, MonthIsFirst ? m : d ); o << '/';
  359.     dateOut( o, MonthIsFirst ? d : m ); o << '/';
  360.     dateOut( o, y % 100 );
  361. }
  362.  
  363. #define PRE_DATE i >> c; if( c!='0' ) i.putback(c); n=0; i >> n;
  364. void CDate::get( istream& i )
  365. {
  366.     char c; int n;
  367.     PRE_DATE; d = n; i >> c;
  368.     PRE_DATE; m = n; i >> c;
  369.     PRE_DATE; y = n;
  370.     if( y < 100 && y )
  371.         y += 1900;
  372.     if( MonthIsFirst )
  373.     {
  374.         int tmp = d;
  375.         d = m;
  376.         m = tmp;
  377.     }
  378. }
  379.  
  380. static isleap( unsigned y )
  381. {
  382.     return y%400==0 || (y%4 == 0 && y%100 != 0);
  383. }
  384.  
  385. static m2d( int m )
  386. {
  387.     return (m*3057-3007)/100;
  388. }
  389.  
  390. static long y2d( int y )
  391. {
  392.     return y*365L+y/4-y/100+y/400;
  393. }
  394.  
  395. long CDate::i() const
  396. {
  397.     long n = d+m2d( m );
  398.     if ( m > 2 )
  399.         n -= isleap(y) ? 1 : 2;
  400.     n += y2d( y-1 );
  401.     return n;
  402. }
  403.  
  404. void CDate::set( long n )
  405. {
  406.     int i;
  407.     for( i = (int)(n*400L/146097L );
  408.         y2d( i ) < n; i++ ){}
  409.     y = i;
  410.     i = (int) (n - y2d( i-1 ));
  411.     if( i > 59 )
  412.     {
  413.         i += 2;
  414.         if( isleap( y ))
  415.             i -= i > 62 ? 1 : 2;
  416.     }
  417.     m = (int)(( i*100+3007 )/3057);
  418.     d = i - m2d( m );
  419. }
  420.  
  421. CDate::CDate() : CType( idDate )
  422. {
  423.     time_t timer = time( 0 );
  424.     struct tm *t = localtime( &timer );
  425.     y = t->tm_year+1900;
  426.     m = t->tm_mon+1;
  427.     d = t->tm_mday;
  428. }
  429.  
  430.