Skip to content

Commit fcc93e7

Browse files
Xavier DucrohetAndroid Git Automerger
authored andcommitted
am 135b5ba: Layoutlib: Read and close XML files as soon as possible. do not merge.
* commit '135b5ba52431b147d51a81b807784009cd0510dd': Layoutlib: Read and close XML files as soon as possible. do not merge.
2 parents 82f0ba7 + 135b5ba commit fcc93e7

File tree

1 file changed

+68
-3
lines changed

1 file changed

+68
-3
lines changed

tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
import org.xmlpull.v1.XmlPullParser;
2222
import org.xmlpull.v1.XmlPullParserException;
2323

24+
import java.io.BufferedInputStream;
25+
import java.io.ByteArrayInputStream;
2426
import java.io.File;
2527
import java.io.FileInputStream;
2628
import java.io.FileNotFoundException;
29+
import java.io.IOException;
2730
import java.io.InputStream;
2831

2932
/**
@@ -38,14 +41,21 @@ public class ParserFactory {
3841

3942
public static XmlPullParser create(File f)
4043
throws XmlPullParserException, FileNotFoundException {
41-
KXmlParser parser = instantiateParser(f.getName());
42-
parser.setInput(new FileInputStream(f), ENCODING);
43-
return parser;
44+
InputStream stream = new FileInputStream(f);
45+
return create(stream, f.getName(), f.length());
4446
}
4547

4648
public static XmlPullParser create(InputStream stream, String name)
49+
throws XmlPullParserException {
50+
return create(stream, name, -1);
51+
}
52+
53+
private static XmlPullParser create(InputStream stream, String name, long size)
4754
throws XmlPullParserException {
4855
KXmlParser parser = instantiateParser(name);
56+
57+
stream = readAndClose(stream, name, size);
58+
4959
parser.setInput(stream, ENCODING);
5060
return parser;
5161
}
@@ -61,6 +71,61 @@ private static KXmlParser instantiateParser(String name) throws XmlPullParserExc
6171
return parser;
6272
}
6373

74+
private static InputStream readAndClose(InputStream stream, String name, long size)
75+
throws XmlPullParserException {
76+
// just a sanity check. It's doubtful we'll have such big files!
77+
if (size > Integer.MAX_VALUE) {
78+
throw new XmlPullParserException("File " + name + " is too big to be parsed");
79+
}
80+
int intSize = (int) size;
81+
82+
// create a buffered reader to facilitate reading.
83+
BufferedInputStream bufferedStream = new BufferedInputStream(stream);
84+
try {
85+
int avail;
86+
if (intSize != -1) {
87+
avail = intSize;
88+
} else {
89+
// get the size to read.
90+
avail = bufferedStream.available();
91+
}
92+
93+
// create the initial buffer and read it.
94+
byte[] buffer = new byte[avail];
95+
int read = stream.read(buffer);
96+
97+
// this is the easy case.
98+
if (read == intSize) {
99+
return new ByteArrayInputStream(buffer);
100+
}
101+
102+
// check if there is more to read (read() does not necessarily read all that
103+
// available() returned!)
104+
while ((avail = bufferedStream.available()) > 0) {
105+
if (read + avail > buffer.length) {
106+
// just allocate what is needed. We're mostly reading small files
107+
// so it shouldn't be too problematic.
108+
byte[] moreBuffer = new byte[read + avail];
109+
System.arraycopy(buffer, 0, moreBuffer, 0, read);
110+
buffer = moreBuffer;
111+
}
112+
113+
read += stream.read(buffer, read, avail);
114+
}
115+
116+
// return a new stream encapsulating this buffer.
117+
return new ByteArrayInputStream(buffer);
118+
119+
} catch (IOException e) {
120+
throw new XmlPullParserException("Failed to read " + name, null, e);
121+
} finally {
122+
try {
123+
bufferedStream.close();
124+
} catch (IOException e) {
125+
}
126+
}
127+
}
128+
64129
private static class CustomParser extends KXmlParser {
65130
private final String mName;
66131

0 commit comments

Comments
 (0)