symport/f32/sfsrv/cl_ftext.cpp
changeset 1 0a7b44b10206
child 2 806186ab5e14
equal deleted inserted replaced
0:c55016431358 1:0a7b44b10206
       
     1 // Copyright (c) 1996-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 the License "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // f32\sfsrv\cl_ftext.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "cl_std.h"
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 EXPORT_C TFileText::TFileText()
       
    24 /**
       
    25 Default constructor.
       
    26 */
       
    27 	{}
       
    28 
       
    29 
       
    30 
       
    31 
       
    32 EXPORT_C void TFileText::Set(RFile& aFile)
       
    33 /**
       
    34 Sets the Unicode file to be read from, or written to.
       
    35 
       
    36 This function must be called before 
       
    37 Read(), Write() or Seek() can be used.
       
    38 
       
    39 @param aFile The file to be used. Must be open.
       
    40 
       
    41 @see TFileText::Read
       
    42 @see TFileText::Write
       
    43 @see TFileText::Seek
       
    44 */
       
    45 	{
       
    46 
       
    47 	iFile=aFile;
       
    48 	iReadBuf.Zero();
       
    49 	iNext=(TText*)iReadBuf.Ptr();
       
    50 	iEnd=iNext;
       
    51 	TInt pos = 0;
       
    52 	iFile.Seek(ESeekCurrent,pos);
       
    53  	if (pos == 0)
       
    54  		iState = EStartOfFile;
       
    55  	else
       
    56  		iState = ENormal;
       
    57 	}
       
    58 
       
    59 
       
    60 
       
    61 
       
    62 EXPORT_C TInt TFileText::Read(TDes& aDes)
       
    63 /**
       
    64 Reads single line text record from a Unicode file into the specified descriptor.
       
    65 
       
    66 The read operation begins at the current file position, and ends when
       
    67 a line delimiter character is read.
       
    68 
       
    69 If the maximum length of the descriptor is insufficient to hold the record, 
       
    70 the function returns KErrTooBig and the descriptor is filled to its maximum 
       
    71 length.
       
    72 
       
    73 If Read() is called when the current position is the end of the file (that 
       
    74 is, after the last line delimiter in the file), KErrEof is returned, and the 
       
    75 length of the buffer is set to zero.
       
    76 
       
    77 @param aDes On return, contains the single record read from the file. Any 
       
    78             previous contents are overwritten.
       
    79 
       
    80 @return KErrNone if successful, otherwise one of the other system-wide error 
       
    81         codes.
       
    82 */
       
    83 	{
       
    84 
       
    85 	TText* pD=(TText*)aDes.Ptr();
       
    86 	TInt len=aDes.MaxLength();
       
    87 	TInt newLen=0;
       
    88 	while (newLen<len)
       
    89 		{
       
    90 		if (iNext>=iEnd)
       
    91 			{
       
    92 			TInt r=FillBuffer();
       
    93 			if (r!=KErrNone && r!=KErrEof)
       
    94 				return(r);
       
    95 			if (r==KErrEof)
       
    96 				{
       
    97 				aDes.SetLength(newLen);
       
    98 				return(newLen ? KErrNone : KErrEof);
       
    99 				}
       
   100 			continue;
       
   101 			}
       
   102 		TBool terminate=newLen;
       
   103 		TInt r=CheckForTerminator(terminate);
       
   104 		if (r!=KErrNone || terminate)
       
   105 			{
       
   106 			aDes.SetLength(newLen);
       
   107 			return(r);
       
   108 			}
       
   109 		*pD++=(*iNext++);
       
   110 		newLen++;
       
   111 		}
       
   112 	aDes.SetLength(newLen);
       
   113 	TBool terminate=newLen;
       
   114 	TInt r=CheckForTerminator(terminate);
       
   115 	if (r!=KErrNone || terminate)
       
   116 		return(r);
       
   117 	NextRecord();
       
   118 	return(KErrTooBig);
       
   119 	}
       
   120 
       
   121 void TFileText::NextRecord()
       
   122 //
       
   123 // Move to the start of the next record
       
   124 //
       
   125 	{
       
   126 
       
   127 	FOREVER
       
   128 		{
       
   129 		TBool terminate=EFalse;
       
   130 		TInt r=CheckForTerminator(terminate);
       
   131 		if (r!=KErrNone || terminate)
       
   132 			return;
       
   133 		iNext++;
       
   134 		}
       
   135 	}
       
   136 
       
   137 static void SwapWords(TText* aStart,TInt aCount)
       
   138  	{
       
   139  	TUint8* p = (TUint8*)aStart;
       
   140  	while (aCount-- > 0)
       
   141  		{
       
   142  		TUint8 temp = *p;
       
   143  		*p = p[1];
       
   144  		p[1] = temp;
       
   145  		p += 2;
       
   146    		}
       
   147    	}
       
   148 
       
   149 TInt TFileText::FillBuffer()
       
   150 //
       
   151 // Read the new data from the file
       
   152 //
       
   153 	{
       
   154 	
       
   155 	TInt r=iFile.Read(iReadBuf);
       
   156 	if (r!=KErrNone)
       
   157 		return(r);
       
   158 	if (iReadBuf.Length()==0)
       
   159 		return(KErrEof);
       
   160 	iNext=(const TText*)iReadBuf.Ptr();
       
   161 	iEnd=iNext+iReadBuf.Length()/sizeof(TText);
       
   162 	 
       
   163  	// Use any leading byte order marker to determine endianness.
       
   164  	if (iState == EStartOfFile)
       
   165  		{
       
   166  		iState = ENormal;
       
   167 
       
   168  		// Ignore an ordinary byte order marker.
       
   169  		if (*iNext == 0xFEFF)
       
   170  			iNext++;
       
   171 
       
   172  		// Set the endianness state to 'reverse' if a reversed byte order marker is found.
       
   173  		else if (*iNext == 0xFFFE)
       
   174  			{
       
   175  			iNext++;
       
   176  			iState = EReverse;
       
   177  			}
       
   178  
       
   179  		if (iNext == iEnd)
       
   180  			return KErrEof;
       
   181  		}
       
   182  
       
   183  	if (iState == EReverse)
       
   184 		SwapWords((TText*)iNext,(iEnd - iNext));
       
   185 
       
   186 	return(KErrNone);
       
   187 	}
       
   188 
       
   189 TInt TFileText::CheckForTerminator(TBool& anAnswer)
       
   190 //
       
   191 // Return ETrue if the next char is a record terminator: PARAGRAPH SEPARATOR (U+2029), LINE SEPARATOR (U+2028),
       
   192 // CR-LF (U+000D, U+000A), or LF (U+000A)
       
   193 //
       
   194 	{
       
   195 
       
   196 	if (iNext>=iEnd)
       
   197 		{
       
   198 		TInt r=FillBuffer();
       
   199 		if (r!=KErrNone)
       
   200 			{
       
   201 			if (r==KErrEof && anAnswer)
       
   202 				return(KErrNone);
       
   203 			return(r);
       
   204 			}
       
   205 		}
       
   206 
       
   207 	anAnswer=EFalse;
       
   208 	const TText* oldNext=iNext;
       
   209 	TInt oldBufferLength=iReadBuf.Length();
       
   210 	TText c=(*iNext);
       
   211 	TBool peek=EFalse;
       
   212 
       
   213 	// Check for unambiguous paragraph or line separator.
       
   214  	if (c == 0x2029 || c == 0x2028)
       
   215  		{
       
   216  		iNext++;
       
   217  		anAnswer = ETrue;
       
   218 		return KErrNone;
       
   219  		}
       
   220  
       
   221  	// Check for CR-LF or LF.
       
   222  	if (c == 0x000D)
       
   223 		{
       
   224 		iNext++;
       
   225 		if (iNext<iEnd)
       
   226 			c=(*iNext);
       
   227 		else
       
   228 			{
       
   229 			peek=ETrue;
       
   230 			TInt r=FillBuffer();
       
   231 			if (r!=KErrNone && r!=KErrEof)
       
   232 				return(r);
       
   233 			if (r==KErrNone)
       
   234 				c=(*iNext);
       
   235 			}
       
   236 		}
       
   237 
       
   238 	if (c == 0x000A)
       
   239 		{
       
   240 		iNext++;
       
   241 		anAnswer=ETrue;
       
   242 		return(KErrNone);
       
   243 		}
       
   244 
       
   245 	iNext=oldNext;
       
   246 	if (!peek)
       
   247 		return(KErrNone);
       
   248 
       
   249 	TInt pos=(-1)*(oldBufferLength+iReadBuf.Length());
       
   250 	TInt r=iFile.Seek(ESeekCurrent,pos);
       
   251 	if (r==KErrNone)
       
   252 		r=FillBuffer();
       
   253 	if (r!=KErrNone)
       
   254 		return(r);
       
   255 	iNext=oldNext;
       
   256 	return(KErrNone);
       
   257 	}
       
   258 
       
   259 
       
   260 
       
   261 
       
   262 EXPORT_C TInt TFileText::Write(const TDesC& aDes)
       
   263 /**
       
   264 Writes the contents of a descriptor to the end of a Unicode file.
       
   265 
       
   266 A line delimiter is appended to the descriptor, and the current file position
       
   267 is set to the new end of file.
       
   268 
       
   269 If the descriptor contains one or more paragraph delimiters, Read() will treat 
       
   270 the contents of the descriptor as more than one record.
       
   271 
       
   272 @param aDes The descriptor content to be appended to the file.
       
   273 
       
   274 @return KErrNone if successful, otherwise one of the other system-wide error 
       
   275         codes.
       
   276         
       
   277 @see TFileText::Read
       
   278 */
       
   279 	{
       
   280 
       
   281 	TInt r=Seek(ESeekEnd);
       
   282 	if (r!=KErrNone)
       
   283 		return(r);
       
   284 	TPtrC8 writeBuf((const TUint8*)aDes.Ptr(),aDes.Size());
       
   285 	r=iFile.Write(writeBuf);
       
   286 	if (r!=KErrNone)
       
   287 		return(r);
       
   288  	TText lf = 0x000A;
       
   289  	TPtrC8 lf8((const TUint8*)&lf,sizeof(TText));
       
   290  	r=iFile.Write(lf8);
       
   291 	return(r);
       
   292 	}
       
   293 
       
   294 
       
   295 
       
   296 
       
   297 EXPORT_C TInt TFileText::Seek(TSeek aMode)
       
   298 /**
       
   299 Seeks to start or end of file.
       
   300 
       
   301 It is only necessary to call this function before 
       
   302 using Read() because Write() always seeks to the end of the file
       
   303 before writing.
       
   304 
       
   305 @param aMode ESeekStart to seek to the start of the file;
       
   306              ESeekEnd to seek to the end.
       
   307              
       
   308 @return KErrNone if successful, otherwise one of the other system-wide error 
       
   309         codes.
       
   310 
       
   311 @panic FSCLIENT 5 if aMode is neither ESeekStart nor ESeekEnd.
       
   312 
       
   313 @see TFileText::Read
       
   314 @see TFileText::Write
       
   315 */
       
   316 	{
       
   317 
       
   318 	__ASSERT_ALWAYS(aMode==ESeekStart || aMode==ESeekEnd,Panic(EFTextIllegalSeekMode));
       
   319 	TInt pos=0;
       
   320 	TInt ret=iFile.Seek(aMode,pos);
       
   321  	if (ret == 0 && aMode == ESeekStart)
       
   322  		iState = EStartOfFile;
       
   323 	iNext = (TText*)iReadBuf.Ptr();
       
   324  	iEnd = iNext;
       
   325 	return ret;
       
   326 	}
       
   327