/* Copyright (c) MediaArea.net SARL. All Rights Reserved.
*
* Use of this source code is governed by a zlib-style license that can
* be found in the License.txt file in the root of the source tree.
*/
//---------------------------------------------------------------------------
#include "ZenLib/PreComp.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "ZenLib/Conf_Internal.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <algorithm>
#include "ZenLib/ZtringList.h"
using namespace std;
#if defined(_MSC_VER) && _MSC_VER <= 1200
using std::vector; //Visual C++ 6 patch
#endif
//---------------------------------------------------------------------------
namespace ZenLib
{
//---------------------------------------------------------------------------
extern Ztring EmptyZtring;
//---------------------------------------------------------------------------
//***************************************************************************
// Constructors/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
// Constructors
ZtringList::ZtringList ()
: std::vector<ZenLib::Ztring, std::allocator<ZenLib::Ztring> > ()
{
Separator[0]=__T(";");
Quote=__T("\"");
Max[0]=Error;
}
ZtringList::ZtringList(const ZtringList &Source)
: std::vector<ZenLib::Ztring, std::allocator<ZenLib::Ztring> > ()
{
Separator[0]=Source.Separator[0];
Quote=Source.Quote;
reserve(Source.size());
for (intu Pos=0; Pos<Source.size(); Pos++)
push_back(Source[Pos]);
}
ZtringList::ZtringList (const Ztring &Source)
{
Separator[0]=__T(";");
Quote=__T("\"");
Max[0]=Error;
Write(Source.c_str());
}
ZtringList::ZtringList (const Char *Source)
{
Separator[0]=__T(";");
Quote=__T("\"");
Max[0]=Error;
Write(Source);
}
#ifdef _UNICODE
ZtringList::ZtringList (const char* S)
{
Write(Ztring(S));
}
#endif
//***************************************************************************
// Operator
//***************************************************************************
//---------------------------------------------------------------------------
// Operator ==
bool ZtringList::operator== (const ZtringList &Source) const
{
return (Read()==Source.Read());
}
//---------------------------------------------------------------------------
// Operator !=
bool ZtringList::operator!= (const ZtringList &Source) const
{
return (!(Read()==Source.Read()));
}
//---------------------------------------------------------------------------
// Operator +=
ZtringList &ZtringList::operator+= (const ZtringList &Source)
{
reserve(size()+Source.size());
for (size_type Pos=0; Pos<Source.size(); Pos++)
push_back(Source[Pos]);
return *this;
}
//---------------------------------------------------------------------------
// Operator =
ZtringList &ZtringList::operator= (const ZtringList &Source)
{
if (this == &Source)
return *this;
clear();
Ztring C=Separator[0];
Ztring Q=Quote;
Separator[0]=Source.Separator[0];
Quote=Source.Quote;
reserve(Source.size());
for (size_type Pos=0; Pos<Source.size(); Pos++)
push_back(Source[Pos]);
Separator[0]=C;
Quote=Q;
return *this;
}
//---------------------------------------------------------------------------
// Operator ()
Ztring &ZtringList::operator() (size_type Pos)
{
if (Pos>=size())
Write(Ztring(), Pos);
return operator[](Pos);
}
//***************************************************************************
// In/Out
//***************************************************************************
//---------------------------------------------------------------------------
// Read
Ztring ZtringList::Read () const
{
//Integrity
if (size()==0)
return Ztring();
Ztring Retour;
Ztring ToFind=Separator[0]+Quote+__T("\r\n");
for (size_type Pos=0; Pos<size(); Pos++)
{
if (operator[](Pos).find_first_of(ToFind)==std::string::npos)
Retour+=operator[](Pos)+Separator[0];
else if (operator[](Pos).find(Separator[0])==std::string::npos
&& (Quote.empty() || operator[](Pos).find(Quote)==std::string::npos)
&& operator[](Pos).find('\r')==std::string::npos
&& operator[](Pos).find('\n')==std::string::npos)
Retour+=operator[](Pos)+Separator[0];
else
{
if (Quote.empty() || operator[](Pos).find(Quote)==std::string::npos)
Retour+=Quote+operator[](Pos)+Quote+Separator[0];
else
{
Ztring Value=operator[](Pos);
Value.FindAndReplace(Quote, Quote+Quote, 0, Ztring_Recursive);
Retour+=Quote+Value+Quote+Separator[0];
}
}
}
//delete all useless separators at the end
//while (Retour.find(Separator[0].c_str(), Retour.size()-Separator[0].size())!=std::string::npos)
if (Retour.find(Separator[0].c_str(), Retour.size()-Separator[0].size())!=std::string::npos)
Retour.resize(Retour.size()-Separator[0].size());
return Retour;
}
const Ztring &ZtringList::Read (size_type Pos) const
{
//Integrity
if (Pos>=size())
return EmptyZtring;
return operator[](Pos);
}
//---------------------------------------------------------------------------
// Write
void ZtringList::Write(const Ztring &ToWrite)
{
clear();
if (ToWrite.empty())
return;
size_type PosC=0;
bool Fini=false;
Ztring C1;
Ztring DelimiterL;
Ztring DelimiterR;
do
{
//Searching quotes
if (!Quote.empty() && ToWrite[PosC]==Quote[0])
{
size_t Pos_End=PosC+1;
while (Pos_End<ToWrite.size())
{
if (ToWrite[Pos_End]==Quote[0] && Pos_End+1<ToWrite.size() && ToWrite[Pos_End+1]==Quote[0])
Pos_End+=2; //Double quote, skipping
else
{
if (ToWrite[Pos_End]==Quote[0])
break;
Pos_End++;
}
}
C1=ToWrite.substr(PosC+Quote.size(), Pos_End-PosC);
PosC+=C1.size()+Quote.size();
if (C1.size()>0 && C1[C1.size()-1]==Quote[0])
{
C1.resize(C1.size()-1);
PosC+=Quote.size();
}
}
else //Normal
{
C1=ToWrite.SubString(tstring(), Separator[0], PosC, Ztring_AddLastItem);
PosC+=C1.size()+Separator[0].size();
}
if (!Quote.empty())
C1.FindAndReplace(Quote+Quote, Quote, 0, Ztring_Recursive);
if (size()<Max[0])
push_back(C1);
if (PosC>=ToWrite.size())
Fini=true;
}
while (!Fini);
return;
}
void ZtringList::Write(const Ztring &ToWrite, size_type Pos)
{
if (Pos==Error)
return;
if (Pos>=size())
{
//Resource reservation
size_t ToReserve=1;
while (ToReserve<Pos)
ToReserve*=2;
reserve(ToReserve);
while (Pos>size())
push_back(Ztring());
push_back(ToWrite);
}
else
operator[](Pos)=ToWrite;
return;
}
//***************************************************************************
// Edition
//***************************************************************************
//---------------------------------------------------------------------------
// Swap
void ZtringList::Swap (size_type Pos0_A, size_type Pos0_B)
{
//Integrity
size_type Pos_Max;
if (Pos0_A<Pos0_B)
Pos_Max=Pos0_B;
else
Pos_Max=Pos0_A;
if (Pos_Max>=size())
Write(Ztring(), Pos_Max);
operator [] (Pos0_A).swap(operator [] (Pos0_B));
}
//---------------------------------------------------------------------------
// Sort
void ZtringList::Sort(ztring_t)
{
std::stable_sort(begin(), end());
return;
}
//***************************************************************************
// Information
//***************************************************************************
//---------------------------------------------------------------------------
// Find
Ztring::size_type ZtringList::Find (const Ztring &ToFind, size_type Pos, const Ztring &Comparator, ztring_t Options) const
{
while (Pos<size() && !(operator[](Pos).Compare(ToFind, Comparator, Options)))
Pos++;
if (Pos>=size())
return Error;
return Pos;
}
//---------------------------------------------------------------------------
// Return the length of the longest string in the list.
Ztring::size_type ZtringList::MaxStringLength_Get ()
{
size_type Max = 0;
for (ZtringList::const_iterator it=begin(); it!=end(); ++it)
if (it->size()>Max)
Max=it->size();
return Max;
}
//***************************************************************************
// Configuration
//***************************************************************************
//---------------------------------------------------------------------------
// Separator
void ZtringList::Separator_Set (size_type Level, const Ztring &NewSeparator)
{
if (NewSeparator.empty() || Level>0)
return;
if (Separator[Level]==NewSeparator)
return;
Separator[Level]=NewSeparator;
}
//---------------------------------------------------------------------------
// Quote
void ZtringList::Quote_Set (const Ztring &NewQuote)
{
if (Quote==NewQuote)
return;
Quote=NewQuote;
}
//---------------------------------------------------------------------------
// Separator
void ZtringList::Max_Set (size_type Level, size_type Max_New)
{
if (Level>0 || Max_New==0)
return;
Max[Level]=Max_New;
}
} //namespace
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: Max.
↑ V688 The 'Max' local variable possesses the same name as one of the class members, which can result in a confusion.
↑ V730 It is possible that not all members of a class are initialized inside the constructor. Consider inspecting: Max.
↑ V820 The 'C' variable is not used after copying. Copying can be replaced with move/swap for optimization.
↑ V820 The 'Q' variable is not used after copying. Copying can be replaced with move/swap for optimization.