1818import com .reandroid .archive .block .CertificateBlock ;
1919import com .reandroid .arsc .array .ResValueMapArray ;
2020import com .reandroid .arsc .chunk .PackageBlock ;
21+ import com .reandroid .arsc .chunk .xml .*;
2122import com .reandroid .arsc .container .SpecTypePair ;
23+ import com .reandroid .arsc .header .StringPoolHeader ;
24+ import com .reandroid .arsc .item .StringItem ;
2225import com .reandroid .arsc .model .ResourceEntry ;
23- import com .reandroid .arsc .value .Entry ;
24- import com .reandroid .arsc .value .ResTableMapEntry ;
25- import com .reandroid .arsc .value .ResValue ;
26- import com .reandroid .arsc .value .ResValueMap ;
26+ import com .reandroid .arsc .pool .StringPool ;
27+ import com .reandroid .arsc .value .*;
28+ import com .reandroid .common .Namespace ;
2729import com .reandroid .dex .model .DexFile ;
2830import com .reandroid .dex .sections .MapItem ;
2931import com .reandroid .dex .sections .MapList ;
@@ -44,6 +46,140 @@ public InfoWriterText(Writer writer) {
4446 super (writer );
4547 }
4648
49+ @ Override
50+ public void writeStringPool (StringPool <?> stringPool ) throws IOException {
51+ Writer writer = getWriter ();
52+ writer .write ("String pool of " );
53+ writer .write (Integer .toString (stringPool .size ()));
54+ writer .write (" unique " );
55+ if (stringPool .isUtf8 ()) {
56+ writer .write ("UTF-8 " );
57+ } else {
58+ writer .write ("UTF-16 " );
59+ }
60+ StringPoolHeader header = stringPool .getHeaderBlock ();
61+ if (!header .isSorted ()) {
62+ writer .write ("non-" );
63+ }
64+ writer .write ("sorted strings, " );
65+ writer .write (Integer .toString (stringPool .size ()));
66+ writer .write (" entries and " );
67+ writer .write (Integer .toString (stringPool .countStyles ()));
68+ writer .write (" styles using " );
69+ writer .write (Integer .toString (header .getChunkSize ()));
70+ writer .write (" bytes:" );
71+ writer .write ("\n " );
72+ int size = stringPool .size ();
73+ for (int i = 0 ; i < size ; i ++ ) {
74+ StringItem item = stringPool .get (i );
75+ writer .write ("String #" );
76+ writer .write (Integer .toString (i ));
77+ writer .write (": " );
78+ writer .write (item .get ());
79+ writer .write ("\n " );
80+ }
81+ }
82+
83+ @ Override
84+ public void writeXmlDocument (String sourcePath , ResXmlDocument xmlDocument ) throws IOException {
85+ writeNameValue ("source-path" , sourcePath );
86+ for (ResXmlNode node : xmlDocument ) {
87+ if (node instanceof ResXmlElement ) {
88+ writeElement ((ResXmlElement ) node );
89+ } else if (node instanceof ResXmlTextNode ) {
90+ writeTextNode (0 , (ResXmlTextNode ) node );
91+ }
92+ }
93+ Writer writer = getWriter ();
94+ writer .flush ();
95+ }
96+ private void writeElement (ResXmlElement element ) throws IOException {
97+ int indent = element .getDepth () * 2 ;
98+
99+ int count = element .getNamespaceCount ();
100+ for (int i = 0 ; i < count ; i ++) {
101+ writeNamespace (indent , element .getNamespaceAt (i ));
102+ }
103+ indent = indent + 2 ;
104+ Writer writer = getWriter ();
105+ writeIndent (indent );
106+ writer .write ("E: " );
107+ writer .write (element .getName (true ));
108+ writer .write (" (line=" );
109+ writer .write (Integer .toString (element .getLineNumber ()));
110+ writer .write (")" );
111+ writer .write ("\n " );
112+
113+ Iterator <ResXmlAttribute > attributes = element .getAttributes ();
114+ while (attributes .hasNext ()) {
115+ writeAttribute (indent , attributes .next ());
116+ }
117+ flush ();
118+ Iterator <ResXmlNode > iterator = element .iterator ();
119+ while (iterator .hasNext ()) {
120+ ResXmlNode node = iterator .next ();
121+ if (node instanceof ResXmlElement ) {
122+ writeElement ((ResXmlElement ) node );
123+ } else if (node instanceof ResXmlTextNode ) {
124+ writeTextNode (indent , (ResXmlTextNode ) node );
125+ }
126+ }
127+ }
128+ private void writeTextNode (int indent , ResXmlTextNode textNode ) throws IOException {
129+ Writer writer = getWriter ();
130+ writeIndent (indent + 2 );
131+ writer .write ("T: \" " );
132+ writer .write (textNode .getText ());
133+ writer .write ("\" " );
134+ writer .write ("\n " );
135+ }
136+ private void writeNamespace (int indent , ResXmlNamespace namespace ) throws IOException {
137+ Writer writer = getWriter ();
138+ writeIndent (indent );
139+ writer .write ("N: " );
140+ writer .write (namespace .getPrefix ());
141+ writer .write ("=" );
142+ writer .write (namespace .getUri ());
143+ writer .write ("\n " );
144+ }
145+ private void writeAttribute (int indent , ResXmlAttribute attribute ) throws IOException {
146+ Writer writer = getWriter ();
147+ writeIndent (indent + 2 );
148+ writer .write ("A: " );
149+ Namespace namespace = attribute .getNamespace ();
150+ if (namespace != null ) {
151+ writer .write (namespace .getPrefix ());
152+ writer .append (':' );
153+ }
154+ writer .write (attribute .getName ());
155+ int id = attribute .getNameId ();
156+ if (id != 0 ) {
157+ writer .append ('(' );
158+ writer .write (HexUtil .toHex8 (id ));
159+ writer .append (')' );
160+ }
161+ writer .append ('=' );
162+ ValueType valueType = attribute .getValueType ();
163+ if (valueType == ValueType .STRING ) {
164+ writer .append ('"' );
165+ writer .write (attribute .getDataAsPoolString ().getXml ());
166+ writer .append ('"' );
167+ writer .write (" (Raw: \" " );
168+ writer .write (attribute .getValueString ());
169+ writer .write ("\" )" );
170+ } else if (valueType == ValueType .BOOLEAN ) {
171+ writer .append ('"' );
172+ writer .write (attribute .getValueAsBoolean () ? "true" : "false" );
173+ writer .append ('"' );
174+ } else {
175+ writer .write ("(type " );
176+ writer .write (HexUtil .toHex (valueType .getByte () & 0xff , 1 ));
177+ writer .write (")" );
178+ writer .write (HexUtil .toHex (attribute .getData (), 1 ));
179+ }
180+ writer .write ("\n " );
181+ }
182+
47183 @ Override
48184 public void writeCertificates (List <CertificateBlock > certificateList , boolean base64 ) throws IOException {
49185 Writer writer = getWriter ();
@@ -296,6 +432,9 @@ public void flush() throws IOException {
296432 }
297433
298434
435+ private void writeIndent (int amount ) throws IOException {
436+ writeSpaces (getWriter (), amount );
437+ }
299438 private void writeWithTab (Writer writer , String tab , String value ) throws IOException {
300439 String [] splits = StringsUtil .split (value , '\n' );
301440 for (String line : splits ){
0 commit comments