/* * Copyright (C) 2007-2008 Esmertec AG. * Copyright (C) 2007-2008 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.google.android.mms.pdu; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; /** * Encoded-string-value = Text-string | Value-length Char-set Text-string */ public class EncodedStringValue implements Cloneable { private static final String TAG = "EncodedStringValue"; private static final boolean DEBUG = false; private static final boolean LOCAL_LOGV = false; /** * The Char-set value. */ private int mCharacterSet; /** * The Text-string value. */ private byte[] mData; /** * Constructor. * * @param charset the Char-set value * @param data the Text-string value * @throws NullPointerException if Text-string value is null. */ public EncodedStringValue(int charset, byte[] data) { // TODO: CharSet needs to be validated against MIBEnum. if(null == data) { throw new NullPointerException("EncodedStringValue: Text-string is null."); } mCharacterSet = charset; mData = new byte[data.length]; System.arraycopy(data, 0, mData, 0, data.length); } /** * Constructor. * * @param data the Text-string value * @throws NullPointerException if Text-string value is null. */ public EncodedStringValue(byte[] data) { this(CharacterSets.DEFAULT_CHARSET, data); } public EncodedStringValue(String data) { try { mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME); mCharacterSet = CharacterSets.DEFAULT_CHARSET; } catch (UnsupportedEncodingException e) { Log.e(TAG, "Default encoding must be supported.", e); } } /** * Get Char-set value. * * @return the value */ public int getCharacterSet() { return mCharacterSet; } /** * Set Char-set value. * * @param charset the Char-set value */ public void setCharacterSet(int charset) { // TODO: CharSet needs to be validated against MIBEnum. mCharacterSet = charset; } /** * Get Text-string value. * * @return the value */ public byte[] getTextString() { byte[] byteArray = new byte[mData.length]; System.arraycopy(mData, 0, byteArray, 0, mData.length); return byteArray; } /** * Set Text-string value. * * @param textString the Text-string value * @throws NullPointerException if Text-string value is null. */ public void setTextString(byte[] textString) { if(null == textString) { throw new NullPointerException("EncodedStringValue: Text-string is null."); } mData = new byte[textString.length]; System.arraycopy(textString, 0, mData, 0, textString.length); } /** * Convert this object to a {@link java.lang.String}. If the encoding of * the EncodedStringValue is null or unsupported, it will be * treated as iso-8859-1 encoding. * * @return The decoded String. */ public String getString() { if (CharacterSets.ANY_CHARSET == mCharacterSet) { return new String(mData); // system default encoding. } else { try { String name = CharacterSets.getMimeName(mCharacterSet); return new String(mData, name); } catch (UnsupportedEncodingException e) { if (LOCAL_LOGV) { Log.v(TAG, e.getMessage(), e); } try { return new String(mData, CharacterSets.MIMENAME_ISO_8859_1); } catch (UnsupportedEncodingException _) { return new String(mData); // system default encoding. } } } } /** * Append to Text-string. * * @param textString the textString to append * @throws NullPointerException if the text String is null * or an IOException occured. */ public void appendTextString(byte[] textString) { if(null == textString) { throw new NullPointerException("Text-string is null."); } if(null == mData) { mData = new byte[textString.length]; System.arraycopy(textString, 0, mData, 0, textString.length); } else { ByteArrayOutputStream newTextString = new ByteArrayOutputStream(); try { newTextString.write(mData); newTextString.write(textString); } catch (IOException e) { e.printStackTrace(); throw new NullPointerException( "appendTextString: failed when write a new Text-string"); } mData = newTextString.toByteArray(); } } /* * (non-Javadoc) * @see java.lang.Object#clone() */ @Override public Object clone() throws CloneNotSupportedException { super.clone(); int len = mData.length; byte[] dstBytes = new byte[len]; System.arraycopy(mData, 0, dstBytes, 0, len); try { return new EncodedStringValue(mCharacterSet, dstBytes); } catch (Exception e) { Log.e(TAG, "failed to clone an EncodedStringValue: " + this); e.printStackTrace(); throw new CloneNotSupportedException(e.getMessage()); } } /** * Split this encoded string around matches of the given pattern. * * @param pattern the delimiting pattern * @return the array of encoded strings computed by splitting this encoded * string around matches of the given pattern */ public EncodedStringValue[] split(String pattern) { String[] temp = getString().split(pattern); EncodedStringValue[] ret = new EncodedStringValue[temp.length]; for (int i = 0; i < ret.length; ++i) { try { ret[i] = new EncodedStringValue(mCharacterSet, temp[i].getBytes()); } catch (NullPointerException _) { // Can't arrive here return null; } } return ret; } /** * Extract an EncodedStringValue[] from a given String. */ public static EncodedStringValue[] extract(String src) { String[] values = src.split(";"); ArrayList list = new ArrayList(); for (int i = 0; i < values.length; i++) { if (values[i].length() > 0) { list.add(new EncodedStringValue(values[i])); } } int len = list.size(); if (len > 0) { return list.toArray(new EncodedStringValue[len]); } else { return null; } } /** * Concatenate an EncodedStringValue[] into a single String. */ public static String concat(EncodedStringValue[] addr) { StringBuilder sb = new StringBuilder(); int maxIndex = addr.length - 1; for (int i = 0; i <= maxIndex; i++) { sb.append(addr[i].getString()); if (i < maxIndex) { sb.append(";"); } } return sb.toString(); } public static EncodedStringValue copy(EncodedStringValue value) { if (value == null) { return null; } return new EncodedStringValue(value.mCharacterSet, value.mData); } public static EncodedStringValue[] encodeStrings(String[] array) { int count = array.length; if (count > 0) { EncodedStringValue[] encodedArray = new EncodedStringValue[count]; for (int i = 0; i < count; i++) { encodedArray[i] = new EncodedStringValue(array[i]); } return encodedArray; } return null; } }