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 }