Merge change I37f5ced1 into eclair-mr2
* changes: Move various utility classes to android-common
This commit is contained in:
172
common/java/com/android/common/ArrayListCursor.java
Normal file
172
common/java/com/android/common/ArrayListCursor.java
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.common;
|
||||||
|
|
||||||
|
import android.database.AbstractCursor;
|
||||||
|
import android.database.CursorWindow;
|
||||||
|
|
||||||
|
import java.lang.System;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience class that presents a two-dimensional ArrayList
|
||||||
|
* as a Cursor.
|
||||||
|
* @deprecated This is has been replaced by MatrixCursor.
|
||||||
|
*/
|
||||||
|
public class ArrayListCursor extends AbstractCursor {
|
||||||
|
private String[] mColumnNames;
|
||||||
|
private ArrayList<Object>[] mRows;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public ArrayListCursor(String[] columnNames, ArrayList<ArrayList> rows) {
|
||||||
|
int colCount = columnNames.length;
|
||||||
|
boolean foundID = false;
|
||||||
|
// Add an _id column if not in columnNames
|
||||||
|
for (int i = 0; i < colCount; ++i) {
|
||||||
|
if (columnNames[i].compareToIgnoreCase("_id") == 0) {
|
||||||
|
mColumnNames = columnNames;
|
||||||
|
foundID = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundID) {
|
||||||
|
mColumnNames = new String[colCount + 1];
|
||||||
|
System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
|
||||||
|
mColumnNames[colCount] = "_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
int rowCount = rows.size();
|
||||||
|
mRows = new ArrayList[rowCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < rowCount; ++i) {
|
||||||
|
mRows[i] = rows.get(i);
|
||||||
|
if (!foundID) {
|
||||||
|
mRows[i].add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillWindow(int position, CursorWindow window) {
|
||||||
|
if (position < 0 || position > getCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.acquireReference();
|
||||||
|
try {
|
||||||
|
int oldpos = mPos;
|
||||||
|
mPos = position - 1;
|
||||||
|
window.clear();
|
||||||
|
window.setStartPosition(position);
|
||||||
|
int columnNum = getColumnCount();
|
||||||
|
window.setNumColumns(columnNum);
|
||||||
|
while (moveToNext() && window.allocRow()) {
|
||||||
|
for (int i = 0; i < columnNum; i++) {
|
||||||
|
final Object data = mRows[mPos].get(i);
|
||||||
|
if (data != null) {
|
||||||
|
if (data instanceof byte[]) {
|
||||||
|
byte[] field = (byte[]) data;
|
||||||
|
if (!window.putBlob(field, mPos, i)) {
|
||||||
|
window.freeLastRow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String field = data.toString();
|
||||||
|
if (!window.putString(field, mPos, i)) {
|
||||||
|
window.freeLastRow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!window.putNull(mPos, i)) {
|
||||||
|
window.freeLastRow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mPos = oldpos;
|
||||||
|
} catch (IllegalStateException e){
|
||||||
|
// simply ignore it
|
||||||
|
} finally {
|
||||||
|
window.releaseReference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mRows.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteRow() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getColumnNames() {
|
||||||
|
return mColumnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBlob(int columnIndex) {
|
||||||
|
return (byte[]) mRows[mPos].get(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) {
|
||||||
|
Object cell = mRows[mPos].get(columnIndex);
|
||||||
|
return (cell == null) ? null : cell.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int columnIndex) {
|
||||||
|
Number num = (Number) mRows[mPos].get(columnIndex);
|
||||||
|
return num.shortValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int columnIndex) {
|
||||||
|
Number num = (Number) mRows[mPos].get(columnIndex);
|
||||||
|
return num.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int columnIndex) {
|
||||||
|
Number num = (Number) mRows[mPos].get(columnIndex);
|
||||||
|
return num.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFloat(int columnIndex) {
|
||||||
|
Number num = (Number) mRows[mPos].get(columnIndex);
|
||||||
|
return num.floatValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(int columnIndex) {
|
||||||
|
Number num = (Number) mRows[mPos].get(columnIndex);
|
||||||
|
return num.doubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNull(int columnIndex) {
|
||||||
|
return mRows[mPos].get(columnIndex) == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
365
common/java/com/android/common/FastXmlSerializer.java
Normal file
365
common/java/com/android/common/FastXmlSerializer.java
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.common;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.CharsetEncoder;
|
||||||
|
import java.nio.charset.CoderResult;
|
||||||
|
import java.nio.charset.IllegalCharsetNameException;
|
||||||
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a quick and dirty implementation of XmlSerializer that isn't horribly
|
||||||
|
* painfully slow like the normal one. It only does what is needed for the
|
||||||
|
* specific XML files being written with it.
|
||||||
|
*/
|
||||||
|
public class FastXmlSerializer implements XmlSerializer {
|
||||||
|
private static final String ESCAPE_TABLE[] = new String[] {
|
||||||
|
null, null, null, null, null, null, null, null, // 0-7
|
||||||
|
null, null, null, null, null, null, null, null, // 8-15
|
||||||
|
null, null, null, null, null, null, null, null, // 16-23
|
||||||
|
null, null, null, null, null, null, null, null, // 24-31
|
||||||
|
null, null, """, null, null, null, "&", null, // 32-39
|
||||||
|
null, null, null, null, null, null, null, null, // 40-47
|
||||||
|
null, null, null, null, null, null, null, null, // 48-55
|
||||||
|
null, null, null, null, "<", null, ">", null, // 56-63
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int BUFFER_LEN = 8192;
|
||||||
|
|
||||||
|
private final char[] mText = new char[BUFFER_LEN];
|
||||||
|
private int mPos;
|
||||||
|
|
||||||
|
private Writer mWriter;
|
||||||
|
|
||||||
|
private OutputStream mOutputStream;
|
||||||
|
private CharsetEncoder mCharset;
|
||||||
|
private ByteBuffer mBytes = ByteBuffer.allocate(BUFFER_LEN);
|
||||||
|
|
||||||
|
private boolean mInTag;
|
||||||
|
|
||||||
|
private void append(char c) throws IOException {
|
||||||
|
int pos = mPos;
|
||||||
|
if (pos >= (BUFFER_LEN-1)) {
|
||||||
|
flush();
|
||||||
|
pos = mPos;
|
||||||
|
}
|
||||||
|
mText[pos] = c;
|
||||||
|
mPos = pos+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(String str, int i, final int length) throws IOException {
|
||||||
|
if (length > BUFFER_LEN) {
|
||||||
|
final int end = i + length;
|
||||||
|
while (i < end) {
|
||||||
|
int next = i + BUFFER_LEN;
|
||||||
|
append(str, i, next<end ? BUFFER_LEN : (end-i));
|
||||||
|
i = next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int pos = mPos;
|
||||||
|
if ((pos+length) > BUFFER_LEN) {
|
||||||
|
flush();
|
||||||
|
pos = mPos;
|
||||||
|
}
|
||||||
|
str.getChars(i, i+length, mText, pos);
|
||||||
|
mPos = pos + length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(char[] buf, int i, final int length) throws IOException {
|
||||||
|
if (length > BUFFER_LEN) {
|
||||||
|
final int end = i + length;
|
||||||
|
while (i < end) {
|
||||||
|
int next = i + BUFFER_LEN;
|
||||||
|
append(buf, i, next<end ? BUFFER_LEN : (end-i));
|
||||||
|
i = next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int pos = mPos;
|
||||||
|
if ((pos+length) > BUFFER_LEN) {
|
||||||
|
flush();
|
||||||
|
pos = mPos;
|
||||||
|
}
|
||||||
|
System.arraycopy(buf, i, mText, pos, length);
|
||||||
|
mPos = pos + length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(String str) throws IOException {
|
||||||
|
append(str, 0, str.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void escapeAndAppendString(final String string) throws IOException {
|
||||||
|
final int N = string.length();
|
||||||
|
final char NE = (char)ESCAPE_TABLE.length;
|
||||||
|
final String[] escapes = ESCAPE_TABLE;
|
||||||
|
int lastPos = 0;
|
||||||
|
int pos;
|
||||||
|
for (pos=0; pos<N; pos++) {
|
||||||
|
char c = string.charAt(pos);
|
||||||
|
if (c >= NE) continue;
|
||||||
|
String escape = escapes[c];
|
||||||
|
if (escape == null) continue;
|
||||||
|
if (lastPos < pos) append(string, lastPos, pos-lastPos);
|
||||||
|
lastPos = pos + 1;
|
||||||
|
append(escape);
|
||||||
|
}
|
||||||
|
if (lastPos < pos) append(string, lastPos, pos-lastPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void escapeAndAppendString(char[] buf, int start, int len) throws IOException {
|
||||||
|
final char NE = (char)ESCAPE_TABLE.length;
|
||||||
|
final String[] escapes = ESCAPE_TABLE;
|
||||||
|
int end = start+len;
|
||||||
|
int lastPos = start;
|
||||||
|
int pos;
|
||||||
|
for (pos=start; pos<end; pos++) {
|
||||||
|
char c = buf[pos];
|
||||||
|
if (c >= NE) continue;
|
||||||
|
String escape = escapes[c];
|
||||||
|
if (escape == null) continue;
|
||||||
|
if (lastPos < pos) append(buf, lastPos, pos-lastPos);
|
||||||
|
lastPos = pos + 1;
|
||||||
|
append(escape);
|
||||||
|
}
|
||||||
|
if (lastPos < pos) append(buf, lastPos, pos-lastPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlSerializer attribute(String namespace, String name, String value) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
append(' ');
|
||||||
|
if (namespace != null) {
|
||||||
|
append(namespace);
|
||||||
|
append(':');
|
||||||
|
}
|
||||||
|
append(name);
|
||||||
|
append("=\"");
|
||||||
|
|
||||||
|
escapeAndAppendString(value);
|
||||||
|
append('"');
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cdsect(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void comment(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void docdecl(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endDocument() throws IOException, IllegalArgumentException, IllegalStateException {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlSerializer endTag(String namespace, String name) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
if (mInTag) {
|
||||||
|
append(" />\n");
|
||||||
|
} else {
|
||||||
|
append("</");
|
||||||
|
if (namespace != null) {
|
||||||
|
append(namespace);
|
||||||
|
append(':');
|
||||||
|
}
|
||||||
|
append(name);
|
||||||
|
append(">\n");
|
||||||
|
}
|
||||||
|
mInTag = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void entityRef(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flushBytes() throws IOException {
|
||||||
|
int position;
|
||||||
|
if ((position = mBytes.position()) > 0) {
|
||||||
|
mBytes.flip();
|
||||||
|
mOutputStream.write(mBytes.array(), 0, position);
|
||||||
|
mBytes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException {
|
||||||
|
//Log.i("PackageManager", "flush mPos=" + mPos);
|
||||||
|
if (mPos > 0) {
|
||||||
|
if (mOutputStream != null) {
|
||||||
|
CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos);
|
||||||
|
CoderResult result = mCharset.encode(charBuffer, mBytes, true);
|
||||||
|
while (true) {
|
||||||
|
if (result.isError()) {
|
||||||
|
throw new IOException(result.toString());
|
||||||
|
} else if (result.isOverflow()) {
|
||||||
|
flushBytes();
|
||||||
|
result = mCharset.encode(charBuffer, mBytes, true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flushBytes();
|
||||||
|
mOutputStream.flush();
|
||||||
|
} else {
|
||||||
|
mWriter.write(mText, 0, mPos);
|
||||||
|
mWriter.flush();
|
||||||
|
}
|
||||||
|
mPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDepth() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getFeature(String name) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix(String namespace, boolean generatePrefix)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getProperty(String name) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ignorableWhitespace(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processingInstruction(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeature(String name, boolean state) throws IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
if (name.equals("http://xmlpull.org/v1/doc/features.html#indent-output")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutput(OutputStream os, String encoding) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
if (os == null)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
if (true) {
|
||||||
|
try {
|
||||||
|
mCharset = Charset.forName(encoding).newEncoder();
|
||||||
|
} catch (IllegalCharsetNameException e) {
|
||||||
|
throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
|
||||||
|
encoding).initCause(e));
|
||||||
|
} catch (UnsupportedCharsetException e) {
|
||||||
|
throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
|
||||||
|
encoding).initCause(e));
|
||||||
|
}
|
||||||
|
mOutputStream = os;
|
||||||
|
} else {
|
||||||
|
setOutput(
|
||||||
|
encoding == null
|
||||||
|
? new OutputStreamWriter(os)
|
||||||
|
: new OutputStreamWriter(os, encoding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutput(Writer writer) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
mWriter = writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String prefix, String namespace) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperty(String name, Object value) throws IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startDocument(String encoding, Boolean standalone) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
append("<?xml version='1.0' encoding='utf-8' standalone='"
|
||||||
|
+ (standalone ? "yes" : "no") + "' ?>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlSerializer startTag(String namespace, String name) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
if (mInTag) {
|
||||||
|
append(">\n");
|
||||||
|
}
|
||||||
|
append('<');
|
||||||
|
if (namespace != null) {
|
||||||
|
append(namespace);
|
||||||
|
append(':');
|
||||||
|
}
|
||||||
|
append(name);
|
||||||
|
mInTag = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlSerializer text(char[] buf, int start, int len) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException {
|
||||||
|
if (mInTag) {
|
||||||
|
append(">");
|
||||||
|
mInTag = false;
|
||||||
|
}
|
||||||
|
escapeAndAppendString(buf, start, len);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlSerializer text(String text) throws IOException, IllegalArgumentException,
|
||||||
|
IllegalStateException {
|
||||||
|
if (mInTag) {
|
||||||
|
append(">");
|
||||||
|
mInTag = false;
|
||||||
|
}
|
||||||
|
escapeAndAppendString(text);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
224
common/java/com/android/common/NetworkConnectivityListener.java
Normal file
224
common/java/com/android/common/NetworkConnectivityListener.java
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.common;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper for a broadcast receiver that provides network connectivity
|
||||||
|
* state information, independent of network type (mobile, Wi-Fi, etc.).
|
||||||
|
* @deprecated Code tempted to use this class should simply listen for connectivity intents
|
||||||
|
* (or poll ConnectivityManager) directly.
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public class NetworkConnectivityListener {
|
||||||
|
private static final String TAG = "NetworkConnectivityListener";
|
||||||
|
private static final boolean DBG = false;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private HashMap<Handler, Integer> mHandlers = new HashMap<Handler, Integer>();
|
||||||
|
private State mState;
|
||||||
|
private boolean mListening;
|
||||||
|
private String mReason;
|
||||||
|
private boolean mIsFailover;
|
||||||
|
|
||||||
|
/** Network connectivity information */
|
||||||
|
private NetworkInfo mNetworkInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case of a Disconnect, the connectivity manager may have
|
||||||
|
* already established, or may be attempting to establish, connectivity
|
||||||
|
* with another network. If so, {@code mOtherNetworkInfo} will be non-null.
|
||||||
|
*/
|
||||||
|
private NetworkInfo mOtherNetworkInfo;
|
||||||
|
|
||||||
|
private ConnectivityBroadcastReceiver mReceiver;
|
||||||
|
|
||||||
|
private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
|
||||||
|
if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
|
||||||
|
mListening == false) {
|
||||||
|
Log.w(TAG, "onReceived() called with " + mState.toString() + " and " + intent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean noConnectivity =
|
||||||
|
intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
|
||||||
|
|
||||||
|
if (noConnectivity) {
|
||||||
|
mState = State.NOT_CONNECTED;
|
||||||
|
} else {
|
||||||
|
mState = State.CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
mNetworkInfo = (NetworkInfo)
|
||||||
|
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
|
||||||
|
mOtherNetworkInfo = (NetworkInfo)
|
||||||
|
intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
|
||||||
|
|
||||||
|
mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
|
||||||
|
mIsFailover =
|
||||||
|
intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
|
||||||
|
|
||||||
|
if (DBG) {
|
||||||
|
Log.d(TAG, "onReceive(): mNetworkInfo=" + mNetworkInfo + " mOtherNetworkInfo = "
|
||||||
|
+ (mOtherNetworkInfo == null ? "[none]" : mOtherNetworkInfo +
|
||||||
|
" noConn=" + noConnectivity) + " mState=" + mState.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifiy any handlers.
|
||||||
|
Iterator<Handler> it = mHandlers.keySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Handler target = it.next();
|
||||||
|
Message message = Message.obtain(target, mHandlers.get(target));
|
||||||
|
target.sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum State {
|
||||||
|
UNKNOWN,
|
||||||
|
|
||||||
|
/** This state is returned if there is connectivity to any network **/
|
||||||
|
CONNECTED,
|
||||||
|
/**
|
||||||
|
* This state is returned if there is no connectivity to any network. This is set
|
||||||
|
* to true under two circumstances:
|
||||||
|
* <ul>
|
||||||
|
* <li>When connectivity is lost to one network, and there is no other available
|
||||||
|
* network to attempt to switch to.</li>
|
||||||
|
* <li>When connectivity is lost to one network, and the attempt to switch to
|
||||||
|
* another network fails.</li>
|
||||||
|
*/
|
||||||
|
NOT_CONNECTED
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new NetworkConnectivityListener.
|
||||||
|
*/
|
||||||
|
public NetworkConnectivityListener() {
|
||||||
|
mState = State.UNKNOWN;
|
||||||
|
mReceiver = new ConnectivityBroadcastReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method starts listening for network connectivity state changes.
|
||||||
|
* @param context
|
||||||
|
*/
|
||||||
|
public synchronized void startListening(Context context) {
|
||||||
|
if (!mListening) {
|
||||||
|
mContext = context;
|
||||||
|
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
|
context.registerReceiver(mReceiver, filter);
|
||||||
|
mListening = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method stops this class from listening for network changes.
|
||||||
|
*/
|
||||||
|
public synchronized void stopListening() {
|
||||||
|
if (mListening) {
|
||||||
|
mContext.unregisterReceiver(mReceiver);
|
||||||
|
mContext = null;
|
||||||
|
mNetworkInfo = null;
|
||||||
|
mOtherNetworkInfo = null;
|
||||||
|
mIsFailover = false;
|
||||||
|
mReason = null;
|
||||||
|
mListening = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This methods registers a Handler to be called back onto with the specified what code when
|
||||||
|
* the network connectivity state changes.
|
||||||
|
*
|
||||||
|
* @param target The target handler.
|
||||||
|
* @param what The what code to be used when posting a message to the handler.
|
||||||
|
*/
|
||||||
|
public void registerHandler(Handler target, int what) {
|
||||||
|
mHandlers.put(target, what);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This methods unregisters the specified Handler.
|
||||||
|
* @param target
|
||||||
|
*/
|
||||||
|
public void unregisterHandler(Handler target) {
|
||||||
|
mHandlers.remove(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the NetworkInfo associated with the most recent connectivity event.
|
||||||
|
* @return {@code NetworkInfo} for the network that had the most recent connectivity event.
|
||||||
|
*/
|
||||||
|
public NetworkInfo getNetworkInfo() {
|
||||||
|
return mNetworkInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the most recent connectivity event was a DISCONNECT, return
|
||||||
|
* any information supplied in the broadcast about an alternate
|
||||||
|
* network that might be available. If this returns a non-null
|
||||||
|
* value, then another broadcast should follow shortly indicating
|
||||||
|
* whether connection to the other network succeeded.
|
||||||
|
*
|
||||||
|
* @return NetworkInfo
|
||||||
|
*/
|
||||||
|
public NetworkInfo getOtherNetworkInfo() {
|
||||||
|
return mOtherNetworkInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the most recent event was for an attempt to switch over to
|
||||||
|
* a new network following loss of connectivity on another network.
|
||||||
|
* @return {@code true} if this was a failover attempt, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isFailover() {
|
||||||
|
return mIsFailover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An optional reason for the connectivity state change may have been supplied.
|
||||||
|
* This returns it.
|
||||||
|
* @return the reason for the state change, if available, or {@code null}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public String getReason() {
|
||||||
|
return mReason;
|
||||||
|
}
|
||||||
|
}
|
||||||
796
common/java/com/android/common/XmlUtils.java
Normal file
796
common/java/com/android/common/XmlUtils.java
Normal file
@@ -0,0 +1,796 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.common;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import android.util.Xml;
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public class XmlUtils
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void skipCurrentTag(XmlPullParser parser)
|
||||||
|
throws XmlPullParserException, IOException {
|
||||||
|
int outerDepth = parser.getDepth();
|
||||||
|
int type;
|
||||||
|
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
|
||||||
|
&& (type != XmlPullParser.END_TAG
|
||||||
|
|| parser.getDepth() > outerDepth)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int
|
||||||
|
convertValueToList(CharSequence value, String[] options, int defaultValue)
|
||||||
|
{
|
||||||
|
if (null != value) {
|
||||||
|
for (int i = 0; i < options.length; i++) {
|
||||||
|
if (value.equals(options[i]))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final boolean
|
||||||
|
convertValueToBoolean(CharSequence value, boolean defaultValue)
|
||||||
|
{
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
if (null == value)
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
if (value.equals("1")
|
||||||
|
|| value.equals("true")
|
||||||
|
|| value.equals("TRUE"))
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int
|
||||||
|
convertValueToInt(CharSequence charSeq, int defaultValue)
|
||||||
|
{
|
||||||
|
if (null == charSeq)
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
String nm = charSeq.toString();
|
||||||
|
|
||||||
|
// XXX This code is copied from Integer.decode() so we don't
|
||||||
|
// have to instantiate an Integer!
|
||||||
|
|
||||||
|
int value;
|
||||||
|
int sign = 1;
|
||||||
|
int index = 0;
|
||||||
|
int len = nm.length();
|
||||||
|
int base = 10;
|
||||||
|
|
||||||
|
if ('-' == nm.charAt(0)) {
|
||||||
|
sign = -1;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('0' == nm.charAt(index)) {
|
||||||
|
// Quick check for a zero by itself
|
||||||
|
if (index == (len - 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
char c = nm.charAt(index + 1);
|
||||||
|
|
||||||
|
if ('x' == c || 'X' == c) {
|
||||||
|
index += 2;
|
||||||
|
base = 16;
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ('#' == nm.charAt(index))
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.parseInt(nm.substring(index), base) * sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int
|
||||||
|
convertValueToUnsignedInt(String value, int defaultValue)
|
||||||
|
{
|
||||||
|
if (null == value)
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
return parseUnsignedIntAttribute(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int
|
||||||
|
parseUnsignedIntAttribute(CharSequence charSeq)
|
||||||
|
{
|
||||||
|
String value = charSeq.toString();
|
||||||
|
|
||||||
|
long bits;
|
||||||
|
int index = 0;
|
||||||
|
int len = value.length();
|
||||||
|
int base = 10;
|
||||||
|
|
||||||
|
if ('0' == value.charAt(index)) {
|
||||||
|
// Quick check for zero by itself
|
||||||
|
if (index == (len - 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
char c = value.charAt(index + 1);
|
||||||
|
|
||||||
|
if ('x' == c || 'X' == c) { // check for hex
|
||||||
|
index += 2;
|
||||||
|
base = 16;
|
||||||
|
} else { // check for octal
|
||||||
|
index++;
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
} else if ('#' == value.charAt(index)) {
|
||||||
|
index++;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) Long.parseLong(value.substring(index), base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten a Map into an output stream as XML. The map can later be
|
||||||
|
* read back with readMapXml().
|
||||||
|
*
|
||||||
|
* @param val The map to be flattened.
|
||||||
|
* @param out Where to write the XML data.
|
||||||
|
*
|
||||||
|
* @see #writeMapXml(Map, String, XmlSerializer)
|
||||||
|
* @see #writeListXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
* @see #readMapXml
|
||||||
|
*/
|
||||||
|
public static final void writeMapXml(Map val, OutputStream out)
|
||||||
|
throws XmlPullParserException, java.io.IOException {
|
||||||
|
XmlSerializer serializer = new FastXmlSerializer();
|
||||||
|
serializer.setOutput(out, "utf-8");
|
||||||
|
serializer.startDocument(null, true);
|
||||||
|
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||||
|
writeMapXml(val, null, serializer);
|
||||||
|
serializer.endDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten a List into an output stream as XML. The list can later be
|
||||||
|
* read back with readListXml().
|
||||||
|
*
|
||||||
|
* @param val The list to be flattened.
|
||||||
|
* @param out Where to write the XML data.
|
||||||
|
*
|
||||||
|
* @see #writeListXml(List, String, XmlSerializer)
|
||||||
|
* @see #writeMapXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
* @see #readListXml
|
||||||
|
*/
|
||||||
|
public static final void writeListXml(List val, OutputStream out)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = Xml.newSerializer();
|
||||||
|
serializer.setOutput(out, "utf-8");
|
||||||
|
serializer.startDocument(null, true);
|
||||||
|
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||||
|
writeListXml(val, null, serializer);
|
||||||
|
serializer.endDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten a Map into an XmlSerializer. The map can later be read back
|
||||||
|
* with readThisMapXml().
|
||||||
|
*
|
||||||
|
* @param val The map to be flattened.
|
||||||
|
* @param name Name attribute to include with this list's tag, or null for
|
||||||
|
* none.
|
||||||
|
* @param out XmlSerializer to write the map into.
|
||||||
|
*
|
||||||
|
* @see #writeMapXml(Map, OutputStream)
|
||||||
|
* @see #writeListXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
* @see #readMapXml
|
||||||
|
*/
|
||||||
|
public static final void writeMapXml(Map val, String name, XmlSerializer out)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
if (val == null) {
|
||||||
|
out.startTag(null, "null");
|
||||||
|
out.endTag(null, "null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set s = val.entrySet();
|
||||||
|
Iterator i = s.iterator();
|
||||||
|
|
||||||
|
out.startTag(null, "map");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i.hasNext()) {
|
||||||
|
Map.Entry e = (Map.Entry)i.next();
|
||||||
|
writeValueXml(e.getValue(), (String)e.getKey(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.endTag(null, "map");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten a List into an XmlSerializer. The list can later be read back
|
||||||
|
* with readThisListXml().
|
||||||
|
*
|
||||||
|
* @param val The list to be flattened.
|
||||||
|
* @param name Name attribute to include with this list's tag, or null for
|
||||||
|
* none.
|
||||||
|
* @param out XmlSerializer to write the list into.
|
||||||
|
*
|
||||||
|
* @see #writeListXml(List, OutputStream)
|
||||||
|
* @see #writeMapXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
* @see #readListXml
|
||||||
|
*/
|
||||||
|
public static final void writeListXml(List val, String name, XmlSerializer out)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
if (val == null) {
|
||||||
|
out.startTag(null, "null");
|
||||||
|
out.endTag(null, "null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.startTag(null, "list");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int N = val.size();
|
||||||
|
int i=0;
|
||||||
|
while (i < N) {
|
||||||
|
writeValueXml(val.get(i), null, out);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.endTag(null, "list");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten a byte[] into an XmlSerializer. The list can later be read back
|
||||||
|
* with readThisByteArrayXml().
|
||||||
|
*
|
||||||
|
* @param val The byte array to be flattened.
|
||||||
|
* @param name Name attribute to include with this array's tag, or null for
|
||||||
|
* none.
|
||||||
|
* @param out XmlSerializer to write the array into.
|
||||||
|
*
|
||||||
|
* @see #writeMapXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
*/
|
||||||
|
public static final void writeByteArrayXml(byte[] val, String name,
|
||||||
|
XmlSerializer out)
|
||||||
|
throws XmlPullParserException, java.io.IOException {
|
||||||
|
|
||||||
|
if (val == null) {
|
||||||
|
out.startTag(null, "null");
|
||||||
|
out.endTag(null, "null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.startTag(null, "byte-array");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
final int N = val.length;
|
||||||
|
out.attribute(null, "num", Integer.toString(N));
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(val.length*2);
|
||||||
|
for (int i=0; i<N; i++) {
|
||||||
|
int b = val[i];
|
||||||
|
int h = b>>4;
|
||||||
|
sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
|
||||||
|
h = b&0xff;
|
||||||
|
sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
|
||||||
|
}
|
||||||
|
|
||||||
|
out.text(sb.toString());
|
||||||
|
|
||||||
|
out.endTag(null, "byte-array");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten an int[] into an XmlSerializer. The list can later be read back
|
||||||
|
* with readThisIntArrayXml().
|
||||||
|
*
|
||||||
|
* @param val The int array to be flattened.
|
||||||
|
* @param name Name attribute to include with this array's tag, or null for
|
||||||
|
* none.
|
||||||
|
* @param out XmlSerializer to write the array into.
|
||||||
|
*
|
||||||
|
* @see #writeMapXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
* @see #readThisIntArrayXml
|
||||||
|
*/
|
||||||
|
public static final void writeIntArrayXml(int[] val, String name,
|
||||||
|
XmlSerializer out)
|
||||||
|
throws XmlPullParserException, java.io.IOException {
|
||||||
|
|
||||||
|
if (val == null) {
|
||||||
|
out.startTag(null, "null");
|
||||||
|
out.endTag(null, "null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.startTag(null, "int-array");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
final int N = val.length;
|
||||||
|
out.attribute(null, "num", Integer.toString(N));
|
||||||
|
|
||||||
|
for (int i=0; i<N; i++) {
|
||||||
|
out.startTag(null, "item");
|
||||||
|
out.attribute(null, "value", Integer.toString(val[i]));
|
||||||
|
out.endTag(null, "item");
|
||||||
|
}
|
||||||
|
|
||||||
|
out.endTag(null, "int-array");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten an object's value into an XmlSerializer. The value can later
|
||||||
|
* be read back with readThisValueXml().
|
||||||
|
*
|
||||||
|
* Currently supported value types are: null, String, Integer, Long,
|
||||||
|
* Float, Double Boolean, Map, List.
|
||||||
|
*
|
||||||
|
* @param v The object to be flattened.
|
||||||
|
* @param name Name attribute to include with this value's tag, or null
|
||||||
|
* for none.
|
||||||
|
* @param out XmlSerializer to write the object into.
|
||||||
|
*
|
||||||
|
* @see #writeMapXml
|
||||||
|
* @see #writeListXml
|
||||||
|
* @see #readValueXml
|
||||||
|
*/
|
||||||
|
public static final void writeValueXml(Object v, String name, XmlSerializer out)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
String typeStr;
|
||||||
|
if (v == null) {
|
||||||
|
out.startTag(null, "null");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
out.endTag(null, "null");
|
||||||
|
return;
|
||||||
|
} else if (v instanceof String) {
|
||||||
|
out.startTag(null, "string");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
out.text(v.toString());
|
||||||
|
out.endTag(null, "string");
|
||||||
|
return;
|
||||||
|
} else if (v instanceof Integer) {
|
||||||
|
typeStr = "int";
|
||||||
|
} else if (v instanceof Long) {
|
||||||
|
typeStr = "long";
|
||||||
|
} else if (v instanceof Float) {
|
||||||
|
typeStr = "float";
|
||||||
|
} else if (v instanceof Double) {
|
||||||
|
typeStr = "double";
|
||||||
|
} else if (v instanceof Boolean) {
|
||||||
|
typeStr = "boolean";
|
||||||
|
} else if (v instanceof byte[]) {
|
||||||
|
writeByteArrayXml((byte[])v, name, out);
|
||||||
|
return;
|
||||||
|
} else if (v instanceof int[]) {
|
||||||
|
writeIntArrayXml((int[])v, name, out);
|
||||||
|
return;
|
||||||
|
} else if (v instanceof Map) {
|
||||||
|
writeMapXml((Map)v, name, out);
|
||||||
|
return;
|
||||||
|
} else if (v instanceof List) {
|
||||||
|
writeListXml((List)v, name, out);
|
||||||
|
return;
|
||||||
|
} else if (v instanceof CharSequence) {
|
||||||
|
// XXX This is to allow us to at least write something if
|
||||||
|
// we encounter styled text... but it means we will drop all
|
||||||
|
// of the styling information. :(
|
||||||
|
out.startTag(null, "string");
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
out.text(v.toString());
|
||||||
|
out.endTag(null, "string");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("writeValueXml: unable to write value " + v);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.startTag(null, typeStr);
|
||||||
|
if (name != null) {
|
||||||
|
out.attribute(null, "name", name);
|
||||||
|
}
|
||||||
|
out.attribute(null, "value", v.toString());
|
||||||
|
out.endTag(null, typeStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a HashMap from an InputStream containing XML. The stream can
|
||||||
|
* previously have been written by writeMapXml().
|
||||||
|
*
|
||||||
|
* @param in The InputStream from which to read.
|
||||||
|
*
|
||||||
|
* @return HashMap The resulting map.
|
||||||
|
*
|
||||||
|
* @see #readListXml
|
||||||
|
* @see #readValueXml
|
||||||
|
* @see #readThisMapXml
|
||||||
|
* #see #writeMapXml
|
||||||
|
*/
|
||||||
|
public static final HashMap readMapXml(InputStream in)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
|
parser.setInput(in, null);
|
||||||
|
return (HashMap)readValueXml(parser, new String[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an ArrayList from an InputStream containing XML. The stream can
|
||||||
|
* previously have been written by writeListXml().
|
||||||
|
*
|
||||||
|
* @param in The InputStream from which to read.
|
||||||
|
*
|
||||||
|
* @return HashMap The resulting list.
|
||||||
|
*
|
||||||
|
* @see #readMapXml
|
||||||
|
* @see #readValueXml
|
||||||
|
* @see #readThisListXml
|
||||||
|
* @see #writeListXml
|
||||||
|
*/
|
||||||
|
public static final ArrayList readListXml(InputStream in)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
|
parser.setInput(in, null);
|
||||||
|
return (ArrayList)readValueXml(parser, new String[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a HashMap object from an XmlPullParser. The XML data could
|
||||||
|
* previously have been generated by writeMapXml(). The XmlPullParser
|
||||||
|
* must be positioned <em>after</em> the tag that begins the map.
|
||||||
|
*
|
||||||
|
* @param parser The XmlPullParser from which to read the map data.
|
||||||
|
* @param endTag Name of the tag that will end the map, usually "map".
|
||||||
|
* @param name An array of one string, used to return the name attribute
|
||||||
|
* of the map's tag.
|
||||||
|
*
|
||||||
|
* @return HashMap The newly generated map.
|
||||||
|
*
|
||||||
|
* @see #readMapXml
|
||||||
|
*/
|
||||||
|
public static final HashMap readThisMapXml(XmlPullParser parser, String endTag, String[] name)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
HashMap map = new HashMap();
|
||||||
|
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == parser.START_TAG) {
|
||||||
|
Object val = readThisValueXml(parser, name);
|
||||||
|
if (name[0] != null) {
|
||||||
|
//System.out.println("Adding to map: " + name + " -> " + val);
|
||||||
|
map.put(name[0], val);
|
||||||
|
} else {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Map value without name attribute: " + parser.getName());
|
||||||
|
}
|
||||||
|
} else if (eventType == parser.END_TAG) {
|
||||||
|
if (parser.getName().equals(endTag)) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Expected " + endTag + " end tag at: " + parser.getName());
|
||||||
|
}
|
||||||
|
eventType = parser.next();
|
||||||
|
} while (eventType != parser.END_DOCUMENT);
|
||||||
|
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Document ended before " + endTag + " end tag");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an ArrayList object from an XmlPullParser. The XML data could
|
||||||
|
* previously have been generated by writeListXml(). The XmlPullParser
|
||||||
|
* must be positioned <em>after</em> the tag that begins the list.
|
||||||
|
*
|
||||||
|
* @param parser The XmlPullParser from which to read the list data.
|
||||||
|
* @param endTag Name of the tag that will end the list, usually "list".
|
||||||
|
* @param name An array of one string, used to return the name attribute
|
||||||
|
* of the list's tag.
|
||||||
|
*
|
||||||
|
* @return HashMap The newly generated list.
|
||||||
|
*
|
||||||
|
* @see #readListXml
|
||||||
|
*/
|
||||||
|
public static final ArrayList readThisListXml(XmlPullParser parser, String endTag, String[] name)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
ArrayList list = new ArrayList();
|
||||||
|
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == parser.START_TAG) {
|
||||||
|
Object val = readThisValueXml(parser, name);
|
||||||
|
list.add(val);
|
||||||
|
//System.out.println("Adding to list: " + val);
|
||||||
|
} else if (eventType == parser.END_TAG) {
|
||||||
|
if (parser.getName().equals(endTag)) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Expected " + endTag + " end tag at: " + parser.getName());
|
||||||
|
}
|
||||||
|
eventType = parser.next();
|
||||||
|
} while (eventType != parser.END_DOCUMENT);
|
||||||
|
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Document ended before " + endTag + " end tag");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an int[] object from an XmlPullParser. The XML data could
|
||||||
|
* previously have been generated by writeIntArrayXml(). The XmlPullParser
|
||||||
|
* must be positioned <em>after</em> the tag that begins the list.
|
||||||
|
*
|
||||||
|
* @param parser The XmlPullParser from which to read the list data.
|
||||||
|
* @param endTag Name of the tag that will end the list, usually "list".
|
||||||
|
* @param name An array of one string, used to return the name attribute
|
||||||
|
* of the list's tag.
|
||||||
|
*
|
||||||
|
* @return Returns a newly generated int[].
|
||||||
|
*
|
||||||
|
* @see #readListXml
|
||||||
|
*/
|
||||||
|
public static final int[] readThisIntArrayXml(XmlPullParser parser,
|
||||||
|
String endTag, String[] name)
|
||||||
|
throws XmlPullParserException, java.io.IOException {
|
||||||
|
|
||||||
|
int num;
|
||||||
|
try {
|
||||||
|
num = Integer.parseInt(parser.getAttributeValue(null, "num"));
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Need num attribute in byte-array");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Not a number in num attribute in byte-array");
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] array = new int[num];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == parser.START_TAG) {
|
||||||
|
if (parser.getName().equals("item")) {
|
||||||
|
try {
|
||||||
|
array[i] = Integer.parseInt(
|
||||||
|
parser.getAttributeValue(null, "value"));
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Need value attribute in item");
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Not a number in value attribute in item");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Expected item tag at: " + parser.getName());
|
||||||
|
}
|
||||||
|
} else if (eventType == parser.END_TAG) {
|
||||||
|
if (parser.getName().equals(endTag)) {
|
||||||
|
return array;
|
||||||
|
} else if (parser.getName().equals("item")) {
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Expected " + endTag + " end tag at: "
|
||||||
|
+ parser.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eventType = parser.next();
|
||||||
|
} while (eventType != parser.END_DOCUMENT);
|
||||||
|
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Document ended before " + endTag + " end tag");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a flattened object from an XmlPullParser. The XML data could
|
||||||
|
* previously have been written with writeMapXml(), writeListXml(), or
|
||||||
|
* writeValueXml(). The XmlPullParser must be positioned <em>at</em> the
|
||||||
|
* tag that defines the value.
|
||||||
|
*
|
||||||
|
* @param parser The XmlPullParser from which to read the object.
|
||||||
|
* @param name An array of one string, used to return the name attribute
|
||||||
|
* of the value's tag.
|
||||||
|
*
|
||||||
|
* @return Object The newly generated value object.
|
||||||
|
*
|
||||||
|
* @see #readMapXml
|
||||||
|
* @see #readListXml
|
||||||
|
* @see #writeValueXml
|
||||||
|
*/
|
||||||
|
public static final Object readValueXml(XmlPullParser parser, String[] name)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == parser.START_TAG) {
|
||||||
|
return readThisValueXml(parser, name);
|
||||||
|
} else if (eventType == parser.END_TAG) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected end tag at: " + parser.getName());
|
||||||
|
} else if (eventType == parser.TEXT) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected text: " + parser.getText());
|
||||||
|
}
|
||||||
|
eventType = parser.next();
|
||||||
|
} while (eventType != parser.END_DOCUMENT);
|
||||||
|
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected end of document");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object readThisValueXml(XmlPullParser parser, String[] name)
|
||||||
|
throws XmlPullParserException, java.io.IOException
|
||||||
|
{
|
||||||
|
final String valueName = parser.getAttributeValue(null, "name");
|
||||||
|
final String tagName = parser.getName();
|
||||||
|
|
||||||
|
//System.out.println("Reading this value tag: " + tagName + ", name=" + valueName);
|
||||||
|
|
||||||
|
Object res;
|
||||||
|
|
||||||
|
if (tagName.equals("null")) {
|
||||||
|
res = null;
|
||||||
|
} else if (tagName.equals("string")) {
|
||||||
|
String value = "";
|
||||||
|
int eventType;
|
||||||
|
while ((eventType = parser.next()) != parser.END_DOCUMENT) {
|
||||||
|
if (eventType == parser.END_TAG) {
|
||||||
|
if (parser.getName().equals("string")) {
|
||||||
|
name[0] = valueName;
|
||||||
|
//System.out.println("Returning value for " + valueName + ": " + value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected end tag in <string>: " + parser.getName());
|
||||||
|
} else if (eventType == parser.TEXT) {
|
||||||
|
value += parser.getText();
|
||||||
|
} else if (eventType == parser.START_TAG) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected start tag in <string>: " + parser.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected end of document in <string>");
|
||||||
|
} else if (tagName.equals("int")) {
|
||||||
|
res = Integer.parseInt(parser.getAttributeValue(null, "value"));
|
||||||
|
} else if (tagName.equals("long")) {
|
||||||
|
res = Long.valueOf(parser.getAttributeValue(null, "value"));
|
||||||
|
} else if (tagName.equals("float")) {
|
||||||
|
res = new Float(parser.getAttributeValue(null, "value"));
|
||||||
|
} else if (tagName.equals("double")) {
|
||||||
|
res = new Double(parser.getAttributeValue(null, "value"));
|
||||||
|
} else if (tagName.equals("boolean")) {
|
||||||
|
res = Boolean.valueOf(parser.getAttributeValue(null, "value"));
|
||||||
|
} else if (tagName.equals("int-array")) {
|
||||||
|
parser.next();
|
||||||
|
res = readThisIntArrayXml(parser, "int-array", name);
|
||||||
|
name[0] = valueName;
|
||||||
|
//System.out.println("Returning value for " + valueName + ": " + res);
|
||||||
|
return res;
|
||||||
|
} else if (tagName.equals("map")) {
|
||||||
|
parser.next();
|
||||||
|
res = readThisMapXml(parser, "map", name);
|
||||||
|
name[0] = valueName;
|
||||||
|
//System.out.println("Returning value for " + valueName + ": " + res);
|
||||||
|
return res;
|
||||||
|
} else if (tagName.equals("list")) {
|
||||||
|
parser.next();
|
||||||
|
res = readThisListXml(parser, "list", name);
|
||||||
|
name[0] = valueName;
|
||||||
|
//System.out.println("Returning value for " + valueName + ": " + res);
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unknown tag: " + tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip through to end tag.
|
||||||
|
int eventType;
|
||||||
|
while ((eventType = parser.next()) != parser.END_DOCUMENT) {
|
||||||
|
if (eventType == parser.END_TAG) {
|
||||||
|
if (parser.getName().equals(tagName)) {
|
||||||
|
name[0] = valueName;
|
||||||
|
//System.out.println("Returning value for " + valueName + ": " + res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected end tag in <" + tagName + ">: " + parser.getName());
|
||||||
|
} else if (eventType == parser.TEXT) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected text in <" + tagName + ">: " + parser.getName());
|
||||||
|
} else if (eventType == parser.START_TAG) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected start tag in <" + tagName + ">: " + parser.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unexpected end of document in <" + tagName + ">");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
while ((type=parser.next()) != parser.START_TAG
|
||||||
|
&& type != parser.END_DOCUMENT) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != parser.START_TAG) {
|
||||||
|
throw new XmlPullParserException("No start tag found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parser.getName().equals(firstElementName)) {
|
||||||
|
throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
|
||||||
|
", expected " + firstElementName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
while ((type=parser.next()) != parser.START_TAG
|
||||||
|
&& type != parser.END_DOCUMENT) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user