Symbian
Symbian OS Library

FAQ-0276 How do I convert a Java string with special characters to an 8-bit descriptor?

[Index][spacer] [Previous] [Next]



 

Classification: Java Category: JNI
Created: 09/23/99 Modified: 07/03/2001
Number: FAQ-0276
Platform: ER5

Question:
I have a native function called from Java through the JNI mechanism which receives a java.lang.String as one of its parameters. The string contains special characters previously input through the Sysmbian OS "Insert special character" dialog (shift-ctrl-alt-C on the emulator, shift-ctrl-fn-C on an EPOC machine). How do I convert that string to an EPOC 8-bit descriptor?

Answer:
The standard "StringUTF" functions supplied by the JNI library for conversion of Java Unicode strings to native 8-bit text is valid only for ASCII characters from 0 to 127. If the full cp1252 character set (from 0 to 255) used by EPOC 8-bit descriptors must be correctly converted, then functions from the CHARCONV engine must be employed.
The strategy is to obtain a copy of the Java string data (received as a jstring) as a native Unicode string, create a temporary 16-bit descriptor from that data, then copy and convert that data into a separate 8-bit buffer descriptor. A typical implementation might look like this:

#include

/*
* Class: Example
* Method: _native
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_Example__1native(JNIEnv* aJNI, jclass, jstring aFile)
{

const jsize len = aJNI->GetStringLength(aFile);
if (len > KMaxFileName)
return KErrBadName;
const jchar* const ptr = aJNI->GetStringChars(aFile, NULL);
TPtrC16 file16(ptr, len);
TFileName file;
CCnvCharacterSetConverter::ConvertFromUnicodeToNative8BitBuild(file, file16);
aJNI->ReleaseStringChars(aFile, ptr); // don't need original string now
jint error = NativeStuff(file);
return error;
}

Notes:


    1. The GetStringChars() method returns a pointer to an array of Unicode characters. It is best to declare the pointer as const jchar* const to help forestall any attempt to modify the Java string in place.

    2. Because a jchar is an unsigned integer, no REINTERPRET_CAST is required in constructing a 16-bit descriptor from it (unlike with the 8-bit case).

    3. Use a TPtrC16 to point to the Unicode data (without modifying it). The TFileName (a TBuf) has its own buffer to which the cp1252 data is copied. The original Unicode version can immediately be released with a call to ReleaseStringChars() and the cp1252 version used and/or modified as wished.

    4. The code will have to link with charconv.lib. This can be done with the EXTRA_LIBS flag in the Makefile.

    5. To perform the reverse transcription, the ConvertToUnicodeFromNative8BitBuild() function should be used. This converts a Symbian OS cp1252 descriptor to an intermediate Unicode descriptor from which a Java string can be built with the NewString() JNI method.

    6. For further details about standard JNI methods see http://java.sun.com/products/jdk/1.2/docs/guide/jni/spec/jniTOC.doc.html

    7. While this approach works under ER5 (Series 5mx, netBook, Series7), it is well to be aware that the CHARCONV APIs it uses is superceded by new APIs from v6 of the Symbian OS.