/* Android IMSI-Catcher Detector | (c) AIMSICD Privacy Project * ----------------------------------------------------------- * LICENSE: http://git.io/vki47 | TERMS: http://git.io/vki4o * ----------------------------------------------------------- */ package com.secupwn.aimsicd.utils; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * StackOverflowXmlParser populates a List of entries with data from the feed */ public class StackOverflowXmlParser { // We don't use namespaces private static final String ns = null; public List<Cell> parse(InputStream in) throws XmlPullParserException, IOException { try { XmlPullParser parser = Xml.newPullParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(in, null); parser.nextTag(); return readCells(parser); } finally { in.close(); } } private List<Cell> readCells(XmlPullParser parser) throws XmlPullParserException, IOException { List<Cell> cells = new ArrayList<>(); parser.require(XmlPullParser.START_TAG, ns, "rsp"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); // Starts by looking for the entry tag if (name.equals("cell")) { cells.add(readCell(parser)); } else { skip(parser); } } return cells; } // Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off // to their respective "read" methods for processing. Otherwise, skips the tag. private Cell readCell(XmlPullParser parser) throws XmlPullParserException, IOException { Cell cell = new Cell(); parser.require(XmlPullParser.START_TAG, ns, "cell"); while (parser.next() != XmlPullParser.END_TAG) { if (parser.getEventType() != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); switch (name) { case "lat": cell.setLat(readDouble(parser)); break; case "lon": cell.setLon(readDouble(parser)); break; case "mcc": cell.setMobileCountryCode(readInt(parser)); break; case "mnc": cell.setMobileNetworkCode(readInt(parser)); break; case "cellid": cell.setCellId(readInt(parser)); break; case "lac": cell.setLocationAreaCode(readInt(parser)); break; default: skip(parser); break; } } return cell; } // For the tags title and summary, extracts their text values. private String readText(XmlPullParser parser) throws IOException, XmlPullParserException { String result = ""; if (parser.next() == XmlPullParser.TEXT) { result = parser.getText(); parser.nextTag(); } return result; } // For tags containing double values. private double readDouble(XmlPullParser parser) throws IOException, XmlPullParserException { String result = ""; if (parser.next() == XmlPullParser.TEXT) { result = parser.getText(); parser.nextTag(); } return Double.valueOf(result); } // For tags containing double values. private int readInt(XmlPullParser parser) throws IOException, XmlPullParserException { String result = ""; if (parser.next() == XmlPullParser.TEXT) { result = parser.getText(); parser.nextTag(); } return Integer.valueOf(result); } private void skip(XmlPullParser parser) throws XmlPullParserException, IOException { if (parser.getEventType() != XmlPullParser.START_TAG) { throw new IllegalStateException(); } int depth = 1; while (depth != 0) { switch (parser.next()) { case XmlPullParser.END_TAG: depth--; break; case XmlPullParser.START_TAG: depth++; break; } } } }