diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/sisxlibrary/utils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/secureswitools/swisistools/source/sisxlibrary/utils.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,284 @@ +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Note: This file may contain code to generate corrupt files for test purposes. +* Such code is excluded from production builds by use of compiler defines; +* it is recommended that such code should be removed if this code is ever published publicly. +* INCLUDES +* +*/ + + +/** + @file + @internalComponent + @released +*/ + +#include "utils.h" +#include +#include "utf8.h" +#include "utility_interface.h" + +#define TMP_FILE_STUB L"~si" + +// =========================================================================== +// GLOBAL UTILS FUNCTIONS +// =========================================================================== + +bool FileIsUnicode(LPCWSTR fileName, TEncodingScheme& encScheme) +// check whether a text file is in UNICODE format & whether little/big-endian or utf8 + { + BYTE pBuf[3] = { 0,0,0 }; + DWORD dwNumBytes; + DWORD ok; + const BYTE cUtf8[] = { 0xEF,0xBB, 0xBF }; + const BYTE cUcs2LE[] = { 0xFF,0xFE }; + const BYTE cUcs2BE[] = { 0xFE,0xFF }; + + HANDLE hFile = ::MakeSISOpenFile(fileName, GENERIC_READ, OPEN_EXISTING); + if(hFile == INVALID_HANDLE_VALUE) + throw ErrCannotOpenFile; + + // Make sure we're at the beginning of the file + ::SetFilePointer(hFile, 0L, NULL, FILE_BEGIN); + + ok=::ReadFile(hFile, (LPVOID)pBuf, sizeof(pBuf), &dwNumBytes, NULL); + + ::CloseHandle(hFile); + + if (!ok) throw ErrCannotReadFile; + + if (dwNumBytes>=2 && memcmp(pBuf,cUcs2LE,sizeof(cUcs2LE)) == 0) + { + encScheme=EUcs2LE; + return true; + } + else if (dwNumBytes>=2 && memcmp(pBuf,cUcs2BE,sizeof(cUcs2BE)) == 0) + { + encScheme=EUcs2BE; + return true; + } + else + { + if (dwNumBytes==sizeof(pBuf) && memcmp(pBuf,cUtf8,sizeof(pBuf)) == 0) + encScheme=EUtf8; + else + encScheme=EAscii; + return false; + } + } + +LPWSTR ConvertUCS2FileToUCS4(LPCWSTR fileName) +// convert a UCS-2 file to UCS-4 format + { + LPWSTR pszTempSource; + DWORD dwNumBytes; + HANDLE hFile; + DWORD fileSize; + UTF16 *pBuf; + BOOL ok; + + // open file & get file size + hFile = ::MakeSISOpenFile(fileName, GENERIC_READ, OPEN_EXISTING); + if(hFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; + fileSize = ::GetFileSize(hFile, NULL); + + // read in whole file + pBuf = new UTF16 [fileSize/2+1]; + ok=::ReadFile(hFile, (LPVOID)pBuf, fileSize, &dwNumBytes, NULL); + ::CloseHandle(hFile); + if (!ok) throw ErrCannotReadFile; + + int targetLength = (fileSize/2)*sizeof(WCHAR); + UCS4 *ptrUCS4 = new UCS4[targetLength + 1]; + UTF16* sourceStart = reinterpret_cast(pBuf); + UTF16* sourceEnd = sourceStart + (fileSize/2)*(sizeof(WCHAR)/2); + UCS4* targetStart = reinterpret_cast(ptrUCS4); + UCS4* targetEnd = targetStart + targetLength; + ConvertUTF16toUCS4(&sourceStart, sourceEnd, &targetStart, targetEnd); + int endOffset = (UCS4*)targetStart - ptrUCS4; + targetStart = reinterpret_cast(ptrUCS4) + endOffset; + *targetStart = 0; + + + // write to new temporary file + pszTempSource=TempFileName(); + hFile = ::MakeSISOpenFile(pszTempSource, GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS); + if (hFile==INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; + + ok = ::WriteFile(hFile, (LPVOID)ptrUCS4, targetLength, &dwNumBytes, NULL); + ::CloseHandle(hFile); + + delete [] pBuf; + + if (!ok) + { + _wunlink(pszTempSource); + throw ErrCannotConvertFile; + } + return pszTempSource; + } + + +LPWSTR ConvertUCS2FileToLittleEndianUnicode(LPCWSTR fileName) +// convert a UCS-2 big-endian UNICODE file to a little-endian UNICODE file + { + LPWSTR pszTempSource; + DWORD dwNumBytes; + HANDLE hFile; + DWORD fileSize; + LPWSTR pBuf; + BOOL ok; + + // open file & get file size + hFile = ::MakeSISOpenFile(fileName, GENERIC_READ, OPEN_EXISTING); + if(hFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; + fileSize = ::GetFileSize(hFile, NULL); + + // read in whole file + pBuf = new WCHAR [fileSize/2+1]; + ok=::ReadFile(hFile, (LPVOID)pBuf, fileSize, &dwNumBytes, NULL); + ::CloseHandle(hFile); + if (!ok) throw ErrCannotReadFile; + + // convert text to little endian unicode + for (DWORD i=0; i<(fileSize/2); i++) + pBuf[i]=(WCHAR)(((pBuf[i]&0xFF00)>>8) | ((pBuf[i]&0xFF)<<8)); + + // write to new temporary file + pszTempSource=TempFileName(); + hFile = ::MakeSISOpenFile(pszTempSource, GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS); + if (hFile==INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; + ok=::WriteFile(hFile, (LPVOID)pBuf, fileSize, &dwNumBytes, NULL); + ::CloseHandle(hFile); + delete [] pBuf; + if (!ok) + { + _wunlink(pszTempSource); + throw ErrCannotWriteFile; + } + return pszTempSource; + } + +LPWSTR ConvertFileToUnicode(LPCWSTR fileName, TEncodingScheme encScheme) +// convert text file to UNICODE + { + LPWSTR pszTempSource; + DWORD dwNumBytes; + HANDLE hFile; + DWORD fileSize; + LPSTR pNarrowBuf; + LPWSTR pBufU; + BOOL ok; + + // open file & get file size + hFile = ::MakeSISOpenFile(fileName, GENERIC_READ, OPEN_EXISTING); + if(hFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; + fileSize = ::GetFileSize(hFile, NULL); + + // read in whole file + // Linux needs mbstowcs(NULL,src,0)+1 for buffer allocation so added +1. + pNarrowBuf = new CHAR [fileSize+1]; + ok=::ReadFile(hFile, (LPVOID)pNarrowBuf, fileSize, &dwNumBytes, NULL); + ::CloseHandle(hFile); + if (!ok) throw ErrCannotReadFile; + + if ( EAscii == encScheme ) + { + if ( !CorrectUTF8(pNarrowBuf,dwNumBytes) ) + throw ErrCannotConvertFile; + } + DWORD dwConvCount = ConvertMultiByteToWideChar(pNarrowBuf,dwNumBytes,0,0); + pBufU=new WCHAR [dwConvCount]; + + // make sure the buffer is zeroed + memset(pBufU,0,sizeof(WCHAR)*dwConvCount); + + dwConvCount = ConvertMultiByteToWideChar(pNarrowBuf,dwNumBytes,pBufU,dwConvCount); + if ( !dwConvCount ) throw ErrCannotConvertFile; + + // write to new temporary file + pszTempSource=TempFileName(); + hFile = ::MakeSISOpenFile(pszTempSource, GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS); + if (hFile==INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; + + ok = ::WriteFile(hFile, (LPVOID)pBufU, dwConvCount*sizeof(WCHAR), &dwNumBytes, NULL); + ::CloseHandle(hFile); + + delete [] pNarrowBuf; + delete [] pBufU; + if (!ok) + { + _wunlink(pszTempSource); + throw ErrCannotConvertFile; + } + + return pszTempSource; + } + +LPWSTR TempFileName() +// generate a unique temporary filename +// creates a sub-directory in TEMP and uses fileName as a guide for the +// filename +// returns name of temporary directory if fileName is NULL + { + static WCHAR tmpFileName[PATHMAX]={'\0'}; + static WCHAR tmpPath[PATHMAX]={'\0'}; + if (*tmpPath=='\0') + { + GetTempPathW(PATHMAX,tmpPath); + tmpFileName [0] = 0; + GetTempFileNameW (tmpPath, TMP_FILE_STUB, 0, tmpFileName); + } + return tmpFileName; + } + +bool CorrectUTF8(LPSTR pNarrowBuf, DWORD dwNumBytes) + { + bool bUtf8Text = true; + int nBadUtf = 0; + wchar_t szDbg[255] = {L"0"}; + for (DWORD i = 1; i < dwNumBytes; i++) + { + if ( (pNarrowBuf[i] & 0xC0) == 0x80 ) + // if the uppermost bit in current byte is set... + { + if ( (pNarrowBuf[i-1] & 0x80) == 0x00 ) + // but previous byte has it reset... + { + // if current byte is not 'No-Break Space' char... + if ( pNarrowBuf[i] != (CHAR)0xA0 ) + { + nBadUtf ++; + wprintf(L"Detecting illegal UTF8 character at position 0x%02X : 0x%02X \n",i,pNarrowBuf[i]); + } + } + } + else + // Overlong encoding: lead-byte of a 2 byte sequence, but code point <= 127 + { + if ( (pNarrowBuf[i-1] & 0xC0) == 0xC0 ) + { + nBadUtf ++; + wprintf(L"Detecting illegal UTF8 character at position 0x%02X: 0x%02X\n",i,pNarrowBuf[i]); + } + } + } + if ( nBadUtf ) + bUtf8Text = false; + + return bUtf8Text; + } +