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