]> git.lyx.org Git - lyx.git/blob - src/mathed/array.C
mathed58.diff
[lyx.git] / src / mathed / array.C
1
2 #include <config.h>
3
4 #ifdef __GNUG__
5 #pragma implementation
6 #endif
7
8 #include "array.h"
9 #include "math_iter.h"
10 #include "math_inset.h"
11
12 #include "support/LOstream.h"
13
14 using std::ostream;
15 using std::endl;
16
17 static inline
18 void * my_memcpy(void * ps_in, void const * pt_in, size_t n)
19 {
20         char * ps = static_cast<char *>(ps_in);
21         char const * pt = static_cast<char const *>(pt_in);
22         while (n--) *ps++ = *pt++;
23         return ps_in;
24 }
25
26
27 MathedArray::MathedArray()
28         : bf_(1, '\0'), last_(0)
29 {}
30
31
32 MathedArray::~MathedArray()
33 {
34         // deep destruction
35         // let's leak for a while... 
36 /*
37         MathedIter it;
38         it.SetData(this);
39         while (it.OK()) {
40                 if (it.IsInset()) {
41                         MathedInset * inset = it.GetInset();
42                         delete inset;
43                 }
44                 it.Next();
45         }
46 */
47 }
48
49
50 MathedArray::MathedArray(MathedArray const & array)
51 {
52         // this "implementation" is obviously wrong: MathedIter should be
53         // implemented by MathedArray (not the other way round) but I think
54         // getting the _interface_ of MathedArray right is more important right
55         // now (Andre')
56
57         // shallow copy
58         bf_   = array.bf_;
59         last_ = array.last_;
60
61         // deep copy
62         deep_copy();
63 }
64
65 void MathedArray::deep_copy()
66 {
67         MathedIter it(this);
68         while (it.OK()) {
69                 if (it.IsInset()) {
70                         MathedInset * inset = it.GetInset();
71                         inset = inset->Clone();
72                         raw_pointer_insert(inset, it.getPos() + 1);
73                 }
74                 it.Next();
75         }
76 }
77
78
79 MathedArray & MathedArray::operator=(MathedArray const & array)
80 {
81         MathedArray tmp(array);
82         swap(tmp);
83         return *this;
84 }
85
86 void MathedArray::clear()
87 {
88         last_ = 0;
89         bf_.resize(1);
90         bf_[0] = 0;
91 }
92
93 void MathedArray::swap(MathedArray & array)
94 {
95         if (this != &array) {
96                 bf_.swap(array.bf_);
97                 std::swap(last_, array.last_);
98         }
99 }
100
101
102 MathedArray::iterator MathedArray::begin() 
103 {
104         return bf_.begin();
105 }
106
107
108 MathedArray::iterator MathedArray::end() 
109 {
110         return bf_.end();
111 }
112
113
114 MathedArray::const_iterator MathedArray::begin() const
115 {
116         return bf_.begin();
117 }
118
119
120 MathedArray::const_iterator MathedArray::end() const
121 {
122         return bf_.end();
123 }
124
125
126 int MathedArray::empty() const
127 {
128         return (last_ == 0);
129 }
130    
131
132 int MathedArray::last() const
133 {
134         return last_;
135 }
136
137
138 void MathedArray::last(int l)
139 {
140         last_ = l;
141 }
142
143
144 void MathedArray::need_size(int needed)
145 {
146         if (needed >= static_cast<int>(bf_.size()))
147                 resize(needed);
148 }
149
150
151 void MathedArray::resize(int newsize)
152 {
153         // still a bit smelly...
154         ++newsize;
155         bf_.resize(newsize + 1);
156         if (last_ >= newsize)
157                 last_ = newsize - 1;
158         bf_[last_] = 0;
159 }
160
161
162 void MathedArray::move(int p, int shift)
163 {
164         if (p <= last_) {
165                 need_size(last_ + shift);
166                 memmove(&bf_[p + shift], &bf_[p], last_ - p);
167                 last_ += shift;
168                 bf_[last_] = 0;
169         }
170 }
171
172
173
174 void MathedArray::shrink(int pos1, int pos2)
175 {
176         if (pos1 == 0 && pos2 >= last())        
177                 return;
178
179         short fc = 0;
180         if (pos1 > 0 && bf_[pos1] > ' ') {
181                 for (int p = pos1; p >= 0; --p) {
182                         if (MathIsFont(bf_[p])) {
183                                 if (p != pos1 - 1)
184                                         fc = bf_[p];
185                                 else
186                                         --pos1;
187                                 break;
188                         }
189                 }
190         }
191
192         if (pos2 > 0 && bf_[pos2] >= ' ' && MathIsFont(bf_[pos2 - 1]))
193                 --pos2;
194
195         int dx = pos2 - pos1;
196         MathedArray a;
197         a.resize(dx + 1);
198         strange_copy(&a, (fc) ? 1 : 0, pos1, dx);
199         if (fc) {
200                 a[0] = fc;
201                 ++dx;
202         }
203         a.last(dx);
204         a[dx] = '\0';
205
206         swap(a);
207         deep_copy();
208 }
209
210
211 #if 0
212 void MathedArray::insert(MathedArray::iterator pos,
213                          MathedArray::const_iterator beg,
214                          MathedArray::const_iterator end)
215 {
216         bf_.insert(pos, beg, end);
217         last_ = bf_.size() - 1;
218 }
219 #else
220 void MathedArray::merge(MathedArray const & a, int p)
221 {
222         my_memcpy(&bf_[p], &a.bf_[0], a.last());
223 }
224 #endif
225
226
227 void MathedArray::raw_pointer_copy(MathedInset ** p, int pos) const
228 {
229         my_memcpy(p, &bf_[pos], sizeof(MathedInset*));
230 }
231
232
233 #if 0
234 void MathedArray::insertInset(int pos, MathedInset * p, int type)
235 {
236         //bf_.insert(pos, type);
237         InsetTable tmp(pos, p);
238         insetList_.push_back(tmp);
239 }
240
241
242 MathedInset * MathedArray::getInset(int pos) 
243 {
244         InsetList::const_iterator cit = insetList_.begin();
245         InsetList::const_iterator end = insetList_.end();
246         for (; cit != end; ++cit) {
247                 if ((*cit).pos == pos)
248                         return (*cit).inset;
249         }
250         // not found
251         return 0;
252         // We would really like to throw an exception instead... (Lgb)
253         // throw inset_not_found();
254 }
255
256 #else
257 void MathedArray::raw_pointer_insert(void * p, int pos)
258 {
259         my_memcpy(&bf_[pos], &p, sizeof(p));
260 }
261 #endif
262
263
264 void MathedArray::strange_copy(MathedArray * dest, int dpos,
265                                 int spos, int len)
266 {
267         my_memcpy(&dest->bf_[dpos], &bf_[spos], len);
268 }
269
270
271 byte MathedArray::operator[](int i) const
272 {
273         return bf_[i];
274 }
275
276
277 byte & MathedArray::operator[](int i)
278 {
279         return bf_[i];
280 }
281
282
283 void MathedArray::dump(ostream & os) const
284 {
285         buffer_type::const_iterator cit = bf_.begin();
286         buffer_type::const_iterator end = bf_.end();
287         for (; cit != end; ++cit) {
288                 os << (*cit);
289         }
290         os << endl;
291 }
292
293