Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Parsing UTF-8 encoded settings file

From Wiki
Jump to: navigation, search

This code snippet shows how to read simple plain text settings file stored in the UTF-8 format using Symbian C++.

Article Metadata
Tested with
Devices(s): Nokia N97
Compatibility
Platform(s): S60 3rd Edition, FP1, FP2
S60 5th Edition
S60 5th Edition
S60 3rd Edition FP2
S60 3rd Edition FP1
Article
Keywords: UTF-8,ConvertToUnicodeFromUtf8
Created: isalento (02 Jul 2009)
Last edited: hamishwillee (30 May 2013)

Settings are stored as key value pairs in the text file.

For example:

Name: Föx Mǔlder

Remember to add LIBRARY charconv.lib to your project's .mmp file.

Header file

#ifndef CUTF8FILEPARSER_H
#define CUTF8FILEPARSER_H
 
#include <e32std.h>
#include <e32base.h>
 
class CUTF8FileParser : public CBase
{
public:
//Destructor
~CUTF8FileParser();
//Two-phased constructor
static CUTF8FileParser* NewL();
static CUTF8FileParser* NewLC();
 
//aSettingsFileName UTF-8 encoded file to be parsed
int ParseSettingsFileL(const TDesC& aSettingsFileName);
 
private:
//Splits the line into a key and value
void ParseLine(const TDesC& aLine, TPtrC16& aKey, TPtrC16& aValue);
 
//Constructor for performing 1st stage construction */
CUTF8FileParser();
void ConstructL();
 
private:
RFs iFs;
};
#endif // CUTF8FILEPARSER_H

source file

#include <f32file.h>
#include <utf.h>
 
#include "UTF8FileParser.h"
 
//setting keys
_LIT(KVersion,"Version:");
_LIT(KText,"Text:");
 
_LIT8(KBOM, "\xEF\xBB\xBF"); //notepad uses bom (byte order mark) when saving as UTF-8
_LIT8(KCRLF,"\x0D\x0A"); //windows newline
_LIT8(KLF,"\x0A"); //linux newline
 
CUTF8FileParser::CUTF8FileParser() { }
 
CUTF8FileParser::~CUTF8FileParser()
{
iFs.Close();
}
 
CUTF8FileParser* CUTF8FileParser::NewLC()
{
CUTF8FileParser* self = new (ELeave) CUTF8FileParser();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
 
CUTF8FileParser* CUTF8FileParser::NewL()
{
CUTF8FileParser* self = CUTF8FileParser::NewLC();
CleanupStack::Pop(); // self;
return self;
}
 
void CUTF8FileParser::ConstructL()
{
User::LeaveIfError(iFs.Connect());
}
 
int CUTF8FileParser::ParseSettingsFileL(const TDesC& aSettingsFileName)
{
TInt size=0;
 
TInt posNewLineDelim = KErrNotFound;
 
RDebug::Print(_L("#### Parsing file %S"), &aSettingsFileName);
 
RFile file;
TInt err;
err = file.Open(iFs,aSettingsFileName, EFileRead);
 
if(err != KErrNone)
{
RDebug::Print(_L("#### Error opening descriptor file %d"), err);
User::LeaveIfError(err);
}
 
CleanupClosePushL(file);
 
file.Size(size);
HBufC8 *fileContents = HBufC8::NewLC(size);
 
TPtr8 fileContentsPtr = fileContents->Des();
file.Read(fileContentsPtr);
 
//check newline used in the file http://en.wikipedia.org/wiki/Newline
//start with windows
TPtrC8 newlineDelimeter;
newlineDelimeter.Set(KCRLF);
 
if(fileContentsPtr.Find(newlineDelimeter) == KErrNotFound) //unix file or no newlines
{
RDebug::Print(_L("#### Newline delimeter set to unix"));
newlineDelimeter.Set(KLF);
}
 
//skip BOM if present
if(fileContentsPtr.Find(KBOM) != KErrNotFound)
{
fileContentsPtr= fileContentsPtr.Right(fileContentsPtr.Length()-KBOM().Length());
RDebug::Print(_L("#### bom stripped"));
RDebug::Print(_L("#### remaining length %d"), fileContentsPtr.Length());
}
 
//Parse file line by line
while((posNewLineDelim = fileContentsPtr.Find(newlineDelimeter)) != KErrNotFound )
{
 
RDebug::Print(_L("#### position newline %d"), posNewLineDelim);
TPtrC8 line(fileContentsPtr.Mid(0,posNewLineDelim));
 
HBufC *unicode = HBufC::NewLC(line.Length());
TPtr16 p16 = unicode->Des();
 
//convert to unicode
CnvUtfConverter::ConvertToUnicodeFromUtf8( p16 , line );
 
RDebug::Print(_L("#### Line %S"), &(*unicode));
 
TPtrC16 key, value;
 
//try to find key and value from the line of text
ParseLine(*unicode, key, value);
 
if(key.Length() > 0)
{
if(key.Compare(KVersion)==0)
; // do something with the version information
 
if(key.Compare(KText)==0)
; // do something with the text
}
 
 
fileContentsPtr =fileContentsPtr.Right( fileContentsPtr.Length() - (posNewLineDelim+newlineDelimeter.Length()));
RDebug::Print(_L("#### remaining length %d"), fileContentsPtr.Length());
CleanupStack::PopAndDestroy(unicode);
}
 
CleanupStack::PopAndDestroy(2,&file); //filecontents, file
return KErrNone;
}
 
void CUTF8FileParser::ParseLine(const TDesC& aLine, TPtrC16& aKey, TPtrC16& aValue)
{
//one can easily implement comment option by skipping
//lines starting with specific character
 
TLex lexer(aLine);
 
lexer.SkipSpace(); //skip start space
 
lexer.Mark();
lexer.SkipCharacters();
 
aKey.Set(lexer.MarkedToken()); //key
 
lexer.SkipSpaceAndMark();
aValue.Set(lexer.Remainder()); //value
}
This page was last modified on 30 May 2013, at 04:35.
38 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×