1+ #include " QAndroidAttribute.h"
2+ #include < QDebug>
3+ #include < QDomDocument>
4+ #include < QFile>
5+ #include < QRegularExpression>
6+
7+ void TAttributeFlags::appendFlag (const QDomNode& _node)
8+ {
9+ QDomNamedNodeMap t_attrMap = _node.attributes ();
10+ if (t_attrMap.isEmpty ())
11+ return ;
12+ TAttributeFlag t_flag;
13+ t_flag.Name = t_attrMap.namedItem (" name" ).nodeValue ();
14+ QString t_svalue = t_attrMap.namedItem (" value" ).nodeValue ();
15+ if (t_svalue.startsWith (" 0x" ))
16+ {
17+ t_flag.bit = true ;
18+ t_flag.value = t_svalue.toUInt (nullptr , 16 );
19+ }
20+ else
21+ {
22+ t_flag.bit = false ;
23+ t_flag.value = (uint32_t )t_svalue.toInt (nullptr , 10 );
24+ }
25+ flags.insert (t_flag, 0 );
26+ flagValueMap.insert (t_flag.Name , t_flag.value );
27+ }
28+ uint32_t TAttributeFlags::string2value (const QString& _sname, const QString& _svalue)
29+ {
30+ uint32_t t_value = 0 ;
31+ QStringList t_sflags = _svalue.split (" |" , Qt::SkipEmptyParts);
32+ for (QStringList::iterator i = t_sflags.begin (); i != t_sflags.end (); ++i)
33+ {
34+ if (flagValueMap.contains (*i))
35+ t_value += flagValueMap[*i];
36+ else
37+ qDebug () << " Attribute:" << _sname << " unknow attr string:" << *i;
38+ }
39+ return t_value;
40+ }
41+ QString TAttributeFlags::value2string (const QString& _sname, uint32_t _value)
42+ {
43+ QString t_svalue;
44+ // 从大到小来匹配标志位
45+ for (QMap<TAttributeFlag, int >::iterator i = flags.begin (); i != flags.end (); ++i)
46+ {
47+ const TAttributeFlag& t_flag = i.key ();
48+ if (t_flag.bit && (_value & t_flag.value ) == t_flag.value )
49+ {
50+ if (t_flag.value == 0 && t_svalue.length () > 0 )
51+ break ;
52+ t_svalue += t_flag.Name + " |" ;
53+ _value ^= t_flag.value ;
54+ if (_value == 0 )
55+ break ;
56+ }
57+ }
58+ if (_value != 0 )
59+ {
60+ for (QMap<TAttributeFlag, int >::iterator i = flags.begin (); i != flags.end (); ++i)
61+ {
62+ const TAttributeFlag& t_flag = i.key ();
63+ if (!t_flag.bit && _value == t_flag.value )
64+ {
65+ t_svalue += t_flag.Name + " |" ;
66+ _value = 0 ;
67+ break ;
68+ }
69+ }
70+ }
71+ qDebug () << " Attribute:" << _sname << " unknow attr value:" << _value;
72+ return t_svalue.mid (0 , t_svalue.length () - 1 );
73+ }
74+ QAndroidAttribute::QAndroidAttribute (QObject* _parent)
75+ :QObject(_parent)
76+ {
77+ initAttributes (" :/res/res/attrs.xml" );
78+ initAttributes (" :/res/res/attrs_manifest.xml" );
79+ }
80+ QAndroidAttribute::~QAndroidAttribute ()
81+ {
82+
83+ }
84+ void QAndroidAttribute::initAttributes (const QString& _path)
85+ {
86+ QFile t_ReadFile (_path);
87+ if (!t_ReadFile.exists ()) return ;
88+
89+ if (!t_ReadFile.open (QFile::ReadOnly))
90+ return ;
91+ QDomDocument t_domTree;
92+ if (!t_domTree.setContent (&t_ReadFile))
93+ {
94+ t_ReadFile.close ();
95+ return ;
96+ }
97+ QDomElement t_root = t_domTree.documentElement ();
98+ QDomNode t_subNode = t_root.firstChild ();
99+ while (!t_subNode.isNull ())
100+ {
101+ analysisNode (t_subNode);
102+ t_subNode = t_subNode.nextSibling ();
103+ }
104+ t_ReadFile.close ();
105+ }
106+ void QAndroidAttribute::analysisNode (const QDomNode& _node)
107+ {
108+ QString t_nodeName = _node.nodeName ();
109+ if (t_nodeName != " attr" )
110+ {
111+ QDomNode t_subNode = _node.firstChild ();
112+ while (!t_subNode.isNull ())
113+ {
114+ analysisNode (t_subNode);
115+ t_subNode = t_subNode.nextSibling ();
116+ }
117+ return ;
118+ }
119+ if (!_node.hasChildNodes ())
120+ return ;
121+ QDomNamedNodeMap t_attrMap = _node.attributes ();
122+ QString t_name = t_attrMap.namedItem (" name" ).nodeValue ();
123+ Q_ASSERT (!m_attrs.contains (" android:" + t_name));
124+ TAttributeFlags t_flags;
125+ QDomNode t_flagNode = _node.firstChild ();
126+ while (!t_flagNode.isNull ())
127+ {
128+ t_flags.appendFlag (t_flagNode);
129+ t_flagNode = t_flagNode.nextSibling ();
130+ }
131+ if (t_flags.flags .size () > 0 )
132+ m_attrs.insert (" android:" + t_name, t_flags);
133+ }
134+ uint32_t QAndroidAttribute::string2value (const QString& _sname, const QString& _svalue)
135+ {
136+ bool t_ok = true ;
137+ uint32_t t_value;
138+ static QRegularExpression t_numberRegExp (" ^[0-9a-fA-FxX]{1,10}$" );
139+ // 只有非数值的字符串才去分析
140+ if (m_attrs.contains (_sname) && !t_numberRegExp.match (_svalue).hasMatch ())
141+ t_value = m_attrs[_sname].string2value (_sname, _svalue);
142+ else if (_svalue.startsWith (" 0x" , Qt::CaseInsensitive))
143+ t_value = _svalue.toUInt (&t_ok, 16 );
144+ else
145+ t_value = _svalue.toUInt (&t_ok, 10 );
146+ if (!t_ok)
147+ qDebug () << " Attribute:" << _sname << " unknow attr string:" << _svalue;
148+ return t_value;
149+ }
150+ QString QAndroidAttribute::value2string (const QString& _sname, uint32_t _value, bool _hex)
151+ {
152+ if (m_attrs.contains (_sname))
153+ return m_attrs[_sname].value2string (_sname, _value);
154+ else if (_hex)
155+ return QString (" 0x%1" ).arg (_value, 0 , 16 );
156+ else
157+ return QString::number (_value);
158+ }
159+ bool QAndroidAttribute::contains (const QString& _sname)
160+ {
161+ return m_attrs.contains (_sname);
162+ }
163+ QAndroidAttribute* g_androidAttribute;
0 commit comments