genericopenlibs/openenvcore/backend/src/StdioRedir/Server/inidata.cpp
changeset 0 e4d67989cc36
child 29 3520f1ef6bf6
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name        : inidata.cpp
       
    15 // Part of     : stdio server
       
    16 // To read ini file
       
    17 // 
       
    18 //
       
    19 
       
    20  #include "inidata.h"
       
    21  #include <f32file.h>
       
    22  #include <e32std.h>
       
    23 
       
    24  // Default directory to look for INI file
       
    25  _LIT(KIniFileDir,"\\System\\Data\\");
       
    26 
       
    27 
       
    28  const TInt KTokenSize=256;
       
    29 
       
    30  enum TIniPanic
       
    31      {
       
    32      ESectionNameTooBig,
       
    33      EKeyNameTooBig,
       
    34      };
       
    35 
       
    36  
       
    37  ////////////////////////////////////////////////////////////////////////////////
       
    38  void Panic(TIniPanic aPanic)
       
    39      {
       
    40      _LIT(CIniData,"stdioserver");
       
    41      User::Panic(CIniData,aPanic);
       
    42      }
       
    43 
       
    44 
       
    45 
       
    46  CIniData::CIniData()
       
    47      : iPtr(NULL,0)
       
    48  /* Constructor
       
    49  */
       
    50      {
       
    51      __DECLARE_NAME(_S("CIniData"));
       
    52      }
       
    53 
       
    54 
       
    55  CIniData::~CIniData()
       
    56  /*Destructor.
       
    57 
       
    58   Frees the resources located in second-phase constructor
       
    59 
       
    60  */
       
    61      {
       
    62 
       
    63      delete (TText*)iPtr.Ptr();
       
    64      delete iToken;
       
    65      delete iName;
       
    66      }
       
    67 
       
    68 
       
    69  CIniData* CIniData::NewL(const TDesC& aName)
       
    70  /*
       
    71   Creates, and returns a pointer to CIniData object, leave on failure
       
    72 
       
    73   @return A pointer to the CiniData object
       
    74  */
       
    75      {
       
    76      CIniData* p=new(ELeave) CIniData;
       
    77      CleanupStack::PushL(p);
       
    78      p->ConstructL(aName);
       
    79      CleanupStack::Pop();
       
    80      return p;
       
    81      }
       
    82 
       
    83 
       
    84  void CIniData::ConstructL(const TDesC& aName)
       
    85  /*
       
    86   Second-phase constructor.
       
    87 
       
    88   The function attempts to allocate a buffer and Read file's contents into iPtr
       
    89 
       
    90   @param aName the name of the file which contains the ini data
       
    91 
       
    92   @leave One of the system-wide error codes
       
    93  */
       
    94      {
       
    95      // Allocate space for token
       
    96      iToken=HBufC::NewL(KTokenSize+2);   // 2 extra chars for [tokenName]
       
    97 
       
    98      // Connect to file server
       
    99      TAutoClose<RFs> fs;
       
   100      User::LeaveIfError(fs.iObj.Connect());
       
   101      fs.PushL();
       
   102 
       
   103 	 //Add system drive to KIniFileDir with path delemiter
       
   104 	 TBuf16<30> iniFilePath;
       
   105 	 iniFilePath.Append(fs.iObj.GetSystemDriveChar());
       
   106 	 iniFilePath.Append(TChar(KDriveDelimiter));
       
   107 	 iniFilePath.Append(KIniFileDir);
       
   108      // Find file, given name
       
   109      TFindFile ff(fs.iObj);
       
   110      User::LeaveIfError(ff.FindByDir(aName, iniFilePath));
       
   111      iName=ff.File().AllocL();
       
   112 
       
   113      // Open file
       
   114      TAutoClose<RFile> file;
       
   115      TInt size;
       
   116      User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileShareReadersOrWriters));
       
   117      file.PushL();
       
   118 
       
   119      // Get file size and read in
       
   120      User::LeaveIfError(file.iObj.Size(size));
       
   121      TText* data=(TText*)User::AllocL(size);
       
   122      iPtr.Set(data, size/sizeof(TText), size/sizeof(TText));
       
   123      TPtr8 dest((TUint8*)data, 0, size);
       
   124      User::LeaveIfError(file.iObj.Read(dest));
       
   125      TUint8* ptr = (TUint8*)data;
       
   126 
       
   127      //
       
   128      // This is orderred as FEFF assuming the processor is Little Endian
       
   129      // The data in the file is FFFE.        PRR 28/9/98
       
   130      //
       
   131      if(size>=(TInt)sizeof(TText) && iPtr[0]==0xFEFF)
       
   132      {
       
   133          // UNICODE Text file so lose the FFFE
       
   134          Mem::Copy(ptr, ptr+sizeof(TText), size-sizeof(TText));
       
   135          iPtr.Set(data, size/sizeof(TText)-1, size/sizeof(TText)-1);
       
   136      }
       
   137      else if(size)
       
   138      {
       
   139          // NON-UNICODE so convert to UNICODE
       
   140          TText* newdata = (TText*)User::AllocL(size*sizeof(TText));
       
   141          iPtr.Set(newdata, size, size);
       
   142          TInt i;
       
   143          for(i=0 ; i<size ; ++i)
       
   144              iPtr[i]=ptr[i];
       
   145          delete data;
       
   146      }
       
   147 
       
   148      file.Pop();
       
   149      fs.Pop();
       
   150  }
       
   151 
       
   152 
       
   153  ////////////////////////////////////////////////////////////////////////////////
       
   154  //
       
   155  // Find a key's value given a section name and a key name
       
   156  //
       
   157 
       
   158  TBool CIniData::FindVar(const TDesC &aSectName,const TDesC &aKeyName,TPtrC &aResult)
       
   159  /* Find a text value from given aKeyName and aSecName in the ini data file
       
   160 
       
   161  @param aSectName Section containing key
       
   162  @param aKeyName Key being searched for in aSectName
       
   163  @param aResult On return, contains the text result
       
   164 
       
   165  @return ETrue if found, otherwise EFalse
       
   166 
       
   167  */
       
   168      {
       
   169 
       
   170      __ASSERT_DEBUG(aSectName.Length()<=KTokenSize,Panic(ESectionNameTooBig));
       
   171      __ASSERT_DEBUG(aKeyName.Length()<=KTokenSize,Panic(EKeyNameTooBig));
       
   172 
       
   173      TInt posStartOfSection(0);
       
   174      TInt posEndOfSection(iPtr.Length()); // Default to the entire length of the ini data
       
   175      TPtrC SearchBuf;
       
   176 
       
   177      // If we have a section, set pos to section start
       
   178      TInt posI(0);   // Position in internal data Buffer
       
   179      if( aSectName.Length() > 0 )
       
   180          {
       
   181          TBool FoundSection(false);
       
   182          while ( ! FoundSection )
       
   183              {
       
   184              // Move search buffer to next area of interest
       
   185              SearchBuf.Set(iPtr.Mid(posI));
       
   186 
       
   187              // Make up token "[SECTIONNAME]", to search for
       
   188              TPtr sectionToken=iToken->Des();
       
   189              _LIT(sectionTokenFmtString,"[%S]");
       
   190              sectionToken.Format(sectionTokenFmtString,&aSectName);
       
   191 
       
   192              // Search for next occurrence of aSectName
       
   193              TInt posSB = SearchBuf.Find(sectionToken);
       
   194 
       
   195              if (posSB==KErrNotFound)
       
   196                  return(EFalse);
       
   197 
       
   198              // Check this is at beginning of line (ie. non-commented)
       
   199              // ie. Check preceding char was LF
       
   200              if(posSB>0)
       
   201                  {
       
   202                  // Create a Buffer, starting one char before found subBuf
       
   203                  TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1));
       
   204                  // Check first char is end of prev
       
   205                  if(CharBefore[0] == '\n')
       
   206                      {
       
   207                      FoundSection = ETrue;       // found
       
   208                      posI = posI + posSB;
       
   209                      }
       
   210                  else
       
   211                      {
       
   212                      posI = posI + posSB + 1;    // try again
       
   213                      }
       
   214                  }
       
   215              else
       
   216                  {
       
   217                  FoundSection = ETrue;
       
   218                  }
       
   219 
       
   220              }   // while ( ! FoundSection )
       
   221 
       
   222          // Set start of section, after section name, (incl '[' and ']')
       
   223          posStartOfSection = posI + aSectName.Length() + 2;
       
   224 
       
   225          // Set end of section, by finding begin of next section or end
       
   226          SearchBuf.Set(iPtr.Mid(posI));
       
   227          _LIT(nextSectionBuf,"\n[");
       
   228          TInt posSB = SearchBuf.Find(nextSectionBuf);
       
   229          if(posSB != KErrNotFound)
       
   230              {
       
   231              posEndOfSection = posI + posSB;
       
   232              }
       
   233          else
       
   234              {
       
   235              posEndOfSection = iPtr.Length();
       
   236              }
       
   237 
       
   238          }   // if( aSectName.Length() > 0 )
       
   239 
       
   240      // Look for key in ini file data Buffer
       
   241      posI = posStartOfSection;
       
   242      TBool FoundKey(false);
       
   243      while ( ! FoundKey )
       
   244          {
       
   245          // Search for next occurrence of aKeyName
       
   246          SearchBuf.Set(iPtr.Mid(posI,posEndOfSection-posI));
       
   247          TInt posSB = SearchBuf.Find(aKeyName);
       
   248 
       
   249          // If not found, return
       
   250          if (posSB==KErrNotFound)
       
   251              return(EFalse);
       
   252 
       
   253          // Check this is at beginning of line (ie. non-commented)
       
   254          // ie. Check preceding char was CR or LF
       
   255          if(posSB>0)
       
   256              {
       
   257              // Create a Buffer, starting one char before found subBuf
       
   258              TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1));
       
   259              // Check if the first char is end of prev and also check
       
   260              // if the token found is not a substring of another string
       
   261              TBool beginningOK = ((CharBefore[0] == '\n') || (CharBefore[0] == ' ') || (CharBefore[0] == '\t'));
       
   262              TBool endingOK = ((CharBefore[aKeyName.Length()+1] == '=') || (CharBefore[aKeyName.Length()+1] == ' ') ||
       
   263 (CharBefore[aKeyName.Length()+1] == '\t'));
       
   264              if (beginningOK && endingOK)
       
   265                  {
       
   266                  FoundKey = ETrue;
       
   267                  posI = posI + posSB;
       
   268                  }
       
   269              else
       
   270                  {
       
   271                  posI = posI + posSB + 1;
       
   272                  }
       
   273              }
       
   274          else
       
   275              {
       
   276              FoundKey = ETrue;
       
   277              }
       
   278          }   // while ( ! FoundKey )
       
   279 
       
   280 // Set pos, to just after '=' sign
       
   281 SearchBuf.Set(iPtr.Mid(posI));
       
   282 TInt posSB = SearchBuf.Locate('=');
       
   283 if(posSB==KErrNotFound)     // Illegal format, should flag this...
       
   284     return(EFalse);
       
   285 
       
   286 // Identify start and end of data (EOL or EOF)
       
   287 posI = posI + posSB + 1;    // 1 char after '='
       
   288 TInt posValStart = posI;
       
   289 TInt posValEnd;
       
   290 SearchBuf.Set(iPtr.Mid(posI));
       
   291 posSB = SearchBuf.Locate('\r');
       
   292 if(posSB!=KErrNotFound)
       
   293     {
       
   294     posValEnd = posI + posSB;
       
   295     }
       
   296 else
       
   297     {
       
   298     posValEnd = iPtr.Length();
       
   299     }
       
   300 
       
   301 // Check we are still in the section requested
       
   302 if( aSectName.Length() > 0 )
       
   303     {
       
   304     if( posValEnd > posEndOfSection )
       
   305         {
       
   306         return(EFalse);
       
   307         }
       
   308     }
       
   309 // Parse Buffer from posn of key
       
   310 // Start one space after '='
       
   311 TLex lex(iPtr.Mid(posValStart, posValEnd-posValStart));
       
   312 lex.SkipSpaceAndMark();     // Should be at the start of the data
       
   313 aResult.Set(lex.MarkedToken().Ptr(),posValEnd-posValStart - lex.Offset() );
       
   314 return(ETrue);
       
   315 }
       
   316 
       
   317 ////////////////////////////////////////////////////////////////////////////////
       
   318 TBool CIniData::FindVar(const TDesC &aSection,const TDesC &aKeyName,TInt &aResult)
       
   319 /* Find an integer value from given aKeyName and aSecName in the ini data file
       
   320 
       
   321 @param aSectName Section containing key
       
   322 @param aKeyName Key being searched for  in aSectName
       
   323 @param aResult On return, contains TInt result
       
   324 
       
   325 @return ETrue if found, otherwise EFalse
       
   326 
       
   327 */
       
   328 {
       
   329 TPtrC ptr(NULL,0);
       
   330 if (FindVar(aSection,aKeyName,ptr))
       
   331     {
       
   332     TLex lex(ptr);
       
   333     if (lex.Val(aResult)==KErrNone)
       
   334         return(ETrue);
       
   335     }
       
   336 return(EFalse);
       
   337 }