From 625baa03f175577dc2ee1cd98b8826e4cf915c3f Mon Sep 17 00:00:00 2001 From: REAndroid Date: Wed, 30 Nov 2022 11:11:23 -0500 Subject: [PATCH] V1.0.3 (to/from json convert) --- build.gradle | 1 + libs/ArchiveUtil.jar | Bin 24935 -> 28513 bytes libs/json.jar | Bin 0 -> 69370 bytes .../java/com/reandroid/lib/apk/ApkEntry.java | 10 + .../java/com/reandroid/lib/apk/ApkModule.java | 170 ++++++++ .../java/com/reandroid/lib/apk/ApkUtil.java | 15 + .../reandroid/lib/apk/BlockInputSource.java | 24 ++ .../java/com/reandroid/lib/apk/ResFile.java | 33 ++ .../lib/arsc/array/EntryBlockArray.java | 43 +- .../lib/arsc/array/LibraryInfoArray.java | 34 +- .../lib/arsc/array/PackageArray.java | 31 +- .../lib/arsc/array/ResValueBagItemArray.java | 28 +- .../lib/arsc/array/ResXmlAttributeArray.java | 29 +- .../lib/arsc/array/ResXmlIDArray.java | 24 +- .../lib/arsc/array/SpecTypePairArray.java | 30 +- .../reandroid/lib/arsc/array/StringArray.java | 48 ++- .../reandroid/lib/arsc/array/StyleArray.java | 20 +- .../lib/arsc/array/TableStringArray.java | 1 + .../lib/arsc/array/TypeBlockArray.java | 30 +- .../lib/arsc/chunk/BaseTypeBlock.java | 9 + .../lib/arsc/chunk/LibraryBlock.java | 14 +- .../lib/arsc/chunk/PackageBlock.java | 36 +- .../reandroid/lib/arsc/chunk/SpecBlock.java | 16 +- .../reandroid/lib/arsc/chunk/TableBlock.java | 32 +- .../reandroid/lib/arsc/chunk/TypeBlock.java | 27 +- .../arsc/chunk/xml/AndroidManifestBlock.java | 12 + .../lib/arsc/chunk/xml/ResXmlAttribute.java | 59 ++- .../lib/arsc/chunk/xml/ResXmlBlock.java | 27 +- .../lib/arsc/chunk/xml/ResXmlElement.java | 62 ++- .../arsc/chunk/xml/ResXmlStartElement.java | 13 + .../lib/arsc/container/SpecTypePair.java | 17 +- .../reandroid/lib/arsc/group/EntryGroup.java | 21 +- .../com/reandroid/lib/arsc/item/ResXmlID.java | 31 +- .../reandroid/lib/arsc/item/StringItem.java | 44 +- .../reandroid/lib/arsc/item/StyleItem.java | 195 ++++++--- .../reandroid/lib/arsc/item/TableString.java | 18 + .../lib/arsc/model/StyleSpanInfo.java | 72 +++- .../lib/arsc/pool/BaseStringPool.java | 18 +- .../lib/arsc/pool/TableStringPool.java | 1 + .../lib/arsc/value/BaseResValue.java | 10 +- .../lib/arsc/value/BaseResValueItem.java | 19 +- .../reandroid/lib/arsc/value/EntryBlock.java | 61 ++- .../reandroid/lib/arsc/value/LibraryInfo.java | 16 +- .../reandroid/lib/arsc/value/ResConfig.java | 384 +++++++++++++++++- .../lib/arsc/value/ResConfigHelper.java | 378 ++++++++++++++++- .../reandroid/lib/arsc/value/ResValueBag.java | 23 +- .../lib/arsc/value/ResValueBagItem.java | 49 +++ .../reandroid/lib/arsc/value/ResValueInt.java | 54 ++- .../lib/arsc/value/ResValueReference.java | 21 + .../java/com/reandroid/lib/json/JsonItem.java | 6 + .../java/com/reandroid/lib/json/JsonUtil.java | 62 +++ 51 files changed, 2201 insertions(+), 177 deletions(-) create mode 100755 libs/json.jar create mode 100644 src/main/java/com/reandroid/lib/apk/ApkEntry.java create mode 100644 src/main/java/com/reandroid/lib/apk/ApkModule.java create mode 100644 src/main/java/com/reandroid/lib/apk/ApkUtil.java create mode 100644 src/main/java/com/reandroid/lib/apk/BlockInputSource.java create mode 100644 src/main/java/com/reandroid/lib/apk/ResFile.java create mode 100644 src/main/java/com/reandroid/lib/arsc/value/ResValueReference.java create mode 100644 src/main/java/com/reandroid/lib/json/JsonItem.java create mode 100644 src/main/java/com/reandroid/lib/json/JsonUtil.java diff --git a/build.gradle b/build.gradle index 1bac861..817d1c8 100755 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,7 @@ repositories { dependencies { compile(files("$rootProject.projectDir/libs/ArchiveUtil.jar")) + compile(files("$rootProject.projectDir/libs/json.jar")) } processResources { diff --git a/libs/ArchiveUtil.jar b/libs/ArchiveUtil.jar index 222aafb8f9f7cf152dc2853dc7eabef6d484aa4e..44b6cd7b56aafa85396ce88fe7bda2512b289aa8 100644 GIT binary patch delta 17050 zcmZ5|Wk4KD(=HO+g1fuBTOhc*ySuwB?h;sBgS)#1C%6;b7I%lBH#y(E-+SJ>e|omJ zrmJhVrn}~;dgibnd}k9JNl6y+6Fe9gEEpJ`xL+a?Ipp7lo%U~2ZwQ43ImPP-v_#_v zsOfv6t7B{csdA**?7yx;BaqF&7s*S%R*0(>HV11YsUSftO=s<`>Pb;MTlD`D-od`= zM__i|2^qHxfcw$6ukx59hn~rlniJvs*#5ZQ_$YX|?)^S}2>{a)XAI))N*jdVR3wW~ z7t~|B7J;bU`P!{1M-t9yA7EBc6qj%hxQYt9|0FaN&L!07w9=1h4{+E)K*+)iu->T% zYlw=DVuS?QjwuI>_PVwB>8@jj)zs>QHQc=J?jk|X#(8|jOQ)lkbZ~#Pnd@eusYja~zNQfu>~t#cu8FnOTB|{c(zNjP7z>F4(B<)~ zT2|hIgj2?m#Pu6U#4^v)e9-e8Gc-$~^i&fv$s`IKq~3fA`{R^txOn!3h*9brM(w$Z zvkH?7BBy35F)>!4Uy(Smp zMEIjMoMo%hz5f0g7PcqN5~{BVpd0zT0qjjlQ%z|Wa(~p;6Q9~?Zm=b;_NqCKu4e5C zdQb4>$Bi8Ws2~o3#~MWCu=2C8HyT;>UCAAuzruCpdIN^5XDB}I(kaHjZ4*TYHU3%L zC*b|vV0`eAE1)-lD*&RFV^j=^!oZ--AjfmUGg}{D*fv`0J-5m|9ghzapyym`^!4c8 zN_LSaqyM((5|xo4U)u0ke4p93IO1{ju9#j6eN154utO)LTh622?+H=Xge$C-@^apn zVU5|)XyWVz2C7S=lkxO9OsjLw(2;g0&IeJ3;Lx6a&aq{MZ1$|g0S_3_5?mq`N3{L% z<$V>C(Xl8`RFv_jS+C6u;3L%yZ&QAs`(E}T>=Xui>ZX(f=1tuA2wL=0?fmKi!Hz&r z@(a?iY5{BZZaS<6=+&6=3R=13GHjj)T@2T9&|5->q=olUbCZHklAzDK00A;pGP^Ll zvE4Efr;I^(AiZx>L~opdJ+zpTYnUA#mj6 zFQKnbnA6Qx1HY z$t-pIT|LnpX*N;6eg=`n*L2)|P^cpG*v-NxiTHULm1#tGv$8#o`(qA9R{3$cDR|fV zu{~tWH0WqqF9gSkX!*e;xB!kVxTMDmfRZc>thw$HO$Q_x7#R#0*x&me0}K`x7Ho#g z4|s_o3{V|+nE!$y2uv$?w$d5v{PJ8d6{6!dFJ2)-17V!p5+nMEZn-D7A5ZVQUTZQ? zLV^{^NgUP&(kfv4Zo%5)Su;(L=X>ycSnIe2e%9A$ywe_sx5~9t=U_Y_0hxu>!q8P$ zH#xJMCUXKAUa`h&UWNpUGSVWDri^d6t(OwI0yvAM>?;#o9VJuGoyC~QE1HjOKgmRy z;aqcIHl4=?KdsAt(gaeZq9;)IsTsgeYhq^zMKw}jILDIkO%MD(i9x{g52rlw~pal7+@Y`&1kJ)sNY z11LNkD!F{oIn#dEz;o4<2{^~G=*Z-zi`-SKxKcW@7O3CmJNiEEbShQ!te^cQ2|NG^V{?_G_)%=7m2_WRCv}}&d)5oNfRMNS$DSrFgb zIhIN=2N%q9rr>9+^w7>@D3_bUC47odb!}MyopWS%q2K@}0aa&A%4>IsZ?d{hZPa5x zU#Fy1h@*$Eu+r&#hiJE)pT1rrNexIO-X~Jh+b@0))>DXuBkZ4Z6K;|#hjWxJ#F#r2Sj&ubQ@_$^2 z8)!%g4{$_h{rsLi;?QYlMZ;Ko1M5Fyr&CXtMues=3NBVOL!=VDkkwd^rn%<6@BUob z=0uAIGnhdfhU564#3g>xmwWBi<7grD@|Z^~41QL)-`D4gV&3I6d!;lai+#$(rDw;+ zLzp4u+NJ5X`(w{|0_e=cqC*9G@S`|lO`a26n_kc9 z_Esg~!^@5O*>p&rYUNBa0>`bY+jA>CldOZ(shze?vyoBj`z57&MUS{B#k`p1*cO3Q zd5c=PN+sA2&7wd8z|`W`)z3B1pD#5jnSw`*pmjGZ)~m#fb)!5Yn0c9c@;<pYiUK4-CnG~jcaDe9k*R5k==oh^J-Z=%(`6BR;)cSlJ$WBC12r$iiWW|W+n zV*ICu?p9w#0CLz%nw8`Si*k>j2DTp$|iR|TpwGibfQBcIa zlB5^0U%?hrzHx%uEvEz@IfVlPUXZtO9|Y{SQzO_M(&{7mEjn%MqPf#X?mXBS?dGUI1siyaQwzFEXWhI7>{xGo*SM=Axu$%7I)!*qnM# zH97R5`dlGJg?{;N$ng=6!d8?iP@_6a%*2aA#rh2Q=qMS7A)S(+p*Vh%?R;{3wl#%rp*4ER z6xT+43du?~vcHvr5_S@y)}rQ5*STXTF)25;_e8Z6QZ%A;r%NbG1^7I2iK9a9xrB)6 z@?P1AXgt-JJ}K-;U^Ums2$&CH`fkA|TbgNIBQ8a(zFG^U9A%mVkXz-2=zsrwmYt8& zG`)>uwgXXIyL1eFPOtSn2Y83(kC{|ul4E8Q>R`cEW{O)!jh?y!gtP1ClFBz45NhVK zhAPE4$C%<>XTIg3^wn(b5CBcOX znVOQQTQq2C(eNcUarB+h@ikfl%Wr;AvArBHc<8acT+^X{+svA@K*tIKO|Ef&eEhil zcn5WRKb2p596H;WDQ;&;HVMII$2^Mg!V#oi6c73 zk;alk46KFC@rTawhgEw5ljov>{(EUJDUQ4$Zx|`+c$6Vhl$a{@fQacs3yV zLe6T{2beZxJ>n?fY^&eWBzOXKr~ z6OH-4-cx(HE(aaLM&YrtH@yC#lf=P_Ji=?diO^8LRO@7lP zK;GSfZsF+T>`Tw~T87z=oJU&1Yw0*~m_vD_{+)F(61)=H>Ku3r!ng^Xo5_VfaCT~S z4nLiNH$0(%ZuS5&;JezsB{J4HRB>M)>P(-Z5{_0& zvjibGGuG7Be)j~TLp96KZ(dTJnDpX|0qV~6Xr&g`gNbPtyfl^wo0mGFBC2S+^-!Ug zEGPU7NDNeP6}@9WnM<&a`mo)F8Q10Xb_IO3uHHGLrKYr^Om-fX)K}fFLNUMf!zXk> zFc^cMm}aWX3RPlr;$6Z$8sJ09ANWsCAZfivW=%~; zZ^!Tvaa~dRt@M%-EL~#~8ZKUQ8hZ>*>WsS0d2YxFS(h@ZB42NwU&qHkh*|3DY8LpL zC#g%1p|^l^Gh+QoNX^hD?5COc04?m_lURpq1WZ2#MXcyh6>fsO4~$WLAZd$`{0O&L zuH^m3dt0v~<1b+&x6Hk!)jyznA};Ztz=;;Gzd{Q4e}zUSGu<9}iVDixwS*2}s(Kf# zt3=DP+)ndS>zjk~^o;_<91_*36sb{UpFxghA3ihXJl+h#C#Ljz7hBY+ld7LN>zjp%`_?B&VlCqeU^ii@)N#~4V}pe5qAC#6_8b;M{X#jN#nv*KB5hQ6xC zoB6mIH+6tH0g_^*!6OFBZ|Q*+_7kF}=nI&z`q^YNn=T@fIlyHH41(M6kvqXSy*~N{ z4T|@ygj16K&@<_XEW{AJGJjS3eBImm@%$iS z5?j)DwOe6FJhMIAY)aBL@czk>d;(Ar{PZ49V$9;vj@2iKHi*;x)s*EgwE63OAGqPO#W@Vmmi;!A zCuX0#?<+TQp!?eN#)PZ#C^ReHpm1`QOkD*NXG{+w@{BmhY7|kyB|e-VwW>(&;ivuX zC;DYEzry%C$S3bnhffdcT<-2nfec(RVrCH5R)v!1V%AKJgQ5n zqXB_dUaX8*izJ$%57`H-dM?!c`Mx~bXu5pi=8sOi6ol!c)Ub-7m6JnE<5IjzYCb@LdJv<1-1;2l9{&E1?%<@=jTV`Q{wuOOwG`BgbR& zbAy43_3<%6Qe44?7psLeLpg~M449&6%LZOHTzu=HeFib#Q#1IArsa47ppaY^(iH%w zPKuVNPbQas|M!97=djLpD!#SV<*{S2>P(80xxg|7v}PSN@x#uNCnC27i52CR&l`*D z{`Af$&i45A4y9+vT)%UQFEIPfDTUW$0+__}j}C*A@|qc{Pt9Ai?gF>$hd53cN)iK@ znM@(v6)*2Pe;!{nbj>=4taFAQN{`AMf&eNS#>TnBK!!Nor_Pv_2bY>|(fHQUYY*NY znRw5i*Y+-5lJUeTpzaTtzcD3T2jmmMAK-Em{of(w--iu*YHFaLA!g${M;7=$Po{r6 z6e&>vOs00muC6(n)>>+Zm;ub}6NKS0y)bHwmhai zr+hbEdv5)2U+?KP!R>kxz^jJP!Mm_(5x$H7PQ`D-!Irk0aJpv`xTD@D1Gu#V4Z!?MnplW#HrEjInx z5g=S`nBeb6$)+lzZvtAM;xaR$bW32}glc5sPTVHf6DKHK+#@k3jjmLr$D}(#huWo` z*#v<&{H}`*OnbLWw2kFi8hkNpTLc*i4HxokJ!GJ+&}eXfhH@R;5HI8uoU}C;`DQn1YH@eUI)LUwW~Bh%S`XvXZl4KYrc%Pe&JjJ`$3tgY<*NZAHBvMUx^`+ z4QGTt74T2ie5UEI$zf!8W8A*;No4SPD)KC(5FBX4n3cPq34W#kubU84#NX*a`hEz8X-`)KY@}VTeWMEWdTUW10N8aM~4IT_$v41sXg5zD7%WzLE0%<{2R+X z0@RPe+9xC0RlE2p|^7S!Xg->SkNOli5!7={h1|g>ih{ zo+HRMTvAv5(RRtpW})g~r#0YJq3^Oj2PW)BS@?Z>g!s^%4F%GDigFclKvIiZyTi4H z2hLr*R&94&5Sh2bVk{*|e^QIr8>0m|tK4gNj;JY5H%3(4bz{VGCH-m2l4{EW)52oe zO?@fM=g|Aq`nU~17eBnKq^PKjx+K0>H$kdzRYU*qZH?K^+CgyCS@2Y)i1BfjJfAdK zAIl|AU=dWYlE>CW=*-xMRC12Qs7BR{p4yo{9f>7-)LuEjqx5yiS^$43yb}l!zf7hXtVj$-3 z;`U}kbN*77uST8zD;~P9<|Z2m@(KN2?#NbC%CDSip-@MWj<-OEjF`v7g-7HBV@vQ< zLyGO4Y-(vsJLh2gWE50hm>ILGT&LPRKmp3TYhzB~%iO8w&6&4{R5pCR-sTD1M6N7T(m~>vj2o{5UL1KiuZCBd z^97ay0yID-HedkRm-5=^4}^L!StWa2Sbm*4+(*Fj=d^+>^7qtT#S_N1G`zw1>Sbt@ z^V?|G^Sm8BqcyA=?>j=drMH(7Y+g zu0Vap0SXnm9@g`-Hv(X?wJ=C44Q;Z4L8E1*ERc}Pax;2Wr{0zNg4}{E8Sf|~VGFuc zxgBsxmMp}kzIb`;&>0JbMpYLUViU#fB%jtAWMxCWoz->S&k_96kF*)1wXD9Ww8;}D zo(RpS_Dd-MH%1VL?>v#pQ7;a5!2ti>=LWKh zaEhSSfWb3`z%f<7h0K{KbF=&Gub29@_$2_z^Ni!6NbCp742W(_;OB;UlM^vffe;Gx z*->h{imzoc(Lv^RF>>x{St=`ysZ>Y!KAVjJMU~{)!m?z?11L~dGeuU@4)4CmR$53O z-vB~CZB{8fe-wY(Vs>G)E{M8sx>0FJn^UnLEjP?UCqbzoM0#_G<42l3^L$qVEiXWF z_C!0n!jd+6Ql$w9lC(c;olR;4fZ;r$uXc-qLx7nB_s)=bJLy)w4G)~}JE0&1;#B08=5e{ID?NnA> zcMK*tOy};`1R(9R-C--cB4M({>q!PyQ@kbI_w8KLm|{ux$7M_zTp9AmQ4LqMGZVDO zrm}_JhH!~x5*LoZGzM$L6vZtnrqC8`e4q5^=X#k;N6H&*SD$#L%QO_M{cTJ)XZ2)_$aa=SgviE z`CUb2hFxvLbq`)`{i!GJxC;7sa9fZ70Y5m&35*bauy1;>fSz!G;g8P$q{*z?j1Nh=EVhWOv66t3CtOup@d~#aiOC`i?5FyCs z8z!Y~p~Zpyq?0ZM^fF>2;zbi)c^!Z&^c}QAgS8XVaQd}jXMj~NCgJB9Dy|S6mv9LP zq|7ixZMF|o_Jhw$T`6SaCmJyIk|Gi&rxvDfoF2XU&F3dl6`)MiLotwMKA`F5#~Izs z)Kd$WIb!ZDv(&=`o%e0T@#mF1AwcouDK%WHMfecIu9C+p-r5R>$4nu8)OlozqJ5@1 zKVVrXojvC|xY$_p_uBb|>F@-h9P+%xh0)^|x;%L-2KF?jy>quYh9ZeGIQn*KZmtW& z!x049%FYN0&`MTg#`mq&bB`$x9}bRYO%g2tFkH$|$R3V|-x4X#@=-SoA29KTTf>30 zr)qIP)o3){*oxyUaaItnervR1nQ-5s3K69P{+V%qiE6}x@xuCJ>l0Ib=$d&Iv)0OM zsC$b3OkIRx)oe#=+ska_;Anmg77< zA~4YKgo2#hdEe;qE8tre|GtVi1lhwll1o+@I;|XUxGJ zDfqY&Luy&SkeFeJlXmj#tB}+ zax%3cYER>SjI_JbYjMVMrJ*NtMrqbLxeGfxy2gmtR1|dCZ_&$t>s@+;F;OovjyqZ! zgVgNRfjo_qK1>UVEP*5tg9|ym(-d^M^Ma?5i(M3Scnt|D3<$M1;(qvf6&xgTht~!T z3C#u9QmoD&vfVk=E3{q#l7tS3&BJLU^u&3hHCVV#>dFtw+c|_r{yEVPHnebRf_vA{ zu;avKx^3QNV)RK8QEryCekW!Zjj*IA?14K3NZp+jY2InX(sa%NYpvbt)dPLI-} z%X5|E*X$ZLDQiZzu+XbxrXM$3LBggzK={;L(ajc3XS^7%0~|TDHKHi>Z;au60?;c8PUMxQx?o<- zwrWf#{@M&u*@}nxn@qFntp?ZgyH9c}A;HiZmrk;v#E5mMBX8JG+J$Vj7bZ>Wp$C(} znKHlj2gK>L@Yeiajkg${5>G#bXVv(T-dM%Zr}L3CN$3U_$k#{KYO9u;!@t1+&IW_X#*>lj1p5%sP1pItiigDRa8Ar^#+eNm zp3_AuonfQ#Gf;}2PPsP^txvp_2Zu!x3We57FwU%|#^;_fgXJz);yByinshrD-aJiF z^q1V#X2_DTEzWHHyuSpNa^DlXz~FlW6Dd7yt(FOFPSBK&ch1O0OQJ^8MD(3 zc~*Xnf~K)PS#wPPGJT3`Jz|>L(yfB%3Aw2zs+TZR(Kwgh7X63S)UCsQQTV-_I0wyaW(%JoGfHc;p zz`q~;{9s;dT-Ged?X5N0^9@1vSzf9#PlR7Oi|=K6Fe*CLjUV9-IozTF_uP_&)^N=B z*iU0DOYn=koj&f;pB&7E%o5OrAfJ1th`e-R{h*w8y46(ZmFN=94(q8OFoL*b%M%uF znLh(1&HK3xHcJq(W|F^MgNK^(-Z2#|ON7wmsj!IRt4zZOwoG6F%8#|eB4y?N=UkD} zf}*5^dNATRb3fRTDFFidkXsi$0qPOZ`%w4%ywiGTTj#=%zO_9W38;-3)J6^Z_8RZT zYC|8Xd^9Cnk3wM}CchgBc+}<~Vai;!@JD<`En^Z~*e|}Dt652Qh-s4GBbGd0SOK^< zNi5^V7qXH9y=({VQB*ArQ>Hr)zO=NKIR;4w^YjZ{I~+VXY<54^jD!0=V|2+6z|?|wVMu3=&lox~kn zX5Q@82}n^Qw5$sT{+cDrlXHNkQpe`qH8+Ye`F6T9c5v+!c>itM=clcSF*LQ}WuNW0 z80~?)E6vx8$*TZLqd0IIudV;7Ul>=8Z4&(h8;0Qgt#4`cmKK3T{ga3Ouj&Pw#C!sP zxPzOEx011&)&HP|#hPob=!cje)y*AR25Swmam+lQb_1J|l=3;i&pHN~K4a_Z$vLqG znK9C~L^9BJd?AsaL+GZmpYxS6F?oY<og$)u9TgAHY zdTn?2-BGu&t_e}MFs}tsTi>2~pu3H#%{W6XYqWn=n{CoDP##w7>ls_ig#c>JQX0c5 z!e=wwoGG=Zbi(A?)5j^QU3_>w1+(;irYK-k>}Oe4pRirNv}aA5(c^X4yEfY}*}@HJAIWJ*@~n$3*Hcd!OM4cn)moDwTE7wMANjoK+z@D@!r9C!^`rOLyy-M{e2Qa(Q z9`9;JY_X1>tvQ80D^$TQMmOv6ZQqX85$@%MT$Pa_=Jc*XJs|q({->Lp%)wXt`dy{2 z1YJh=o0a~gOlv^m@e;S&G0fQxwPSLg0m_foB2rCzQ9_}CetE0N@@}3j&K(@{B>rg{ zr0>&RFq2&gEwYc>-ozcazQmiIGW)V)kqWp)c9Pus=OpIHE~Q%shud#f^T1o9t`uM^$_oyayzi7Nnwg6_J%G=6<#XsJ3!u1Ri} zo)!3T6Na~)^nvxA?YIhyz=jS8oRfa5-G+l=I|+`uiHHnjWeFzdktx&18D`D(VHv)4 zX!4II5*~g#nh~OW;5t@^anDH`)SG){zgzJ-`}%3^ircLS4P{%tYD03Qcv%pqJXBlK zQXuu|vpx}Eg8rs*!27alE&*gNjhC2l|xrF+ACv)Q4_TstN`Qi>Z zW7`72Rsl2S?E8pQ9dh;Hp3$`lJHIsZ|0GukS9+=O0zLVLN0LKY;z0#~Df2OEh3UM4 z?yCv^JC~}n^n1Col7#wW5bMJ$%uy%g79F(Y1qluc<>^tLCXD-8_AlxMo+rt!_@K#e zD6_)LFb1L*6pNkG(;^-Iv2tr83mFV|A{u~Q99!0@MrkTHQ<+d}V^f)I7a)7N1*EXm z0&fCuNlg|%_JUdRQTVogX+;{XYGHw<>1%i2b}3q`Uqa3|z#(F+a<~AG(5oh*^G|23 zyN#tK&_EPl_#urbtwP(Ag}_5HkEHJ53Y=@~1q8w);zx12)by>uj|CP=3H^o6Yk7b~ zzac}HyWAvKi0eTc{~Dip3vQ<1x>>`uW+3DpbRJR0Vy?3**E^VgD`%WE@?=fThp$)T z!PhFjD+cx2nMd_qzxX2W+@DyO1(NpU$OT*%#Hx{Q3Z{L=(^MXhmNQX>g)x?Cy0J-o z9-N*(5g7T3a+J9EOlw`_L2O|IA`6{>*EwA zDPon00o-_GyyZfY9^+5nVIX%b&F{)YFH7{f3M`Crc$VYe_nNcZFSzQPG*m7q~LwTlRZo{fF zuawni^1tqr{0K&Qhsqng%$5UkK<^t*WvsY9Y;LV=y-!j6czb(O1iR=hmA*4t>W#u` z+9|>zlHOGopt>N!9w?^(z{n!HN)vn$ib9=;!EUL`!SY0a#sWGyNg&FSea{jDH=t(! z1T7<7#6lmgglGP9nf4uo zd_g6~p`a*idZV~vpy1nJXt7R0*l&zGKm5joqVX$7t32HO(U zGD%e6nHE_5DPbxKB860>m5LWkX^qJT`BFlTr<};imWbmn@t76=ELVu3;5o*&cVrZQ z)M3O+a_W8)TXB&^Vj#}tH$5EK=|ew*1^9mzucgSxdQ8&-G|9xIC`g3{6i+aqTf_~3DN8t>pUltQ zCtVt^IGrKmzs24=EAR}lG9#wS-{o%&QrU4iO%2X_4G&`3an;MGyDr=B8mwFHY71EI zatSz^(EG>(1OmyaY9woe-#_fNA(_+Ddr8sff2Mn(GUIx!4AL*lHx>2}r}p>KX=FAn zlz3x!NW!vFkYs>e-V+alc=t5>b%lBgaGp zy2h(-&7R>{m9TJrOSXojmMr$*Rg{`-;by8i;yly=P;wdl;_H?n4{7F1r!jKo;t4CT zML?ps=Grt?FfUUy&cm*v`Y^kn%D+KIAQ%jR0}xJkAKb z@PzUurdu}9z4WqtqvUs~G{R}U$tPyOe@a)T@&}ab6>(4rOe61E*g?Eh5ouu*&e1$3 z68>TW*w^xKiTF~En2w8gj@|&}KfPam<{fvp^g_G=dk*z?QD4Tmdw=9>&NFNx3TSt8 zgD1UVqT-;jw2_{Y6KPn2<$>n_gW&2lS`(h&jV+CLyARMtn1(? zF~ezWAb~G5qV^DO%c_FCS!<1sTN+ zaa^eQff;xw{>7p1f@aC=Q&Gs5JHy1!^Fw!ZXxP@V<8{^9A`OUq>4k#o=EXAFA;uU{9b0!ideG|ws6l*(IoEH5bOCa5=*HvUmI}{x#9cgU zpP@R~I(KQ^F@M=fmzO@|{dhf0MOZ|-L*vtW#j#D_p3;T$LQixs4d-}}!5~k0Qpe!8 z{t<#>qUTIqiB)*$u^vV`d}dLJI8W742f%)*%ky0!_cuwiou))|bZz5ygs|XC{FMDez@6=J_FqxUZ5B^*9*066?VF zLZU8_dDK|C4)BG7RJffL6cuDW%UzX<6RG=pUxF60X@Mb z20veeTc-1en9Twt){>8wbGkHU4M6_Dy}Qq{?!r;&WEIxAgec#-${+8!#3!U?`1CO^b0Z7IbS%!S7A`~FU*y%S`SkX^(ktmRb;S?qI>gd1of&6- zKH8yI4-Gn|M@IjERcLx>`!--U4(KEPmidN-AF&WG6m2FoeRrfntaB!7cc$!n=Ov>n z?rA9FyU6GDenWgrM0e1E*;MkPVPsH&#U!5?ZK@6Wz=uqzw<=w}!-8Uw#NDSw%wqJ* z9AsLEvJ?<4OYAE=V|te{0!%8Au}Un*m@>qU6tVY1Gx3b9so8)V*D%N&gMp18{d+I_ zOS~IV5db`D68yq^w^-RQPD?CDsNy5pGY2Ons0?C|H8Lv%OF~4Gkiky{mtf#Gvs990 zR=8aBh(<4^8Ima)gqC%&E9H$s=kNY~_=?HPtJ1^IZx*RIW$WXu(+QPfWpK{=3(=!oLVT-}fSHHMaG{1(*@1a>p3w>@-N`Sj>i>6ld6Bk)ItK-a5z=13|rzykXDa>2sKOkgZ zAqDVnz>5wXsL6O9%!dc-kH=^LK1vH02Fi$YTZ2&sg>zdoCmeO)%v*JaX;pqfvOBS7%`5YGFavbadbR`JGsHNoi%PPsq2Sf4@ICGZ zC%y|E@}ghx=dm0R%*(9M^^9TgE&V*pmQt?sZjTzTzESLWe5LhYnhf;KUQksfR0BAa zlz35Q0+o$Y+jK1sAd0?QBPpwW*M^G!g_WidsK;>#Z`wr3Y%7qwhkaG{lo?%H>6L`M zqLB#;+qR-IgWU;vipPKrkR4r1bD6`&Sg1`t%5}3W+|?!=PmUO7 z<_UkR%UApi`zAK@^tx9hqV!wgu?&Etd5zT1)OX4xB*=alQ$5tY=nprAH`Tm`n*{2 z1?NX;K7I&Z4>MT+iGc9nJRTEBlA)Yv+{KQ%dK#$%dTn3iwGBg)LvKhCwgceTPIg*~ zC*hnBEZ;g5w(ch}(5N+2M+2WXzzK!q8Cw=E$x^bzm#gCZl|!($ueT^XZwCsAd6%;N z3JXbiggNxNINUG_y?JP!MB`OwVEidAd~4Se&!F#;^A)_-#!J3Tcvl^33lEQCAbEUs z_L^NHm{TQZXl>SxT3JaIF$*xLX}o0??~4BxpSTp2;FtJ2OsSrL)h>edxcsyP@i0A? zOGN>i8?zqMpUx_~ly7aHhq5f&n7=vZ&L|pzA}Lj#wGWQmTIxPch2v!{QhiS-tXxfa z@8L%#<^Ztx;dkf#QvZEZ zQF5Tx_UNWk5uD{}Y#T<)LF@vW+R4plrDe`H>(&n_lTu%uWoEUhw>Jl=^r5fPs;!#V z3SDTsDRQ1p&SDSWa@GLXBYM0d1}E~=>-aY!t=+}K9%j>o;X zjHSQia+)m=75$-^Bkn(`x{3__pz-W&usDdKt`<&Vo9mX|XhB+i*XlXXjg1XMVWpKG z*i1EMfXH0L+22v!dp=GvveKq4&{U*~h~f&+`;hml8s+NYcK`rTko-nluAL{|Nw*-T z2=#u~p_9(#v_;(Ex81^85+6GGp~`gKYd_Vvs0aJ|NwzEz=vRB%BA? z>xbFvvlV`zLhhw(BU=Ple)1|zeoTl!9?A=vjxpRvQj2S5D(HxD?h40)((kjn!Xtwx zk}OnehBpw^PwU_$LK0hqS~!g;2!ax0-tf^sxYuRwG&m^ePJzcSt4KWHX02JXvSJ4{ z?E{!$9+sM6zbKOsP;;-|V>2syb{F8rOnv5z&y>+4ZG_s-RQClZ`N-*?r}nlR^a|( zluRZa^m-QRw={pauw4~231Z#~XZX_ciliWK^i4VG-(U7RN7xU=FQk`2`MG1&UOi3p z%UDQEMyJacftS)^I)!~nuc#}XE>HxBJIEGab7;OO5z-zqjII#9AkMhlTf*iL+qYwHf(Zs zq__wV5l}>;)HnDXIWsf*1b)6SH6WT8m#|y{j4N=%sKnSiKs~Rc{WL2KzvmZcW+$Q4 zawzyZ)D%rcIgM(KV%a58zXn-cyLZgM6zqVQuopC&ws_&{elrk->zOjRr4LL0ME@T3 z1CTKAL_pa>fgu%90DHfe_sXg{}6E?yDt6TmjM8cb$S13 zb98~oe_|8$|B#7+LVD69e?j#BkVnD582?2F1Ov0h0?rzd1Gf!70jKoXAO>-Ovm7{o zn5Cru@JRnu6G2?!{nJ&0`xz)?gh=v-YpQNA&}UuyhcR~XXNFY&HC!CoKf-dP|0DcY z_rHmW|E>EQ)&J@?poINnH#h_a*#A(U|KbHA2KW%aX#N?`!+@0JPnY^%zS{qztI_?J zVr2S%1g8y1{xSI9Mab0uC8)>vkKhSC>ObcE9ksq-J~QYK39b*~554xkgeSTG2r~j> z3=sbr_1}dt|1DU``+rTrBKh-|sQ)LK@&8{Sm#_b*XENf0fK~YC5GYN~@Nd)qUbBCL zC^Y{yBW>k>PMS7=<@!$!wjC%p#5i_|7WHOpk#ua#57UtkWT>HVV5Y) P2a1nwU<>#_21o?}zg;gp delta 13457 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 literal 0 HcmV?d00001 diff --git a/src/main/java/com/reandroid/lib/apk/ApkEntry.java b/src/main/java/com/reandroid/lib/apk/ApkEntry.java new file mode 100644 index 0000000..7054a3e --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/ApkEntry.java @@ -0,0 +1,10 @@ +package com.reandroid.lib.apk; + +import com.reandroid.archive.InputSource; + +public class ApkEntry { + private InputSource mInputSource; + public ApkEntry(InputSource inputSource){ + this.mInputSource=inputSource; + } +} diff --git a/src/main/java/com/reandroid/lib/apk/ApkModule.java b/src/main/java/com/reandroid/lib/apk/ApkModule.java new file mode 100644 index 0000000..29aecbc --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/ApkModule.java @@ -0,0 +1,170 @@ +package com.reandroid.lib.apk; + +import com.reandroid.archive.APKArchive; +import com.reandroid.archive.InputSource; +import com.reandroid.lib.arsc.array.PackageArray; +import com.reandroid.lib.arsc.chunk.PackageBlock; +import com.reandroid.lib.arsc.chunk.TableBlock; +import com.reandroid.lib.arsc.chunk.xml.AndroidManifestBlock; +import com.reandroid.lib.arsc.group.StringGroup; +import com.reandroid.lib.arsc.item.TableString; +import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.lib.arsc.value.EntryBlock; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +public class ApkModule { + private final APKArchive apkArchive; + private boolean loadDefaultFramework = true; + private TableBlock mTableBlock; + private AndroidManifestBlock mManifestBlock; + private ApkModule(APKArchive apkArchive){ + this.apkArchive=apkArchive; + } + public void writeTo(File file) throws IOException { + APKArchive archive=getApkArchive(); + archive.writeApk(file); + } + public void removeDir(String dirName){ + getApkArchive().removeDir(dirName); + } + public void setResourcesRootDir(String dirName) throws IOException { + List resFileList = listResFiles(); + Set existPaths=new HashSet<>(); + List sourceList = getApkArchive().listInputSources(); + for(InputSource inputSource:sourceList){ + existPaths.add(inputSource.getAlias()); + } + for(ResFile resFile:resFileList){ + String path=resFile.getFilePath(); + String pathNew=ApkUtil.replaceRootDir(path, dirName); + if(existPaths.contains(pathNew)){ + continue; + } + existPaths.remove(path); + existPaths.add(pathNew); + resFile.setFilePath(pathNew); + } + TableStringPool stringPool= getTableBlock().getTableStringPool(); + stringPool.refreshUniqueIdMap(); + } + public List listResFiles() throws IOException { + List results=new ArrayList<>(); + TableBlock tableBlock=getTableBlock(); + TableStringPool stringPool= tableBlock.getTableStringPool(); + for(InputSource inputSource:getApkArchive().listInputSources()){ + String name=inputSource.getAlias(); + StringGroup groupTableString = stringPool.get(name); + if(groupTableString==null){ + continue; + } + for(TableString tableString:groupTableString.listItems()){ + List entryBlockList = tableString.listReferencedEntries(); + ResFile resFile=new ResFile(inputSource, entryBlockList); + results.add(resFile); + } + } + return results; + } + public String getPackageName() throws IOException { + if(hasAndroidManifestBlock()){ + return getAndroidManifestBlock().getPackageName(); + } + if(!hasTableBlock()){ + return null; + } + TableBlock tableBlock=getTableBlock(); + PackageArray pkgArray = tableBlock.getPackageArray(); + PackageBlock pkg = pkgArray.get(0); + if(pkg==null){ + return null; + } + return pkg.getPackageName(); + } + public void setPackageName(String name) throws IOException { + String old=getPackageName(); + if(hasAndroidManifestBlock()){ + getAndroidManifestBlock().setPackageName(name); + } + if(!hasTableBlock()){ + return; + } + TableBlock tableBlock=getTableBlock(); + PackageArray pkgArray = tableBlock.getPackageArray(); + for(PackageBlock pkg:pkgArray.listItems()){ + if(pkgArray.childesCount()==1){ + pkg.setPackageName(name); + continue; + } + String pkgName=pkg.getPackageName(); + if(pkgName.startsWith(old)){ + pkgName=pkgName.replace(old, name); + pkg.setPackageName(pkgName); + } + } + } + public boolean hasAndroidManifestBlock(){ + return mManifestBlock!=null + || getApkArchive().getInputSource(AndroidManifestBlock.FILE_NAME)!=null; + } + public AndroidManifestBlock getAndroidManifestBlock() throws IOException { + if(mManifestBlock!=null){ + return mManifestBlock; + } + APKArchive archive=getApkArchive(); + InputSource inputSource = archive.getInputSource(AndroidManifestBlock.FILE_NAME); + if(inputSource==null){ + throw new IOException("Entry not found: "+AndroidManifestBlock.FILE_NAME); + } + InputStream inputStream = inputSource.openStream(); + AndroidManifestBlock manifestBlock=AndroidManifestBlock.load(inputStream); + inputStream.close(); + BlockInputSource blockInputSource=new BlockInputSource<>(inputSource.getName(),manifestBlock); + blockInputSource.setSort(inputSource.getSort()); + blockInputSource.setMethod(inputSource.getMethod()); + archive.add(blockInputSource); + mManifestBlock=manifestBlock; + return mManifestBlock; + } + public boolean hasTableBlock(){ + return mTableBlock!=null + || getApkArchive().getInputSource(TableBlock.FILE_NAME)!=null; + } + public TableBlock getTableBlock() throws IOException { + if(mTableBlock!=null){ + return mTableBlock; + } + APKArchive archive=getApkArchive(); + InputSource inputSource = archive.getInputSource(TableBlock.FILE_NAME); + if(inputSource==null){ + throw new IOException("Entry not found: "+TableBlock.FILE_NAME); + } + TableBlock tableBlock; + InputStream inputStream = inputSource.openStream(); + if(loadDefaultFramework){ + tableBlock=TableBlock.loadWithAndroidFramework(inputStream); + }else { + tableBlock=TableBlock.load(inputStream); + } + inputStream.close(); + mTableBlock=tableBlock; + BlockInputSource blockInputSource=new BlockInputSource<>(inputSource.getName(),tableBlock); + blockInputSource.setMethod(inputSource.getMethod()); + blockInputSource.setSort(inputSource.getSort()); + archive.add(blockInputSource); + return mTableBlock; + } + public APKArchive getApkArchive() { + return apkArchive; + } + public void setLoadDefaultFramework(boolean loadDefaultFramework) { + this.loadDefaultFramework = loadDefaultFramework; + } + public static ApkModule loadApkFile(File apkFile) throws IOException { + APKArchive archive=APKArchive.loadZippedApk(apkFile); + return new ApkModule(archive); + } +} diff --git a/src/main/java/com/reandroid/lib/apk/ApkUtil.java b/src/main/java/com/reandroid/lib/apk/ApkUtil.java new file mode 100644 index 0000000..adc5097 --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/ApkUtil.java @@ -0,0 +1,15 @@ +package com.reandroid.lib.apk; + +public class ApkUtil { + public static String replaceRootDir(String path, String dirName){ + int i=path.indexOf('/')+1; + path=path.substring(i); + if(dirName != null && dirName.length()>0){ + if(!dirName.endsWith("/")){ + dirName=dirName+"/"; + } + path=dirName+path; + } + return path; + } +} diff --git a/src/main/java/com/reandroid/lib/apk/BlockInputSource.java b/src/main/java/com/reandroid/lib/apk/BlockInputSource.java new file mode 100644 index 0000000..9c5010a --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/BlockInputSource.java @@ -0,0 +1,24 @@ +package com.reandroid.lib.apk; + +import com.reandroid.archive.InputSource; +import com.reandroid.lib.arsc.chunk.BaseChunk; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +public class BlockInputSource extends InputSource { + private final T mBlock; + public BlockInputSource(String name, T block) { + super(name); + this.mBlock=block; + } + public T getBlock() { + return mBlock; + } + @Override + public InputStream openStream(){ + T block=getBlock(); + block.refresh(); + return new ByteArrayInputStream(block.getBytes()); + } +} diff --git a/src/main/java/com/reandroid/lib/apk/ResFile.java b/src/main/java/com/reandroid/lib/apk/ResFile.java new file mode 100644 index 0000000..2c856ec --- /dev/null +++ b/src/main/java/com/reandroid/lib/apk/ResFile.java @@ -0,0 +1,33 @@ +package com.reandroid.lib.apk; + +import com.reandroid.archive.InputSource; +import com.reandroid.lib.arsc.value.EntryBlock; + +import java.util.List; + +public class ResFile { + private final List entryBlockList; + private final InputSource inputSource; + public ResFile(InputSource inputSource, List entryBlockList){ + this.inputSource=inputSource; + this.entryBlockList=entryBlockList; + } + public String getFilePath(){ + return getInputSource().getAlias(); + } + public void setFilePath(String filePath){ + getInputSource().setAlias(filePath); + for(EntryBlock entryBlock:entryBlockList){ + entryBlock.getValueAsTableString().set(filePath); + } + } + public InputSource getInputSource() { + return inputSource; + } + @Override + public String toString(){ + return getFilePath(); + } + + public static final String DIR_NAME="res"; +} diff --git a/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java b/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java index 2d56f09..3182eef 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/EntryBlockArray.java @@ -3,9 +3,12 @@ package com.reandroid.lib.arsc.array; import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.value.EntryBlock; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; +import org.json.JSONObject; -public class EntryBlockArray extends OffsetBlockArray { +public class EntryBlockArray extends OffsetBlockArray implements JsonItem { public EntryBlockArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart){ super(offsets, itemCount, itemStart); } @@ -38,4 +41,42 @@ public class EntryBlockArray extends OffsetBlockArray { return new EntryBlock[len]; } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + int index=0; + for(EntryBlock entryBlock:listItems()){ + JSONObject childObject = entryBlock.toJson(); + if(childObject==null){ + continue; + } + childObject.put(NAME_id, entryBlock.getIndex()); + jsonArray.put(index, childObject); + index++; + } + return jsonArray; + } + + @Override + public void fromJson(JSONArray json) { + clearChildes(); + int length=json.length(); + ensureSize(length); + for(int i=0;i { +public class LibraryInfoArray extends BlockArray implements JsonItem { private final IntegerItem mInfoCount; public LibraryInfoArray(IntegerItem infoCount){ this.mInfoCount=infoCount; @@ -30,4 +34,32 @@ public class LibraryInfoArray extends BlockArray { setChildesCount(mInfoCount.get()); super.onReadBytes(reader); } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + int i=0; + for(LibraryInfo libraryInfo:listItems()){ + JSONObject jsonObject= libraryInfo.toJson(); + if(jsonObject==null){ + continue; + } + jsonArray.put(i, jsonObject); + i++; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + clearChildes(); + if(json==null){ + return; + } + int length= json.length(); + ensureSize(length); + for (int i=0;i implements BlockLoad { +public class PackageArray extends BlockArray implements BlockLoad, JsonItem { private final IntegerItem mPackageCount; public PackageArray(IntegerItem packageCount){ this.mPackageCount=packageCount; @@ -60,4 +64,29 @@ public class PackageArray extends BlockArray implements BlockLoad setChildesCount(mPackageCount.get()); } } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + int i=0; + for(PackageBlock packageBlock:listItems()){ + JSONObject jsonObject= packageBlock.toJson(); + if(jsonObject==null){ + continue; + } + jsonArray.put(i, jsonObject); + i++; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + int length= json.length(); + clearChildes(); + ensureSize(length); + for (int i=0;i { +public class ResValueBagItemArray extends BlockArray implements JsonItem { public ResValueBagItemArray(){ super(); } @@ -21,4 +23,28 @@ public class ResValueBagItemArray extends BlockArray { protected void onRefreshed() { } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + if(isNull()){ + return jsonArray; + } + ResValueBagItem[] childes = getChildes(); + for(int i=0;i implements Comparator { +public class ResXmlAttributeArray extends BlockArray + implements Comparator, JsonItem { private final HeaderBlock mHeaderBlock; private final ShortItem mAttributeStart; private final ShortItem mAttributeCount; @@ -70,4 +74,27 @@ public class ResXmlAttributeArray extends BlockArray implements public int compare(ResXmlAttribute attr1, ResXmlAttribute attr2) { return attr1.compareTo(attr2); } + + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + int i=0; + for(ResXmlAttribute attr:listItems()){ + JSONObject jsonObject = attr.toJson(); + jsonArray.put(i, jsonObject); + i++; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + clearChildes(); + int length= json.length(); + ensureSize(length); + for(int i=0;i { +public class ResXmlIDArray extends BlockArray implements JsonItem { private final HeaderBlock mHeaderBlock; private final Map mResIdMap; private boolean mUpdated; @@ -86,4 +89,23 @@ public class ResXmlIDArray extends BlockArray { count=count/4; return count; } + @Override + public JSONArray toJson() { + if(childesCount()==0){ + return null; + } + JSONArray jsonArray=new JSONArray(); + int i=0; + for(ResXmlID xmlID:listItems()){ + JSONObject jsonObject=xmlID.toJson(); + jsonArray.put(i,jsonObject); + i++; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + //TODO + throw new IllegalArgumentException("Not implemented yet"); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java b/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java index 77c5bca..84eeb8e 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/SpecTypePairArray.java @@ -4,10 +4,13 @@ import com.reandroid.lib.arsc.base.BlockArray; import com.reandroid.lib.arsc.chunk.TypeBlock; import com.reandroid.lib.arsc.container.SpecTypePair; import com.reandroid.lib.arsc.value.EntryBlock; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; +import org.json.JSONObject; import java.util.*; -public class SpecTypePairArray extends BlockArray { +public class SpecTypePairArray extends BlockArray implements JsonItem { public SpecTypePairArray(){ super(); } @@ -140,4 +143,29 @@ public class SpecTypePairArray extends BlockArray { } return results; } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + int i=0; + for(SpecTypePair specTypePair:listItems()){ + JSONObject jsonObject= specTypePair.toJson(); + if(jsonObject==null){ + continue; + } + jsonArray.put(i, jsonObject); + i++; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + int length= json.length(); + clearChildes(); + ensureSize(length); + for (int i=0;i extends OffsetBlockArray{ +public abstract class StringArray extends OffsetBlockArray implements JsonItem { private boolean mUtf8; public StringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { @@ -50,5 +53,48 @@ public abstract class StringArray extends OffsetBlockArray protected void refreshChildes(){ // Not required } + @Override + public JSONArray toJson() { + return toJson(true); + } + public JSONArray toJson(boolean styledOnly) { + if(childesCount()==0){ + return null; + } + JSONArray jsonArray=new JSONArray(); + int i=0; + for(T item:listItems()){ + if(item.isNull()){ + continue; + } + if(styledOnly && !item.hasStyle()){ + continue; + } + JSONObject jsonObject= item.toJson(); + if(jsonObject==null){ + continue; + } + jsonArray.put(i, jsonObject); + i++; + } + if(i==0){ + return null; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + clearChildes(); + if(json==null){ + return; + } + int length = json.length(); + ensureSize(length); + for(int i=0; i { +public class StyleArray extends OffsetBlockArray implements JsonItem { public StyleArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart) { super(offsets, itemCount, itemStart); setEndBytes(END_BYTE); @@ -51,5 +53,21 @@ public class StyleArray extends OffsetBlockArray { public StyleItem[] newInstance(int len) { return new StyleItem[len]; } + + @Override + public JSONArray toJson() { + if(childesCount()==0){ + return null; + } + int i=0; + for(StyleItem styleItem:listItems()){ + + } + return null; + } + @Override + public void fromJson(JSONArray json) { + + } private static final byte END_BYTE= (byte) 0xFF; } diff --git a/src/main/java/com/reandroid/lib/arsc/array/TableStringArray.java b/src/main/java/com/reandroid/lib/arsc/array/TableStringArray.java index 086e0c1..fe13ce3 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/TableStringArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/TableStringArray.java @@ -3,6 +3,7 @@ package com.reandroid.lib.arsc.array; import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.TableString; +import org.json.JSONArray; public class TableStringArray extends StringArray { public TableStringArray(IntegerArray offsets, IntegerItem itemCount, IntegerItem itemStart, boolean is_utf8) { diff --git a/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java b/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java index ce0dc31..238f1b8 100755 --- a/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java +++ b/src/main/java/com/reandroid/lib/arsc/array/TypeBlockArray.java @@ -10,13 +10,16 @@ import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; +import org.json.JSONObject; import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; import java.util.List; -public class TypeBlockArray extends BlockArray { +public class TypeBlockArray extends BlockArray implements JsonItem { private byte mTypeId; public TypeBlockArray(){ super(); @@ -232,4 +235,29 @@ public class TypeBlockArray extends BlockArray { } return null; } + @Override + public JSONArray toJson() { + JSONArray jsonArray=new JSONArray(); + int i=0; + for(TypeBlock typeBlock:listItems()){ + JSONObject jsonObject= typeBlock.toJson(); + if(jsonObject==null){ + continue; + } + jsonArray.put(i, jsonObject); + i++; + } + return jsonArray; + } + @Override + public void fromJson(JSONArray json) { + int length= json.length(); + clearChildes(); + ensureSize(length); + for (int i=0;i listLibraryInfo(){ - return mLibraryInfoArray.listItems(); + return getLibraryInfoArray().listItems(); } @Override public boolean isNull(){ diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java index 5634b67..1b79380 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/PackageBlock.java @@ -1,5 +1,6 @@ package com.reandroid.lib.arsc.chunk; +import com.reandroid.lib.arsc.array.LibraryInfoArray; import com.reandroid.lib.arsc.array.SpecTypePairArray; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.container.PackageLastBlocks; @@ -14,11 +15,13 @@ import com.reandroid.lib.arsc.pool.TableStringPool; import com.reandroid.lib.arsc.pool.TypeStringPool; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.LibraryInfo; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.util.*; -public class PackageBlock extends BaseChunk { +public class PackageBlock extends BaseChunk implements JsonItem { private final IntegerItem mPackageId; private final PackageName mPackageName; @@ -157,11 +160,7 @@ public class PackageBlock extends BaseChunk { if(libraryBlock==null){ return; } - LibraryInfo[] allInfo=libraryBlock.getAllInfo(); - if (allInfo==null){ - return; - } - for(LibraryInfo info:allInfo){ + for(LibraryInfo info:libraryBlock.getLibraryInfoArray().listItems()){ addLibraryInfo(info); } } @@ -268,6 +267,26 @@ public class PackageBlock extends BaseChunk { refreshKeyStrings(); } + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put(NAME_id, getId()); + jsonObject.put(NAME_name, getName()); + jsonObject.put(NAME_specs, getSpecTypePairArray().toJson()); + LibraryInfoArray libraryInfoArray = mLibraryBlock.getLibraryInfoArray(); + if(libraryInfoArray.childesCount()>0){ + jsonObject.put(NAME_libraries,libraryInfoArray.toJson()); + } + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + setId(json.getInt(NAME_id)); + setName(json.getString(NAME_name)); + getSpecTypePairArray().fromJson(json.getJSONArray(NAME_specs)); + LibraryInfoArray libraryInfoArray = mLibraryBlock.getLibraryInfoArray(); + libraryInfoArray.fromJson(json.optJSONArray(NAME_libraries)); + } @Override public String toString(){ StringBuilder builder=new StringBuilder(); @@ -283,4 +302,9 @@ public class PackageBlock extends BaseChunk { } return builder.toString(); } + + private static final String NAME_id="id"; + private static final String NAME_name="name"; + private static final String NAME_specs="specs"; + private static final String NAME_libraries="libraries"; } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java index 3c889d2..5bd4051 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/SpecBlock.java @@ -7,10 +7,12 @@ import com.reandroid.lib.arsc.io.BlockLoad; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.io.IOException; -public class SpecBlock extends BaseTypeBlock implements BlockLoad { +public class SpecBlock extends BaseTypeBlock implements BlockLoad , JsonItem { private final IntegerArray mOffsets; public SpecBlock() { super(ChunkType.SPEC, 1); @@ -51,4 +53,16 @@ public class SpecBlock extends BaseTypeBlock implements BlockLoad { } return builder.toString(); } + + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put("id", getTypeId()); + return jsonObject; + } + + @Override + public void fromJson(JSONObject json) { + setTypeId((byte) json.getInt("id")); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java index b0fba2b..25e5935 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TableBlock.java @@ -8,13 +8,16 @@ import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.pool.TableStringPool; import com.reandroid.lib.common.Frameworks; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; +import org.json.JSONObject; import java.io.*; import java.util.Collection; import java.util.HashSet; import java.util.Set; -public class TableBlock extends BaseChunk { +public class TableBlock extends BaseChunk implements JsonItem { private final IntegerItem mPackageCount; private final TableStringPool mTableStringPool; private final PackageArray mPackageArray; @@ -116,10 +119,33 @@ public class TableBlock extends BaseChunk { } mFrameWorks.add(tableBlock); } + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put(NAME_packages, getPackageArray().toJson()); + JSONArray jsonArray = getTableStringPool().toJson(); + if(jsonArray!=null){ + jsonObject.put(NAME_styled_strings, jsonArray); + } + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + JSONArray jsonArray= json.optJSONArray(NAME_styled_strings); + if(jsonArray!=null){ + getTableStringPool().fromJson(jsonArray); + } + getPackageArray().fromJson(json.getJSONArray(NAME_packages)); + refresh(); + } public static TableBlock loadWithAndroidFramework(InputStream inputStream) throws IOException{ + TableBlock tableBlock=load(inputStream); + tableBlock.addFramework(Frameworks.getAndroid()); + return tableBlock; + } + public static TableBlock load(InputStream inputStream) throws IOException{ TableBlock tableBlock=new TableBlock(); tableBlock.readBytes(inputStream); - tableBlock.addFramework(Frameworks.getAndroid()); return tableBlock; } @@ -164,4 +190,6 @@ public class TableBlock extends BaseChunk { } public static final String FILE_NAME="resources.arsc"; + private static final String NAME_packages="packages"; + private static final String NAME_styled_strings="styled_strings"; } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java index fbaeaeb..daa321f 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/TypeBlock.java @@ -5,14 +5,17 @@ import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.container.SpecTypePair; import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; +import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class TypeBlock extends BaseTypeBlock { +public class TypeBlock extends BaseTypeBlock implements JsonItem { private final IntegerItem mEntriesStart; private final ResConfig mResConfig; private final IntegerArray mEntryOffsets; @@ -113,6 +116,28 @@ public class TypeBlock extends BaseTypeBlock { super.onPreRefreshRefresh(); } @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put("id", getTypeId()); + TypeString typeString=getTypeString(); + if(typeString!=null){ + jsonObject.put("name", typeString.get()); + } + jsonObject.put("config", getResConfig().toJson()); + jsonObject.put("entries", getEntryBlockArray().toJson()); + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + setTypeId((byte) json.getInt("id")); + String name= json.optString("name"); + if(name!=null){ + setTypeName(name); + } + getEntryBlockArray().fromJson(json.getJSONArray("entries")); + getResConfig().fromJson(json.getJSONObject("config")); + } + @Override public String toString(){ StringBuilder builder=new StringBuilder(); builder.append(getResConfig().toString()); diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java index 48161c2..7a563f2 100644 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/AndroidManifestBlock.java @@ -4,6 +4,10 @@ import com.reandroid.lib.arsc.item.ResXmlString; import com.reandroid.lib.arsc.pool.ResXmlStringPool; import com.reandroid.lib.arsc.value.ValueType; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -219,6 +223,14 @@ public class AndroidManifestBlock extends ResXmlBlock{ builder.append("}"); return builder.toString(); } + public static AndroidManifestBlock load(File file) throws IOException { + return load(new FileInputStream(file)); + } + public static AndroidManifestBlock load(InputStream inputStream) throws IOException { + AndroidManifestBlock manifestBlock=new AndroidManifestBlock(); + manifestBlock.readBytes(inputStream); + return manifestBlock; + } public static final String TAG_manifest ="manifest"; public static final String TAG_uses_permission="uses-permission"; public static final String TAG_application ="application"; diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java index a4ed4da..b0d906b 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlAttribute.java @@ -6,8 +6,11 @@ import com.reandroid.lib.arsc.container.FixedBlockContainer; import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.pool.ResXmlStringPool; import com.reandroid.lib.arsc.value.ValueType; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; -public class ResXmlAttribute extends FixedBlockContainer implements Comparable{ +public class ResXmlAttribute extends FixedBlockContainer + implements Comparable, JsonItem { private final IntegerItem mNamespaceReference; private final IntegerItem mNameReference; private final IntegerItem mValueStringReference; @@ -105,6 +108,17 @@ public class ResXmlAttribute extends FixedBlockContainer implements Comparable { private final ResXmlStringPool mResXmlStringPool; private final ResXmlIDMap mResXmlIDMap; private ResXmlElement mResXmlElement; @@ -129,6 +132,26 @@ public class ResXmlBlock extends BaseChunk { outputStream.close(); return length; } + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put(NAME_element, getResXmlElement().toJson()); + JSONArray pool =getStringPool().toJson(); + if(pool!=null){ + jsonObject.put(NAME_styled_strings, getResXmlElement().toJson()); + } + JSONArray idArray = getResXmlIDMap().getResXmlIDArray().toJson(); + if(idArray!=null){ + jsonObject.put("resource_ids", idArray); + } + return jsonObject; + } + + @Override + public void fromJson(JSONObject json) { + // TODO + throw new IllegalArgumentException("Not implemented yet"); + } public static boolean isResXmlBlock(File file){ if(file==null){ @@ -167,4 +190,6 @@ public class ResXmlBlock extends BaseChunk { ChunkType chunkType=headerBlock.getChunkType(); return chunkType==ChunkType.XML; } + private static final String NAME_element ="element"; + private static final String NAME_styled_strings="styled_strings"; } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java index 9ec14f6..e5fa8c1 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlElement.java @@ -9,6 +9,9 @@ import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.ResXmlString; import com.reandroid.lib.arsc.pool.ResXmlStringPool; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; +import org.json.JSONObject; import java.io.IOException; @@ -16,7 +19,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class ResXmlElement extends FixedBlockContainer { +public class ResXmlElement extends FixedBlockContainer implements JsonItem { private final BlockList mStartNamespaceList; private final SingleBlockContainer mStartElementContainer; private final BlockList mBody; @@ -492,6 +495,55 @@ public class ResXmlElement extends FixedBlockContainer { } } @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + ResXmlStartElement start = getStartElement(); + jsonObject.put(NAME_line, start.getLineNumber()); + int i=0; + JSONArray nsList=new JSONArray(); + for(ResXmlStartNamespace namespace:getStartNamespaceList()){ + JSONObject ns=new JSONObject(); + ns.put(NAME_namespace_uri, namespace.getUri()); + ns.put(NAME_namespace_prefix, namespace.getPrefix()); + nsList.put(i, ns); + i++; + } + if(i>0){ + jsonObject.put(NAME_namespaces, nsList); + } + jsonObject.put(NAME_name, start.getName()); + String uri=start.getUri(); + if(uri!=null){ + jsonObject.put(NAME_namespace_uri, uri); + jsonObject.put(NAME_namespace_prefix, start.getPrefix()); + } + JSONArray attrArray=start.getResXmlAttributeArray().toJson(); + jsonObject.put(NAME_attributes, attrArray); + i=0; + JSONArray childes=new JSONArray(); + for(ResXmlElement element:listElements()){ + childes.put(i, element.toJson()); + i++; + } + if(i>0){ + jsonObject.put(NAME_childes, childes); + } + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + ResXmlStartElement start = getStartElement(); + start.setLineNumber(json.getInt(NAME_line)); + String uri= json.optString(NAME_namespace_uri); + String prefix= json.optString(NAME_namespace_prefix); + if(uri!=null && prefix!=null){ + ResXmlStartNamespace ns = getOrCreateNamespace(uri, prefix); + start.setNamespaceReference(ns.getUriReference()); + } + JSONArray attributes = json.getJSONArray(NAME_attributes); + start.getResXmlAttributeArray().fromJson(attributes); + } + @Override public String toString(){ ResXmlStartElement start = getStartElement(); if(start!=null){ @@ -524,4 +576,12 @@ public class ResXmlElement extends FixedBlockContainer { public static final String NS_ANDROID_URI = "http://schemas.android.com/apk/res/android"; public static final String NS_ANDROID_PREFIX = "android"; + + private static final String NAME_name = "name"; + private static final String NAME_namespaces = "namespaces"; + private static final String NAME_namespace_uri = "namespace_uri"; + private static final String NAME_namespace_prefix = "namespace_name"; + private static final String NAME_line = "line"; + private static final String NAME_attributes = "attributes"; + private static final String NAME_childes = "childes"; } diff --git a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java index 8e4679d..4987e98 100755 --- a/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java +++ b/src/main/java/com/reandroid/lib/arsc/chunk/xml/ResXmlStartElement.java @@ -74,6 +74,19 @@ public class ResXmlStartElement extends BaseXmlChunk { public ResXmlAttributeArray getResXmlAttributeArray(){ return mAttributeArray; } + + public String getUri(){ + int uriRef=getNamespaceReference(); + if(uriRef<0){ + return null; + } + ResXmlElement parentElement=getParentResXmlElement(); + ResXmlStartNamespace startNamespace=parentElement.getStartNamespaceByUriRef(uriRef); + if(startNamespace!=null){ + return startNamespace.getUri(); + } + return null; + } public String getPrefix(){ int uriRef=getNamespaceReference(); if(uriRef<0){ diff --git a/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java b/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java index 81d732f..f461fc3 100755 --- a/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java +++ b/src/main/java/com/reandroid/lib/arsc/container/SpecTypePair.java @@ -12,6 +12,8 @@ import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.TypeString; import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.ResConfig; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; @@ -19,7 +21,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; -public class SpecTypePair extends BlockContainer { +public class SpecTypePair extends BlockContainer implements JsonItem { private final Block[] mChildes; private final SpecBlock mSpecBlock; private final TypeBlockArray mTypeBlockArray; @@ -140,4 +142,17 @@ public class SpecTypePair extends BlockContainer { public TypeString getTypeString(){ return getTypeBlockArray().getTypeString(); } + + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put("id", getSpecBlock().getTypeId()); + jsonObject.put("types", getTypeBlockArray().toJson()); + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + getSpecBlock().setTypeId((byte) json.getInt("id")); + getTypeBlockArray().fromJson(json.getJSONArray("types")); + } } diff --git a/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java b/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java index bebad35..c86139e 100755 --- a/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java +++ b/src/main/java/com/reandroid/lib/arsc/group/EntryGroup.java @@ -28,13 +28,28 @@ public class EntryGroup extends ItemGroup { if(specStringPool==null){ return false; } - String oldName=getSpecName(); - if(name.equals(oldName)){ - return false; + if(isAllSameSpec()){ + String oldName=getSpecName(); + if(name.equals(oldName)){ + return false; + } } SpecString specString=specStringPool.getOrCreate(name); return renameSpec(specString.getIndex()); } + private boolean isAllSameSpec(){ + EntryBlock first=null; + for(EntryBlock entryBlock:listItems()){ + if(first==null){ + first=entryBlock; + continue; + } + if(first.getSpecReference()!=entryBlock.getSpecReference()){ + return false; + } + } + return true; + } public boolean renameSpec(int specReference){ EntryBlock[] items=getItems(); if(items==null){ diff --git a/src/main/java/com/reandroid/lib/arsc/item/ResXmlID.java b/src/main/java/com/reandroid/lib/arsc/item/ResXmlID.java index 4199305..06a4fd4 100755 --- a/src/main/java/com/reandroid/lib/arsc/item/ResXmlID.java +++ b/src/main/java/com/reandroid/lib/arsc/item/ResXmlID.java @@ -1,10 +1,16 @@ package com.reandroid.lib.arsc.item; +import com.reandroid.lib.arsc.base.Block; +import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock; +import com.reandroid.lib.arsc.pool.ResXmlStringPool; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class ResXmlID extends IntegerItem { +public class ResXmlID extends IntegerItem implements JsonItem { private final List mReferencedList; public ResXmlID(int resId){ super(resId); @@ -47,6 +53,29 @@ public class ResXmlID extends IntegerItem { public void onIndexChanged(int oldIndex, int newIndex){ reUpdateReferences(newIndex); } + + private ResXmlStringPool getXmlStringPool(){ + Block parent=this; + while (parent!=null){ + if(parent instanceof ResXmlBlock){ + return ((ResXmlBlock)parent).getStringPool(); + } + parent=parent.getParent(); + } + return null; + } + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put("id", get()); + jsonObject.put("name", getXmlStringPool().get(getIndex()).getHtml()); + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + //TODO + throw new IllegalArgumentException("Not implemented yet"); + } @Override public String toString(){ return getIndex()+": "+String.format("0x%08x", get()); diff --git a/src/main/java/com/reandroid/lib/arsc/item/StringItem.java b/src/main/java/com/reandroid/lib/arsc/item/StringItem.java index d233bc4..a4d41d0 100755 --- a/src/main/java/com/reandroid/lib/arsc/item/StringItem.java +++ b/src/main/java/com/reandroid/lib/arsc/item/StringItem.java @@ -3,6 +3,8 @@ package com.reandroid.lib.arsc.item; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.pool.BaseStringPool; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.io.IOException; @@ -15,7 +17,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class StringItem extends BlockItem { +public class StringItem extends BlockItem implements JsonItem { private String mCache; private boolean mUtf8; private final List mReferencedList; @@ -166,27 +168,54 @@ public class StringItem extends BlockItem { return new String(allStringBytes, offLen[0], offLen[1], StandardCharsets.UTF_16LE); } } - - + public boolean hasStyle(){ + StyleItem styleItem=getStyle(); + if(styleItem==null){ + return false; + } + return !styleItem.isNull(); + } public StyleItem getStyle(){ - BaseStringPool stringPool=getStringPool(); + BaseStringPool stringPool=getStringPool(); if(stringPool==null){ return null; } int index=getIndex(); return stringPool.getStyle(index); } - private BaseStringPool getStringPool(){ + private BaseStringPool getStringPool(){ Block parent=getParent(); while (parent!=null){ if(parent instanceof BaseStringPool){ - return (BaseStringPool)parent; + return (BaseStringPool)parent; } parent=parent.getParent(); } return null; } @Override + public JSONObject toJson() { + if(isNull()){ + return null; + } + JSONObject jsonObject=new JSONObject(); + jsonObject.put(NAME_string, get()); + StyleItem styleItem=getStyle(); + if(styleItem!=null){ + JSONObject styleJson=styleItem.toJson(); + if(styleJson!=null){ + jsonObject.put(NAME_style, styleJson); + } + } + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + String str = json.getString(NAME_string); + set(str); + throw new IllegalArgumentException("Not implemented"); + } + @Override public String toString(){ String str=get(); if(str==null){ @@ -332,4 +361,7 @@ public class StringItem extends BlockItem { private final CharsetDecoder UTF16LE_DECODER = StandardCharsets.UTF_16LE.newDecoder(); private final CharsetDecoder UTF8_DECODER = StandardCharsets.UTF_8.newDecoder(); + + private static final String NAME_string="string"; + private static final String NAME_style="style"; } diff --git a/src/main/java/com/reandroid/lib/arsc/item/StyleItem.java b/src/main/java/com/reandroid/lib/arsc/item/StyleItem.java index f166118..509ad0f 100755 --- a/src/main/java/com/reandroid/lib/arsc/item/StyleItem.java +++ b/src/main/java/com/reandroid/lib/arsc/item/StyleItem.java @@ -4,16 +4,19 @@ import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.model.StyleSpanInfo; import com.reandroid.lib.arsc.pool.BaseStringPool; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; +import org.json.JSONObject; import java.io.IOException; +import java.util.AbstractList; import java.util.ArrayList; import java.util.List; -public class StyleItem extends IntegerArray{ - private List mStyleList; +public class StyleItem extends IntegerArray implements JsonItem { + private List mSpanInfoList; public StyleItem() { super(); - mStyleList=createStyleList(); } private void setEndValue(int negOne){ super.put(size()-1, negOne); @@ -22,54 +25,67 @@ public class StyleItem extends IntegerArray{ return super.get(size()-1); } final Integer getStringRef(int index){ - int i=index*STYLE_PIECE_COUNT+STRING_REF; + int i=index * INTEGERS_COUNT + INDEX_STRING_REF; return super.get(i); } final void setStringRef(int index, int val){ - int i=index*STYLE_PIECE_COUNT+STRING_REF; + int i=index * INTEGERS_COUNT + INDEX_STRING_REF; super.put(i, val); } final Integer getFirstChar(int index){ - int i=index*STYLE_PIECE_COUNT+CHAR_FIRST; + int i=index * INTEGERS_COUNT + INDEX_CHAR_FIRST; return super.get(i); } final void setFirstChar(int index, int val){ - int i=index*STYLE_PIECE_COUNT+CHAR_FIRST; + int i=index * INTEGERS_COUNT + INDEX_CHAR_FIRST; super.put(i, val); } final Integer getLastChar(int index){ - int i=index*STYLE_PIECE_COUNT+CHAR_LAST; + int i=index * INTEGERS_COUNT + INDEX_CHAR_LAST; return super.get(i); } final void setLastChar(int index, int val){ - int i=index*STYLE_PIECE_COUNT+CHAR_LAST; + int i=index * INTEGERS_COUNT + INDEX_CHAR_LAST; super.put(i, val); } + public void addStylePiece(String tag, int firstChar, int lastChar){ + BaseStringPool stringPool = getStringPool(); + if(stringPool==null){ + throw new IllegalArgumentException("Null string pool, must be added to parent StyleArray first"); + } + StringItem stringItem=stringPool.getOrCreate(tag); + addStylePiece(stringItem.getIndex(), firstChar, lastChar); + } + public void addStylePiece(int refString, int firstChar, int lastChar){ + int index=getStylePieceCount(); + setStylePieceCount(index+1); + setStylePiece(index, refString, firstChar, lastChar); + } final void setStylePiece(int index, int refString, int firstChar, int lastChar){ - int i=index*STYLE_PIECE_COUNT; - super.put(i+STRING_REF, refString); - super.put(i+CHAR_FIRST, firstChar); - super.put(i+CHAR_LAST, lastChar); + int i=index * INTEGERS_COUNT; + super.put(i+ INDEX_STRING_REF, refString); + super.put(i+ INDEX_CHAR_FIRST, firstChar); + super.put(i+ INDEX_CHAR_LAST, lastChar); } final int[] getStylePiece(int index){ if(index<0||index>= getStylePieceCount()){ return null; } - int[] result=new int[STYLE_PIECE_COUNT]; - int i=index*STYLE_PIECE_COUNT; - result[STRING_REF]=super.get(i); - result[CHAR_FIRST]=super.get(i+CHAR_FIRST); - result[CHAR_LAST]=super.get(i+CHAR_LAST); + int[] result=new int[INTEGERS_COUNT]; + int i=index * INTEGERS_COUNT; + result[INDEX_STRING_REF]=super.get(i); + result[INDEX_CHAR_FIRST]=super.get(i+ INDEX_CHAR_FIRST); + result[INDEX_CHAR_LAST]=super.get(i+ INDEX_CHAR_LAST); return result; } final void setStylePiece(int index, int[] three){ - if(three==null || three.length copy=new ArrayList<>(mStyleList); + List copy=new ArrayList<>(getIntSpanInfoList()); Integer end= getEndValue(); if(end==null){ end=END_VALUE; @@ -117,42 +133,54 @@ public class StyleItem extends IntegerArray{ } setEndValue(end); } - final List getStyleList(){ - return mStyleList; + private List getIntSpanInfoList(){ + return new AbstractList() { + @Override + public int[] get(int i) { + return StyleItem.this.getStylePiece(i); + } + @Override + public int size() { + return StyleItem.this.getStylePieceCount(); + } + }; } - private List createStyleList(){ - List results=new ArrayList<>(); - int max=getStylePieceCount(); - for(int i=0;i getSpanInfoList(){ + if(mSpanInfoList!=null){ + return mSpanInfoList; } - return results; + mSpanInfoList = new AbstractList() { + @Override + public StyleSpanInfo get(int i) { + int ref=getStringRef(i); + return new StyleSpanInfo( + getStringFromPool(ref), + getFirstChar(i), + getLastChar(i)); + } + @Override + public int size() { + return getStylePieceCount(); + } + }; + return mSpanInfoList; } - final List getSpanInfo(){ - BaseStringPool stringPool= getStringPool(); + private String getStringFromPool(int ref){ + BaseStringPool stringPool = getStringPool(); if(stringPool==null){ return null; } - List allPiece=getStyleList(); - List results=new ArrayList<>(); - for(int[] piece:allPiece){ - StringItem stringItem=stringPool.get(piece[STRING_REF]); - if(stringItem==null){ - return null; - } - StyleSpanInfo info=new StyleSpanInfo(stringItem.get(), piece[CHAR_FIRST], piece[CHAR_LAST]); - results.add(info); - } - if(results.size()==0){ + StringItem stringItem = stringPool.get(ref); + if(stringItem==null){ return null; } - return results; + return stringItem.get(); } - private BaseStringPool getStringPool(){ + private BaseStringPool getStringPool(){ Block parent=getParent(); while (parent!=null){ if(parent instanceof BaseStringPool){ - return (BaseStringPool)parent; + return (BaseStringPool)parent; } parent=parent.getParent(); } @@ -163,8 +191,8 @@ public class StyleItem extends IntegerArray{ if(str==null){ return null; } - List allInfo=getSpanInfo(); - if(allInfo==null){ + List spanInfoList = getSpanInfoList(); + if(spanInfoList.size()==0){ return str; } StringBuilder builder=new StringBuilder(); @@ -173,9 +201,9 @@ public class StyleItem extends IntegerArray{ for(int i=0;i stringPool = getStringPool(); + if(stringPool==null){ + throw new IllegalArgumentException("Null string pool, must be added to parent StyleArray first"); + } + StringItem stringItem=stringPool.getOrCreate(tag); + setStylePiece(index, stringItem.getIndex(), first, last); + } + @Override + public JSONObject toJson() { + if(isNull()){ + return null; + } + JSONObject jsonObject=new JSONObject(); + JSONArray jsonArray=new JSONArray(); + int i=0; + for(StyleSpanInfo spanInfo:getSpanInfoList()){ + JSONObject jsonObjectSpan=spanInfo.toJson(); + jsonArray.put(i, jsonObjectSpan); + i++; + } + jsonObject.put(NAME_spans, jsonArray); + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + setNull(true); + if(json==null){ + return; + } + JSONArray jsonArray= json.getJSONArray(NAME_spans); + int length = jsonArray.length(); + for(int i=0;i listReferencedEntries(){ + List results=new ArrayList<>(); + for(ReferenceItem ref:getReferencedList()){ + if(!(ref instanceof ResValueReference)){ + continue; + } + EntryBlock entryBlock=((ResValueReference)ref).getEntryBlock(); + if(entryBlock==null){ + continue; + } + results.add(entryBlock); + } + return results; + } @Override public String toString(){ List refList = getReferencedList(); diff --git a/src/main/java/com/reandroid/lib/arsc/model/StyleSpanInfo.java b/src/main/java/com/reandroid/lib/arsc/model/StyleSpanInfo.java index 48823db..4cb7a25 100755 --- a/src/main/java/com/reandroid/lib/arsc/model/StyleSpanInfo.java +++ b/src/main/java/com/reandroid/lib/arsc/model/StyleSpanInfo.java @@ -1,44 +1,84 @@ package com.reandroid.lib.arsc.model; -public class StyleSpanInfo { - public final String TAG; - public final int FIRST; - public final int LAST; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; + +public class StyleSpanInfo implements JsonItem { + private String mTag; + private int mFirst; + private int mLast; public StyleSpanInfo(String tag, int first, int last){ - this.TAG=tag; - this.FIRST=first; - this.LAST=last; + this.mTag = tag; + this.mFirst = first; + this.mLast = last; } + public int getFirst() { + return mFirst; + } + public void setFirst(int first) { + this.mFirst = first; + } + public int getLast() { + return mLast; + } + public void setLast(int last) { + this.mLast = last; + } + public String getTag() { + return mTag; + } + public void setTag(String tag) { + this.mTag = tag; + } + public String getStartTag(){ - int i=TAG.indexOf(';'); + int i= mTag.indexOf(';'); StringBuilder builder=new StringBuilder(); builder.append('<'); if(i<0){ - builder.append(TAG); + builder.append(mTag); }else { - builder.append(TAG, 0, i); + builder.append(mTag, 0, i); builder.append(' '); - builder.append(TAG.substring(i+1)); + builder.append(mTag.substring(i+1)); } builder.append('>'); return builder.toString(); } public String getEndTag(){ - int i=TAG.indexOf(';'); + int i= mTag.indexOf(';'); StringBuilder builder=new StringBuilder(); builder.append('<'); builder.append('/'); if(i<0){ - builder.append(TAG); + builder.append(mTag); }else { - builder.append(TAG, 0, i); + builder.append(mTag, 0, i); } builder.append('>'); return builder.toString(); } @Override - public String toString(){ - return TAG+" ("+FIRST+", "+LAST+")"; + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put(NAME_tag, mTag); + jsonObject.put(NAME_first, mFirst); + jsonObject.put(NAME_last, mLast); + return jsonObject; } + @Override + public void fromJson(JSONObject json) { + setTag(json.getString(NAME_tag)); + setFirst(json.getInt(NAME_first)); + setLast(json.getInt(NAME_last)); + } + @Override + public String toString(){ + return mTag +" ("+ mFirst +", "+ mLast +")"; + } + + private static final String NAME_tag="tag"; + private static final String NAME_first="first"; + private static final String NAME_last="last"; } diff --git a/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java b/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java index d2e12aa..69f2fa4 100755 --- a/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java +++ b/src/main/java/com/reandroid/lib/arsc/pool/BaseStringPool.java @@ -10,12 +10,14 @@ import com.reandroid.lib.arsc.io.BlockLoad; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.pool.builder.StyleBuilder; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONArray; import java.io.IOException; import java.util.*; -public abstract class BaseStringPool extends BaseChunk implements BlockLoad { +public abstract class BaseStringPool extends BaseChunk implements BlockLoad, JsonItem { private final IntegerItem mCountStrings; private final IntegerItem mCountStyles; private final ShortItem mFlagUtf8; @@ -64,6 +66,10 @@ public abstract class BaseStringPool extends BaseChunk imp mUniqueMap=new HashMap<>(); } + // call this after modifying string values + public void refreshUniqueIdMap(){ + reUpdateUniqueMap(); + } public void recreateStyles(){ StyleArray styleArray = getStyleArray(); //styleArray.clearChildes(); @@ -249,6 +255,16 @@ public abstract class BaseStringPool extends BaseChunk imp mArrayStrings.setUtf8(isUtf8Flag()); } } + @Override + public JSONArray toJson() { + return getStringsArray().toJson(); + } + @Override + public void fromJson(JSONArray json) { + getStringsArray().fromJson(json); + refreshUniqueIdMap(); + refresh(); + } private static final short UTF8_FLAG_VALUE=0x0100; private static final short FLAG_UTF8 = 0x0100; diff --git a/src/main/java/com/reandroid/lib/arsc/pool/TableStringPool.java b/src/main/java/com/reandroid/lib/arsc/pool/TableStringPool.java index beb4ac6..1a9bba0 100755 --- a/src/main/java/com/reandroid/lib/arsc/pool/TableStringPool.java +++ b/src/main/java/com/reandroid/lib/arsc/pool/TableStringPool.java @@ -6,6 +6,7 @@ import com.reandroid.lib.arsc.item.IntegerArray; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.ReferenceItem; import com.reandroid.lib.arsc.item.TableString; +import org.json.JSONArray; public class TableStringPool extends BaseStringPool { public TableStringPool(boolean is_utf8) { diff --git a/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java b/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java index a4094bd..10532b8 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java +++ b/src/main/java/com/reandroid/lib/arsc/value/BaseResValue.java @@ -3,8 +3,10 @@ package com.reandroid.lib.arsc.value; import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.item.BlockItem; import com.reandroid.lib.arsc.item.ReferenceItem; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; -public abstract class BaseResValue extends BlockItem { +public abstract class BaseResValue extends BlockItem implements JsonItem { BaseResValue(int bytesLength){ super(bytesLength); } @@ -95,4 +97,10 @@ public abstract class BaseResValue extends BlockItem { byte getByte(int offset){ return getBytesInternal()[offset]; } + + static final String NAME_data = "data"; + static final String NAME_value_type="value_type"; + static final String NAME_id="id"; + static final String NAME_parent="parent"; + static final String NAME_items="items"; } diff --git a/src/main/java/com/reandroid/lib/arsc/value/BaseResValueItem.java b/src/main/java/com/reandroid/lib/arsc/value/BaseResValueItem.java index ea61098..918eb55 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/BaseResValueItem.java +++ b/src/main/java/com/reandroid/lib/arsc/value/BaseResValueItem.java @@ -46,7 +46,7 @@ public abstract class BaseResValueItem extends BaseResValue implements ResValueI return null; } if(mReferenceItem==null){ - mReferenceItem=createReferenceItem(); + mReferenceItem=new ResValueReference(this); } return mReferenceItem; } @@ -62,23 +62,6 @@ public abstract class BaseResValueItem extends BaseResValue implements ResValueI mReferenceItem=null; return entryBlock.removeTableReference(ref); } - private ReferenceItem createReferenceItem(){ - return new ReferenceItem() { - @Override - public void set(int val) { - if(getValueType()==ValueType.STRING){ - BaseResValueItem.this.setData(val); - } - } - @Override - public int get() { - if(getValueType()==ValueType.STRING){ - return BaseResValueItem.this.getData(); - } - return -1; - } - }; - } public ValueType getValueType(){ return ValueType.valueOf(getType()); diff --git a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java index bece53f..314568b 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java +++ b/src/main/java/com/reandroid/lib/arsc/value/EntryBlock.java @@ -10,6 +10,8 @@ import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.*; import com.reandroid.lib.arsc.pool.SpecStringPool; import com.reandroid.lib.arsc.pool.TableStringPool; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.io.IOException; @@ -17,7 +19,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -public class EntryBlock extends Block{ +public class EntryBlock extends Block implements JsonItem { private ShortItem mHeaderSize; private ShortItem mFlags; private IntegerItem mSpecReference; @@ -84,7 +86,18 @@ public class EntryBlock extends Block{ resValueInt.setData(tableString.getIndex()); return resValueInt; } + public boolean getValueAsBoolean(){ + int data = ((ResValueInt)getResValue()).getData(); + return data!=0; + } public String getValueAsString(){ + TableString tableString= getValueAsTableString(); + if(tableString==null){ + return null; + } + return tableString.getHtml(); + } + public TableString getValueAsTableString(){ TableStringPool stringPool=getTableStringPool(); if(stringPool==null){ return null; @@ -98,7 +111,7 @@ public class EntryBlock extends Block{ if(tableString==null){ return null; } - return tableString.getHtml(); + return tableString; } private TableStringPool getTableStringPool(){ PackageBlock pkg=getPackageBlock(); @@ -298,6 +311,11 @@ public class EntryBlock extends Block{ } return specString.get(); } + private void setName(String name){ + PackageBlock packageBlock=getPackageBlock(); + EntryGroup entryGroup = packageBlock.getEntryGroup(getResourceId()); + entryGroup.renameSpec(name); + } public String getTypeName(){ TypeString typeString=getTypeString(); if(typeString==null){ @@ -479,6 +497,12 @@ public class EntryBlock extends Block{ private boolean isFlagsComplex(){ return ((mFlags.get() & FLAG_COMPLEX_MASK) != 0); } + public boolean isArray(){ + return ((mFlags.get() & FLAG_COMPLEX_MASK) != 0); + } + public void setIsArray(boolean is_array){ + setFlagComplex(is_array); + } @Override public void setNull(boolean is_null){ if(is_null){ @@ -596,6 +620,35 @@ public class EntryBlock extends Block{ updateSpecRef(); } @Override + public JSONObject toJson() { + if(isNull()){ + return null; + } + JSONObject jsonObject=new JSONObject(); + jsonObject.put(NAME_name, getSpecString().get()); + jsonObject.put(NAME_is_array, isArray()); + jsonObject.put(NAME_value, getResValue().toJson()); + return jsonObject; + } + + @Override + public void fromJson(JSONObject json) { + if(json==null){ + setNull(true); + return; + } + setName(json.getString(NAME_name)); + setNull(false); + BaseResValue baseResValue; + if(json.getBoolean(NAME_is_array)){ + baseResValue=new ResValueInt(); + }else { + baseResValue=new ResValueBag(); + } + setResValue(baseResValue); + baseResValue.fromJson(json.getJSONObject(NAME_value)); + } + @Override public String toString(){ StringBuilder builder=new StringBuilder(); builder.append(getClass().getSimpleName()); @@ -654,4 +707,8 @@ public class EntryBlock extends Block{ private final static short HEADER_COMPLEX=0x0010; private final static short HEADER_INT=0x0008; + private static final String NAME_name="name"; + private static final String NAME_is_array="is_array"; + private static final String NAME_value="value"; + } diff --git a/src/main/java/com/reandroid/lib/arsc/value/LibraryInfo.java b/src/main/java/com/reandroid/lib/arsc/value/LibraryInfo.java index 385a7a7..2d1bdc5 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/LibraryInfo.java +++ b/src/main/java/com/reandroid/lib/arsc/value/LibraryInfo.java @@ -5,11 +5,13 @@ import com.reandroid.lib.arsc.base.BlockCounter; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.PackageName; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.io.IOException; import java.io.OutputStream; -public class LibraryInfo extends Block { +public class LibraryInfo extends Block implements JsonItem { private final IntegerItem mPackageId; private final PackageName mPackageName; @@ -74,6 +76,18 @@ public class LibraryInfo extends Block { mPackageName.readBytes(reader); } + @Override + public JSONObject toJson() { + JSONObject jsonObject=new JSONObject(); + jsonObject.put("id", getPackageId()); + jsonObject.put("name", getPackageName()); + return jsonObject; + } + @Override + public void fromJson(JSONObject json) { + setPackageId(json.getInt("id")); + setPackageName(json.getString("name")); + } @Override public String toString(){ StringBuilder builder=new StringBuilder(); diff --git a/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java b/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java index a39d467..a287407 100755 --- a/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java +++ b/src/main/java/com/reandroid/lib/arsc/value/ResConfig.java @@ -6,12 +6,13 @@ import com.reandroid.lib.arsc.io.BlockLoad; import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.item.ByteArray; import com.reandroid.lib.arsc.item.IntegerItem; +import com.reandroid.lib.json.JsonItem; +import org.json.JSONObject; import java.io.IOException; import java.util.Arrays; -import java.util.Objects; -public class ResConfig extends FixedBlockContainer implements BlockLoad { +public class ResConfig extends FixedBlockContainer implements BlockLoad, JsonItem { private final IntegerItem configSize; private final ByteArray mValuesContainer; @@ -156,7 +157,17 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad { } return mValuesContainer.get(OFFSET_languageIn1); } - public char[] getLanguage(){ + public String getLanguage(){ + return ResConfigHelper.decodeLanguage(getLanguageChars()); + } + public void setLanguage(String language){ + char[] chs=new char[2]; + if(language!=null){ + chs=language.toCharArray(); + } + setLanguage(chs); + } + public char[] getLanguageChars(){ byte b0=getLanguageIn0(); byte b1=getLanguageIn1(); return unpackLanguageOrRegion(b0, b1, 'a'); @@ -201,7 +212,10 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad { } return mValuesContainer.get(OFFSET_countryIn1); } - public char[] getRegion(){ + public String getRegion(){ + return ResConfigHelper.decodeRegion(getRegionChars()); + } + public char[] getRegionChars(){ byte b0=getCountryIn0(); byte b1=getCountryIn1(); return unpackLanguageOrRegion(b0, b1, '0'); @@ -225,12 +239,18 @@ public class ResConfig extends FixedBlockContainer implements BlockLoad { } mValuesContainer.put(OFFSET_orientation, b); } - public byte getOrientation(){ + public byte getOrientationByte(){ if(getConfigSize()