×
Namespaces

Variants
Actions

Parsing UTF-8 encoded settings file

From Nokia Developer 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.
36 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.

×