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 #ifdef ZENLIB_USEWX
20     #include <wx/strconv.h>
21 #endif //ZENLIB_USEWX
22 #include <algorithm>
23 #include "ZenLib/InfoMap.h"
24 using namespace std;
25 //---------------------------------------------------------------------------
26 
27 namespace ZenLib
28 {
29 
30 //---------------------------------------------------------------------------
31 const Ztring InfoMap_EmptyZtring_Const; //Use it when we can't return a reference to a true Ztring, const version
32 //---------------------------------------------------------------------------
33 
34 //***************************************************************************
35 // Constructors/Destructor
36 //***************************************************************************
37 
38 //---------------------------------------------------------------------------
39 // Constructors
InfoMap()40 InfoMap::InfoMap()
41 : std::multimap<ZenLib::Ztring, ZenLib::ZtringList> ()
42 {
43     Separator[0]=EOL;
44     Separator[1]=__T(";");
45 }
46 
InfoMap(const Ztring & Source)47 InfoMap::InfoMap(const Ztring &Source)
48 : std::multimap<ZenLib::Ztring, ZenLib::ZtringList> ()
49 {
50     Separator[0]=EOL;
51     Separator[1]=__T(";");
52     Write(Source);
53 }
54 
InfoMap(const Char * Source)55 InfoMap::InfoMap(const Char *Source)
56 : std::multimap<ZenLib::Ztring, ZenLib::ZtringList> ()
57 {
58     Separator[0]=EOL;
59     Separator[1]=__T(";");
60     Write(Source);
61 }
62 
63 #ifdef _UNICODE
InfoMap(const char * S)64 InfoMap::InfoMap (const char* S)
65 : std::multimap<ZenLib::Ztring, ZenLib::ZtringList> ()
66 {
67     Separator[0]=EOL;
68     Separator[1]=__T(";");
69     Write(Ztring(S));
70 }
71 #endif
72 
73 //***************************************************************************
74 // In/Out
75 //***************************************************************************
76 
77 //---------------------------------------------------------------------------
Get(const Ztring & Value,size_t Pos) const78 const Ztring &InfoMap::Get (const Ztring &Value, size_t Pos) const
79 {
80     InfoMap::const_iterator List=find(Value);
81     if (List==end())
82         return InfoMap_EmptyZtring_Const; //Not found
83     if (Pos<List->second.size())
84         return List->second[Pos];
85     else
86         return InfoMap_EmptyZtring_Const; //Not found
87 }
88 
89 //---------------------------------------------------------------------------
Get(const Ztring & Value,size_t Pos,const Ztring & WithValue,size_t WithValue_Pos) const90 const Ztring &InfoMap::Get (const Ztring &Value, size_t Pos, const Ztring &WithValue, size_t WithValue_Pos) const
91 {
92     InfoMap::const_iterator List=find(Value);
93     if (List==end())
94         return InfoMap_EmptyZtring_Const; //Not found
95     if (Pos<List->second.size())
96     {
97         if (List->second[WithValue_Pos]==WithValue)
98             return List->second[Pos];
99         else
100         {
101             ++List; //The second one, this is a stupid hack for a 2 value, should be changed later...
102             if (List!=end() && Pos<List->second.size())
103             {
104                 if (List->second[WithValue_Pos]==WithValue)
105                     return List->second[Pos];
106                 else
107                     return InfoMap_EmptyZtring_Const; //Not found
108             }
109             else
110                 return InfoMap_EmptyZtring_Const; //Not found
111         }
112     }
113     else
114         return InfoMap_EmptyZtring_Const; //Not found
115 }
116 
117 //---------------------------------------------------------------------------
118 // Set
Write(const Ztring & NewInfoMap)119 void InfoMap::Write(const Ztring &NewInfoMap)
120 {
121     clear();
122 
123     if (NewInfoMap.empty())
124         return;
125 
126     size_t Pos1=0, Pos2_EOL=0, Pos2_Separator=0;
127 
128     while (Pos2_EOL!=(size_t)-1)
129     {
130         Pos2_EOL=NewInfoMap.find(__T('\n'), Pos1);
131         Pos2_Separator=NewInfoMap.find(__T(';'), Pos1);
132         if (Pos2_Separator<Pos2_EOL)
133         {
134             ZtringList List; List.Write(NewInfoMap.substr(Pos1, Pos2_EOL-Pos1));
135             insert (pair<Ztring, ZtringList>(NewInfoMap.substr(Pos1, Pos2_Separator-Pos1), List));
136         }
137         Pos1=Pos2_EOL+1;
138     }
139 }
140 
141 //***************************************************************************
142 // Configuration
143 //***************************************************************************
144 
145 //---------------------------------------------------------------------------
146 // Separator
Separator_Set(size_type Level,const Ztring & NewSeparator)147 void InfoMap::Separator_Set (size_type Level, const Ztring &NewSeparator)
148 {
149     if (Level>1)
150         return;
151 
152     Separator[Level]=NewSeparator;
153 }
154 
155 //***************************************************************************
156 // C++
157 //***************************************************************************
158 
159 } //namespace
160