Skip to content

Commit e868894

Browse files
committed
针对字符串出现重复的处理。
1 parent 0cf29d1 commit e868894

5 files changed

Lines changed: 66 additions & 19 deletions

File tree

src/QResArscParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ QResArscParser::QResArscParser(QObject* parent)
1010
: QObject(parent)
1111
{
1212
m_publicFinal = new QPublicFinal(this);
13-
m_stringPool = new QStringPool(true, this);
13+
m_stringPool = new QStringPool("GlobalStringPool", true, this);
1414
g_publicStrPool = m_stringPool;
1515
g_publicFinal = m_publicFinal;
1616
}

src/QStringPool.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ bool TArscRichString::operator<(const TArscRichString& _other) const
3838

3939
QStringPool* g_publicStrPool;
4040

41-
QStringPool::QStringPool(bool _removeUnuse, QObject* _parent)
42-
: QObject(_parent), m_removeUnuse(_removeUnuse), m_stringPoolHeader()
41+
QStringPool::QStringPool(const QString& _name, bool _removeUnuse, QObject* _parent)
42+
: QObject(_parent), m_name(_name), m_removeUnuse(_removeUnuse), m_stringPoolHeader()
4343
, m_strings(ArscRichStringLessThanFuncWrapper(&styleFirstLessThan))
4444
, m_string_to_guid(ArscRichStringLessThanFuncWrapper(&strongLessThan))
4545
//m_strings(styleFirstLessThan), m_string_to_guid(strongLessThan)
@@ -99,14 +99,44 @@ void QStringPool::readBuff(const char* _buff)
9999
t_pStyleBuff += sizeof(ResStringPool_span);
100100
}
101101
}
102+
//-----------查找重复的字符串---------------------------------
103+
ArscRichStringLessThanFuncWrapper t_funcWrapper(&strongLessThan);
104+
ArscRichStringMap t_string_to_guid(t_funcWrapper);
102105
for (QVector<PArscRichString>::iterator i = t_strings.begin(); i != t_strings.end(); ++i)
103106
{
107+
ArscRichStringMap::iterator t_findIt = t_string_to_guid.find(*i);
108+
if (t_findIt != t_string_to_guid.end())
109+
{
110+
qDebug() << Qt::hex << Qt::showbase << m_name << "duplicate string:" << (*i)->string << "guid:" << (*i)->guid << "->" << (t_findIt->second);
111+
m_repeat_string_guid_map.insert((*i)->guid, t_findIt->second);
112+
continue;
113+
}
114+
t_string_to_guid.insert(ArscRichStringMap::value_type(*i, (*i)->guid));
115+
}
116+
for (QVector<PArscRichString>::iterator i = t_strings.begin(); i != t_strings.end(); ++i)
117+
{
118+
PArscRichString& t_pArscRichString = *i;
119+
for (int j = 0; j < t_pArscRichString->styles.count(); ++j)
120+
{
121+
int t_oldGuid = t_pArscRichString->styles[j].ref->guid;
122+
if (m_repeat_string_guid_map.find(t_oldGuid) != m_repeat_string_guid_map.end())
123+
{
124+
int t_newGuid = m_repeat_string_guid_map.value(t_oldGuid);
125+
t_pArscRichString->styles[j].ref->guid = t_newGuid;
126+
}
127+
}
128+
}
129+
//-----------填充字符串池---------------------------------
130+
for (QVector<PArscRichString>::iterator i = t_strings.begin(); i != t_strings.end(); ++i)
131+
{
132+
if (m_string_to_guid.find(*i) != m_string_to_guid.end())
133+
continue;
104134
m_strings.insert(ArscRichStringMap::value_type(*i, (*i)->guid));
105135
m_guid_to_string.insert((*i)->guid, *i);
106136
//理论上,同样的字符串不应该重复出现。但是结果某些工具(比如AntiSplit-M)处理的,可能出现这个问题。
107-
Q_ASSERT(m_string_to_guid.find(*i) == m_string_to_guid.end());
108137
m_string_to_guid.insert(ArscRichStringMap::value_type(*i, (*i)->guid));
109138
}
139+
m_stringPoolHeader.stringCount -= m_repeat_string_guid_map.size();
110140
t_strings.clear();
111141
}
112142
void QStringPool::writeBuff(QByteArray& _buff)
@@ -198,6 +228,14 @@ bool QStringPool::strongLessThan(const PArscRichString& _p1, const PArscRichStri
198228
PArscRichString QStringPool::getGuidRef(uint32_t _guid) const
199229
{
200230
QMap<int, PArscRichString>::const_iterator t_pIter = m_guid_to_string.find(_guid);
231+
if (t_pIter == m_guid_to_string.end())
232+
{
233+
QMap<int, int>::const_iterator t_repeatIter = m_repeat_string_guid_map.find(_guid);
234+
if (t_repeatIter != m_repeat_string_guid_map.end())
235+
{
236+
t_pIter = m_guid_to_string.find(t_repeatIter.value());
237+
}
238+
}
201239
return (t_pIter == m_guid_to_string.end()) ? PArscRichString() : t_pIter.value();
202240
}
203241
uint32_t QStringPool::getRefIndex(const PArscRichString& _s) const

src/QStringPool.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ using ArscRichStringMap = sbtree_multimap <PArscRichString, int, ArscRichStringL
5858
class QStringPool : public QObject
5959
{
6060
public:
61-
QStringPool(bool _removeUnuse = false, QObject* _parent = NULL);
61+
QStringPool(const QString& _name = "", bool _removeUnuse = false, QObject* _parent = NULL);
6262
QStringPool(const QStringPool&) = delete;
6363
QStringPool& operator=(const QStringPool&) = delete;
6464
~QStringPool();
@@ -85,6 +85,7 @@ class QStringPool : public QObject
8585
void removeUnusedString(void);
8686
private:
8787
public:
88+
QString m_name;
8889
GuidFactory m_GuidFactory;
8990
bool m_removeUnuse; //回写的时候删除未使用的
9091
ResStringPool_header m_stringPoolHeader;
@@ -93,6 +94,7 @@ class QStringPool : public QObject
9394
QMap<int, PArscRichString> m_guid_to_string;
9495
//使用strongLessThan排序的map
9596
ArscRichStringMap m_string_to_guid;
97+
QMap<int, int> m_repeat_string_guid_map;
9698
};
9799

98100
//最小引用次数,因为上面有3个map,所以有3次引用,如果等于这个值,就可以释放掉了。

src/QTablePackage.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#include "SimpleRichText.h"
55

66
QTablePackage::QTablePackage(QObject* _parent)
7-
: QObject(_parent), m_packageInfo(), m_typeStringPool(false), m_keyStringPool(false)
7+
: QObject(_parent), m_packageInfo(), m_typeStringPool("TypeStringPool", false),
8+
m_keyStringPool("KeyStringPool", false)
89
{
910
}
1011

src/QTableType.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
#include "QTablePackage.h"
12
#include "QTableType.h"
23
#include "SimpleRichText.h"
3-
#include "QTablePackage.h"
44
#include <QDebug>
55
static float complexToFloat(quint32 _v)
66
{
@@ -72,14 +72,16 @@ uint32_t TTableValueEntry::readBuff(const char* _buff)
7272
};
7373
void TTableValueEntry::writeBuff(QTablePackage* _tablePackage, QByteArray& _buff)
7474
{
75-
if ((entry.key.index >> 16) == 0)
75+
ResTable_entry t_newEntry = entry;
76+
if ((t_newEntry.key.index >> 16) == 0)
7677
{
7778
//如果m_keyStringPool内容或者排列有修改,那就需要重新计算索引,而且不能在原有entry上面修改,需要复制一个新的entry,
78-
uint32_t t_newIdx = _tablePackage->keyGuidToIndex(entry.key.index);
79-
Q_ASSERT(t_newIdx == entry.key.index);
79+
uint32_t t_newIdx = _tablePackage->keyGuidToIndex(t_newEntry.key.index);
80+
if (t_newIdx != t_newEntry.key.index)
81+
t_newEntry.key.index = t_newIdx;
8082
}
8183

82-
_buff.append(reinterpret_cast<const char*>(&entry), sizeof(ResTable_entry));
84+
_buff.append(reinterpret_cast<const char*>(&t_newEntry), sizeof(ResTable_entry));
8385
Res_value t_tmpv(value);
8486
if (t_tmpv.dataType == Res_value::_DataType::TYPE_STRING)
8587
{
@@ -108,12 +110,14 @@ uint32_t ResTable_pairs::readBuff(const char* _buff)
108110
}
109111
void ResTable_pairs::writeBuff(QTablePackage* _tablePackage, QByteArray& _buff)
110112
{
111-
if ((key.ident >> 16) == 0)
113+
ResTable_ref t_newKey = key;
114+
if ((t_newKey.ident >> 16) == 0)
112115
{
113-
uint32_t t_newIdent = _tablePackage->keyGuidToIndex(key.ident);
114-
Q_ASSERT(t_newIdent == key.ident);
116+
uint32_t t_newIdent = _tablePackage->keyGuidToIndex(t_newKey.ident);
117+
if (t_newIdent != t_newKey.ident)
118+
t_newKey.ident = t_newIdent;
115119
}
116-
_buff.append(reinterpret_cast<const char*>(&key), sizeof(ResTable_ref));
120+
_buff.append(reinterpret_cast<const char*>(&t_newKey), sizeof(ResTable_ref));
117121
Res_value t_tmpv(value);
118122
if (t_tmpv.dataType == Res_value::_DataType::TYPE_STRING)
119123
{
@@ -146,12 +150,14 @@ uint32_t TTableMapEntry::readBuff(const char* _buff)
146150
};
147151
void TTableMapEntry::writeBuff(QTablePackage* _tablePackage, QByteArray& _buff)
148152
{
149-
if ((entry.key.index >> 16) == 0)
153+
ResTable_map_entry t_newEntry = entry;
154+
if ((t_newEntry.key.index >> 16) == 0)
150155
{
151-
uint32_t t_newIdx = _tablePackage->keyGuidToIndex(entry.key.index);
152-
Q_ASSERT(t_newIdx == entry.key.index);
156+
uint32_t t_newIdx = _tablePackage->keyGuidToIndex(t_newEntry.key.index);
157+
if (t_newIdx != t_newEntry.key.index)
158+
t_newEntry.key.index = t_newIdx;
153159
}
154-
_buff.append(reinterpret_cast<const char*>(&entry), sizeof(ResTable_map_entry));
160+
_buff.append(reinterpret_cast<const char*>(&t_newEntry), sizeof(ResTable_map_entry));
155161
for (int i = 0; i < pairs.size(); ++i)
156162
pairs[i]->writeBuff(_tablePackage, _buff);
157163
};

0 commit comments

Comments
 (0)