Subversion Repositories spk

Rev

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