Subversion Repositories spk

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#ifndef __BASE_ENGINE_STRINGLIST_H__
2
#define __BASE_ENGINE_STRINGLIST_H__
3
 
8 cycrow 4
#include "Utils/String.h"
1 cycrow 5
#include "CyString.h"
6
#include "spkdll.h"
7
#include "spkdef.h"
8 cycrow 8
#include "lists.h"
1 cycrow 9
 
10
typedef struct STRUCT_STRINGLIST {
11
	struct STRUCT_STRINGLIST *next;
12
	struct STRUCT_STRINGLIST *prev;
13
	CyString str;
14
	CyString data;
15
	bool remove;
16
} SStringList;
17
 
18
class SPKEXPORT CyStringList
19
{
20
public:
21
	CyStringList () { m_head = m_tail = NULL; m_iCount = 0; }
22
	~CyStringList ()
23
	{
24
		SStringList *node = m_head;
25
		while ( node )
26
		{
27
			SStringList *nextnode = node->next;
28
			delete node;
29
			node = nextnode;
30
		}
31
	}
32
 
33
	void SplitToken ( char token, CyString str )
34
	{
35
		int num = 0;
36
		CyString *s = str.SplitToken ( token, &num );
37
 
38
		for ( int i = 0; i < num; i++ )
39
			PushBack ( s[i] );
40
 
41
		CLEANSPLIT(s, num);
42
	}
43
 
44
	CyStringList &operator= ( CyStringList &list )
45
	{
46
		for ( SStringList *node = list.Head(); node; node = node->next )
47
		{
48
			if ( node->remove )
49
				continue;
50
                        PushBack ( node->str, node->data );
51
		}
52
		return (*this);
53
	}
54
 
14 cycrow 55
	SStringList *Head () const { return m_head; }
56
	SStringList *Tail () const { return m_tail; }
1 cycrow 57
 
58
	bool Empty() { if ( m_head ) return false; return true; }
59
 
60
	void Clear()
61
	{
62
		SStringList *node = m_head;
63
		while ( node )
64
		{
65
			SStringList *nextnode = node->next;
66
			delete node;
67
			node = nextnode;
68
		}
69
		m_head = m_tail = NULL;
70
		m_iCount = 0;
71
	}
72
 
73
	int Count () { return m_iCount; }
74
 
75
	SStringList *GetAt ( int at )
76
	{
77
		if ( at >= m_iCount ) return NULL;
78
 
79
		SStringList *node = m_head;
80
		for ( int i = 0; i < at; i++ )
81
		{
82
			node = node->next;
83
		}
84
		return node;
85
	}
86
 
87
	CyString StringAt(int at)
88
	{
89
		SStringList *strList = this->GetAt(at);
90
		if ( !strList )
91
			return NullString;
92
		return strList->str;
93
	}
94
 
95
	bool Insert(SStringList *node, CyString str, CyString data = NullString)
96
	{
97
		// if no node, then add at the end
98
		if ( !node )
99
		{
100
			SStringList *newNode = NewNode(str, data);
101
			m_tail->next = newNode;
102
			newNode->prev = m_tail;
103
			m_tail = newNode;
104
			++m_iCount;
105
		}
106
		// first node (ie pushfront
107
		else if ( node == m_head )
108
			PushFront(str, data);
109
		else // somewhere in the middle
110
		{
111
			SStringList *newNode = NewNode(str, data);
112
			newNode->next = node;
113
			newNode->prev = node->prev;
114
			node->prev->next = newNode;
115
			node->prev = newNode;
116
			++m_iCount;
117
		}
118
 
119
		return true;
120
	}
121
	bool Insert(int pos, CyString str, CyString data = NullString)
122
	{
123
		if ( pos < 0 )
124
			return false;
125
 
126
		SStringList *tmpNode = m_head;
127
		for ( int i = 0; i < pos; i++ )
128
		{
129
			tmpNode = tmpNode->next;
130
			if ( !tmpNode )
131
				break;
132
		}
133
 
134
		return Insert(tmpNode, str, data);
135
	}
136
 
137
	void DontRemove ( CyString str )
138
	{
139
		SStringList *node = m_head;
140
		while ( node )
141
		{
142
			if ( node->str == str )
143
			{
144
				node->remove = false;
145
				break;
146
			}
147
			node = node->next;
148
		}
149
	}
150
 
151
	int FindStringPos ( CyString str )
152
	{
153
		int pos = 0;
154
		for ( SStringList *node = m_head; node; node = node->next )
155
		{
156
			if ( node->str == str )
157
				return pos;
158
			++pos;
159
		}
160
		return -1;
161
	}
162
	SStringList *FindString ( CyString str )
163
	{
164
		for ( SStringList *node = m_head; node; node = node->next )
165
		{
166
			if ( node->str == str )
167
				return node;
168
		}
169
		return NULL;
170
	}
171
	SStringList *FindData ( CyString str )
172
	{
173
		for ( SStringList *node = m_head; node; node = node->next )
174
		{
175
			if ( node->data == str )
176
				return node;
177
		}
178
		return NULL;
179
	}
180
 
181
	void RemoveMarked ()
182
	{
183
		SStringList *node = m_head;
184
		while ( node )
185
		{
186
			if ( node->remove )
187
			{
188
				if ( node->prev )
189
					node->prev->next = node->next;
190
				else
191
					m_head = node->next;
192
 
193
				if ( node->next )
194
					node->next->prev = node->prev;
195
				else
196
					m_tail = node->prev;
197
 
198
				SStringList *nextnode = node->next;
199
				delete node;
200
				node = nextnode;
201
				--m_iCount;
202
			}
203
			else
204
				node = node->next;
205
		}
206
	}
207
 
208
	bool Remove ( CyString str, bool single = true )
209
	{
210
		bool removed = false;
211
 
212
		SStringList *node = m_head;
213
		while ( node )
214
		{
215
			if ( node->str == str )
216
			{
217
				if ( node->prev )
218
					node->prev->next = node->next;
219
				else
220
					m_head = node->next;
221
 
222
				if ( node->next )
223
					node->next->prev = node->prev;
224
				else
225
					m_tail = node->prev;
226
 
227
				SStringList *nextnode = node->next;
228
				delete node;
229
				removed = true;
230
				--m_iCount;
231
				node = nextnode;
232
				if ( single )
233
					break;
234
			}
235
			else
236
				node = node->next;
237
		}
238
		return removed;
239
	}
240
 
241
	SStringList *Change ( CyString str, CyString to )
242
	{
243
		SStringList *node = m_head;
244
		while ( node )
245
		{
246
			if ( node->str == str )
247
			{
248
				node->str = to;
249
				return node;
250
			}
251
			node = node->next;
252
		}
253
		return NULL;
254
	}
255
 
256
	void PopBack ()
257
	{
258
		if ( !m_head )
259
			return;
260
 
261
		if ( m_tail->prev )
262
			m_tail->prev->next = NULL;
263
		else
264
			m_head = NULL;
265
		SStringList *node = m_tail->prev;
266
		delete m_tail;
267
		m_tail = node;
268
		--m_iCount;
269
	}
270
 
271
	void PopFront ()
272
	{
273
		if ( !m_head )
274
			return;
275
 
276
		if ( m_head->next )
277
			m_head->next->prev = NULL;
278
		else
279
			m_tail = NULL;
280
		SStringList *node = m_head->next;
281
		delete m_head;
282
		m_head = node;
283
		--m_iCount;
284
	}
285
 
286
	void DeleteFrom ( SStringList *node )
287
	{
288
		if ( !node ) return;
289
 
290
		m_tail = node->prev;
291
		if ( !m_tail )
292
			m_head = NULL;
293
		else
294
			m_tail->next = NULL;
295
 
296
		while ( node )
297
		{
298
			SStringList *nextnode = node->next;
299
			delete node;
300
			--m_iCount;
301
			node = nextnode;
302
		}
303
	}
304
 
305
	void DeleteFrom(int pos)
306
	{
307
		DeleteFrom(GetAt(pos));
308
	}
309
 
310
	void PushFront ( const char *str, const char *data = 0) { return this->PushFront(CyString(str), (data) ? CyString(data) : NullString); }
311
    void PushFront ( const char *str, CyString data ) { return this->PushFront(CyString(str), data); }
312
	void PushFront ( CyString str, const char *data = 0) { return this->PushFront(str, (data) ? CyString(data) : NullString); }
313
    void PushFront ( CyString str, CyString data )
314
	{
315
		SStringList *s = NewNode(str, data);
316
		if ( !m_tail )
317
			m_tail = s;
318
		else
319
		{
320
			m_head->prev = s;
321
			s->next = m_head;
322
		}
323
		m_head = s;
324
		++m_iCount;
325
	}
326
 
327
	SStringList *PushBack ( const char *str, const char *data, bool search = false ) { return PushBack(CyString(str), CyString(data), search); }
328
    SStringList *PushBack ( const char *str, CyString data, bool search = false ) { return PushBack(CyString(str), data, search); }
329
    SStringList *PushBack ( CyString str, const char *data, bool search = false ) { return PushBack(str, CyString(data), search); }
330
    SStringList *PushBack ( CyString str, CyString data, bool search = false )
331
	{
332
		if ( search )
333
		{
334
			SStringList *n = FindString(str);
335
			if ( n )
336
			{
337
				n->data = data;
338
				n->remove = false;
339
				return n;
340
			}
341
		}
342
		SStringList *s = NewNode(str, data);
343
		if ( !m_head )
344
			m_head = s;
345
		else
346
		{
347
			m_tail->next = s;
348
			s->prev = m_tail;
349
		}
350
		m_tail = s;
351
		++m_iCount;
352
		return m_tail;
353
	}
354
 
355
	SStringList *PushBack ( const char *str, bool search = false ) { return PushBack(CyString(str), search); }
356
	SStringList *PushBack ( CyString str, bool search = false )
357
	{
358
		if ( search )
359
		{
360
			SStringList *n = FindString(str);
361
			if ( n )
362
			{
363
				n->remove = false;
364
				return n;
365
			}
366
		}
367
		SStringList *s = NewNode(str);
368
		if ( !m_head )
369
			m_head = s;
370
		else
371
		{
372
			m_tail->next = s;
373
			s->prev = m_tail;
374
		}
375
		m_tail = s;
376
		++m_iCount;
377
		return m_tail;
378
	}
379
 
380
	CyString First()
381
	{
382
		if ( m_head )
383
			return m_head->str;
384
		return NullString;
385
	}
386
 
387
private:
388
	SStringList *NewNode(CyString str, CyString data = NullString)
389
	{
390
		SStringList *s = new SStringList;
391
		s->next = s->prev = NULL;
392
		s->str = str;
393
		s->data = data;
394
		s->remove = false;
395
 
396
		return s;
397
	}
398
 
399
	SStringList *m_head;
400
	SStringList *m_tail;
401
 
402
	int m_iCount;
403
};
404
 
405
#endif //__BASE_ENGINE_STRINGLIST_H__