FileReadUTF16LE skips optional BOM and FileWriteUTF16LE can write a BOM with the /BOM switch
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6626 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
37c81f74f8
commit
b54c831ff0
7 changed files with 59 additions and 13 deletions
|
@ -1370,11 +1370,12 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
DWORD dw;
|
||||
int l; // number of bytes to write
|
||||
TCHAR *t=var0;
|
||||
if (parm2) // FileWriteByte or FileWriteWord
|
||||
const int writeCodPt = parm2, ansi = EW_FPUTS == which;
|
||||
if (writeCodPt) // FileWriteByte or FileWriteWord
|
||||
{
|
||||
// Note: In Unicode version, we put a WORD in buf1[0] and will write 1 or 2 bytes, depending on FileWriteByte/Word.
|
||||
((_TUCHAR *)buf1)[0]=(_TUCHAR) GetIntFromParm(1); // FIX_ENDIAN_INT16 needed?
|
||||
l=(which==EW_FPUTS)?1:sizeof(TCHAR); // Note: This is optimized by the compiler into l=1 for ANSI compilation
|
||||
l=(ansi)?1:sizeof(TCHAR);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
else if (which==EW_FPUTS)
|
||||
|
@ -1388,10 +1389,16 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
{
|
||||
l=mystrlen(GetStringFromParm(0x11))*sizeof(TCHAR);
|
||||
}
|
||||
if (!*t || !WriteFile((HANDLE)strtoiptr(t),buf1,l,&dw,NULL))
|
||||
if (*t)
|
||||
{
|
||||
exec_error++;
|
||||
const HANDLE hFile = (HANDLE) strtoiptr(t);
|
||||
#ifdef _UNICODE
|
||||
if ((ansi | writeCodPt) || !parm3 || SUCCEEDED(UTF16LEBOM(hFile,(INT_PTR)hFile)))
|
||||
#endif
|
||||
if (WriteFile(hFile,buf1,l,&dw,NULL))
|
||||
break; // Success
|
||||
}
|
||||
exec_error++;
|
||||
}
|
||||
break;
|
||||
case EW_FGETS:
|
||||
|
@ -1433,6 +1440,9 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
if (!parm3 && 0 == rpos && FAILED(UTF16LEBOM(h,FALSE))) break;
|
||||
#endif
|
||||
// Read 1 TCHAR (FileReadUTF16LE, (Ansi)FileRead, FileReadWord)
|
||||
if (!myReadFile(h,&c,sizeof(TCHAR))) break;
|
||||
}
|
||||
|
|
|
@ -456,6 +456,31 @@ BOOL NSISCALL myReadFile(HANDLE h, LPVOID buf, DWORD cb)
|
|||
return r && cb == cbio;
|
||||
}
|
||||
|
||||
// Reading skips the BOM if present, writing writes it to a empty file
|
||||
HRESULT NSISCALL UTF16LEBOM(HANDLE h, INT_PTR ForWrite)
|
||||
{
|
||||
DWORD orgpos = SetFilePointer(h, 0, NULL, FILE_CURRENT), cbio;
|
||||
if (0 == orgpos)
|
||||
{
|
||||
BYTE bom[2];
|
||||
if (myReadFile(h, bom, 2) && (0xff == bom[0] && 0xfe == bom[1]))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
else if (ForWrite)
|
||||
{
|
||||
if (0 == SetFilePointer(h, 0, NULL, FILE_CURRENT)) // Is the file empty?
|
||||
{
|
||||
static const BYTE bom16le[] = { 0xff, 0xfe };
|
||||
return (WriteFile(h, bom16le, 2, &cbio, NULL) && 2 == cbio)
|
||||
? S_OK : E_FAIL;
|
||||
}
|
||||
}
|
||||
SetFilePointer(h, 0, NULL, FILE_BEGIN); // The file may have starting with something that was not a BOM, undo the read
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
||||
#ifndef _WIN64
|
||||
/** Modifies the wininit.ini file to rename / delete a file.
|
||||
|
|
|
@ -44,6 +44,7 @@ TCHAR * NSISCALL mystrstr(TCHAR *a, TCHAR *b);
|
|||
WIN32_FIND_DATA * NSISCALL file_exists(TCHAR *buf);
|
||||
TCHAR * NSISCALL my_GetTempFileName(TCHAR *buf, const TCHAR *dir);
|
||||
BOOL NSISCALL myReadFile(HANDLE h, LPVOID buf, DWORD cb);
|
||||
HRESULT NSISCALL UTF16LEBOM(HANDLE h, INT_PTR ForWrite);
|
||||
|
||||
//BOOL NSISCALL my_SetWindowText(HWND hWnd, const TCHAR *val);
|
||||
#define my_SetWindowText SetWindowText
|
||||
|
|
|
@ -5690,11 +5690,17 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
ERROR_MSG(_T("Error: %") NPRIs _T(" is only available when building a Unicode installer\n"), line.gettoken_str(0));
|
||||
return PS_ERROR;
|
||||
}
|
||||
ent.which=EW_FPUTWS;
|
||||
ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
|
||||
ent.offsets[1]=add_string(line.gettoken_str(2));
|
||||
if (ent.offsets[0]<0) PRINTHELP()
|
||||
SCRIPT_MSG(_T("FileWriteUTF16LE: %") NPRIs _T("->%") NPRIs _T("\n"),line.gettoken_str(2),line.gettoken_str(1));
|
||||
{
|
||||
UINT bom=0, swofs=0;
|
||||
if (!_tcsicmp(_T("/BOM"),line.gettoken_str(swofs+1))) ++bom, ++swofs;
|
||||
if (!_tcsicmp(_T("/NoBOM"),line.gettoken_str(swofs+1))) bom = 0, ++swofs; // Undocumented switch
|
||||
ent.which=EW_FPUTWS;
|
||||
ent.offsets[0]=GetUserVarIndex(line, swofs+1); // file handle
|
||||
ent.offsets[1]=add_string(line.gettoken_str(swofs+2));
|
||||
ent.offsets[3]=bom;
|
||||
if (ent.offsets[0]<0 || line.getnumtokens()-swofs != 3) PRINTHELP()
|
||||
SCRIPT_MSG(_T("FileWriteUTF16LE: %") NPRIs _T("->%") NPRIs _T("\n"),line.gettoken_str(swofs+2),line.gettoken_str(swofs+1));
|
||||
}
|
||||
return add_entry(&ent);
|
||||
case TOK_FILEREADWORD:
|
||||
if (!build_unicode)
|
||||
|
|
|
@ -99,7 +99,7 @@ static tokenType tokenlist[TOK__LAST] =
|
|||
{TOK_FILEWRITEBYTE,_T("FileWriteByte"),2,0,_T("$(user_var: handle input) bytevalue"),TP_CODE},
|
||||
#ifdef _UNICODE
|
||||
{TOK_FILEREADUTF16LE,_T("FileReadUTF16LE"),2,1,_T("$(user_var: handle input) $(user_var: text output) [maxlen]"),TP_CODE},
|
||||
{TOK_FILEWRITEUTF16LE,_T("FileWriteUTF16LE"),2,0,_T("$(user_var: handle input) text"),TP_CODE},
|
||||
{TOK_FILEWRITEUTF16LE,_T("FileWriteUTF16LE"),2,1,_T("[/BOM] $(user_var: handle input) text"),TP_CODE},
|
||||
{TOK_FILEREADWORD,_T("FileReadWord"),2,0,_T("$(user_var: handle input) $(user_var: wordvalue output)"),TP_CODE},
|
||||
{TOK_FILEWRITEWORD,_T("FileWriteWord"),2,0,_T("$(user_var: handle input) wordvalue"),TP_CODE},
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue