Skip to content

Commit

Permalink
implement namespace features as per xmlpull #18
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed May 3, 2023
1 parent db3a18b commit b8d4108
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 22 deletions.
33 changes: 21 additions & 12 deletions src/main/java/com/reandroid/arsc/chunk/xml/ResXmlPullParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ public class ResXmlPullParser implements XmlResourceParser {
private DocumentLoadedListener documentLoadedListener;
private boolean processNamespaces;
private boolean reportNamespaceAttrs;
private boolean mIsTagStared;

public ResXmlPullParser(Decoder decoder){
this.mDecoder = decoder;
this.processNamespaces = true;
this.reportNamespaceAttrs = true;
this.processNamespaces = false;
this.reportNamespaceAttrs = false;
}
public ResXmlPullParser(){
this(null);
Expand Down Expand Up @@ -93,6 +94,7 @@ private void initializeDecoder(ResXmlDocument xmlDocument){

public void closeDocument(){
mEventList.clear();
mIsTagStared = false;
destroyDocument();
}
private void destroyDocument(){
Expand All @@ -118,14 +120,14 @@ public int getAttributeCount() {
return 0;
}
int count = element.getAttributeCount();
if(reportNamespaceAttrs){
if(isCountNamespacesAsAttribute()){
count += element.getNamespaceCount();
}
return count;
}
@Override
public String getAttributeName(int index) {
if(reportNamespaceAttrs){
if(isCountNamespacesAsAttribute()){
int nsCount = getNamespaceCountInternal();
if(index < nsCount){
return getNamespaceAttributeName(index);
Expand All @@ -135,7 +137,7 @@ public String getAttributeName(int index) {
}
@Override
public String getAttributeValue(int index) {
if(reportNamespaceAttrs){
if(isCountNamespacesAsAttribute()){
int nsCount = getNamespaceCountInternal();
if(index < nsCount){
return getNamespaceAttributeValue(index);
Expand Down Expand Up @@ -345,13 +347,20 @@ public int getStyleAttribute() {

@Override
public void setFeature(String name, boolean state) throws XmlPullParserException {
boolean changed;
if(FEATURE_PROCESS_NAMESPACES.equals(name)) {
changed = processNamespaces != state;
processNamespaces = state;
}else if(FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
changed = reportNamespaceAttrs != state;
reportNamespaceAttrs = state;
}else {
throw new XmlPullParserException("Unsupported feature: " + name);
}
if(changed && mIsTagStared){
throw new XmlPullParserException("Feature changed during parsing: "
+ name + ", state=" + state);
}
}

@Override
Expand Down Expand Up @@ -392,7 +401,7 @@ public void defineEntityReplacementText(String entityName, String replacementTex
}
@Override
public int getNamespaceCount(int depth) throws XmlPullParserException {
if(reportNamespaceAttrs){
if(isCountNamespacesAsAttribute()){
return 0;
}
ResXmlElement element = getCurrentElement();
Expand Down Expand Up @@ -593,7 +602,7 @@ public ResXmlElement getCurrentElement() {
return null;
}
private int getRealAttributeIndex(int index){
if(reportNamespaceAttrs){
if(isCountNamespacesAsAttribute()){
index = index - getNamespaceCountInternal();
}
return index;
Expand All @@ -605,6 +614,9 @@ private int getNamespaceCountInternal(){
}
return 0;
}
private boolean isCountNamespacesAsAttribute(){
return processNamespaces & reportNamespaceAttrs;
}
private String getNamespaceAttributeName(int index){
ResXmlStartNamespace namespace = getCurrentElement()
.getNamespace(index);
Expand All @@ -628,9 +640,9 @@ public int next() throws XmlPullParserException, IOException {
mEventList.next();
int type = mEventList.getType();
if(type == START_TAG){
onStartTag();
mIsTagStared = true;
}
return mEventList.getType();
return type;
}
@Override
public int nextToken() throws XmlPullParserException, IOException {
Expand Down Expand Up @@ -711,9 +723,6 @@ private void initDefaultFeatures(){
processNamespaces = true;
reportNamespaceAttrs = true;
}
private void onStartTag(){

}

public static interface DocumentLoadedListener{
public ResXmlDocument onDocumentLoaded(ResXmlDocument resXmlDocument);
Expand Down
64 changes: 54 additions & 10 deletions src/main/java/com/reandroid/xml/XmlParserToSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,52 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.Closeable;
import java.io.IOException;

public class XmlParserToSerializer {
private final XmlSerializer serializer;
private final XmlResourceParser parser;
private final XmlPullParser parser;
private boolean enableIndent;
boolean processNamespace;
boolean reportNamespaceAttrs;

public XmlParserToSerializer(XmlResourceParser parser, XmlSerializer serializer){
public XmlParserToSerializer(XmlPullParser parser, XmlSerializer serializer){
this.parser = parser;
this.serializer = serializer;
this.enableIndent = true;
setFeatureSafe(parser, XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
setFeatureSafe(parser, XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, true);
}

public void setEnableIndent(boolean enableIndent) {
this.enableIndent = enableIndent;
}

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();
while (nextEvent(event)){
event = parser.next();
}
close();
}
private void close(){
parser.close();
private void close() throws IOException {
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 {
boolean hasNext = true;
Expand Down Expand Up @@ -78,12 +97,17 @@ private void onStartDocument() throws IOException{
serializer.startDocument("utf-8", null);
}
private void onStartTag() throws IOException, XmlPullParserException {
XmlResourceParser parser = this.parser;
XmlPullParser parser = this.parser;
XmlSerializer serializer = this.serializer;
boolean processNamespace = parser.getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
boolean reportNamespaceAttrs = parser.getFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES);
serializer.setFeature(FEATURE_INDENT_OUTPUT, enableIndent);
if(!reportNamespaceAttrs){

boolean processNamespace = this.processNamespace;
boolean countNamespaceAsAttribute = processNamespace && reportNamespaceAttrs;

if(enableIndent){
setFeatureSafe(serializer, FEATURE_INDENT_OUTPUT, true);
}

if(!countNamespaceAsAttribute){
int nsCount = parser.getNamespaceCount(parser.getDepth());
for(int i=0; i<nsCount; i++){
String prefix = parser.getNamespacePrefix(i);
Expand Down Expand Up @@ -115,5 +139,25 @@ private void onEndDocument() throws IOException{
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";
}

0 comments on commit b8d4108

Please sign in to comment.