1 // Copyright (c) 1994, 1996 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident	"%Z%%M%	%I%	%E% SMI"
4 
5 #ifndef StringOf_DEF_INCLUDED
6 #define StringOf_DEF_INCLUDED 1
7 
8 #include <string.h>
9 #include <stddef.h>
10 
11 #ifdef SP_NAMESPACE
12 namespace SP_NAMESPACE {
13 #endif
14 
15 template<class T>
String(const T * ptr,size_t length)16 String<T>::String(const T *ptr, size_t length)
17 : length_(length), alloc_(length)
18 {
19   if (length) {
20     ptr_ = new T[length];
21     memcpy(ptr_, ptr, length*sizeof(T));
22   }
23   else
24     ptr_ = 0;
25 }
26 
27 template<class T>
String()28 String<T>::String()
29 : ptr_(0), length_(0), alloc_(0)
30 {
31 }
32 
33 template<class T>
String(const String<T> & s)34 String<T>::String(const String<T> &s)
35 : length_(s.length_), alloc_(s.length_)
36 {
37   if (length_) {
38     ptr_ = new T[length_];
39     memcpy(ptr_, s.ptr_, length_*sizeof(T));
40   }
41   else
42     ptr_ = 0;
43 }
44 
45 template<class T>
operator =(const String<T> & s)46 String<T> &String<T>::operator=(const String<T> &s)
47 {
48   if (&s != this) {
49     if (s.length_ > alloc_) {
50       T *oldPtr = ptr_;
51       ptr_ = new T[alloc_ = s.length_];
52       if (oldPtr)
53 	delete [] oldPtr;
54     }
55     memcpy(ptr_, s.ptr_, s.length_*sizeof(T));
56     length_ = s.length_;
57   }
58   return *this;
59 }
60 
61 template<class T>
insert(size_t i,const String<T> & s)62 String<T> &String<T>::insert(size_t i, const String<T> &s)
63 {
64   if (length_ + s.length_ > alloc_)
65     grow(s.length_);
66   for (size_t n = length_ - i; n > 0; n--)
67     ptr_[i + n - 1 + s.length_] = ptr_[i + n - 1];
68   length_ += s.length_;
69   memcpy(ptr_ + i, s.ptr_, s.length_*sizeof(T));
70   return *this;
71 }
72 
73 template<class T>
append(const T * p,size_t length)74 String<T> &String<T>::append(const T *p, size_t length)
75 {
76   if (length_ + length > alloc_)
77     grow(length);
78   memcpy(ptr_ + length_, p, length*sizeof(T));
79   length_ += length;
80   return *this;
81 }
82 
83 template<class T>
grow(size_t n)84 void String<T>::grow(size_t n)
85 {
86   size_t newAlloc = alloc_;
87   if (alloc_ < n)
88     newAlloc += n + 16;
89   else
90     newAlloc += alloc_;
91   T *s = new T[newAlloc];
92   memcpy(s, ptr_, length_*sizeof(T));
93   delete [] ptr_;
94   ptr_ = s;
95   alloc_ = newAlloc;
96 }
97 
98 template<class T>
swap(String<T> & to)99 void String<T>::swap(String<T> &to)
100 {
101   {
102     T *tem = to.ptr_;
103     to.ptr_ = ptr_;
104     ptr_ = tem;
105   }
106   {
107     size_t tem = to.length_;
108     to.length_ = length_;
109     length_ = tem;
110   }
111   {
112     size_t tem = to.alloc_;
113     to.alloc_ = alloc_;
114     alloc_ = tem;
115   }
116 }
117 
118 template<class T>
assign(const T * p,size_t n)119 String<T> &String<T>::assign(const T *p, size_t n)
120 {
121   if (alloc_ < n) {
122     T *oldPtr = ptr_;
123     ptr_ = new T[n];
124     alloc_ = n;
125     if (oldPtr)
126       delete [] oldPtr;
127   }
128   length_ = n;
129   for(T *to = ptr_; n > 0; n--, to++, p++)
130     *to = *p;
131   return *this;
132 }
133 
134 template<class T>
resize(size_t n)135 void String<T>::resize(size_t n)
136 {
137   if (alloc_ < n) {
138     T *oldPtr = ptr_;
139     ptr_ = new T[n];
140     alloc_ = n;
141     if (length_ > 0) {
142       memcpy(ptr_, oldPtr, length_*sizeof(T));
143       delete [] oldPtr;
144     }
145   }
146   length_ = n;
147 }
148 
149 #ifdef SP_NAMESPACE
150 }
151 #endif
152 
153 #endif /* not StringOf_DEF_INCLUDED */
154