ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

text.c
Go to the documentation of this file.
00001 /*
00002  *  Notepad (text.c)
00003  *
00004  *  Copyright 1998,99 Marcel Baur <mbaur@g26.ethz.ch>
00005  *  Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
00006  *  Copyright 2002 Andriy Palamarchuk
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021  */
00022 
00023 #include <notepad.h>
00024 
00025 static BOOL Append(LPWSTR *ppszText, DWORD *pdwTextLen, LPCWSTR pszAppendText, DWORD dwAppendLen)
00026 {
00027     LPWSTR pszNewText;
00028 
00029     if (dwAppendLen > 0)
00030     {
00031         if (*ppszText)
00032         {
00033             pszNewText = (LPWSTR) HeapReAlloc(GetProcessHeap(), 0, *ppszText, (*pdwTextLen + dwAppendLen) * sizeof(WCHAR));
00034         }
00035         else
00036         {
00037             pszNewText = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwAppendLen * sizeof(WCHAR));
00038         }
00039 
00040         if (!pszNewText)
00041             return FALSE;
00042 
00043         memcpy(pszNewText + *pdwTextLen, pszAppendText, dwAppendLen * sizeof(WCHAR));
00044         *ppszText = pszNewText;
00045         *pdwTextLen += dwAppendLen;
00046     }
00047     return TRUE;
00048 }
00049 
00050 BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding, int *piEoln)
00051 {
00052     DWORD dwSize;
00053     LPBYTE pBytes = NULL;
00054     LPWSTR pszText;
00055     LPWSTR pszAllocText = NULL;
00056     DWORD dwPos, i;
00057     DWORD dwCharCount;
00058     BOOL bSuccess = FALSE;
00059     BYTE b = 0;
00060     int iEncoding = ENCODING_ANSI;
00061     int iCodePage = 0;
00062     WCHAR szCrlf[2] = { '\r', '\n' };
00063     DWORD adwEolnCount[3] = { 0, 0, 0 };
00064 
00065     *ppszText = NULL;
00066     *pdwTextLen = 0;
00067 
00068     dwSize = GetFileSize(hFile, NULL);
00069     if (dwSize == INVALID_FILE_SIZE)
00070         goto done;
00071 
00072     pBytes = HeapAlloc(GetProcessHeap(), 0, dwSize + 2);
00073     if (!pBytes)
00074         goto done;
00075 
00076     if (!ReadFile(hFile, pBytes, dwSize, &dwSize, NULL))
00077         goto done;
00078     dwPos = 0;
00079 
00080     /* Make sure that there is a NUL character at the end, in any encoding */
00081     pBytes[dwSize + 0] = '\0';
00082     pBytes[dwSize + 1] = '\0';
00083 
00084     /* Look for Byte Order Marks */
00085     if ((dwSize >= 2) && (pBytes[0] == 0xFF) && (pBytes[1] == 0xFE))
00086     {
00087         iEncoding = ENCODING_UNICODE;
00088         dwPos += 2;
00089     }
00090     else if ((dwSize >= 2) && (pBytes[0] == 0xFE) && (pBytes[1] == 0xFF))
00091     {
00092         iEncoding = ENCODING_UNICODE_BE;
00093         dwPos += 2;
00094     }
00095     else if ((dwSize >= 3) && (pBytes[0] == 0xEF) && (pBytes[1] == 0xBB) && (pBytes[2] == 0xBF))
00096     {
00097         iEncoding = ENCODING_UTF8;
00098         dwPos += 3;
00099     }
00100 
00101     switch(iEncoding)
00102     {
00103     case ENCODING_UNICODE_BE:
00104         for (i = dwPos; i < dwSize-1; i += 2)
00105         {
00106             b = pBytes[i+0];
00107             pBytes[i+0] = pBytes[i+1];
00108             pBytes[i+1] = b;
00109         }
00110         /* fall through */
00111 
00112     case ENCODING_UNICODE:
00113         pszText = (LPWSTR) &pBytes[dwPos];
00114         dwCharCount = (dwSize - dwPos) / sizeof(WCHAR);
00115         break;
00116 
00117     case ENCODING_ANSI:
00118     case ENCODING_UTF8:
00119         if (iEncoding == ENCODING_ANSI)
00120             iCodePage = CP_ACP;
00121         else if (iEncoding == ENCODING_UTF8)
00122             iCodePage = CP_UTF8;
00123 
00124         if ((dwSize - dwPos) > 0)
00125         {
00126             dwCharCount = MultiByteToWideChar(iCodePage, 0, (LPCSTR)&pBytes[dwPos], dwSize - dwPos, NULL, 0);
00127             if (dwCharCount == 0)
00128                 goto done;
00129         }
00130         else
00131         {
00132             /* special case for files with no characters (other than BOMs) */
00133             dwCharCount = 0;
00134         }
00135 
00136         pszAllocText = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, (dwCharCount + 1) * sizeof(WCHAR));
00137         if (!pszAllocText)
00138             goto done;
00139 
00140         if ((dwSize - dwPos) > 0)
00141         {
00142             if (!MultiByteToWideChar(iCodePage, 0, (LPCSTR)&pBytes[dwPos], dwSize - dwPos, pszAllocText, dwCharCount))
00143                 goto done;
00144         }
00145 
00146         pszAllocText[dwCharCount] = '\0';
00147         pszText = pszAllocText;
00148         break;
00149     }
00150 
00151     dwPos = 0;
00152     for (i = 0; i < dwCharCount; i++)
00153     {
00154         switch(pszText[i])
00155         {
00156         case '\r':
00157             if ((i < dwCharCount-1) && (pszText[i+1] == '\n'))
00158             {
00159                 i++;
00160                 adwEolnCount[EOLN_CRLF]++;
00161                 break;
00162             }
00163             /* fall through */
00164 
00165         case '\n':
00166             if (!Append(ppszText, pdwTextLen, &pszText[dwPos], i - dwPos))
00167                 return FALSE;
00168             if (!Append(ppszText, pdwTextLen, szCrlf, sizeof(szCrlf) / sizeof(szCrlf[0])))
00169                 return FALSE;
00170             dwPos = i + 1;
00171 
00172             if (pszText[i] == '\r')
00173                 adwEolnCount[EOLN_CR]++;
00174             else
00175                 adwEolnCount[EOLN_LF]++;
00176             break;
00177 
00178         case '\0':
00179             pszText[i] = ' ';
00180             break;
00181         }
00182     }
00183 
00184     if (!*ppszText && (pszText == pszAllocText))
00185     {
00186         /* special case; don't need to reallocate */
00187         *ppszText = pszAllocText;
00188         *pdwTextLen = dwCharCount;
00189         pszAllocText = NULL;
00190     }
00191     else
00192     {
00193         /* append last remaining text */
00194         if (!Append(ppszText, pdwTextLen, &pszText[dwPos], i - dwPos + 1))
00195             return FALSE;
00196     }
00197 
00198     /* chose which eoln to use */
00199     *piEoln = EOLN_CRLF;
00200     if (adwEolnCount[EOLN_LF] > adwEolnCount[*piEoln])
00201         *piEoln = EOLN_LF;
00202     if (adwEolnCount[EOLN_CR] > adwEolnCount[*piEoln])
00203         *piEoln = EOLN_CR;
00204     *piEncoding = iEncoding;
00205 
00206     bSuccess = TRUE;
00207 
00208 done:
00209     if (pBytes)
00210         HeapFree(GetProcessHeap(), 0, pBytes);
00211     if (pszAllocText)
00212         HeapFree(GetProcessHeap(), 0, pszAllocText);
00213 
00214     if (!bSuccess && *ppszText)
00215     {
00216         HeapFree(GetProcessHeap(), 0, *ppszText);
00217         *ppszText = NULL;
00218         *pdwTextLen = 0;
00219     }
00220     return bSuccess;
00221 }
00222 
00223 static BOOL WriteEncodedText(HANDLE hFile, LPCWSTR pszText, DWORD dwTextLen, int iEncoding)
00224 {
00225     LPBYTE pBytes = NULL;
00226     LPBYTE pAllocBuffer = NULL;
00227     DWORD dwPos = 0;
00228     DWORD dwByteCount;
00229     BYTE buffer[1024];
00230     UINT iCodePage = 0;
00231     DWORD dwDummy, i;
00232     BOOL bSuccess = FALSE;
00233     int iBufferSize, iRequiredBytes;
00234     BYTE b;
00235 
00236     while(dwPos < dwTextLen)
00237     {
00238         switch(iEncoding)
00239         {
00240             case ENCODING_UNICODE:
00241                 pBytes = (LPBYTE) &pszText[dwPos];
00242                 dwByteCount = (dwTextLen - dwPos) * sizeof(WCHAR);
00243                 dwPos = dwTextLen;
00244                 break;
00245 
00246             case ENCODING_UNICODE_BE:
00247                 dwByteCount = (dwTextLen - dwPos) * sizeof(WCHAR);
00248                 if (dwByteCount > sizeof(buffer))
00249                     dwByteCount = sizeof(buffer);
00250 
00251                 memcpy(buffer, &pszText[dwPos], dwByteCount);
00252                 for (i = 0; i < dwByteCount; i += 2)
00253                 {
00254                     b = buffer[i+0];
00255                     buffer[i+0] = buffer[i+1];
00256                     buffer[i+1] = b;
00257                 }
00258                 pBytes = (LPBYTE) &buffer[dwPos];
00259                 dwPos += dwByteCount / sizeof(WCHAR);
00260                 break;
00261 
00262             case ENCODING_ANSI:
00263             case ENCODING_UTF8:
00264                 if (iEncoding == ENCODING_ANSI)
00265                     iCodePage = CP_ACP;
00266                 else if (iEncoding == ENCODING_UTF8)
00267                     iCodePage = CP_UTF8;
00268 
00269                 iRequiredBytes = WideCharToMultiByte(iCodePage, 0, &pszText[dwPos], dwTextLen - dwPos, NULL, 0, NULL, NULL);
00270                 if (iRequiredBytes <= 0)
00271                 {
00272                     goto done;
00273                 }
00274                 else if (iRequiredBytes < sizeof(buffer))
00275                 {
00276                     pBytes = buffer;
00277                     iBufferSize = sizeof(buffer);
00278                 }
00279                 else
00280                 {
00281                     pAllocBuffer = (LPBYTE) HeapAlloc(GetProcessHeap(), 0, iRequiredBytes);
00282                     if (!pAllocBuffer)
00283                         return FALSE;
00284                     pBytes = pAllocBuffer;
00285                     iBufferSize = iRequiredBytes;
00286                 }
00287 
00288                 dwByteCount = WideCharToMultiByte(iCodePage, 0, &pszText[dwPos], dwTextLen - dwPos, (LPSTR) pBytes, iBufferSize, NULL, NULL);
00289                 if (!dwByteCount)
00290                     goto done;
00291 
00292                 dwPos = dwTextLen;
00293                 break;
00294 
00295             default:
00296                 goto done;
00297         }
00298 
00299         if (!WriteFile(hFile, pBytes, dwByteCount, &dwDummy, NULL))
00300             goto done;
00301 
00302         /* free the buffer, if we have allocated one */
00303         if (pAllocBuffer)
00304         {
00305             HeapFree(GetProcessHeap(), 0, pAllocBuffer);
00306             pAllocBuffer = NULL;
00307         }
00308     }
00309     bSuccess = TRUE;
00310 
00311 done:
00312     if (pAllocBuffer)
00313         HeapFree(GetProcessHeap(), 0, pAllocBuffer);
00314     return bSuccess;
00315 }
00316 
00317 BOOL WriteText(HANDLE hFile, LPCWSTR pszText, DWORD dwTextLen, int iEncoding, int iEoln)
00318 {
00319   WCHAR wcBom;
00320   LPCWSTR pszLF = L"\n";
00321   DWORD dwPos, dwNext;
00322 
00323   /* Write the proper byte order marks if not ANSI */
00324   if (iEncoding != ENCODING_ANSI)
00325   {
00326     wcBom = 0xFEFF;
00327     if (!WriteEncodedText(hFile, &wcBom, 1, iEncoding))
00328       return FALSE;
00329   }
00330 
00331   dwPos = 0;
00332 
00333   /* pszText eoln are always \r\n */
00334 
00335   do
00336   {
00337     /* Find the next eoln */
00338     dwNext = dwPos;
00339     while(dwNext < dwTextLen)
00340     {
00341       if (pszText[dwNext] == '\r' && pszText[dwNext + 1] == '\n')
00342         break;
00343       dwNext++;
00344     }
00345 
00346     if (dwNext != dwTextLen)
00347     {
00348       switch (iEoln)
00349       {
00350       case EOLN_LF:
00351         /* Write text (without eoln) */
00352         if (!WriteEncodedText(hFile, &pszText[dwPos], dwNext - dwPos, iEncoding))
00353           return FALSE;
00354         /* Write eoln */
00355         if (!WriteEncodedText(hFile, pszLF, 1, iEncoding))
00356           return FALSE;
00357         break;
00358       case EOLN_CR:
00359         /* Write text (including \r as eoln) */
00360         if (!WriteEncodedText(hFile, &pszText[dwPos], dwNext - dwPos + 1, iEncoding))
00361           return FALSE;
00362         break;
00363       case EOLN_CRLF:
00364         /* Write text (including \r\n as eoln) */
00365         if (!WriteEncodedText(hFile, &pszText[dwPos], dwNext - dwPos + 2, iEncoding))
00366           return FALSE;
00367         break;
00368       default:
00369         return FALSE;
00370       }
00371     }
00372     else
00373     {
00374       /* Write text (without eoln, since this is the end of the file) */
00375       if (!WriteEncodedText(hFile, &pszText[dwPos], dwNext - dwPos, iEncoding))
00376         return FALSE;
00377     }
00378 
00379     /* Skip \r\n */
00380     dwPos = dwNext + 2;
00381   }
00382   while (dwPos < dwTextLen);
00383 
00384   return TRUE;
00385 }
00386 

Generated on Sun May 27 2012 04:17:18 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.