WinCEでのファイル入出力

投稿者: | 2005年12月2日

今作成中のSQLite用ツールにテキストファイル読み込みの処理を追加しようと格闘中。
やはり、文字コードの問題が立ちはだかる。
このあたりの情報がネット上にあまり無い。まあ、たぶん見方が悪いのだろうけど。
ソース公開しているソフトを参考にしようと思って、いろいろ探していたらこんなサイト(l’agenda 仕様 サンプルアプリケーション UNICODE SHIFT-JIS 対応テキストビューワ)を発見。
ソフトウエアコンテストの企画に絡めた記事のようだ。添付されていたソースを参考にファイル読み込み処理を検討してみた。


ファイル名取得の後の処理に絞ってまとめてみた。

TCHAR TextBuffer[MAX_TEXT + 1];
TCHAR szFileName[MAX_PATH + 1] = _T(“”);
ReadTextFile(szFileName, TextBuffer, MAX_TEXT + 1)
m_Sqline = TextBuffer;
BOOL ReadTextFile(TCHAR *name, TCHAR *buf, DWORD num)
{
    memset(buf, 0, num * sizeof(TCHAR));
    DWORD readSize;
    BYTE *ptr = ReadAllFile(name, &readSize);
    if (!readSize){
        return(TRUE);
    } else if (!ptr){
        return(FALSE);
    }
    if (*(TCHAR *) ptr == 0xfeff){
        _tcscpy(buf, ((TCHAR *) ptr) + 1);
    } else {
        MultiByteToWideChar(CP_ACP, 0, (const char *) ptr, readSize, buf, num - 1);
    }
    LocalFree(ptr);
    return(ExchangeReturn(buf, num));
}
BYTE *ReadAllFile(TCHAR *name, DWORD *size)
{
    HANDLE hFile = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE){
        return(NULL);
    }
    BYTE *ptr = NULL;
    *size = GetFileSize(hFile, NULL);
    if ((*size) && (*size != 0xFFFFFFFF)){
        ptr = (BYTE *) LocalAlloc(LMEM_FIXED, *size + 2);
        if (ptr){
            DWORD readSize;
            memset(ptr, 0, *size + 2);
            if (!ReadFile(hFile, ptr, *size, &readSize, NULL)){
                LocalFree(ptr);
                ptr = NULL;
            }
        }
    }
    CloseHandle(hFile);
    return(ptr);
}
BOOL ExchangeReturn(TCHAR *buf, DWORD num)
{
TCHAR *src = buf;
TCHAR *dst;
if ((dst = (TCHAR *) LocalAlloc(LMEM_FIXED, num * sizeof(TCHAR))) == NULL){
return(FALSE);
}
TCHAR *ptr = dst;
TCHAR *end = ptr + (num - 1);
memset(ptr, 0, num * sizeof(TCHAR));
while(1){
TCHAR code = *buf++;
if (!code){
break;
}
TCHAR code2 = *buf;
if ((code == 0x000d) || (code == 0x000a)){
if ((code == 0x000d) && (code2 == 0x000a)){
buf++;
}
*ptr++ = 0x000d;
if (ptr >= end){
*(ptr - 1) = _T(‘\0’);
break;
}
*ptr++ = 0x000a;
}
else{
*ptr++ = code;
}
if (ptr >= end){
break;
}
}
memcpy(src, dst, num * sizeof(TCHAR));
LocalFree(dst);
return(TRUE);
}

ちゃんと、Shift-JISとUNICODEのテキストファイルが読み込めるようになった。
三つ目の関数は改行コードの変換だ。
改行が CR+LF、CRのみ及びLFのみのそれぞれに対応するための処理だ。