LString Tutorial

LStrings can be used as class member variables, declared in the class declaration and instantiated in ConstructL(), in the constructor or in the constructor initialisation list.

Required background

Before beginning you must know the following:

  • TDes - Build independent modifiable descriptor.

  • TDesC - Build independent non-modifiable descriptor.

  • RBuf - This class provides a buffer that contains, accesses and manipulates TUint16 data. The buffer itself is on the heap, and is managed by the class.

LString is a convenient, general-purpose string class derived from RBuf. LString adds automatic cleanup and on-demand buffer resize facilities. Like an RBuf, an LString can be passed to any function that is prototyped to take a TDes or a TDesC reference. Again like an RBuf , an LString maintains its string data in a heap buffer.

  • Declaring an LString

    LStrings can also be used as class member variables, declared in the class declaration and instantiated in ConstructL() , in the constructor or in the constructor initialisation list.

    LString provides a variety of construction options as show in code snippet below:

            
             
            
            {
    
    _LIT(KOne, "One ");
    _LIT(KTesting, "Testing ");
    
    
    // A default constructed LString starts empty, doesn't
    // allocate any memory on the heap, and therefore the
    // following cannot leave
    LString s;
    
    // You can initialize with a MaxLength value
    LString s(KMaxFileName); // This operation may leave
    
    // You can initialize from any descriptor (or literal) and the
    // string data is copied into the LString
    LString s(KOne); // From a literal
    
    LString half(s.Left(s.Length() / 2)); // Left returns a TPtrC
    
    // On the other hand, you can initialize from a returned
    // HBufC* and the LString automatically takes ownership
    LString own(AllocateNameL(KTesting));
    
    // LStrings can be allocated on the heap if necessary
    LString* s = new(ELeave) LString;
    
    }
           
  • Managing the size of the LString manually

    Although LString supports automatic resizing, it is also possible, and sometimes necessary to manually change the length of the string. When an LString is passed to a function as a TDes or TDesC , it looses its automatic resizing capabilities and therefore care must be taken to ensure sufficient space is allocated before the call is made.

    Extra space can be allocated to the LString by calling ReserveFreeCapacityL() function and the string can be compressed to the minimum length by calling Compress() function. An example code snippet is shown below:

            
             
            
            _LIT(KOne, "One ");
    
    {
        LString s(KOne);
        s.ReserveFreeCapacityL(4);
        test(s.Length() == 4);
        test(s.MaxLength() >= 8);
        s.Compress();
        test(s.MaxLength() >= 4);    //note indefinite test
        s.Reset();
        test(s.Length() == 0);
        test(s.MaxLength() == 0);
    }
           
  • Passing an LString to a function expecting a TDes or TDesC

    LString , derived from RBuf can be passed directly to any method accepting a TDes or TDesC parameter. Be aware though that once passed as a TDes, LString loses its automatic resizing capability. Care must be taken to ensure that sufficient capacity is reserved by calling ReserveFreeCapacityL() function or SetMaxLengthL() function before passing the LString as a TDes. When passed to a function as a TDes a USER 11 panic will be raised if the string is modified and the resulting length of this descriptor is greater than its maximum length.

    An example code snippet is shown below:

            
             
            
            void GetCurrentPath(TDes& aDes)
        {
        aDes = KPath;
        }
    . . .
    {
        LString s;
        test(s.MaxLength() == 0);
        s.SetMaxLengthL(KMaxFileName);
        GetCurrentPath(s);
    }