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
|
@ -44,7 +44,7 @@ DBCS text is supported but conversion output is limited to UCS-2/BMP, surrogate
|
|||
|
||||
\NsisFuncReqU
|
||||
|
||||
Reads a string (UTF-16LE characters) from a file opened with \R{FileOpen}{FileOpen}. The string is read until either a newline (or carriage return newline pair) occurs, or until a null wide-character is read, or until maxlen is met (if specified). By default, strings are limited to 1024 characters (a special build with larger NSIS_MAX_STRLEN can be compiled or downloaded). If the end of file is read and no more data is available, the output string will be empty, and the error flag will be set.
|
||||
Reads a string (UTF-16LE characters) from a file opened with \R{FileOpen}{FileOpen}. The string is read until either a newline (or carriage return newline pair) occurs, or until a null wide-character is read, or until maxlen is met (if specified). By default, strings are limited to 1024 characters (a special build with larger NSIS_MAX_STRLEN can be compiled or downloaded). If the end of file is read and no more data is available, the output string will be empty, and the error flag will be set. If present, the BOM at the start of the file is skipped.
|
||||
|
||||
\c ClearErrors
|
||||
\c FileOpen $0 $INSTDIR\file.dat r
|
||||
|
@ -118,11 +118,11 @@ Writes an ANSI string to a file opened with \R{FileOpen}{FileOpen}. If an error
|
|||
|
||||
\S2{FileWriteUTF16LE} FileWriteUTF16LE
|
||||
|
||||
\c handle string
|
||||
\c [/BOM] handle string
|
||||
|
||||
\NsisFuncReqU
|
||||
|
||||
Writes a Unicode (UTF-16LE) string to a file opened with \R{FileOpen}{FileOpen}. If an error occurs writing, the error flag will be set.
|
||||
Writes a Unicode (UTF-16LE) string to a file opened with \R{FileOpen}{FileOpen}. If an error occurs, the error flag will be set. A BOM can be added to empty files with /BOM.
|
||||
|
||||
\c ClearErrors
|
||||
\c FileOpen $0 $INSTDIR\file.dat w
|
||||
|
|
|
@ -10,10 +10,14 @@ Released on ? ?th, 201?
|
|||
|
||||
\b RequestExecutionLevel now defaults to \c{admin}
|
||||
|
||||
\b FileReadUTF16LE now skips the optional BOM at the start of a file
|
||||
|
||||
\S2{} Minor Changes
|
||||
|
||||
\b Fixed System plugin GUID type output bug on Win98
|
||||
|
||||
\b FileWriteUTF16LE can add a BOM with the /BOM switch
|
||||
|
||||
\b !system and !execute now provide a empty StdIn pipe to work around bugs in some Windows utilities
|
||||
|
||||
\b MakeNSISW now uses WinInet when checking for updates
|
||||
|
|
|
@ -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