mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-04-30 06:14:25 +02:00
implement namespace features as per xmlpull #18
This commit is contained in:
parent
db3a18b039
commit
b8d410803d
@ -36,11 +36,12 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
private DocumentLoadedListener documentLoadedListener;
|
private DocumentLoadedListener documentLoadedListener;
|
||||||
private boolean processNamespaces;
|
private boolean processNamespaces;
|
||||||
private boolean reportNamespaceAttrs;
|
private boolean reportNamespaceAttrs;
|
||||||
|
private boolean mIsTagStared;
|
||||||
|
|
||||||
public ResXmlPullParser(Decoder decoder){
|
public ResXmlPullParser(Decoder decoder){
|
||||||
this.mDecoder = decoder;
|
this.mDecoder = decoder;
|
||||||
this.processNamespaces = true;
|
this.processNamespaces = false;
|
||||||
this.reportNamespaceAttrs = true;
|
this.reportNamespaceAttrs = false;
|
||||||
}
|
}
|
||||||
public ResXmlPullParser(){
|
public ResXmlPullParser(){
|
||||||
this(null);
|
this(null);
|
||||||
@ -93,6 +94,7 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
|
|
||||||
public void closeDocument(){
|
public void closeDocument(){
|
||||||
mEventList.clear();
|
mEventList.clear();
|
||||||
|
mIsTagStared = false;
|
||||||
destroyDocument();
|
destroyDocument();
|
||||||
}
|
}
|
||||||
private void destroyDocument(){
|
private void destroyDocument(){
|
||||||
@ -118,14 +120,14 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int count = element.getAttributeCount();
|
int count = element.getAttributeCount();
|
||||||
if(reportNamespaceAttrs){
|
if(isCountNamespacesAsAttribute()){
|
||||||
count += element.getNamespaceCount();
|
count += element.getNamespaceCount();
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public String getAttributeName(int index) {
|
public String getAttributeName(int index) {
|
||||||
if(reportNamespaceAttrs){
|
if(isCountNamespacesAsAttribute()){
|
||||||
int nsCount = getNamespaceCountInternal();
|
int nsCount = getNamespaceCountInternal();
|
||||||
if(index < nsCount){
|
if(index < nsCount){
|
||||||
return getNamespaceAttributeName(index);
|
return getNamespaceAttributeName(index);
|
||||||
@ -135,7 +137,7 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public String getAttributeValue(int index) {
|
public String getAttributeValue(int index) {
|
||||||
if(reportNamespaceAttrs){
|
if(isCountNamespacesAsAttribute()){
|
||||||
int nsCount = getNamespaceCountInternal();
|
int nsCount = getNamespaceCountInternal();
|
||||||
if(index < nsCount){
|
if(index < nsCount){
|
||||||
return getNamespaceAttributeValue(index);
|
return getNamespaceAttributeValue(index);
|
||||||
@ -345,13 +347,20 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFeature(String name, boolean state) throws XmlPullParserException {
|
public void setFeature(String name, boolean state) throws XmlPullParserException {
|
||||||
|
boolean changed;
|
||||||
if(FEATURE_PROCESS_NAMESPACES.equals(name)) {
|
if(FEATURE_PROCESS_NAMESPACES.equals(name)) {
|
||||||
|
changed = processNamespaces != state;
|
||||||
processNamespaces = state;
|
processNamespaces = state;
|
||||||
}else if(FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
|
}else if(FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
|
||||||
|
changed = reportNamespaceAttrs != state;
|
||||||
reportNamespaceAttrs = state;
|
reportNamespaceAttrs = state;
|
||||||
}else {
|
}else {
|
||||||
throw new XmlPullParserException("Unsupported feature: " + name);
|
throw new XmlPullParserException("Unsupported feature: " + name);
|
||||||
}
|
}
|
||||||
|
if(changed && mIsTagStared){
|
||||||
|
throw new XmlPullParserException("Feature changed during parsing: "
|
||||||
|
+ name + ", state=" + state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -392,7 +401,7 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int getNamespaceCount(int depth) throws XmlPullParserException {
|
public int getNamespaceCount(int depth) throws XmlPullParserException {
|
||||||
if(reportNamespaceAttrs){
|
if(isCountNamespacesAsAttribute()){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ResXmlElement element = getCurrentElement();
|
ResXmlElement element = getCurrentElement();
|
||||||
@ -593,7 +602,7 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
private int getRealAttributeIndex(int index){
|
private int getRealAttributeIndex(int index){
|
||||||
if(reportNamespaceAttrs){
|
if(isCountNamespacesAsAttribute()){
|
||||||
index = index - getNamespaceCountInternal();
|
index = index - getNamespaceCountInternal();
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
@ -605,6 +614,9 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
private boolean isCountNamespacesAsAttribute(){
|
||||||
|
return processNamespaces & reportNamespaceAttrs;
|
||||||
|
}
|
||||||
private String getNamespaceAttributeName(int index){
|
private String getNamespaceAttributeName(int index){
|
||||||
ResXmlStartNamespace namespace = getCurrentElement()
|
ResXmlStartNamespace namespace = getCurrentElement()
|
||||||
.getNamespace(index);
|
.getNamespace(index);
|
||||||
@ -628,9 +640,9 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
mEventList.next();
|
mEventList.next();
|
||||||
int type = mEventList.getType();
|
int type = mEventList.getType();
|
||||||
if(type == START_TAG){
|
if(type == START_TAG){
|
||||||
onStartTag();
|
mIsTagStared = true;
|
||||||
}
|
}
|
||||||
return mEventList.getType();
|
return type;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public int nextToken() throws XmlPullParserException, IOException {
|
public int nextToken() throws XmlPullParserException, IOException {
|
||||||
@ -711,9 +723,6 @@ public class ResXmlPullParser implements XmlResourceParser {
|
|||||||
processNamespaces = true;
|
processNamespaces = true;
|
||||||
reportNamespaceAttrs = true;
|
reportNamespaceAttrs = true;
|
||||||
}
|
}
|
||||||
private void onStartTag(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface DocumentLoadedListener{
|
public static interface DocumentLoadedListener{
|
||||||
public ResXmlDocument onDocumentLoaded(ResXmlDocument resXmlDocument);
|
public ResXmlDocument onDocumentLoaded(ResXmlDocument resXmlDocument);
|
||||||
|
@ -20,17 +20,22 @@ import org.xmlpull.v1.XmlPullParser;
|
|||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class XmlParserToSerializer {
|
public class XmlParserToSerializer {
|
||||||
private final XmlSerializer serializer;
|
private final XmlSerializer serializer;
|
||||||
private final XmlResourceParser parser;
|
private final XmlPullParser parser;
|
||||||
private boolean enableIndent;
|
private boolean enableIndent;
|
||||||
|
boolean processNamespace;
|
||||||
|
boolean reportNamespaceAttrs;
|
||||||
|
|
||||||
public XmlParserToSerializer(XmlResourceParser parser, XmlSerializer serializer){
|
public XmlParserToSerializer(XmlPullParser parser, XmlSerializer serializer){
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
this.enableIndent = true;
|
this.enableIndent = true;
|
||||||
|
setFeatureSafe(parser, XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
|
setFeatureSafe(parser, XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnableIndent(boolean enableIndent) {
|
public void setEnableIndent(boolean enableIndent) {
|
||||||
@ -38,15 +43,29 @@ public class XmlParserToSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void write() throws IOException, XmlPullParserException {
|
public void write() throws IOException, XmlPullParserException {
|
||||||
XmlResourceParser parser = this.parser;
|
XmlPullParser parser = this.parser;
|
||||||
|
|
||||||
|
this.processNamespace = getFeatureSafe(parser,
|
||||||
|
XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||||
|
|
||||||
|
this.reportNamespaceAttrs = getFeatureSafe(parser,
|
||||||
|
XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, false);
|
||||||
|
|
||||||
int event = parser.next();
|
int event = parser.next();
|
||||||
while (nextEvent(event)){
|
while (nextEvent(event)){
|
||||||
event = parser.next();
|
event = parser.next();
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
private void close(){
|
private void close() throws IOException {
|
||||||
parser.close();
|
XmlPullParser parser = this.parser;
|
||||||
|
if(parser instanceof Closeable){
|
||||||
|
((Closeable)parser).close();
|
||||||
|
}
|
||||||
|
XmlSerializer serializer = this.serializer;
|
||||||
|
if(serializer instanceof Closeable){
|
||||||
|
((Closeable)serializer).close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private boolean nextEvent(int event) throws IOException, XmlPullParserException {
|
private boolean nextEvent(int event) throws IOException, XmlPullParserException {
|
||||||
boolean hasNext = true;
|
boolean hasNext = true;
|
||||||
@ -78,12 +97,17 @@ public class XmlParserToSerializer {
|
|||||||
serializer.startDocument("utf-8", null);
|
serializer.startDocument("utf-8", null);
|
||||||
}
|
}
|
||||||
private void onStartTag() throws IOException, XmlPullParserException {
|
private void onStartTag() throws IOException, XmlPullParserException {
|
||||||
XmlResourceParser parser = this.parser;
|
XmlPullParser parser = this.parser;
|
||||||
XmlSerializer serializer = this.serializer;
|
XmlSerializer serializer = this.serializer;
|
||||||
boolean processNamespace = parser.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
|
|
||||||
boolean reportNamespaceAttrs = parser.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES);
|
boolean processNamespace = this.processNamespace;
|
||||||
serializer.setFeature(FEATURE_INDENT_OUTPUT, enableIndent);
|
boolean countNamespaceAsAttribute = processNamespace && reportNamespaceAttrs;
|
||||||
if(!reportNamespaceAttrs){
|
|
||||||
|
if(enableIndent){
|
||||||
|
setFeatureSafe(serializer, FEATURE_INDENT_OUTPUT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!countNamespaceAsAttribute){
|
||||||
int nsCount = parser.getNamespaceCount(parser.getDepth());
|
int nsCount = parser.getNamespaceCount(parser.getDepth());
|
||||||
for(int i=0; i<nsCount; i++){
|
for(int i=0; i<nsCount; i++){
|
||||||
String prefix = parser.getNamespacePrefix(i);
|
String prefix = parser.getNamespacePrefix(i);
|
||||||
@ -115,5 +139,25 @@ public class XmlParserToSerializer {
|
|||||||
serializer.endDocument();
|
serializer.endDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean getFeatureSafe(XmlPullParser parser, String name, boolean def){
|
||||||
|
try{
|
||||||
|
return parser.getFeature(name);
|
||||||
|
}catch (Throwable ignored){
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void setFeatureSafe(XmlPullParser parser, String name, boolean state){
|
||||||
|
try{
|
||||||
|
parser.setFeature(name, state);
|
||||||
|
}catch (Throwable ignored){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void setFeatureSafe(XmlSerializer serializer, String name, boolean state){
|
||||||
|
try{
|
||||||
|
serializer.setFeature(name, state);
|
||||||
|
}catch (Throwable ignored){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final String FEATURE_INDENT_OUTPUT = "http://xmlpull.org/v1/doc/features.html#indent-output";
|
private static final String FEATURE_INDENT_OUTPUT = "http://xmlpull.org/v1/doc/features.html#indent-output";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user