1 /* 2 * Copyright (C) 2007-2008 Esmertec AG. 3 * Copyright (C) 2007-2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.google.android.mms.pdu; 19 20 import android.util.Config; 21 import android.util.Log; 22 23 import java.io.ByteArrayOutputStream; 24 import java.io.IOException; 25 import java.io.UnsupportedEncodingException; 26 import java.util.ArrayList; 27 28 /** 29 * Encoded-string-value = Text-string | Value-length Char-set Text-string 30 */ 31 public class EncodedStringValue implements Cloneable { 32 private static final String TAG = "EncodedStringValue"; 33 private static final boolean DEBUG = false; 34 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 35 36 /** 37 * The Char-set value. 38 */ 39 private int mCharacterSet; 40 41 /** 42 * The Text-string value. 43 */ 44 private byte[] mData; 45 46 /** 47 * Constructor. 48 * 49 * @param charset the Char-set value 50 * @param data the Text-string value 51 * @throws NullPointerException if Text-string value is null. 52 */ 53 public EncodedStringValue(int charset, byte[] data) { 54 // TODO: CharSet needs to be validated against MIBEnum. 55 if(null == data) { 56 throw new NullPointerException("EncodedStringValue: Text-string is null."); 57 } 58 59 mCharacterSet = charset; 60 mData = new byte[data.length]; 61 System.arraycopy(data, 0, mData, 0, data.length); 62 } 63 64 /** 65 * Constructor. 66 * 67 * @param data the Text-string value 68 * @throws NullPointerException if Text-string value is null. 69 */ 70 public EncodedStringValue(byte[] data) { 71 this(CharacterSets.DEFAULT_CHARSET, data); 72 } 73 74 public EncodedStringValue(String data) { 75 try { 76 mData = data.getBytes(CharacterSets.DEFAULT_CHARSET_NAME); 77 mCharacterSet = CharacterSets.DEFAULT_CHARSET; 78 } catch (UnsupportedEncodingException e) { 79 Log.e(TAG, "Default encoding must be supported.", e); 80 } 81 } 82 83 /** 84 * Get Char-set value. 85 * 86 * @return the value 87 */ 88 public int getCharacterSet() { 89 return mCharacterSet; 90 } 91 92 /** 93 * Set Char-set value. 94 * 95 * @param charset the Char-set value 96 */ 97 public void setCharacterSet(int charset) { 98 // TODO: CharSet needs to be validated against MIBEnum. 99 mCharacterSet = charset; 100 } 101 102 /** 103 * Get Text-string value. 104 * 105 * @return the value 106 */ 107 public byte[] getTextString() { 108 byte[] byteArray = new byte[mData.length]; 109 110 System.arraycopy(mData, 0, byteArray, 0, mData.length); 111 return byteArray; 112 } 113 114 /** 115 * Set Text-string value. 116 * 117 * @param textString the Text-string value 118 * @throws NullPointerException if Text-string value is null. 119 */ 120 public void setTextString(byte[] textString) { 121 if(null == textString) { 122 throw new NullPointerException("EncodedStringValue: Text-string is null."); 123 } 124 125 mData = new byte[textString.length]; 126 System.arraycopy(textString, 0, mData, 0, textString.length); 127 } 128 129 /** 130 * Convert this object to a {@link java.lang.String}. If the encoding of 131 * the EncodedStringValue is null or unsupported, it will be 132 * treated as iso-8859-1 encoding. 133 * 134 * @return The decoded String. 135 */ 136 public String getString() { 137 if (CharacterSets.ANY_CHARSET == mCharacterSet) { 138 return new String(mData); // system default encoding. 139 } else { 140 try { 141 String name = CharacterSets.getMimeName(mCharacterSet); 142 return new String(mData, name); 143 } catch (UnsupportedEncodingException e) { 144 if (LOCAL_LOGV) { 145 Log.v(TAG, e.getMessage(), e); 146 } 147 try { 148 return new String(mData, CharacterSets.MIMENAME_ISO_8859_1); 149 } catch (UnsupportedEncodingException _) { 150 return new String(mData); // system default encoding. 151 } 152 } 153 } 154 } 155 156 /** 157 * Append to Text-string. 158 * 159 * @param textString the textString to append 160 * @throws NullPointerException if the text String is null 161 * or an IOException occured. 162 */ 163 public void appendTextString(byte[] textString) { 164 if(null == textString) { 165 throw new NullPointerException("Text-string is null."); 166 } 167 168 if(null == mData) { 169 mData = new byte[textString.length]; 170 System.arraycopy(textString, 0, mData, 0, textString.length); 171 } else { 172 ByteArrayOutputStream newTextString = new ByteArrayOutputStream(); 173 try { 174 newTextString.write(mData); 175 newTextString.write(textString); 176 } catch (IOException e) { 177 e.printStackTrace(); 178 throw new NullPointerException( 179 "appendTextString: failed when write a new Text-string"); 180 } 181 182 mData = newTextString.toByteArray(); 183 } 184 } 185 186 /* 187 * (non-Javadoc) 188 * @see java.lang.Object#clone() 189 */ 190 @Override 191 public Object clone() throws CloneNotSupportedException { 192 super.clone(); 193 int len = mData.length; 194 byte[] dstBytes = new byte[len]; 195 System.arraycopy(mData, 0, dstBytes, 0, len); 196 197 try { 198 return new EncodedStringValue(mCharacterSet, dstBytes); 199 } catch (Exception e) { 200 Log.e(TAG, "failed to clone an EncodedStringValue: " + this); 201 e.printStackTrace(); 202 throw new CloneNotSupportedException(e.getMessage()); 203 } 204 } 205 206 /** 207 * Split this encoded string around matches of the given pattern. 208 * 209 * @param pattern the delimiting pattern 210 * @return the array of encoded strings computed by splitting this encoded 211 * string around matches of the given pattern 212 */ 213 public EncodedStringValue[] split(String pattern) { 214 String[] temp = getString().split(pattern); 215 EncodedStringValue[] ret = new EncodedStringValue[temp.length]; 216 for (int i = 0; i < ret.length; ++i) { 217 try { 218 ret[i] = new EncodedStringValue(mCharacterSet, 219 temp[i].getBytes()); 220 } catch (NullPointerException _) { 221 // Can't arrive here 222 return null; 223 } 224 } 225 return ret; 226 } 227 228 /** 229 * Extract an EncodedStringValue[] from a given String. 230 */ 231 public static EncodedStringValue[] extract(String src) { 232 String[] values = src.split(";"); 233 234 ArrayList<EncodedStringValue> list = new ArrayList<EncodedStringValue>(); 235 for (int i = 0; i < values.length; i++) { 236 if (values[i].length() > 0) { 237 list.add(new EncodedStringValue(values[i])); 238 } 239 } 240 241 int len = list.size(); 242 if (len > 0) { 243 return list.toArray(new EncodedStringValue[len]); 244 } else { 245 return null; 246 } 247 } 248 249 /** 250 * Concatenate an EncodedStringValue[] into a single String. 251 */ 252 public static String concat(EncodedStringValue[] addr) { 253 StringBuilder sb = new StringBuilder(); 254 int maxIndex = addr.length - 1; 255 for (int i = 0; i <= maxIndex; i++) { 256 sb.append(addr[i].getString()); 257 if (i < maxIndex) { 258 sb.append(";"); 259 } 260 } 261 262 return sb.toString(); 263 } 264 265 public static EncodedStringValue copy(EncodedStringValue value) { 266 if (value == null) { 267 return null; 268 } 269 270 return new EncodedStringValue(value.mCharacterSet, value.mData); 271 } 272 273 public static EncodedStringValue[] encodeStrings(String[] array) { 274 int count = array.length; 275 if (count > 0) { 276 EncodedStringValue[] encodedArray = new EncodedStringValue[count]; 277 for (int i = 0; i < count; i++) { 278 encodedArray[i] = new EncodedStringValue(array[i]); 279 } 280 return encodedArray; 281 } 282 return null; 283 } 284 } 285