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