CPtiEngine* eng = CPtiEngine::NewL( ETrue );
CleanupStack::PushL( eng );
if ( eng->NumberOfLanguages() )
{
RArray<TInt> languages;
CleanupClosePushL( languages );
eng->GetAvailableLanguagesL( languages );
........
CleanupStack::PopAndDestroy( &languages );
}
CleanupStack::Pop (eng);
Tuesday, August 26, 2008
Monday, August 25, 2008
Why we require special "Naming convention" for symbian.
* provide common syntax for Symbian OS C++
* help reinforce Symbian OS programming idioms
* help communicate Symbian OS C++ class design for APIs
* serve as checklist for coding
* act as reference during code inspection/review
* helps produce efficient and reliable code for ROM-based devices
Fundamental data types in Symbian
* typedefs of built-in types for integer, floating-point, character, and pointer types (e32def.h), compiler-independent.
* TInt, TUint signed and unsigned 32-bit integers
* TBool, values ETrue (=1) and EFalse (=0)
* TReal, Double precision (64-bit) floating point number
* TText, Build independent general text character, In non-Unicode builds, this is mapped to TText8. In Unicode builds, this is mapped to TText16.
* TAny*, Pointer to anything (use instead of void*)
Symbian OS Classes
* Classes should have a clear role
* One class to one header file is recommended.
* Layout of header files:
#include files;
friend classes;
public,
protected,
private methods;
private,
protected,
public data.
* T-, C-, M-, R- convention to denote different class types
Types of Symbian.C++ classes
T Classes
* Behave like C++ built-in types
* No destructor => can be created on the stack and will be cleaned up correctly when the scope of function exits
* Contain member data which is:
-Built-in types
-Pointers and references with uses a relationship
* Contain all data internally
* Example:
class TInitParams {
public:
TInt iN1;
TInt iN2;
}
C Classes* CBase (defined in e32base.h) is the base class for all C classes.
* All C objects are allocated on the heap.
* When it is first allocated on the heap all member data will be zero-filled
* When no longer needed heap-based objects must be destroyed
* It has a virtual destructor (destroyed properly by deletion through a CBase pointer)
* Example:
class CExample : public CBase
{
...
}
R Classes* R classes are proxies for objects usually owned elsewhere.
* There are two main motivations for this,
- the real object is owned by a server in a different thread or address space
-implementation of real object must be hidden from the client.
* There is no common base class for all R classes.
* The initialization function has a variety of names, like Open(), Create(), Allocate(), etc.
* The termination function has a variety of names, like Close(), Destroy(), Free(), etc.
M Classes
* The only form of multiple inheritance allowed by Symbian OS is where the extra classes are Mixins.
* Mixins (M classes), define an interface but do not provide an implementation of it
* they do not have any data members.
* only pure virtual functions
* A concrete class derived from a Mixin must implement its interface.
* Example:
class MRadio
{
public:
virtual void TuneL() =0;
};
class MClock
{
public:
virtual void CurrentTimeL(TTime& aTime) =0;
};
class CClockRadio : public CBase, public MRadio, public MClock
{
public:
void TuneL();
void CurrentTimeL(TTime& aTime);
};
Class members* Data members: use prefix i -, should be private
* Arguments: prefix a-
* variables start with lower case, Functions Start With Capitals
* Setter functions: SetThing(aThing);
* Getter functions: myThing = Thing(); (return it)
GetThing(myThing); (pass it by ref.)
* Variables including arguments: & for uses-a and * for has-a
* Trailing L,C for functions that cause exceptions (L means leave function, LC means it may leave and the function keep object on cleanupstuck)
* Trailing D for functions that delete object
Thursday, August 21, 2008
_LIT(KFilename,"Z:\\resource\\versions\\model.txt");
RFile file;
User::LeaveIfError(file.Open(CCoeEnv::Static()->FsSession(),KFilename,EFileRead));
CleanupClosePushL(file);
TFileText text;
text.Set(file);
TBuf16<128> szModelName;
User::LeaveIfError(text.Read(szModelName));
CleanupStack::PopAndDestroy(&file);
CAknInformationNote* note = new (ELeave) CAknInformationNote(ETrue);
note->ExecuteLD(szModelName);
Thursday, August 14, 2008
Wednesday, August 13, 2008
Below code is just a .bat file code that automates the process of
1. creating a pkg file.
2. generating key and cert
3. generate a signed sis.
@echo off
echo #{"ErrRd"},(0xEEEEEEEE),0,0,0 >ErrRd.pkg
echo %%{"ErrRd"} >> ErrRd.pkg
echo :"ErrRd" >> ErrRd.pkg
echo [0x101F7961], 0, 0, 0, {"Series60ProductID"} >> ErrRd.pkg
echo "nul"-"c:\resource\ErrRd" >>ErrRd.pkg
makesis ErrRd.pkg
makekeys -cert -password test -dname "CN=Developer OU=MobileDev" test.key test.cert
signsis ErrRd.sis ErrRd.sisx test.cert test.key test
del test.key
del test.cert
del .rnd
del ErrRd.sis
del ErrRd.pkg
pause
How to use it.
1. Create a .bat file in c:\\
2. Copy above code to that file
3. Save File
4. double click on the .bat file.
5. Follow the on screen instructions.
6. At the end ErrRd.sisx will be generated.
7. Install this .sisx on your development device.
note: credit goes to original author "Wizard of Hungary" from forum.nokia.com
http://wiki.forum.nokia.com/index.php/Extended_panic_code
Saturday, August 09, 2008
As you may want to provide user to install you application both on phone memory (C:\) OR on memory Card (E:\) So when try to access your data files you may require to find out which drive your application is installed.
Pre-v9 SDK suppoerted devices.
TFileName fullPath(fileName);
CompleteWithAppPath(fullPath); // from aknutils.h
// fullPath now will contain <drive>:\system\apps\<application_name>
v9.x SDK suppoerted devices. TFileName appPath;
TBuf<2> appDrive;
// Returns private path of this application
// in following format: \Private\<SID of the application>\
// (does not contain drive specification).
iEikonEnv->FsSession().PrivatePath( appPath );
// Extract drive letter into appDrive
appDrive.Copy(iEikonEnv->EikAppUi()->Application()->AppFullName().Left(2));
// Insert drive letter into path
appPath.Insert(0, appDrive);
Profile information are enumerated as below.
EProfileUnknown = -1,
EProfileOffline = 5,
EProfileOffline = -2
Pre-v9 S60 devices.
TInt profileIndex = EUnknownProfile;
CSettingInfo* settingsInfo = CSettingInfo::NewL(NULL);
CleanupStack::PushL(settingsInfo);
User::LeaveIfError(settingsInfo->Get(SettingInfo::EActiveProfile, profileIndex));
CleanupStack::PopAndDestroy(settingsInfo);
// profileIndex contains the profile information
v9.x S60 devices. CRepository* repository = CRepository::NewL(KCRUidProfileEngine);
CleanupStack::PushL(repository);
User::LeaveIfError(repository->Get(KProEngActiveProfile, profileIndex));
CleanupStack::PopAndDestroy(repository);
// profileInde contains the profile information
Friday, August 08, 2008
Tip 1: Never instantiate a TDes or a TDesC
The default constructors of TDes and TDesC are declared private so the compiler won’t let you construct them directly. But there is no copy constructor declared for either class, so the compiler won’t complain if you make a copy of a valid descriptor (in fact, it will go as far as to help you, by invoking an implicitly generated copy constructor).
_LIT(KExample, "Fred");
TPtrC original(KExample); // a valid TDesC-derived descriptor
TDesC copy(original); // Uses the implicit copy constructor
Your code probably won’t crash if it has been written safely, but you will rarely have a valid reason for doing this. The code will fail to work anyway, because TDes and TDesC contain no string data, so in effect are abstract classes.
Tip 2: Check that there is sufficient space before writing to a descriptor.
An attempt to access an area outside the area allocated for descriptor data will cause a panic in both debug and release builds, because the descriptor functions use __ASSERT_ALWAYS internally to check for out-of-bounds access. A panic causes your code will stop executing immediately, whether running in an application, server or test framework. So be absolutely certain that there is space in your target descriptor, if necessary, by doing a check first by using the Length() or MaxLength() methods.
_LIT8(KImageGif, “image/gif”); // 9 characters
TBuf8<8> mimeType8; // Space for only 8 characters
mimeType8.Copy(KImageGif); // So Panic!
Tip 3: Need a small known length descriptor? Use TBuf or TBufC.
These are suitable for when you know the required length at compile time. The recommended maximum length is 256 bytes or fewer (remember that’s 128 characters, a TBuf<128>, because each character occupies 2 bytes).
Tip 4: Need a larger or unknown length descriptor? Use HBufC.
Heap-based descriptors, HBufC, are allocated on the heap at run time. They can be used as local variables or as class members. As with all heap-based objects, memory leaks must be avoided through use of the cleanup stack - for local variables - or deleted by a destructor if ownership is through a member variable.
Tip 5: Need to modify an HBufC? Call Des().
An HBufC is derived from TDesC, and inherits non-modifiable descriptor functionality. Because it is not derived from TDes, it isn’t modifiable. So to write into it, you have to create a modifiable descriptor over the data area. This is done by calling HBufC::Des() which returns a TPtr and thus gives you access to all the modification functions such as Format(), Append() and Fill():
HBufC* buffer = HBufC::NewL(4); // Read Only buffer
TPtr ptrBuffer(buffer->Des()); // Read Write buffer
_LIT(KBert, "Bert");
ptrBuffer.Copy(KBert); // The data area of robert now contains Bert
Remember that that there must be space in the HBufC for the required change because descriptors don’t resize themselves automatically. If there isn’t, it will still compile - but you’ll get a panic at runtime.
HBufC* buffer = HBufC::NewL(2); // Read Only buffer
TPtr ptrBuffer(buffer->Des()); // Read Write buffer
_LIT(KBert, "Bert");
ptrBuffer.Copy(KBert); // Panic! Not enough memory allocated to hold "Bert"
Tip 6: Need to read from an HBufC? Don't call Des().
To read from a descriptor, you only need it to be non-modifiable, a TDesC. Class HBufC derives from TDesC, so it has access to all the non-modifiable functions implemented by TDesC. All you need to do is dereference the pointer.
_LIT(KBert, "Bert");
HBufC* bert = KBert.AllocL();
TPtrC halfOfBert = bert->Left(2);
One of the most common mistakes made when using descriptors is to call Des() on an HBufC* when you only need a constant descriptor.
_LIT(KBert, "Bert");
HBufC* bert = KBert().AllocL();
TPtrC halfOfBert = bert->Des().Left(2); // Unnecessary call to Des()
Tip 7: For API design, use the descriptor base classes as parameters and return values.
In your APIs, use the descriptor base classes TDes and TDesC as parameters and return values. And remember to pass them by reference for efficiency, and never by value. Thus, descriptor parameters should be passed and returned either as const TDesC& for constant descriptors or TDes& when modifiable.
Thus, when defining functions you should always use the abstract base classes as parameters or return values. For example, class RFile defines straightforward file read and write methods as follows:
IMPORT_C TInt Write(const TDesC8& aDes);
IMPORT_C TInt Read(TDes8& aDes) const;
The descriptor to write to the file is a constant descriptor, while to read from the file into a descriptor requires the parameter to be modifiable (the maximum length of the modifiable descriptor determines how much file data can be read into it).
Tip 8: Don't confuse Size() and Length().
The base class TDesC defines both Size() and Length() methods, which are easy to confuse.
Size() returns the number of bytes the descriptor occupies.
Length() returns the number of characters the descriptor contains.
For 8-bit descriptors, where each character occupies a byte, this is the same thing. However, on all releases of Symbian OS since v5u, the native character width has been 16 bits; that is, each character occupies two bytes.
note: Size() always returns a value which is double that of Length().
Tip 9: Beware of calling MaxLength() on the TPtr returned from HBufC::Des()
There's an interesting side effect to calling Des() on an HBufC to return a modifiable descriptor.
Tip 10: Use operator>> and operator<< to internalize and externalize descriptor data. But remember that they can leave!
When externalizing data to a writable stream, or internalizing it from a readable stream, use the operators crafted for this purpose rather than 'rolling your own'.
// Write the contents of aDes to aStream
void CMyClass::ExternalizeL(RWriteStream& aStream, const TDesC& aDes) const
{
aStream << aDes;
}
// Read the contents of aStream and create an HBufC
HBufC* CMyClass::InternalizeL(RReadStream& aStream)
{// KMaxLength is defined elsewhere as the maximum length read from the stream
HBufC* heapBuf = HBufC::NewL(aStream, KMaxLength);
}
referance: http://descriptors.blogspot.com/
Tuesday, August 05, 2008
You can see capability information using petran tool provided with SDK.
you have to use > petran -dump s
exmaple:
C:\Symbian\9.1\S60_3rd_MR\Epoc32\release\GCCE\UREL>petran -dump s testUi.exe
PETRAN - PE file preprocessor V02.01 (Build 549)
Copyright (c) 1996-2005 Symbian Software Ltd.
E32ImageFile 'testUi.exe'
Secure ID: ecb33de7
Vendor ID: 00000000
Capabilities: 00000000 00010010
ReadDeviceData
WriteUserData
Monday, August 04, 2008
S60 Editions and Feature Packs
What are S60 Editions?
S60 platform release versions are named as Editions. Editions include all the main features of the release. The latest S60 release is S60 3rd Edition. S60 3rd Edition includes all the main features of the S60 2nd Edition plus some new features.
What are Feature Packs?
Feature Packs include features that are additional to Edition. Feature Packs may also include device specific features. For example, S60 2nd Edition, Feature Pack 2 introduces WCDMA technology into S60 devices.
The talk about "Feature Packs" is a bit misleading, as they are not something that you can easily upgrade to old devices, like the way you update Service Packs on Windows PCs. Instead, S60 and its Feature Packs are tightly integrated with certain Symbian releases and your hardware, to ensure the best possible user experience. If upgrading new S60 platform versions to old devices becomes possible in the future, I promise that you will hear about it.
Sunday, August 03, 2008
S60 Edition | S60 version | Symbian OS version | Phone Models |
---|---|---|---|
S60, version 0.9 | 0.9 | 6.1 |
|
S60 1st Edition | 1.2 | 6.1 |
|
S60 2nd Edition | 2.0 | 7.0s |
|
S60 2nd Edition, Feature Pack 1 | 2.1 | 7.0s |
|
S60 2nd Edition, Feature Pack 2 | 2.6 | 8.0a |
|
S60 2nd Edition, Feature Pack 3 | 2.8 | 8.1a |
|
S60 3rd Edition | 3.0 | 9.1 |
|
S60 3rd Edition, Feature Pack 1 | 3.1 | 9.2 |
|
S60 3rd Edition, Feature Pack 2 | 3.2 | 9.3 |
|
Saturday, August 02, 2008
TPtr or TPtrC are descriptors which do not own string data; they simply refer to data that exists in another descriptor. So you can use them to return a descriptor which references part of another descriptor argument, as long as its lifetime will not extend beyond that descriptor's lifetime. For example:
TPtrC LeftChar(const TDesC& aInput)
{
if (aInput.Length()>0)
return aInput.Left(1); // Returns the left-most character
else
return KNullDesC;
}
This, however, is not OK because stack-based fred will cease to exist when GetFred() returns:
TPtrC GetFred()
{
_LIT(KFred, "Fred");
TBufC<4> fred(KFred());
TPtrC fredPtr(fred);
return (fredPtr);
}
further reading http://descriptors.blogspot.com/
I want to create a new descriptor in my function. How do I return it to the caller?
You must return an HBufC* as follows:
HBufC* CreateSomeDescriptorL()
{
_LIT(KBert, "bert");
HBufC* newBert = KBert().AllocL();
return (newBert);
}
The calling function needs to know that it must take ownership of the returned heap-based descriptor and be responsible for deleting it when it has finished with it. Failure to do this is a common cause of memory leaks.
A similar function, which leaves the created descriptor on the cleanup stack for the caller, would be coded as follows:
HBufC* CreateSomeDescriptorLC()
{
_LIT(KBert, "bert");
HBufC* newBert = KBert().AllocLC();
return (newBert);
}
further reading http://descriptors.blogspot.com/
The base classes provide and implement the constant and modifiable descriptor operations regardless of the actual type of the derived descriptor. For consistency, they (basic types) should be used as arguments to functions, allowing descriptors to be passed without restricting the caller of the function to using a specific type.
For example, the calling function can call a function with anything derived from TDesC and TDes. For example an HBufC and a TBuf<8>, or a TPtr and a TBuf<3>:
void SomeFunction(const TDesC& aReadOnlyDescriptor, TDes& aReadWriteDescriptor);
further reading http://descriptors.blogspot.com/
This is a common mistake. Des() gives you a modifiable descriptor, TDes, which itself derives from TDesC, so you can use it to call any of the TDesC functions. But it‚is unnecessary.
Here‚is an example of this common mistake:
TBuf<4> stackbasedFred(heapBasedFred->Des()); // Unnecessary, just use
it must be
TBuf<4> stackBasedFred(*heapBasedFred); // More efficient
further reading http://descriptors.blogspot.com/
First you must call HBufC::Des() to get a TPtr, which is modifiable. You can then use that:
TPtr fredPtr(heapbasedFred->Des());
_LIT(KDes,"My Desc");
fredPtr.Copy(KDes);
further reading http://descriptors.blogspot.com/
There are some cases where you do need to hold 8-bit text: MIME types, or binary data, for example. To do this, you should explicitly use the 8 bit descriptors:
_LIT8(KImageGif,"image/gif");
TBufC8<15> mimeType(KImageGif);
further reading http://descriptors.blogspot.com/
If it needs to be modifiable, use a TBuf.
If it's constant, use a TBufC. You'll need to specify the size of stack space allocated for the descriptor's data.
Here‚is an example:
_LIT(KFred, ‚"My sting"); // A string literal, these will be described later
TBufC<8> constantFred(KFred);
In reality, you probably wouldn't do this for a non-modifiable descriptor, since you can use the literal, KFred directly by calling the operator() function. That is, instead of creating constantFred, you could just call KFred().
However, this approach is still useful for modifiable descriptors, for example, for logging purposes:
_LIT8(KError, "RunError: %d");
TBuf8<35> errorBuf;
errorBuf.Format(KError, aError);
further reading http://descriptors.blogspot.com/
The amount of stack space on Symbian OS is pretty limited. So you should avoid creating large stack-based descriptors when it is unnecessary to do so. Every symbian developer should be aware of the this and only use stack-based descriptors.
For example, TFileName is typedef-ed as follows:
typedef TBuf
where: const TInt KMaxFileName=0x100; // = 256 decimal
Each character in a descriptor is 2 bytes, since Symbian OS is a wide, UNICODE. So each TFileName object created on the stack occupies 512 bytes, it does not matter if it does filled with data or not.
For stack conservation, it's advisable to be aware of the amount of space the following objects consume:
* TFileName 512 bytes
* TEntry 544 bytes
* TFullName 512 bytes
* TName 256 bytes
so it is suggested that you try using little of above descriptor types, or try converting then to heap based descriptors.
further reading http://descriptors.blogspot.com/
Friday, August 01, 2008
1. What are descriptors?
Descriptors are Symbian OS strings.
2. why are they called 'descriptors' rather than strings?
They're names as 'descriptors', because they are self describing (not literally, it means you donot have to give any parameters). Each descriptor object holds the length of the string of data it represents as well as its 'type', which identifies the underlying memory layout of the data it holds.
3. Descriptors can be used to store text?
Descriptors can be used for storing text and binary data.
4. Do they store text data as ASCII or Unicode?
It can store both types. There are two types, 8-bit and 16-bit descriptors. The 8-bit variant is used to store ASCII characters and raw binary data. while 16-bit for Unicode.
5. How do I know which I have got?
Each type ends in 8-bit or 16-bit, for example TDesC8 or TDesC16. If nothing specified then default is 16-bit [Platform specific mostly symbian supports 16-bit as default now].
6. Which width/type should I use?
If you need to use 8-bit data, for example, to call a particular API method (such as the RFile::Read() or RFile::Write() functions ), for Internet email, or to manipulate ASCII data, you should use the explicitly 8-bit descriptors. If you want to store a chunk of binary data, use the 8 bit variety too.
If you need to work with 16-bit text, for example, Java strings, and want to indicate this explicitly, use the 16-bit descriptors.
Note: In general, unless you need to make the data width explicit, use the neutral descriptors. If nothing else, your code is more readable and it may even be portable if the default character width changes on a later platform.
7. Are they NULL-terminated like C strings?
No. as the name suggests they're self-describing, descriptors know the length of their internal data. This means there’s no need for the data to be NULL-terminated to mark where the data ends. It also means that binary data can be stored in the same descriptor classes as store text data.
Note: This isn’t possible with C strings because there’s no way of distinguishing the NULL terminating character from valid binary data.
8. Can I use standard C arrays to store my text and binary data, and the C string library to manipulate them, like I have always done?
Yes you can, but symbian native suggests using literals where possible.
9. Why it is recommended to use standard C arrays in native symbian programming.
Standard C arrays are unsafe, as they have no concept of how big they are. Null-terminated strings are clunky and inefficient. What’s more, if you want to write past the end of the allocated space of a standard C string, nothing is going to stop you. This leads to all kinds of mayhem, such as data corruption
10. Do descriptors automatically resize themselves if I need more memory?
No. The memory allocated for a descriptor is fixed, and specified on construction. They do not resize themselves dynamically.
Agree that would make life easier for the programmer, but it could also make them less efficient, and it would require complex code to be exception-safe.
On Symbian OS, efficiency is paramount, so the programmer must take responsibility for memory management.
11. What happens if I overrun a descriptor’s allocated space?
You will get a panic in both debug and release builds. The panic will be part of the USER category.
12. Do descriptors perform garbage collection?
No. In the same way that descriptors do not perform allocation or re-allocation, they do not perform garbage collection, because of the extra overhead that would carry on OS.
13. Is there any size limit for a descriptor?
Yes. Descriptors can be stored on the stack or heap. The normal limitations apply as for other Symbian OS variables:
* Stack descriptors should be kept small: a 256 byte limit (128 double-byte characters) is a good guide.
* Heap descriptors can be much larger, depending on the size of heap memory available on device.
Note: For Heap descriptors the layout of a descriptor object will limit the maximum size of a descriptor to 2^28 bytes (256 MB). Since each UNICODE character = 2 bytes, the maximum length of a descriptor is thus 2^27 characters.
reference: http://descriptors.blogspot.com/