1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a zlib-style license that can
4 * be found in the License.txt file in the root of the source tree.
5 */
6
7 //---------------------------------------------------------------------------
8 #include "ZenLib/PreComp.h"
9 #ifdef __BORLANDC__
10 #pragma hdrstop
11 #endif
12 //---------------------------------------------------------------------------
13
14 //---------------------------------------------------------------------------
15 #include "ZenLib/Conf_Internal.h"
16 //---------------------------------------------------------------------------
17
18 //---------------------------------------------------------------------------
19 #include <algorithm>
20 #include "ZenLib/ZtringListList.h"
21 using namespace std;
22 #if defined(_MSC_VER) && _MSC_VER <= 1200
23 using std::vector; //Visual C++ 6 patch
24 #endif
25 //---------------------------------------------------------------------------
26
27
28 namespace ZenLib
29 {
30
31 //---------------------------------------------------------------------------
32 extern Ztring EmptyZtring;
33 //---------------------------------------------------------------------------
34
35 //***************************************************************************
36 // Constructors/Destructor
37 //***************************************************************************
38
39 //---------------------------------------------------------------------------
40 // Constructors
ZtringListList()41 ZtringListList::ZtringListList()
42 : std::vector<ZenLib::ZtringList, std::allocator<ZenLib::ZtringList> > ()
43 {
44 Separator[0]=EOL;
45 Separator[1]=__T(";");
46 Quote=__T("\"");
47 Max[0]=Error;
48 Max[1]=Error;
49 }
50
ZtringListList(const ZtringListList & Source)51 ZtringListList::ZtringListList(const ZtringListList &Source)
52 : std::vector<ZenLib::ZtringList, std::allocator<ZenLib::ZtringList> > ()
53 {
54 Separator[0]=Source.Separator[0];
55 Separator[1]=Source.Separator[1];
56 Quote=Source.Quote;
57 Max[0]=Source.Max[0];
58 Max[1]=Source.Max[1];
59 reserve(Source.size());
60 for (intu Pos=0; Pos<Source.size(); Pos++)
61 push_back(Source[Pos]);
62 }
63
ZtringListList(const Ztring & Source)64 ZtringListList::ZtringListList(const Ztring &Source)
65 {
66 Separator[0]=EOL;
67 Separator[1]=__T(";");
68 Quote=__T("\"");
69 Max[0]=Error;
70 Max[1]=Error;
71 Write(Source.c_str());
72 }
73
ZtringListList(const Char * Source)74 ZtringListList::ZtringListList(const Char *Source)
75 {
76 Separator[0]=EOL;
77 Separator[1]=__T(";");
78 Quote=__T("\"");
79 Max[0]=Error;
80 Max[1]=Error;
81 Write(Source);
82 }
83
84 #ifdef _UNICODE
ZtringListList(const char * S)85 ZtringListList::ZtringListList (const char* S)
86 {
87 Separator[0]=EOL;
88 Separator[1]=__T(";");
89 Quote=__T("\"");
90 Max[0]=Error;
91 Max[1]=Error;
92 Write(Ztring(S));
93 }
94 #endif
95
96 //***************************************************************************
97 // Operators
98 //***************************************************************************
99
100 //---------------------------------------------------------------------------
101 //Operator ==
operator ==(const ZtringListList & Source) const102 bool ZtringListList::operator== (const ZtringListList &Source) const
103 {
104 return (Read()==Source.Read());
105 }
106
107 //---------------------------------------------------------------------------
108 //Operator !=
operator !=(const ZtringListList & Source) const109 bool ZtringListList::operator!= (const ZtringListList &Source) const
110 {
111 return (!(Read()==Source.Read()));
112 }
113
114 //---------------------------------------------------------------------------
115 // Operator +=
operator +=(const ZtringListList & Source)116 ZtringListList &ZtringListList::operator+= (const ZtringListList &Source)
117 {
118 reserve(size()+Source.size());
119 for (size_type Pos=0; Pos<Source.size(); Pos++)
120 {
121 push_back(Source[Pos]);
122 operator[](size()-1).Separator_Set(0, Separator[1]);
123 operator[](size()-1).Quote_Set(Quote);
124 operator[](size()-1).Max_Set(0, Max[1]);
125 }
126
127 return *this;
128 }
129
130 //---------------------------------------------------------------------------
131 // Operator =
operator =(const ZtringListList & Source)132 ZtringListList &ZtringListList::operator= (const ZtringListList &Source)
133 {
134 if (this == &Source)
135 return *this;
136 clear();
137
138 reserve(Source.size());
139 for (size_type Pos=0; Pos<Source.size(); Pos++)
140 {
141 push_back(Source[Pos]);
142 operator[](size()-1).Separator_Set(0, Separator[1]);
143 operator[](size()-1).Quote_Set(Quote);
144 operator[](size()-1).Max_Set(0, Max[1]);
145 }
146
147 return *this;
148 }
149
150 //---------------------------------------------------------------------------
151 // Operatorr ()
operator ()(size_type Pos0)152 ZtringList &ZtringListList::operator() (size_type Pos0)
153 {
154 //Integrity
155 if (Pos0>=size())
156 Write(Ztring(), Pos0);
157
158 return operator[](Pos0);
159 }
160
operator ()(size_type Pos0,size_type Pos1)161 Ztring &ZtringListList::operator() (size_type Pos0, size_type Pos1)
162 {
163 //Integrity
164 if (Pos0>=size())
165 Write(Ztring(), Pos0);
166
167 return operator[](Pos0).operator()(Pos1);
168 }
169
operator ()(const Ztring & Pos0,size_type Pos0_1,size_type Pos1)170 Ztring &ZtringListList::operator() (const Ztring &Pos0, size_type Pos0_1, size_type Pos1)
171 {
172 size_type Pos=0;
173 size_t Size=size();
174 for (; Pos<Size; Pos++)
175 if (operator[](Pos).size()>Pos0_1)
176 if (operator[](Pos)[Pos0_1]==Pos0)
177 break;
178
179 if (Pos>=Size)
180 {
181 Write(Pos0, Size, Pos0_1);
182 Pos=size()-1;
183 }
184
185 return operator[](Pos).operator()(Pos1);
186 }
187
188 //***************************************************************************
189 // In/Out
190 //***************************************************************************
191
192 //---------------------------------------------------------------------------
193 // Read
Read() const194 Ztring ZtringListList::Read () const
195 {
196 //Integrity
197 if (size()==0)
198 return Ztring();
199
200 Ztring ToReturn;
201 size_type Size=size()-1;
202 for (size_type Pos0=0; Pos0<Size; Pos0++)
203 ToReturn+=Read(Pos0)+Separator[0];
204 ToReturn+=Read(Size);
205
206 //Delete all useless separators at the end
207 //if(ToReturn.size()>0 && Separator[0].size() && ToReturn(ToReturn.size()-1)==Separator[0][Separator[0].size()-1]) //Optimize speed
208 // while (ToReturn.find(Separator[0].c_str(), ToReturn.size()-Separator[0].size())!=std::string::npos)
209 // ToReturn.resize(ToReturn.size()-Separator[0].size());
210
211 return ToReturn;
212 }
213
Read(size_type Pos0) const214 Ztring ZtringListList::Read (size_type Pos0) const
215 {
216 //Integrity
217 if (Pos0>=size())
218 return Ztring();
219
220 return operator[](Pos0).Read();
221 }
222
Read(size_type Pos0,size_type Pos1) const223 const Ztring &ZtringListList::Read (size_type Pos0, size_type Pos1) const
224 {
225 //Integrity
226 if (Pos0>=size())
227 return EmptyZtring;
228
229 return operator[](Pos0).Read(Pos1);
230 }
231
Read(const Ztring & Pos0,size_type Pos1) const232 const Ztring &ZtringListList::Read (const Ztring &Pos0, size_type Pos1) const
233 {
234 size_type Pos=Find(Pos0);
235 if (Pos==Error)
236 return EmptyZtring;
237
238 return operator[](Pos).Read(Pos1);
239 }
240
Read(const Ztring & Pos0,size_type Pos0_1,size_type Pos1) const241 const Ztring &ZtringListList::Read (const Ztring &Pos0, size_type Pos0_1, size_type Pos1) const
242 {
243 size_type Pos=Find(Pos0, Pos0_1);
244 if (Pos==Error)
245 return EmptyZtring;
246
247 return operator[](Pos).Read(Pos1);
248 }
249
Read(const Ztring & Pos0,const Ztring & Default,size_type Pos1) const250 const Ztring &ZtringListList::Read (const Ztring &Pos0, const Ztring &Default, size_type Pos1) const
251 {
252 size_type Pos=Find(Pos0);
253 if (Pos==Error)
254 return Default;
255
256 return operator[](Pos).Read(Pos1);
257 }
258
Read(const Ztring & Pos0,const Ztring & Default,size_type Pos0_1,size_type Pos1) const259 const Ztring &ZtringListList::Read (const Ztring &Pos0, const Ztring &Default, size_type Pos0_1, size_type Pos1) const //Lecture d'un champs en position 0 avec une option par defaut
260 {
261 size_type Pos=Find(Pos0, Pos0_1);
262 if (Pos==Error)
263 return Default;
264
265 return operator[](Pos).Read(Pos1);
266 }
267
Read1(size_type Pos1) const268 Ztring ZtringListList::Read1 (size_type Pos1) const
269 {
270 Ztring ToReturn;
271 size_type Size=size()-1;
272 for (size_type Pos=0; Pos<Size; Pos++)
273 ToReturn+=operator[](Pos).Read(Pos1)+Separator[0];
274 ToReturn+=operator[](Size).Read(Pos1);
275
276 //Delete all useless separators at the end
277 if(ToReturn(ToReturn.size()-1)==Separator[0][Separator[0].size()-1]) //Optimize speed
278 while (ToReturn.find(Separator[0].c_str(), ToReturn.size()-Separator[0].size())!=std::string::npos)
279 ToReturn.resize(ToReturn.size()-Separator[0].size());
280
281 return ToReturn;
282 }
283
284 //---------------------------------------------------------------------------
285 // Write
Write(const Ztring & ToWrite)286 void ZtringListList::Write(const Ztring &ToWrite)
287 {
288 clear();
289
290 if (ToWrite.empty())
291 return;
292
293 //Detecting carriage return format
294 Ztring Separator0;
295 if (Separator[0]==EOL)
296 {
297 size_t CarriageReturn_Pos=ToWrite.find_first_of(__T("\r\n"));
298 if (CarriageReturn_Pos!=string::npos)
299 {
300 if (ToWrite[CarriageReturn_Pos]==__T('\r'))
301 {
302 if (CarriageReturn_Pos+1<ToWrite.size() && ToWrite[CarriageReturn_Pos+1]==__T('\n'))
303 Separator0=__T("\r\n");
304 else
305 Separator0=__T("\r");
306 }
307 else
308 Separator0=__T("\n");
309 }
310 else
311 Separator0=Separator[0];
312 }
313 else
314 Separator0=Separator[0];
315
316 size_t l=ToWrite.size();
317 size_t i=0;
318 bool q=false; //In quotes
319 size_t Quote_Size=Quote.size();
320 size_t Separator0_Size=Separator0.size();
321 size_t Separator1_Size=Separator[1].size();
322 size_t x=0, y=0;
323 while (i<l)
324 {
325 //Quote
326 if (Quote_Size && i+Quote_Size<=l)
327 {
328 bool IsQuote=true;
329 for (size_t j=0; j<Quote_Size; j++)
330 {
331 if (ToWrite[i+j]!=Quote[j])
332 {
333 IsQuote=false;
334 break;
335 }
336 }
337 if (IsQuote)
338 {
339 //Double quote
340 if (i+Quote_Size*2<=l)
341 {
342 IsQuote=false;
343 for (size_t j=0; j<Quote_Size; j++)
344 {
345 if (ToWrite[i+Quote_Size+j]!=Quote[j])
346 {
347 IsQuote=true;
348 break;
349 }
350 }
351 if (!IsQuote)
352 i++; // 2 quote chars transformed to one unique quote
353 }
354 if (IsQuote)
355 {
356 i+=Quote_Size;
357 q=!q;
358 continue;
359 }
360 }
361 }
362
363 if (!q)
364 {
365 //Carriage return
366 if (i+Separator0_Size<=l)
367 {
368 bool IsSeparator0=true;
369 for (size_t j=0; j<Separator0_Size; j++)
370 {
371 if (ToWrite[i+j]!= Separator0[j])
372 {
373 IsSeparator0=false;
374 break;
375 }
376 }
377 if (IsSeparator0)
378 {
379 i+=Separator0_Size;
380 y++;
381 x=0;
382 continue;
383 }
384 }
385
386 //Carriage return
387 if (i+Separator1_Size<=l)
388 {
389 bool IsSeparator1=true;
390 for (size_t j=0; j<Separator1_Size; j++)
391 {
392 if (ToWrite[i+j]!= Separator[1][j])
393 {
394 IsSeparator1=false;
395 break;
396 }
397 }
398 if (IsSeparator1)
399 {
400 i+=Separator1_Size;
401 x++;
402 continue;
403 }
404 }
405 }
406
407 if (y>=size())
408 {
409 resize(y+1);
410 for (size_t j=0; j<=y; j++)
411 {
412 operator[](j).Separator_Set(0, Separator[1]);
413 operator[](j).Quote_Set(Quote);
414 operator[](j).Max_Set(0, Max[1]);
415 }
416 }
417 ZtringList& Line=operator[](y);
418 if (x>=Line.size())
419 Line.resize(x+1);
420 Line.operator[](x).push_back(ToWrite[i]);
421
422 i++;
423 }
424 }
425
Write(const ZtringList & ToWrite,size_type Pos)426 void ZtringListList::Write(const ZtringList &ToWrite, size_type Pos)
427 {
428 //Integrity
429 if (Pos==Error)
430 return;
431
432 //Writing
433 if (Pos>=size())
434 {
435 //Reservation de ressources
436 if (!capacity())
437 reserve(1);
438 while (Pos>=capacity())
439 reserve(capacity()*2);
440
441 while (Pos>size())
442 push_back (Ztring());
443 push_back(ToWrite);
444 }
445 else
446 operator[](Pos)=ToWrite;
447 }
448
Write(const Ztring & ToWrite,size_type Pos0,size_type Pos1)449 void ZtringListList::Write(const Ztring &ToWrite, size_type Pos0, size_type Pos1)
450 {
451 if (Pos0>=size())
452 Write(Ztring(), Pos0);
453
454 operator[](Pos0).Write(ToWrite, Pos1);
455 }
456
push_back(const ZtringList & ToAdd)457 void ZtringListList::push_back (const ZtringList &ToAdd)
458 {
459 vector<ZtringList>::push_back(ToAdd); //Visual C++ 6 patch, should be std::vector
460 operator[](size()-1).Separator_Set(0, Separator[1]);
461 operator[](size()-1).Quote_Set(Quote);
462 operator[](size()-1).Max_Set(0, Max[1]);
463 }
464
push_back(const Ztring & ToAdd)465 void ZtringListList::push_back (const Ztring &ToAdd)
466 {
467 ZtringList ZL1;
468 ZL1.Separator_Set(0, Separator[1]);
469 ZL1.Quote_Set(Quote);
470 ZL1.Max_Set(0, Max[1]);
471 ZL1.Write(ToAdd);
472 push_back(ZL1);
473 }
474
475 //---------------------------------------------------------------------------
476 // Insert
Insert1(const Ztring & ToInsert,size_type Pos1)477 void ZtringListList::Insert1 (const Ztring &ToInsert, size_type Pos1)
478 {
479 for (size_type Pos0=0; Pos0<size(); Pos0++)
480 operator[](Pos0).Insert(ToInsert, Pos1);
481 }
482
483 //---------------------------------------------------------------------------
484 // Delete
Delete(const Ztring & ToFind,size_type Pos1,const Ztring & Comparator,ztring_t Options)485 void ZtringListList::Delete (const Ztring &ToFind, size_type Pos1, const Ztring &Comparator, ztring_t Options)
486 {
487 size_type Pos0=0;
488 while ((Pos0=Find(ToFind, Pos1, Pos0, Comparator, Options))!=Error)
489 operator [] (Pos0).Delete(Pos1);
490 }
491
Delete1(size_type Pos1)492 void ZtringListList::Delete1 (size_type Pos1)
493 {
494 for (size_type Pos0=0; Pos0<size(); Pos0++)
495 operator [] (Pos0).Delete(Pos1);
496 }
497
498 //***************************************************************************
499 // Edition
500 //***************************************************************************
501
502 //---------------------------------------------------------------------------
503 // Swap
Swap(size_type Pos0_A,size_type Pos0_B)504 void ZtringListList::Swap (size_type Pos0_A, size_type Pos0_B)
505 {
506 //Integrity
507 size_type Pos_Max;
508 if (Pos0_A<Pos0_B)
509 Pos_Max=Pos0_B;
510 else
511 Pos_Max=Pos0_A;
512 if (Pos_Max>=size())
513 Write(Ztring(), Pos_Max);
514
515 operator [] (Pos0_A).swap(operator [] (Pos0_B));
516 }
517
Swap1(size_type Pos1_A,size_type Pos1_B)518 void ZtringListList::Swap1 (size_type Pos1_A, size_type Pos1_B)
519 {
520 for (size_type Pos0=0; Pos0<size(); Pos0++)
521 operator () (Pos0, Pos1_A).swap(operator () (Pos0, Pos1_B));
522 }
523
524 //---------------------------------------------------------------------------
525 // Sort
Sort(size_type,ztring_t)526 void ZtringListList::Sort(size_type, ztring_t)
527 {
528 std::stable_sort(begin(), end());
529 return;
530 }
531
532 //---------------------------------------------------------------------------
533 // Find
Find(const Ztring & ToFind,size_type Pos1,size_type Pos0) const534 Ztring::size_type ZtringListList::Find (const Ztring &ToFind, size_type Pos1, size_type Pos0) const
535 {
536 size_t Size=size();
537 for (; Pos0<Size; Pos0++)
538 if (operator[](Pos0).size()>Pos1)
539 if (operator[](Pos0)[Pos1]==ToFind)
540 break;
541
542 if (Pos0>=Size)
543 return Error;
544 return Pos0;
545 }
546
Find_Filled(size_type Pos1,size_type Pos0) const547 Ztring::size_type ZtringListList::Find_Filled (size_type Pos1, size_type Pos0) const
548 {
549 size_t Size=size();
550 for (; Pos0<Size; Pos0++)
551 if (operator[](Pos0).size()>Pos1)
552 if (!operator[](Pos0)[Pos1].empty())
553 break;
554
555 if (Pos0>=Size)
556 return Error;
557 return Pos0;
558 }
559
Find(const Ztring & ToFind,size_type Pos1,size_type Pos0,const Ztring & Comparator,ztring_t Options) const560 Ztring::size_type ZtringListList::Find (const Ztring &ToFind, size_type Pos1, size_type Pos0, const Ztring &Comparator, ztring_t Options) const
561 {
562 while ( Pos0<size()
563 && ( Pos1>=at(Pos0).size()
564 || !at(Pos0).at(Pos1).Compare(ToFind, Comparator, Options)))
565 Pos0++;
566 if (Pos0>=size())
567 return Error;
568 return Pos0;
569 }
570
FindValue(const Ztring & ToFind,size_type Pos1Value,size_type Pos1,size_type Pos0Begin,const Ztring & Comparator,ztring_t) const571 Ztring ZtringListList::FindValue (const Ztring &ToFind, size_type Pos1Value, size_type Pos1, size_type Pos0Begin, const Ztring &Comparator, ztring_t) const
572 {
573 size_type Pos0=Find(ToFind, Pos1, Pos0Begin, Comparator);
574 if (Pos0==Error)
575 return Ztring();
576
577 return Read(Pos0, Pos1Value);
578 }
579
SubSheet(const Ztring & ToFind,size_type Pos1,size_type Pos0,const Ztring & Comparator,ztring_t) const580 ZtringListList ZtringListList::SubSheet (const Ztring &ToFind, size_type Pos1, size_type Pos0, const Ztring &Comparator, ztring_t) const
581 {
582 ZtringListList ToReturn;
583 ToReturn.Separator[0]=Separator[0];
584 ToReturn.Separator[1]=Separator[1];
585 ToReturn.Quote=Quote;
586
587 Pos0--;
588 do
589 {
590 Pos0=Find(ToFind, Pos1, Pos0+1, Comparator);
591 ToReturn.push_back(Read(Pos0));
592 }
593 while (Pos0!=Error);
594
595 return ToReturn;
596 }
597
598 //***************************************************************************
599 // Configuration
600 //***************************************************************************
601
602 //---------------------------------------------------------------------------
603 // Separator
Separator_Set(size_type Level,const Ztring & NewSeparator)604 void ZtringListList::Separator_Set (size_type Level, const Ztring &NewSeparator)
605 {
606 if (NewSeparator.empty() || Level>1)
607 return;
608
609 Separator[Level]=NewSeparator;
610 if (Level==1)
611 for (size_type Pos0=0; Pos0<size(); Pos0++)
612 operator () (Pos0).Separator_Set(0, Separator[1]);
613 }
614
615 //---------------------------------------------------------------------------
616 // Quote
Quote_Set(const Ztring & NewQuote)617 void ZtringListList::Quote_Set (const Ztring &NewQuote)
618 {
619 Quote=NewQuote;
620 for (size_type Pos0=0; Pos0<size(); Pos0++)
621 operator () (Pos0).Quote_Set(Quote);
622 }
623
624 //---------------------------------------------------------------------------
625 // Max
Max_Set(size_type Level,size_type NewMax)626 void ZtringListList::Max_Set (size_type Level, size_type NewMax)
627 {
628 if (Level>1 || NewMax==0)
629 return;
630
631 Max[Level]=NewMax;
632 if (Level==1)
633 for (size_type Pos0=0; Pos0<size(); Pos0++)
634 operator () (Pos0).Max_Set(0, Max[1]);
635 }
636
637 //***************************************************************************
638 //
639 //***************************************************************************
640
641 } //namespace
642