Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

int_seq.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Fri Apr 22 13:41:10 EDT 2005 by irina.furman@intel.com 
00020 //      modified on Tue Aug  6 16:35:31 EDT 2002 by ken@xorian.net         
00021 //      modified on Thu Aug  1 11:03:24 EDT 2002 by kcschalk@shr.intel.com 
00022 //      modified on Tue Feb  8 11:56:49 PST 2000 by mann  
00023 //      modified on Thu Jun 27 17:59:15 PDT 1996 by heydon
00024 //      modified on Wed Mar  8 23:18:41 PST 1995 by levin
00025 
00026 
00027 //  *******************************
00028 //  *  Implementation of int_seq  *
00029 //  *******************************
00030 
00031 #include "int_seq.H"
00032 
00033 typedef int_seq_impl::rep rep;
00034 
00035 //  ***************
00036 //  *  Utilities  *
00037 //  ***************
00038 
00039 rep *int_seq_impl::allocate_buffer(int len_hint)
00040 {
00041   // The following odd-looking calculation ensures that the buffer
00042   // will hold at least 'len_hint' integers and will be properly
00043   // aligned.  It assumes that the largest alignment required by 'rep'
00044   // is for type 'int32'.
00045   int size_as_ints = ((int_seq::min_size(len_hint)+sizeof(Basics::int32)-1) /
00046                       sizeof(Basics::int32));
00047   rep* p = (rep*) NEW_PTRFREE_ARRAY(Basics::int32, size_as_ints);
00048   p->h.storage = grow;
00049   p->h.len = 0;
00050   p->h.maxlen = len_hint;
00051   return p;
00052 }
00053 
00054 
00055 //  **********************************
00056 //  *  Constructors and Destructors  *
00057 //  **********************************
00058 
00059 int_seq::int_seq(int len_hint)
00060 {
00061   if (len_hint == 0)
00062     // Defer allocation until needed.  The first allocation might
00063     // be SRPC::recv_int_seq, which can allocate precisely the right
00064     // amount.
00065     p = NULL;
00066   else p = int_seq_impl::allocate_buffer(len_hint);
00067 }
00068 
00069 int_seq::int_seq(Basics::int32 *buffer, int bytes) throw(int_seq::failure)
00070 {
00071   p = (rep *) buffer;
00072   p->h.storage = int_seq_impl::manual;
00073   p->h.len = 0;
00074   p->h.maxlen = (bytes - min_size(0))/sizeof(Basics::int32);
00075 }
00076 
00077 int_seq::int_seq(const Basics::int32 *seq, int len) throw(int_seq::failure)
00078 {
00079   p = int_seq_impl::allocate_buffer(len);
00080   p->h.storage = int_seq_impl::full;
00081   p->h.len = len;
00082   memcpy((char *)&p->base, (char *)seq, len*sizeof(Basics::int32));
00083 }
00084 
00085 int_seq::~int_seq()
00086 {
00087   if (p == NULL || p->h.storage == int_seq_impl::manual) return;
00088   delete[] (Basics::int32 *)p;
00089 }
00090 
00091 /* static */ int int_seq::min_size(int len)
00092 {
00093   // This calculation allows for the possibility that padding will be
00094   // inserted between 'h' and 'base'.  However, on most platforms this
00095   // really shouldn't happen, since 'h' consists of three 'int' fields
00096   // and 'base' is an 'int32', which are normally the same type.
00097   return sizeof(int_seq_impl::rep) + (len-1)*sizeof(Basics::int32);
00098 }
00099 
00100 
00101 //  ***************************
00102 //  *  Sequence modification  *
00103 //  ***************************
00104 
00105 void int_seq::append(Basics::int32 i) throw(int_seq::failure)
00106 {
00107   Basics::int32 *seq;
00108 
00109   if (p == NULL) p = int_seq_impl::allocate_buffer();
00110   if (p->h.len == p->h.maxlen) lengthen(2 * p->h.maxlen);
00111 
00112   seq = &p->base;
00113   seq[p->h.len] = i;
00114   p->h.len++;
00115 }
00116 
00117 void int_seq::lengthen(int len_hint)
00118 {
00119   if (p == NULL) {
00120     p = int_seq_impl::allocate_buffer(len_hint);
00121     return;
00122   }
00123   if (len_hint <= p->h.maxlen) return;
00124   if (p->h.storage != int_seq_impl::grow)
00125     throw(failure("Buffer has insufficient space."));
00126 
00127   rep *new_p = int_seq_impl::allocate_buffer(len_hint);
00128 
00129   new_p->h.len = p->h.len;
00130   memcpy((char *)&new_p->base, (char *)&p->base,
00131          p->h.len * sizeof(Basics::int32));
00132 
00133   delete[] (Basics::int32 *)p;
00134   p = new_p;
00135 }

Generated on Mon May 8 00:48:56 2006 for Vesta by  doxygen 1.4.2