Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / misc / string_mapper.cpp
blob88b81ff072852f814e7bd7bb84d69e84a65b8ef0
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdmisc.h"
22 #include "nel/misc/string_mapper.h"
24 using namespace std;
26 #ifdef DEBUG_NEW
27 #define new DEBUG_NEW
28 #endif
30 namespace NLMISC
33 CStringMapper CStringMapper::s_GlobalMapper;
35 // ****************************************************************************
36 CStringMapper::CStringMapper()
38 m_EmptyId = new string();
41 // ****************************************************************************
42 CStringMapper *CStringMapper::createLocalMapper()
44 return new CStringMapper;
47 // ****************************************************************************
48 TStringId CStringMapper::localMap(const std::string &str)
50 if (str.empty())
51 return NULL;
53 CAutoFastMutex autoMutex(&m_Mutex);
55 TStringTable::const_iterator it = m_StringTable.find((const std::string *)&str);
57 if (it == m_StringTable.end())
59 string *pStr = new string(str);
60 m_StringTable.insert(pStr);
61 return pStr;
63 return (TStringId)(*it);
66 #ifdef NL_CPP14
67 // ****************************************************************************
68 TStringId CStringMapper::localMap(const char *str)
70 if (!str[0])
71 return NULL;
73 CAutoFastMutex autoMutex(&m_Mutex);
75 TStringTable::const_iterator it = m_StringTable.find(str);
77 if (it == m_StringTable.end())
79 string *pStr = new string(str);
80 m_StringTable.insert(pStr);
81 return pStr;
83 return (TStringId)(*it);
85 #endif
87 // ***************************************************************************
88 void CStringMapper::localSerialString(NLMISC::IStream &f, TStringId &id)
90 std::string str;
91 if (f.isReading())
93 f.serial(str);
94 id = localMap(str);
96 else
98 str = localUnmap(id);
99 f.serial(str);
103 // ****************************************************************************
104 void CStringMapper::localClear()
106 CAutoFastMutex autoMutex(&m_Mutex);
108 TStringTable::iterator it = m_StringTable.begin();
109 while (it != m_StringTable.end())
111 const std::string *ptrTmp = (*it);
112 delete ptrTmp;
113 it++;
115 m_StringTable.clear();
118 // ****************************************************************************
119 // CStaticStringMapper
120 // ****************************************************************************
122 // ****************************************************************************
123 TSStringId CStaticStringMapper::add(const std::string &str)
125 nlassert(!_MemoryCompressed);
126 std::map<std::string, TSStringId>::iterator it = _TempStringTable.find(str);
127 if (it == _TempStringTable.end())
129 _TempStringTable.insert(pair<string,TSStringId>(str,_IdCounter));
130 _TempIdTable.insert(pair<TSStringId,string>(_IdCounter,str));
131 _IdCounter++;
132 return _IdCounter-1;
134 else
136 return it->second;
140 // ****************************************************************************
141 bool CStaticStringMapper::isAdded(const std::string &str) const
143 nlassert(!_MemoryCompressed);
144 return _TempStringTable.count(str) != 0;
147 // ****************************************************************************
148 void CStaticStringMapper::memoryUncompress()
150 std::map<std::string, TSStringId> tempStringTable;
151 std::map<TSStringId, std::string> tempIdTable;
152 for(uint k = 0; k < _IdToStr.size(); ++k)
154 tempStringTable[_IdToStr[k]] = (TSStringId) k;
155 tempIdTable[(TSStringId) k] = _IdToStr[k];
157 delete [] _AllStrings;
158 _AllStrings = NULL;
159 contReset(_IdToStr);
160 _TempStringTable.swap(tempStringTable);
161 _TempIdTable.swap(tempIdTable);
162 _MemoryCompressed = false;
165 // ****************************************************************************
166 void CStaticStringMapper::memoryCompress()
168 _MemoryCompressed = true;
169 std::map<TSStringId, std::string>::iterator it = _TempIdTable.begin();
171 uint nTotalSize = 0;
172 uint32 nNbStrings = 0;
173 while (it != _TempIdTable.end())
175 nTotalSize += (uint)it->second.size() + 1;
176 nNbStrings++;
177 it++;
180 _AllStrings = new char[nTotalSize];
181 _IdToStr.resize(nNbStrings);
182 nNbStrings = 0;
183 nTotalSize = 0;
184 it = _TempIdTable.begin();
185 while (it != _TempIdTable.end())
187 strcpy(_AllStrings + nTotalSize, it->second.c_str());
188 _IdToStr[nNbStrings] = _AllStrings + nTotalSize;
189 nTotalSize += (uint)it->second.size() + 1;
190 nNbStrings++;
191 it++;
193 contReset(_TempStringTable);
194 contReset(_TempIdTable);
197 // ****************************************************************************
198 const char *CStaticStringMapper::get(TSStringId stringId)
200 if (_MemoryCompressed)
202 nlassert(stringId < _IdToStr.size());
203 return _IdToStr[stringId];
205 else
207 std::map<TSStringId, std::string>::iterator it = _TempIdTable.find(stringId);
208 if (it != _TempIdTable.end())
209 return it->second.c_str();
210 else
211 return NULL;
215 // ****************************************************************************
216 void CStaticStringMapper::clear()
218 contReset(_TempStringTable);
219 contReset(_TempIdTable);
220 delete [] _AllStrings;
221 contReset(_IdToStr);
223 _IdCounter = 0;
224 _AllStrings = NULL;
225 _MemoryCompressed = false;
226 add("");
229 // ****************************************************************************
230 void CStaticStringMapper::serial(IStream &f, TSStringId &strId)
232 std::string tmp;
233 if (f.isReading())
235 f.serial(tmp);
236 strId = add(tmp);
238 else
240 tmp = get(strId);
241 f.serial(tmp);
245 // ****************************************************************************
246 void CStaticStringMapper::serial(IStream &f, std::vector<TSStringId> &strIdVect)
248 std::vector<std::string> vsTmp;
249 std::string sTmp;
250 // Serialize class components.
251 if (f.isReading())
253 f.serialCont(vsTmp);
254 strIdVect.resize(vsTmp.size());
255 for(uint i = 0; i < vsTmp.size(); ++i)
256 strIdVect[i] = add(vsTmp[i]);
258 else
260 vsTmp.resize(strIdVect.size());
261 for (uint i = 0; i < vsTmp.size(); ++i)
262 vsTmp[i] = get(strIdVect[i]);
263 f.serialCont(vsTmp);
270 } // namespace NLMISC