GsmAlphabetpublic class GsmAlphabet extends Object 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} |
Fields Summary |
---|
private static final String | TAG | public static final byte | GSM_EXTENDED_ESCAPEThis 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 int | UDH_SEPTET_COST_LENGTHUser data header requires one octet for length. Count as one septet, because
all combinations of header elements below will have at least one free bit
when padding to the nearest septet boundary. | public static final int | UDH_SEPTET_COST_ONE_SHIFT_TABLEUsing a non-default language locking shift table OR single shift table
requires a user data header of 3 octets, or 4 septets, plus UDH length. | public static final int | UDH_SEPTET_COST_TWO_SHIFT_TABLESUsing a non-default language locking shift table AND single shift table
requires a user data header of 6 octets, or 7 septets, plus UDH length. | public static final int | UDH_SEPTET_COST_CONCATENATED_MESSAGEMulti-part messages require a user data header of 5 octets, or 6 septets,
plus UDH length. | private static final android.util.SparseIntArray[] | sCharsToGsmTablesReverse mapping from Unicode characters to indexes into language tables. | private static final android.util.SparseIntArray[] | sCharsToShiftTablesReverse mapping from Unicode characters to indexes into language shift tables. | private static int[] | sEnabledSingleShiftTablesOEM configured list of enabled national language single shift tables for encoding. | private static int[] | sEnabledLockingShiftTablesOEM configured list of enabled national language locking shift tables for encoding. | private static int | sHighestEnabledSingleShiftCodeHighest language code to include in array of single shift counters. | private static boolean | sDisableCountryEncodingCheckFlag to bypass check for country-specific overlays (for test cases only). | private static final String[] | sLanguageTablesGSM default 7 bit alphabet plus national language locking shift character tables.
Comment lines above strings indicate the lower four bits of the table position. | private static final String[] | sLanguageShiftTablesGSM default extension table plus national language single shift character tables. |
Constructors Summary |
---|
private GsmAlphabet()
|
Methods Summary |
---|
public static int | charToGsm(char c)Converts a char to a GSM 7 bit table index.
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.
try {
return charToGsm(c, false);
} catch (EncodeException ex) {
// this should never happen
return sCharsToGsmTables[0].get(' ", ' ");
}
| public static int | charToGsm(char c, boolean throwException)Converts a char to a GSM 7 bit table index.
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.
int ret;
ret = sCharsToGsmTables[0].get(c, -1);
if (ret == -1) {
ret = sCharsToShiftTables[0].get(c, -1);
if (ret == -1) {
if (throwException) {
throw new EncodeException(c);
} else {
return sCharsToGsmTables[0].get(' ", ' ");
}
} else {
return GSM_EXTENDED_ESCAPE;
}
}
return ret;
| public static int | charToGsmExtended(char c)Converts a char to an extended GSM 7 bit table index.
Extended chars should be escaped with GSM_EXTENDED_ESCAPE.
Returns ' ' in GSM alphabet if there's no possible match.
int ret;
ret = sCharsToShiftTables[0].get(c, -1);
if (ret == -1) {
return sCharsToGsmTables[0].get(' ", ' ");
}
return ret;
| public static int | countGsmSeptets(char c)Returns the count of 7-bit GSM alphabet characters
needed to represent this character. Counts unencodable char as 1 septet.
try {
return countGsmSeptets(c, false);
} catch (EncodeException ex) {
// This should never happen.
return 0;
}
| public static int | countGsmSeptets(char c, boolean throwsException)Returns the count of 7-bit GSM alphabet characters
needed to represent this character using the default 7 bit GSM alphabet.
if (sCharsToGsmTables[0].get(c, -1) != -1) {
return 1;
}
if (sCharsToShiftTables[0].get(c, -1) != -1) {
return 2;
}
if (throwsException) {
throw new EncodeException(c);
} else {
// count as a space char
return 1;
}
| public static com.android.internal.telephony.GsmAlphabet$TextEncodingDetails | countGsmSeptets(java.lang.CharSequence s, boolean use7bitOnly)Returns the count of 7-bit GSM alphabet characters
needed to represent this string, and the language table and
language shift table used to achieve this result.
For multi-part text messages, each message part may use its
own language table encoding as specified in the message header
for that message. However, this method will only return the
optimal encoding for the message as a whole. When the individual
pieces are encoded, a more optimal encoding may be chosen for each
piece of the message, but the message will be split into pieces
based on the encoding chosen for the message as a whole.
// Load enabled language tables from config.xml, including any MCC overlays
if (!sDisableCountryEncodingCheck) {
enableCountrySpecificEncodings();
}
// fast path for common case where no national language shift tables are enabled
if (sEnabledSingleShiftTables.length + sEnabledLockingShiftTables.length == 0) {
TextEncodingDetails ted = new TextEncodingDetails();
int septets = GsmAlphabet.countGsmSeptetsUsingTables(s, use7bitOnly, 0, 0);
if (septets == -1) {
return null;
}
ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
ted.codeUnitCount = septets;
if (septets > SmsConstants.MAX_USER_DATA_SEPTETS) {
ted.msgCount = (septets + (SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER - 1)) /
SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER;
ted.codeUnitsRemaining = (ted.msgCount *
SmsConstants.MAX_USER_DATA_SEPTETS_WITH_HEADER) - septets;
} else {
ted.msgCount = 1;
ted.codeUnitsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - septets;
}
ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
return ted;
}
int maxSingleShiftCode = sHighestEnabledSingleShiftCode;
List<LanguagePairCount> lpcList = new ArrayList<LanguagePairCount>(
sEnabledLockingShiftTables.length + 1);
// Always add default GSM 7-bit alphabet table
lpcList.add(new LanguagePairCount(0));
for (int i : sEnabledLockingShiftTables) {
// Avoid adding default table twice in case 0 is in the list of allowed tables
if (i != 0 && !sLanguageTables[i].isEmpty()) {
lpcList.add(new LanguagePairCount(i));
}
}
int sz = s.length();
// calculate septet count for each valid table / shift table pair
for (int i = 0; i < sz && !lpcList.isEmpty(); i++) {
char c = s.charAt(i);
if (c == GSM_EXTENDED_ESCAPE) {
Rlog.w(TAG, "countGsmSeptets() string contains Escape character, ignoring!");
continue;
}
// iterate through enabled locking shift tables
for (LanguagePairCount lpc : lpcList) {
int tableIndex = sCharsToGsmTables[lpc.languageCode].get(c, -1);
if (tableIndex == -1) {
// iterate through single shift tables for this locking table
for (int table = 0; table <= maxSingleShiftCode; table++) {
if (lpc.septetCounts[table] != -1) {
int shiftTableIndex = sCharsToShiftTables[table].get(c, -1);
if (shiftTableIndex == -1) {
if (use7bitOnly) {
// can't encode char, use space instead
lpc.septetCounts[table]++;
lpc.unencodableCounts[table]++;
} else {
// can't encode char, remove language pair from list
lpc.septetCounts[table] = -1;
}
} else {
// encode as Escape + index into shift table
lpc.septetCounts[table] += 2;
}
}
}
} else {
// encode as index into locking shift table for all pairs
for (int table = 0; table <= maxSingleShiftCode; table++) {
if (lpc.septetCounts[table] != -1) {
lpc.septetCounts[table]++;
}
}
}
}
}
// find the least cost encoding (lowest message count and most code units remaining)
TextEncodingDetails ted = new TextEncodingDetails();
ted.msgCount = Integer.MAX_VALUE;
ted.codeUnitSize = SmsConstants.ENCODING_7BIT;
int minUnencodableCount = Integer.MAX_VALUE;
for (LanguagePairCount lpc : lpcList) {
for (int shiftTable = 0; shiftTable <= maxSingleShiftCode; shiftTable++) {
int septets = lpc.septetCounts[shiftTable];
if (septets == -1) {
continue;
}
int udhLength;
if (lpc.languageCode != 0 && shiftTable != 0) {
udhLength = UDH_SEPTET_COST_LENGTH + UDH_SEPTET_COST_TWO_SHIFT_TABLES;
} else if (lpc.languageCode != 0 || shiftTable != 0) {
udhLength = UDH_SEPTET_COST_LENGTH + UDH_SEPTET_COST_ONE_SHIFT_TABLE;
} else {
udhLength = 0;
}
int msgCount;
int septetsRemaining;
if (septets + udhLength > SmsConstants.MAX_USER_DATA_SEPTETS) {
if (udhLength == 0) {
udhLength = UDH_SEPTET_COST_LENGTH;
}
udhLength += UDH_SEPTET_COST_CONCATENATED_MESSAGE;
int septetsPerMessage = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength;
msgCount = (septets + septetsPerMessage - 1) / septetsPerMessage;
septetsRemaining = (msgCount * septetsPerMessage) - septets;
} else {
msgCount = 1;
septetsRemaining = SmsConstants.MAX_USER_DATA_SEPTETS - udhLength - septets;
}
// for 7-bit only mode, use language pair with the least unencodable chars
int unencodableCount = lpc.unencodableCounts[shiftTable];
if (use7bitOnly && unencodableCount > minUnencodableCount) {
continue;
}
if ((use7bitOnly && unencodableCount < minUnencodableCount)
|| msgCount < ted.msgCount || (msgCount == ted.msgCount
&& septetsRemaining > ted.codeUnitsRemaining)) {
minUnencodableCount = unencodableCount;
ted.msgCount = msgCount;
ted.codeUnitCount = septets;
ted.codeUnitsRemaining = septetsRemaining;
ted.languageTable = lpc.languageCode;
ted.languageShiftTable = shiftTable;
}
}
}
if (ted.msgCount == Integer.MAX_VALUE) {
return null;
}
return ted;
| public static int | countGsmSeptetsUsingTables(java.lang.CharSequence s, boolean use7bitOnly, int languageTable, int languageShiftTable)Returns the count of 7-bit GSM alphabet characters needed
to represent this string, using the specified 7-bit language table
and extension table (0 for GSM default tables).
int count = 0;
int sz = s.length();
SparseIntArray charToLanguageTable = sCharsToGsmTables[languageTable];
SparseIntArray charToShiftTable = sCharsToShiftTables[languageShiftTable];
for (int i = 0; i < sz; i++) {
char c = s.charAt(i);
if (c == GSM_EXTENDED_ESCAPE) {
Rlog.w(TAG, "countGsmSeptets() string contains Escape character, skipping.");
continue;
}
if (charToLanguageTable.get(c, -1) != -1) {
count++;
} else if (charToShiftTable.get(c, -1) != -1) {
count += 2; // escape + shift table index
} else if (use7bitOnly) {
count++; // encode as space
} else {
return -1; // caller must check for this case
}
}
return count;
| private static void | enableCountrySpecificEncodings()Enable country-specific language tables from MCC-specific overlays.
Resources r = Resources.getSystem();
// See comments in frameworks/base/core/res/res/values/config.xml for allowed values
sEnabledSingleShiftTables = r.getIntArray(R.array.config_sms_enabled_single_shift_tables);
sEnabledLockingShiftTables = r.getIntArray(R.array.config_sms_enabled_locking_shift_tables);
if (sEnabledSingleShiftTables.length > 0) {
sHighestEnabledSingleShiftCode =
sEnabledSingleShiftTables[sEnabledSingleShiftTables.length-1];
} else {
sHighestEnabledSingleShiftCode = 0;
}
| public static int | findGsmSeptetLimitIndex(java.lang.String s, int start, int limit, int langTable, int langShiftTable)Returns the index into s of the first character
after limit septets have been reached, starting at
index start . This is used when dividing messages
into units within the SMS message size limit.
int accumulator = 0;
int size = s.length();
SparseIntArray charToLangTable = sCharsToGsmTables[langTable];
SparseIntArray charToLangShiftTable = sCharsToShiftTables[langShiftTable];
for (int i = start; i < size; i++) {
int encodedSeptet = charToLangTable.get(s.charAt(i), -1);
if (encodedSeptet == -1) {
encodedSeptet = charToLangShiftTable.get(s.charAt(i), -1);
if (encodedSeptet == -1) {
// char not found, assume we're replacing with space
accumulator++;
} else {
accumulator += 2; // escape character + shift table index
}
} else {
accumulator++;
}
if (accumulator > limit) {
return i;
}
}
return size;
| static synchronized int[] | getEnabledLockingShiftTables()Return the array of enabled national language locking shift tables for SMS
encoding. This is used for unit testing. The returned array is not a copy, so
the caller should be careful not to modify it.
return sEnabledLockingShiftTables;
| static synchronized int[] | getEnabledSingleShiftTables()Return the array of enabled national language single shift tables for SMS
encoding. This is used for unit testing. The returned array is not a copy, so
the caller should be careful not to modify it.
return sEnabledSingleShiftTables;
| public static java.lang.String | gsm7BitPackedToString(byte[] pdu, int offset, int lengthSeptets)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
return gsm7BitPackedToString(pdu, offset, lengthSeptets, 0, 0, 0);
| public static java.lang.String | gsm7BitPackedToString(byte[] pdu, int offset, int lengthSeptets, int numPaddingBits, int languageTable, int shiftTable)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
StringBuilder ret = new StringBuilder(lengthSeptets);
if (languageTable < 0 || languageTable > sLanguageTables.length) {
Rlog.w(TAG, "unknown language table " + languageTable + ", using default");
languageTable = 0;
}
if (shiftTable < 0 || shiftTable > sLanguageShiftTables.length) {
Rlog.w(TAG, "unknown single shift table " + shiftTable + ", using default");
shiftTable = 0;
}
try {
boolean prevCharWasEscape = false;
String languageTableToChar = sLanguageTables[languageTable];
String shiftTableToChar = sLanguageShiftTables[shiftTable];
if (languageTableToChar.isEmpty()) {
Rlog.w(TAG, "no language table for code " + languageTable + ", using default");
languageTableToChar = sLanguageTables[0];
}
if (shiftTableToChar.isEmpty()) {
Rlog.w(TAG, "no single shift table for code " + shiftTable + ", using default");
shiftTableToChar = sLanguageShiftTables[0];
}
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) {
if (gsmVal == GSM_EXTENDED_ESCAPE) {
ret.append(' "); // display ' ' for reserved double escape sequence
} else {
char c = shiftTableToChar.charAt(gsmVal);
if (c == ' ") {
ret.append(languageTableToChar.charAt(gsmVal));
} else {
ret.append(c);
}
}
prevCharWasEscape = false;
} else if (gsmVal == GSM_EXTENDED_ESCAPE) {
prevCharWasEscape = true;
} else {
ret.append(languageTableToChar.charAt(gsmVal));
}
}
} catch (RuntimeException ex) {
Rlog.e(TAG, "Error GSM 7 bit packed: ", ex);
return null;
}
return ret.toString();
| public static java.lang.String | gsm8BitUnpackedToString(byte[] data, int offset, int 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.
return gsm8BitUnpackedToString(data, offset, length, "");
| public static java.lang.String | gsm8BitUnpackedToString(byte[] data, int offset, int length, java.lang.String characterset)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.
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);
}
// Always use GSM 7 bit default alphabet table for this method
String languageTableToChar = sLanguageTables[0];
String shiftTableToChar = sLanguageShiftTables[0];
StringBuilder ret = new StringBuilder(length);
boolean 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) {
char shiftChar =
c < shiftTableToChar.length() ? shiftTableToChar.charAt(c) : ' ";
if (shiftChar == ' ") {
// display character from main table if not present in shift table
if (c < languageTableToChar.length()) {
ret.append(languageTableToChar.charAt(c));
} else {
ret.append(' ");
}
} else {
ret.append(shiftChar);
}
} else {
if (!isMbcs || c < 0x80 || i + 1 >= offset + length) {
if (c < languageTableToChar.length()) {
ret.append(languageTableToChar.charAt(c));
} else {
ret.append(' ");
}
} 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();
| public static char | gsmExtendedToChar(int 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, the character from the GSM 7 bit
default table will be used (table 6.2.1.1 of TS 23.038).
if (gsmChar == GSM_EXTENDED_ESCAPE) {
return ' ";
} else if (gsmChar >= 0 && gsmChar < 128) {
char c = sLanguageShiftTables[0].charAt(gsmChar);
if (c == ' ") {
return sLanguageTables[0].charAt(gsmChar);
} else {
return c;
}
} else {
return ' "; // out of range
}
| public static char | gsmToChar(int gsmChar)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.
if (gsmChar >= 0 && gsmChar < 128) {
return sLanguageTables[0].charAt(gsmChar);
} else {
return ' ";
}
| public static boolean | isGsmSeptets(char c)
if (sCharsToGsmTables[0].get(c, -1) != -1) {
return true;
}
if (sCharsToShiftTables[0].get(c, -1) != -1) {
return true;
}
return false;
| private static void | packSmsChar(byte[] packedChars, int bitOffset, int value)Pack a 7-bit char into its appropriate place in a byte array
int byteOffset = bitOffset / 8;
int shift = bitOffset % 8;
packedChars[++byteOffset] |= value << shift;
if (shift > 1) {
packedChars[++byteOffset] = (byte)(value >> (8 - shift));
}
| static synchronized void | setEnabledLockingShiftTables(int[] tables)Modify the array of enabled national language locking shift tables for SMS
encoding. This is used for unit testing, but could also be used to
modify the enabled encodings based on the active MCC/MNC, for example.
sEnabledLockingShiftTables = tables;
sDisableCountryEncodingCheck = true;
| static synchronized void | setEnabledSingleShiftTables(int[] tables)Modify the array of enabled national language single shift tables for SMS
encoding. This is used for unit testing, but could also be used to
modify the enabled encodings based on the active MCC/MNC, for example.
sEnabledSingleShiftTables = tables;
sDisableCountryEncodingCheck = true;
if (tables.length > 0) {
sHighestEnabledSingleShiftCode = tables[tables.length - 1];
} else {
sHighestEnabledSingleShiftCode = 0;
}
| public static byte[] | stringToGsm7BitPacked(java.lang.String data, int languageTable, int languageShiftTable)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.
return stringToGsm7BitPacked(data, 0, true, languageTable, languageShiftTable);
| public static byte[] | stringToGsm7BitPacked(java.lang.String data, int startingSeptetOffset, boolean throwException, int languageTable, int languageShiftTable)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.
int dataLen = data.length();
int septetCount = countGsmSeptetsUsingTables(data, !throwException,
languageTable, languageShiftTable);
if (septetCount == -1) {
throw new EncodeException("countGsmSeptetsUsingTables(): unencodable char");
}
septetCount += 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.
SparseIntArray charToLanguageTable = sCharsToGsmTables[languageTable];
SparseIntArray charToShiftTable = sCharsToShiftTables[languageShiftTable];
for (int i = 0, septets = startingSeptetOffset, bitOffset = startingSeptetOffset * 7;
i < dataLen && septets < septetCount;
i++, bitOffset += 7) {
char c = data.charAt(i);
int v = charToLanguageTable.get(c, -1);
if (v == -1) {
v = charToShiftTable.get(c, -1); // Lookup the extended char.
if (v == -1) {
if (throwException) {
throw new EncodeException("stringToGsm7BitPacked(): unencodable char");
} else {
v = charToLanguageTable.get(' ", ' "); // should return ASCII space
}
} else {
packSmsChar(ret, bitOffset, GSM_EXTENDED_ESCAPE);
bitOffset += 7;
septets++;
}
}
packSmsChar(ret, bitOffset, v);
septets++;
}
ret[0] = (byte) (septetCount); // Validated by check above.
return ret;
| public static byte[] | stringToGsm7BitPacked(java.lang.String data)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.
return stringToGsm7BitPacked(data, 0, true, 0, 0);
| public static byte[] | stringToGsm7BitPackedWithHeader(java.lang.String data, byte[] header)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. This method is used by OEM code.
return stringToGsm7BitPackedWithHeader(data, header, 0, 0);
| public static byte[] | stringToGsm7BitPackedWithHeader(java.lang.String data, byte[] header, int languageTable, int languageShiftTable)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.
if (header == null || header.length == 0) {
return stringToGsm7BitPacked(data, languageTable, languageShiftTable);
}
int headerBits = (header.length + 1) * 8;
int headerSeptets = (headerBits + 6) / 7;
byte[] ret = stringToGsm7BitPacked(data, headerSeptets, true, languageTable,
languageShiftTable);
// Paste in the header
ret[1] = (byte)header.length;
System.arraycopy(header, 0, ret, 2, header.length);
return ret;
| public static byte[] | stringToGsm8BitPacked(java.lang.String s)Convert a string into an 8-bit unpacked GSM alphabet byte array.
Always uses GSM default 7-bit alphabet and extension table.
byte[] ret;
int septets = countGsmSeptetsUsingTables(s, true, 0, 0);
// Enough for all the septets and the length byte prefix
ret = new byte[septets];
stringToGsm8BitUnpackedField(s, ret, 0, ret.length);
return ret;
| public static void | stringToGsm8BitUnpackedField(java.lang.String s, byte[] dest, int offset, int length)Write a String into a GSM 8-bit unpacked field of
Field is padded with 0xff's, string is truncated if necessary
int outByteIndex = offset;
SparseIntArray charToLanguageTable = sCharsToGsmTables[0];
SparseIntArray charToShiftTable = sCharsToShiftTables[0];
// 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 = charToLanguageTable.get(c, -1);
if (v == -1) {
v = charToShiftTable.get(c, -1);
if (v == -1) {
v = charToLanguageTable.get(' ", ' "); // fall back to ASCII space
} else {
// make sure we can fit an escaped char
if (! (outByteIndex + 1 - offset < length)) {
break;
}
dest[outByteIndex++] = GSM_EXTENDED_ESCAPE;
}
}
dest[outByteIndex++] = (byte)v;
}
// pad with 0xff's
while((outByteIndex - offset) < length) {
dest[outByteIndex++] = (byte)0xff;
}
|
|