* Fix some typos in Javadoc and log messages.
* Remove redundant initializer in BluetoothAdapter.readOutOfBandData()
* Use canonical "UTF-8" charset name instead of "UTF8" in
BluetoothDevice.convertPinToBytes()
Change-Id: I58cd5dc48a7ad0053d204c5f590b4b3d438d8672
764 lines
24 KiB
Java
764 lines
24 KiB
Java
/*
|
|
* 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.internal.telephony;
|
|
|
|
import android.text.TextUtils;
|
|
import android.util.SparseIntArray;
|
|
|
|
import android.util.Log;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.charset.Charset;
|
|
|
|
/**
|
|
* This class implements the character set mapping between
|
|
* the GSM SMS 7-bit alphabet specified in TS 23.038 6.2.1
|
|
* and UTF-16
|
|
*
|
|
* {@hide}
|
|
*/
|
|
public class GsmAlphabet {
|
|
static final String LOG_TAG = "GSM";
|
|
|
|
|
|
|
|
//***** Constants
|
|
|
|
/**
|
|
* This escapes extended characters, and when present indicates that the
|
|
* following character should
|
|
* be looked up in the "extended" table
|
|
*
|
|
* gsmToChar(GSM_EXTENDED_ESCAPE) returns 0xffff
|
|
*/
|
|
|
|
public static final byte GSM_EXTENDED_ESCAPE = 0x1B;
|
|
|
|
|
|
/**
|
|
* char to GSM alphabet char
|
|
* Returns ' ' in GSM alphabet if there's no possible match
|
|
* Returns GSM_EXTENDED_ESCAPE if this character is in the extended table
|
|
* In this case, you must call charToGsmExtended() for the value that
|
|
* should follow GSM_EXTENDED_ESCAPE in the GSM alphabet string
|
|
*/
|
|
public static int
|
|
charToGsm(char c) {
|
|
try {
|
|
return charToGsm(c, false);
|
|
} catch (EncodeException ex) {
|
|
// this should never happen
|
|
return sGsmSpaceChar;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* char to GSM alphabet char
|
|
* @param throwException If true, throws EncodeException on invalid char.
|
|
* If false, returns GSM alphabet ' ' char.
|
|
*
|
|
* Returns GSM_EXTENDED_ESCAPE if this character is in the extended table
|
|
* In this case, you must call charToGsmExtended() for the value that
|
|
* should follow GSM_EXTENDED_ESCAPE in the GSM alphabet string
|
|
*/
|
|
|
|
public static int
|
|
charToGsm(char c, boolean throwException) throws EncodeException {
|
|
int ret;
|
|
|
|
ret = charToGsm.get(c, -1);
|
|
|
|
if (ret == -1) {
|
|
ret = charToGsmExtended.get(c, -1);
|
|
|
|
if (ret == -1) {
|
|
if (throwException) {
|
|
throw new EncodeException(c);
|
|
} else {
|
|
return sGsmSpaceChar;
|
|
}
|
|
} else {
|
|
return GSM_EXTENDED_ESCAPE;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* char to extended GSM alphabet char
|
|
*
|
|
* Extended chars should be escaped with GSM_EXTENDED_ESCAPE
|
|
*
|
|
* Returns ' ' in GSM alphabet if there's no possible match
|
|
*
|
|
*/
|
|
public static int
|
|
charToGsmExtended(char c) {
|
|
int ret;
|
|
|
|
ret = charToGsmExtended.get(c, -1);
|
|
|
|
if (ret == -1) {
|
|
return sGsmSpaceChar;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Converts a character in the GSM alphabet into a char
|
|
*
|
|
* if GSM_EXTENDED_ESCAPE is passed, 0xffff is returned. In this case,
|
|
* the following character in the stream should be decoded with
|
|
* gsmExtendedToChar()
|
|
*
|
|
* If an unmappable value is passed (one greater than 127), ' ' is returned
|
|
*/
|
|
|
|
public static char
|
|
gsmToChar(int gsmChar) {
|
|
return (char)gsmToChar.get(gsmChar, ' ');
|
|
}
|
|
|
|
/**
|
|
* Converts a character in the extended GSM alphabet into a char
|
|
*
|
|
* if GSM_EXTENDED_ESCAPE is passed, ' ' is returned since no second
|
|
* extension page has yet been defined (see Note 1 in table 6.2.1.1 of
|
|
* TS 23.038 v7.00)
|
|
*
|
|
* If an unmappable value is passed , ' ' is returned
|
|
*/
|
|
|
|
public static char
|
|
gsmExtendedToChar(int gsmChar) {
|
|
int ret;
|
|
|
|
ret = gsmExtendedToChar.get(gsmChar, -1);
|
|
|
|
if (ret == -1) {
|
|
return ' ';
|
|
}
|
|
|
|
return (char)ret;
|
|
}
|
|
|
|
/**
|
|
* Converts a String into a byte array containing the 7-bit packed
|
|
* GSM Alphabet representation of the string. If a header is provided,
|
|
* this is included in the returned byte array and padded to a septet
|
|
* boundary.
|
|
*
|
|
* Unencodable chars are encoded as spaces
|
|
*
|
|
* Byte 0 in the returned byte array is the count of septets used,
|
|
* including the header and header padding. The returned byte array is
|
|
* the minimum size required to store the packed septets. The returned
|
|
* array cannot contain more than 255 septets.
|
|
*
|
|
* @param data The text string to encode.
|
|
* @param header Optional header (including length byte) that precedes
|
|
* the encoded data, padded to septet boundary.
|
|
* @return Byte array containing header and encoded data.
|
|
*/
|
|
public static byte[] stringToGsm7BitPackedWithHeader(String data, byte[] header)
|
|
throws EncodeException {
|
|
|
|
if (header == null || header.length == 0) {
|
|
return stringToGsm7BitPacked(data);
|
|
}
|
|
|
|
int headerBits = (header.length + 1) * 8;
|
|
int headerSeptets = (headerBits + 6) / 7;
|
|
|
|
byte[] ret = stringToGsm7BitPacked(data, headerSeptets, true);
|
|
|
|
// Paste in the header
|
|
ret[1] = (byte)header.length;
|
|
System.arraycopy(header, 0, ret, 2, header.length);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Converts a String into a byte array containing
|
|
* the 7-bit packed GSM Alphabet representation of the string.
|
|
*
|
|
* Unencodable chars are encoded as spaces
|
|
*
|
|
* Byte 0 in the returned byte array is the count of septets used
|
|
* The returned byte array is the minimum size required to store
|
|
* the packed septets. The returned array cannot contain more than 255
|
|
* septets.
|
|
*
|
|
* @param data the data string to encode
|
|
* @throws EncodeException if String is too large to encode
|
|
*/
|
|
public static byte[] stringToGsm7BitPacked(String data)
|
|
throws EncodeException {
|
|
return stringToGsm7BitPacked(data, 0, true);
|
|
}
|
|
|
|
/**
|
|
* Converts a String into a byte array containing
|
|
* the 7-bit packed GSM Alphabet representation of the string.
|
|
*
|
|
* Byte 0 in the returned byte array is the count of septets used
|
|
* The returned byte array is the minimum size required to store
|
|
* the packed septets. The returned array cannot contain more than 255
|
|
* septets.
|
|
*
|
|
* @param data the text to convert to septets
|
|
* @param startingSeptetOffset the number of padding septets to put before
|
|
* the character data at the beginning of the array
|
|
* @param throwException If true, throws EncodeException on invalid char.
|
|
* If false, replaces unencodable char with GSM alphabet space char.
|
|
*
|
|
* @throws EncodeException if String is too large to encode
|
|
*/
|
|
public static byte[] stringToGsm7BitPacked(String data, int startingSeptetOffset,
|
|
boolean throwException) throws EncodeException {
|
|
int dataLen = data.length();
|
|
int septetCount = countGsmSeptets(data, throwException) + startingSeptetOffset;
|
|
if (septetCount > 255) {
|
|
throw new EncodeException("Payload cannot exceed 255 septets");
|
|
}
|
|
int byteCount = ((septetCount * 7) + 7) / 8;
|
|
byte[] ret = new byte[byteCount + 1]; // Include space for one byte length prefix.
|
|
for (int i = 0, septets = startingSeptetOffset, bitOffset = startingSeptetOffset * 7;
|
|
i < dataLen && septets < septetCount;
|
|
i++, bitOffset += 7) {
|
|
char c = data.charAt(i);
|
|
int v = GsmAlphabet.charToGsm(c, throwException);
|
|
if (v == GSM_EXTENDED_ESCAPE) {
|
|
v = GsmAlphabet.charToGsmExtended(c); // Lookup the extended char.
|
|
packSmsChar(ret, bitOffset, GSM_EXTENDED_ESCAPE);
|
|
bitOffset += 7;
|
|
septets++;
|
|
}
|
|
packSmsChar(ret, bitOffset, v);
|
|
septets++;
|
|
}
|
|
ret[0] = (byte) (septetCount); // Validated by check above.
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Pack a 7-bit char into its appropriate place in a byte array
|
|
*
|
|
* @param bitOffset the bit offset that the septet should be packed at
|
|
* (septet index * 7)
|
|
*/
|
|
private static void
|
|
packSmsChar(byte[] packedChars, int bitOffset, int value) {
|
|
int byteOffset = bitOffset / 8;
|
|
int shift = bitOffset % 8;
|
|
|
|
packedChars[++byteOffset] |= value << shift;
|
|
|
|
if (shift > 1) {
|
|
packedChars[++byteOffset] = (byte)(value >> (8 - shift));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert a GSM alphabet 7 bit packed string (SMS string) into a
|
|
* {@link java.lang.String}.
|
|
*
|
|
* See TS 23.038 6.1.2.1 for SMS Character Packing
|
|
*
|
|
* @param pdu the raw data from the pdu
|
|
* @param offset the byte offset of
|
|
* @param lengthSeptets string length in septets, not bytes
|
|
* @return String representation or null on decoding exception
|
|
*/
|
|
public static String gsm7BitPackedToString(byte[] pdu, int offset,
|
|
int lengthSeptets) {
|
|
return gsm7BitPackedToString(pdu, offset, lengthSeptets, 0);
|
|
}
|
|
|
|
/**
|
|
* Convert a GSM alphabet 7 bit packed string (SMS string) into a
|
|
* {@link java.lang.String}.
|
|
*
|
|
* See TS 23.038 6.1.2.1 for SMS Character Packing
|
|
*
|
|
* @param pdu the raw data from the pdu
|
|
* @param offset the byte offset of
|
|
* @param lengthSeptets string length in septets, not bytes
|
|
* @param numPaddingBits the number of padding bits before the start of the
|
|
* string in the first byte
|
|
* @return String representation or null on decoding exception
|
|
*/
|
|
public static String gsm7BitPackedToString(byte[] pdu, int offset,
|
|
int lengthSeptets, int numPaddingBits) {
|
|
StringBuilder ret = new StringBuilder(lengthSeptets);
|
|
boolean prevCharWasEscape;
|
|
|
|
try {
|
|
prevCharWasEscape = false;
|
|
|
|
for (int i = 0 ; i < lengthSeptets ; i++) {
|
|
int bitOffset = (7 * i) + numPaddingBits;
|
|
|
|
int byteOffset = bitOffset / 8;
|
|
int shift = bitOffset % 8;
|
|
int gsmVal;
|
|
|
|
gsmVal = (0x7f & (pdu[offset + byteOffset] >> shift));
|
|
|
|
// if it crosses a byte boundary
|
|
if (shift > 1) {
|
|
// set msb bits to 0
|
|
gsmVal &= 0x7f >> (shift - 1);
|
|
|
|
gsmVal |= 0x7f & (pdu[offset + byteOffset + 1] << (8 - shift));
|
|
}
|
|
|
|
if (prevCharWasEscape) {
|
|
ret.append(GsmAlphabet.gsmExtendedToChar(gsmVal));
|
|
prevCharWasEscape = false;
|
|
} else if (gsmVal == GSM_EXTENDED_ESCAPE) {
|
|
prevCharWasEscape = true;
|
|
} else {
|
|
ret.append(GsmAlphabet.gsmToChar(gsmVal));
|
|
}
|
|
}
|
|
} catch (RuntimeException ex) {
|
|
Log.e(LOG_TAG, "Error GSM 7 bit packed: ", ex);
|
|
return null;
|
|
}
|
|
|
|
return ret.toString();
|
|
}
|
|
|
|
|
|
/**
|
|
* Convert a GSM alphabet string that's stored in 8-bit unpacked
|
|
* format (as it often appears in SIM records) into a String
|
|
*
|
|
* Field may be padded with trailing 0xff's. The decode stops
|
|
* at the first 0xff encountered.
|
|
*/
|
|
public static String
|
|
gsm8BitUnpackedToString(byte[] data, int offset, int length) {
|
|
return gsm8BitUnpackedToString(data, offset, length, "");
|
|
}
|
|
|
|
/**
|
|
* Convert a GSM alphabet string that's stored in 8-bit unpacked
|
|
* format (as it often appears in SIM records) into a String
|
|
*
|
|
* Field may be padded with trailing 0xff's. The decode stops
|
|
* at the first 0xff encountered.
|
|
*
|
|
* Additionally, in some country(ex. Korea), there are non-ASCII or MBCS characters.
|
|
* If a character set is given, characters in data are treat as MBCS.
|
|
*/
|
|
public static String
|
|
gsm8BitUnpackedToString(byte[] data, int offset, int length, String characterset) {
|
|
boolean isMbcs = false;
|
|
Charset charset = null;
|
|
ByteBuffer mbcsBuffer = null;
|
|
|
|
if (!TextUtils.isEmpty(characterset)
|
|
&& !characterset.equalsIgnoreCase("us-ascii")
|
|
&& Charset.isSupported(characterset)) {
|
|
isMbcs = true;
|
|
charset = Charset.forName(characterset);
|
|
mbcsBuffer = ByteBuffer.allocate(2);
|
|
}
|
|
boolean prevWasEscape;
|
|
StringBuilder ret = new StringBuilder(length);
|
|
|
|
prevWasEscape = false;
|
|
for (int i = offset ; i < offset + length ; i++) {
|
|
// Never underestimate the pain that can be caused
|
|
// by signed bytes
|
|
int c = data[i] & 0xff;
|
|
|
|
if (c == 0xff) {
|
|
break;
|
|
} else if (c == GSM_EXTENDED_ESCAPE) {
|
|
if (prevWasEscape) {
|
|
// Two escape chars in a row
|
|
// We treat this as a space
|
|
// See Note 1 in table 6.2.1.1 of TS 23.038 v7.00
|
|
ret.append(' ');
|
|
prevWasEscape = false;
|
|
} else {
|
|
prevWasEscape = true;
|
|
}
|
|
} else {
|
|
if (prevWasEscape) {
|
|
ret.append((char)gsmExtendedToChar.get(c, ' '));
|
|
} else {
|
|
if (!isMbcs || c < 0x80 || i + 1 >= offset + length) {
|
|
ret.append((char)gsmToChar.get(c, ' '));
|
|
} else {
|
|
// isMbcs must be true. So both mbcsBuffer and charset are initialized.
|
|
mbcsBuffer.clear();
|
|
mbcsBuffer.put(data, i++, 2);
|
|
mbcsBuffer.flip();
|
|
ret.append(charset.decode(mbcsBuffer).toString());
|
|
}
|
|
}
|
|
prevWasEscape = false;
|
|
}
|
|
}
|
|
|
|
return ret.toString();
|
|
}
|
|
|
|
/**
|
|
* Convert a string into an 8-bit unpacked GSM alphabet byte
|
|
* array
|
|
*/
|
|
public static byte[]
|
|
stringToGsm8BitPacked(String s) {
|
|
byte[] ret;
|
|
|
|
int septets = 0;
|
|
|
|
septets = countGsmSeptets(s);
|
|
|
|
// Enough for all the septets and the length byte prefix
|
|
ret = new byte[septets];
|
|
|
|
stringToGsm8BitUnpackedField(s, ret, 0, ret.length);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/**
|
|
* Write a String into a GSM 8-bit unpacked field of
|
|
* @param length size at @param offset in @param dest
|
|
*
|
|
* Field is padded with 0xff's, string is truncated if necessary
|
|
*/
|
|
|
|
public static void
|
|
stringToGsm8BitUnpackedField(String s, byte dest[], int offset, int length) {
|
|
int outByteIndex = offset;
|
|
|
|
// Septets are stored in byte-aligned octets
|
|
for (int i = 0, sz = s.length()
|
|
; i < sz && (outByteIndex - offset) < length
|
|
; i++
|
|
) {
|
|
char c = s.charAt(i);
|
|
|
|
int v = GsmAlphabet.charToGsm(c);
|
|
|
|
if (v == GSM_EXTENDED_ESCAPE) {
|
|
// make sure we can fit an escaped char
|
|
if (! (outByteIndex + 1 - offset < length)) {
|
|
break;
|
|
}
|
|
|
|
dest[outByteIndex++] = GSM_EXTENDED_ESCAPE;
|
|
|
|
v = GsmAlphabet.charToGsmExtended(c);
|
|
}
|
|
|
|
dest[outByteIndex++] = (byte)v;
|
|
}
|
|
|
|
// pad with 0xff's
|
|
while((outByteIndex - offset) < length) {
|
|
dest[outByteIndex++] = (byte)0xff;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the count of 7-bit GSM alphabet characters
|
|
* needed to represent this character. Counts unencodable char as 1 septet.
|
|
*/
|
|
public static int
|
|
countGsmSeptets(char c) {
|
|
try {
|
|
return countGsmSeptets(c, false);
|
|
} catch (EncodeException ex) {
|
|
// This should never happen.
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the count of 7-bit GSM alphabet characters
|
|
* needed to represent this character
|
|
* @param throwsException If true, throws EncodeException if unencodable
|
|
* char. Otherwise, counts invalid char as 1 septet
|
|
*/
|
|
public static int
|
|
countGsmSeptets(char c, boolean throwsException) throws EncodeException {
|
|
if (charToGsm.get(c, -1) != -1) {
|
|
return 1;
|
|
}
|
|
|
|
if (charToGsmExtended.get(c, -1) != -1) {
|
|
return 2;
|
|
}
|
|
|
|
if (throwsException) {
|
|
throw new EncodeException(c);
|
|
} else {
|
|
// count as a space char
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the count of 7-bit GSM alphabet characters
|
|
* needed to represent this string. Counts unencodable char as 1 septet.
|
|
*/
|
|
public static int
|
|
countGsmSeptets(CharSequence s) {
|
|
try {
|
|
return countGsmSeptets(s, false);
|
|
} catch (EncodeException ex) {
|
|
// this should never happen
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the count of 7-bit GSM alphabet characters
|
|
* needed to represent this string.
|
|
* @param throwsException If true, throws EncodeException if unencodable
|
|
* char. Otherwise, counts invalid char as 1 septet
|
|
*/
|
|
public static int
|
|
countGsmSeptets(CharSequence s, boolean throwsException) throws EncodeException {
|
|
int charIndex = 0;
|
|
int sz = s.length();
|
|
int count = 0;
|
|
|
|
while (charIndex < sz) {
|
|
count += countGsmSeptets(s.charAt(charIndex), throwsException);
|
|
charIndex++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/**
|
|
* Returns the index into <code>s</code> of the first character
|
|
* after <code>limit</code> septets have been reached, starting at
|
|
* index <code>start</code>. This is used when dividing messages
|
|
* into units within the SMS message size limit.
|
|
*
|
|
* @param s source string
|
|
* @param start index of where to start counting septets
|
|
* @param limit maximum septets to include,
|
|
* e.g. <code>MAX_USER_DATA_SEPTETS</code>
|
|
* @return index of first character that won't fit, or the length
|
|
* of the entire string if everything fits
|
|
*/
|
|
public static int
|
|
findGsmSeptetLimitIndex(String s, int start, int limit) {
|
|
int accumulator = 0;
|
|
int size = s.length();
|
|
|
|
for (int i = start; i < size; i++) {
|
|
accumulator += countGsmSeptets(s.charAt(i));
|
|
if (accumulator > limit) {
|
|
return i;
|
|
}
|
|
}
|
|
return size;
|
|
}
|
|
|
|
// Set in the static initializer
|
|
private static int sGsmSpaceChar;
|
|
|
|
private static final SparseIntArray charToGsm = new SparseIntArray();
|
|
private static final SparseIntArray gsmToChar = new SparseIntArray();
|
|
private static final SparseIntArray charToGsmExtended = new SparseIntArray();
|
|
private static final SparseIntArray gsmExtendedToChar = new SparseIntArray();
|
|
|
|
static {
|
|
int i = 0;
|
|
|
|
charToGsm.put('@', i++);
|
|
charToGsm.put('\u00a3', i++);
|
|
charToGsm.put('$', i++);
|
|
charToGsm.put('\u00a5', i++);
|
|
charToGsm.put('\u00e8', i++);
|
|
charToGsm.put('\u00e9', i++);
|
|
charToGsm.put('\u00f9', i++);
|
|
charToGsm.put('\u00ec', i++);
|
|
charToGsm.put('\u00f2', i++);
|
|
charToGsm.put('\u00c7', i++);
|
|
charToGsm.put('\n', i++);
|
|
charToGsm.put('\u00d8', i++);
|
|
charToGsm.put('\u00f8', i++);
|
|
charToGsm.put('\r', i++);
|
|
charToGsm.put('\u00c5', i++);
|
|
charToGsm.put('\u00e5', i++);
|
|
|
|
charToGsm.put('\u0394', i++);
|
|
charToGsm.put('_', i++);
|
|
charToGsm.put('\u03a6', i++);
|
|
charToGsm.put('\u0393', i++);
|
|
charToGsm.put('\u039b', i++);
|
|
charToGsm.put('\u03a9', i++);
|
|
charToGsm.put('\u03a0', i++);
|
|
charToGsm.put('\u03a8', i++);
|
|
charToGsm.put('\u03a3', i++);
|
|
charToGsm.put('\u0398', i++);
|
|
charToGsm.put('\u039e', i++);
|
|
charToGsm.put('\uffff', i++);
|
|
charToGsm.put('\u00c6', i++);
|
|
charToGsm.put('\u00e6', i++);
|
|
charToGsm.put('\u00df', i++);
|
|
charToGsm.put('\u00c9', i++);
|
|
|
|
charToGsm.put(' ', i++);
|
|
charToGsm.put('!', i++);
|
|
charToGsm.put('"', i++);
|
|
charToGsm.put('#', i++);
|
|
charToGsm.put('\u00a4', i++);
|
|
charToGsm.put('%', i++);
|
|
charToGsm.put('&', i++);
|
|
charToGsm.put('\'', i++);
|
|
charToGsm.put('(', i++);
|
|
charToGsm.put(')', i++);
|
|
charToGsm.put('*', i++);
|
|
charToGsm.put('+', i++);
|
|
charToGsm.put(',', i++);
|
|
charToGsm.put('-', i++);
|
|
charToGsm.put('.', i++);
|
|
charToGsm.put('/', i++);
|
|
|
|
charToGsm.put('0', i++);
|
|
charToGsm.put('1', i++);
|
|
charToGsm.put('2', i++);
|
|
charToGsm.put('3', i++);
|
|
charToGsm.put('4', i++);
|
|
charToGsm.put('5', i++);
|
|
charToGsm.put('6', i++);
|
|
charToGsm.put('7', i++);
|
|
charToGsm.put('8', i++);
|
|
charToGsm.put('9', i++);
|
|
charToGsm.put(':', i++);
|
|
charToGsm.put(';', i++);
|
|
charToGsm.put('<', i++);
|
|
charToGsm.put('=', i++);
|
|
charToGsm.put('>', i++);
|
|
charToGsm.put('?', i++);
|
|
|
|
charToGsm.put('\u00a1', i++);
|
|
charToGsm.put('A', i++);
|
|
charToGsm.put('B', i++);
|
|
charToGsm.put('C', i++);
|
|
charToGsm.put('D', i++);
|
|
charToGsm.put('E', i++);
|
|
charToGsm.put('F', i++);
|
|
charToGsm.put('G', i++);
|
|
charToGsm.put('H', i++);
|
|
charToGsm.put('I', i++);
|
|
charToGsm.put('J', i++);
|
|
charToGsm.put('K', i++);
|
|
charToGsm.put('L', i++);
|
|
charToGsm.put('M', i++);
|
|
charToGsm.put('N', i++);
|
|
charToGsm.put('O', i++);
|
|
|
|
charToGsm.put('P', i++);
|
|
charToGsm.put('Q', i++);
|
|
charToGsm.put('R', i++);
|
|
charToGsm.put('S', i++);
|
|
charToGsm.put('T', i++);
|
|
charToGsm.put('U', i++);
|
|
charToGsm.put('V', i++);
|
|
charToGsm.put('W', i++);
|
|
charToGsm.put('X', i++);
|
|
charToGsm.put('Y', i++);
|
|
charToGsm.put('Z', i++);
|
|
charToGsm.put('\u00c4', i++);
|
|
charToGsm.put('\u00d6', i++);
|
|
charToGsm.put('\u00d1', i++);
|
|
charToGsm.put('\u00dc', i++);
|
|
charToGsm.put('\u00a7', i++);
|
|
|
|
charToGsm.put('\u00bf', i++);
|
|
charToGsm.put('a', i++);
|
|
charToGsm.put('b', i++);
|
|
charToGsm.put('c', i++);
|
|
charToGsm.put('d', i++);
|
|
charToGsm.put('e', i++);
|
|
charToGsm.put('f', i++);
|
|
charToGsm.put('g', i++);
|
|
charToGsm.put('h', i++);
|
|
charToGsm.put('i', i++);
|
|
charToGsm.put('j', i++);
|
|
charToGsm.put('k', i++);
|
|
charToGsm.put('l', i++);
|
|
charToGsm.put('m', i++);
|
|
charToGsm.put('n', i++);
|
|
charToGsm.put('o', i++);
|
|
|
|
charToGsm.put('p', i++);
|
|
charToGsm.put('q', i++);
|
|
charToGsm.put('r', i++);
|
|
charToGsm.put('s', i++);
|
|
charToGsm.put('t', i++);
|
|
charToGsm.put('u', i++);
|
|
charToGsm.put('v', i++);
|
|
charToGsm.put('w', i++);
|
|
charToGsm.put('x', i++);
|
|
charToGsm.put('y', i++);
|
|
charToGsm.put('z', i++);
|
|
charToGsm.put('\u00e4', i++);
|
|
charToGsm.put('\u00f6', i++);
|
|
charToGsm.put('\u00f1', i++);
|
|
charToGsm.put('\u00fc', i++);
|
|
charToGsm.put('\u00e0', i++);
|
|
|
|
|
|
charToGsmExtended.put('\f', 10);
|
|
charToGsmExtended.put('^', 20);
|
|
charToGsmExtended.put('{', 40);
|
|
charToGsmExtended.put('}', 41);
|
|
charToGsmExtended.put('\\', 47);
|
|
charToGsmExtended.put('[', 60);
|
|
charToGsmExtended.put('~', 61);
|
|
charToGsmExtended.put(']', 62);
|
|
charToGsmExtended.put('|', 64);
|
|
charToGsmExtended.put('\u20ac', 101);
|
|
|
|
int size = charToGsm.size();
|
|
for (int j=0; j<size; j++) {
|
|
gsmToChar.put(charToGsm.valueAt(j), charToGsm.keyAt(j));
|
|
}
|
|
|
|
size = charToGsmExtended.size();
|
|
for (int j=0; j<size; j++) {
|
|
gsmExtendedToChar.put(charToGsmExtended.valueAt(j), charToGsmExtended.keyAt(j));
|
|
}
|
|
|
|
|
|
sGsmSpaceChar = charToGsm.get(' ');
|
|
}
|
|
|
|
|
|
}
|