Корректная перекодировка KOI в WIN
Страница 2. Программы перекодировки KOI в WIN


 

Программы перекодировки KOI в WIN

#ifndef __CODEPAGE_H__
#define __CODEPAGE_H__

// Константы для кодовых страниц
#define CP_KOI8       20866
#define CP_KOI8R      20866
#define CP_KOI8U      21866
#define CP_ISO_8859_5 28595

// Исключительно для удобства
#define CP_1251       1251

// Прототип функции-обертки
BOOL ConvertCP(UINT uiIN, UINT uiOUT, LPSTR lpString);

// Инлайновые обертки для сокращения кода

// Самая нужная из них
inline BOOL ConvertCP(UINT uiIN, UINT uiOUT, CString& szString){
 
BOOL bRet = ConvertCP(uiIN, uiOUT, szString.GetBuffer(szString.GetLength()+1));
 
szString.ReleaseBuffer();
 
return bRet;
}

// Аналогичные можно определить по вкусу, смотря какое
// преобразование используется чаще
inline BOOL ConvertToKOI8(UINT uiIN, LPSTR lpString){
 
return(ConvertCP(uiIN, CP_KOI8R, lpString));
}

inline BOOL ConvertFromKOI8(UINT uiOUI, LPSTR lpString){
 
return(ConvertCP(CP_KOI8R, uiOUI, lpString));
}


inline BOOL ConvertToKOI8(UINT uiIN, CString& szString){
 
return(ConvertCP(uiIN, CP_KOI8R, szString));
}

inline BOOL ConvertFromKOI8(UINT uiOUI, CString& szString){
 
return(ConvertCP(CP_KOI8R, uiOUI, szString));
}

#endif

#include "stdafx.h"
#include "codepage.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Преобразование кодировки "на месте"
BOOL ConvertCP(UINT uiIN, UINT uiOUT, LPSTR lpString){
 
if(!lpString) return FALSE; // Получили NULL - нехорошо, ошибочка
 
if(!lpString[0]) return TRUE; // Пустая строка - OK, преобразования не надо

 // Сперва определяем необходимый размер промежуточного буфера
 
int nRet = MultiByteToWideChar(uiIN, MB_PRECOMPOSED, lpString, -1, NULL, 0);
 
if(nRet == 0) return FALSE;

 
// Создаем его
 
WCHAR* pwcBuffer = new WCHAR[nRet+2];

 
// Преобразование uiIN -> Юникод
 
nRet = MultiByteToWideChar(uiIN, MB_PRECOMPOSED, lpString, -1, pwcBuffer, nRet+2);
 
if(nRet ==

   
delete[] pwcBuffer;
   
return FALSE;
 }

 
// Преобразование Юникод -> uiOUT.
 // Неизвестные символы заменяем "#". Кому такое поведение не нравится, может
 // "поиграть" с параметрами WideCharToMultiByte()
 
nRet = WideCharToMultiByte(uiOUT, 0, pwcBuffer, -1, lpString, strlen(lpString)+1, "#", NULL);
 
// Освобождаем память
 
delete[] pwcBuffer;

 
if(nRet == 0) return FALSE;

 
return TRUE;
}

//из ДОС в Windows
char* Decode_DOS_to_Win(char * str)
{
   
unsigned char *cstr=str; // "unsigned" - чтоб избежать предупреждений комп-ра
   
for(; *cstr; cstr++)
   {
       
if(*cstr<128) continue; // не фиг топтаться дальше, если не нужно конвертить!

       
if(*cstr>=128 && *cstr<=175)
           *
cstr+=64;
       
else if(*cstr>=224 && *cstr<=239)
           *
cstr+=16;
       
else if(*cstr==252) // №
           
*cstr=185;
       
else if(*cstr==240) // Ё, Е с двумя точками - Йо
           
*cstr=168;
       
else if(*cstr==241) //  Ё, е с двумя точками - йо
           
*cstr=184;
       
else if(*cstr==242) // Є, украинское Йе
           
*cstr=170;
       
else if(*cstr==243) // є, украинское йе
           
*cstr=186;
       
else if(*cstr==244) // Ї, украинское Йи
           
*cstr=175;
       
else if(*cstr==245) // ї, украинское йи
           
*cstr=191;
       
else if(*cstr==246) // Ў, беларусская У с хвостиком вверху - черт знает, как читается
           
*cstr=161;
       
else if(*cstr==247) // ў, беларусская У с хвостиком вверху - черт знает, как читается
           
*cstr=162;
       
else if(*cstr==248) // знак градуса
           
*cstr=176;
       
else if(*cstr==250) // маленькая центровая точка
           
*cstr=183;
       
else
           
*cstr='?'; // некий символ, которым заменять несуществующие в CP1251
   
}
   
return str;
}

//из Windows в ДОС
char* Decode_Win_to_DOS(char * str)
{
   
unsigned char *cstr=str;
   
for(;*cstr;cstr++)
   {
       
if(*cstr<128) continue; // не фиг топтаться дальше, если не нужно конвертить!

       
if(*cstr>=240)
           *
cstr-=16;
       
else if(*cstr>=192)
           *
cstr-=64;
       
else if(*cstr==185) // №
           
*cstr=252;
       
else if(*cstr==168) // Ё, Е с двумя точками - Йо
           
*cstr=240;
       
else if(*cstr==184) //  Ё, е с двумя точками - йо
           
*cstr=241;
       
else if(*cstr==170) // Є, украинское Йе
           
*cstr=242;
       
else if(*cstr==186) // є, украинское йе
           
*cstr=243;
       
else if(*cstr==175) // Ї, украинское Йи
           
*cstr=244;
       
else if(*cstr==191) // ї, украинское йи
           
*cstr=245;
       
else if(*cstr==178) // I, украинское И
           
*cstr=73;            // в английскую, т.к. в ДОСе нет
       
else if(*cstr==179) // i, украинское и
           
*cstr=105;         // в английскую, т.к. в ДОСе нет
       
else if(*cstr==161) // Ў, беларусская У с хвостиком вверху - черт знает, как читается
           
*cstr=246;
       
else if(*cstr==162) // ў, беларусская У с хвостиком вверху - черт знает, как читается
           
*cstr=247;
       
else if(*cstr==176) // знак градуса
           
*cstr=248;
       
else if(*cstr==183) // маленькая центровая точка
           
*cstr=250;
       
else
           
*cstr='?'; // некий символ, которым заменять несуществующие в CP1251
   
}
   
return str;
}
 
« Предыдущая статья   Следующая статья »