Commit abcffadb authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

scrrun: Implement WriteLine/Write for ITextStream.

parent c32ae1b3
......@@ -109,6 +109,8 @@ struct textstream {
LONG ref;
IOMode mode;
BOOL unicode;
BOOL first_write;
HANDLE file;
};
......@@ -209,7 +211,7 @@ static BOOL textstream_check_iomode(struct textstream *This, enum iotype type)
if (type == IORead)
return This->mode == ForWriting || This->mode == ForAppending;
else
return TRUE;
return This->mode == ForReading;
}
static HRESULT WINAPI textstream_QueryInterface(ITextStream *iface, REFIID riid, void **obj)
......@@ -374,18 +376,87 @@ static HRESULT WINAPI textstream_ReadAll(ITextStream *iface, BSTR *text)
return E_NOTIMPL;
}
static HRESULT textstream_writestr(struct textstream *stream, BSTR text)
{
DWORD written = 0;
BOOL ret;
if (stream->unicode) {
if (stream->first_write) {
static const WCHAR utf16bom = 0xfeff;
DWORD written = 0;
BOOL ret = WriteFile(stream->file, &utf16bom, sizeof(utf16bom), &written, NULL);
if (!ret || written != sizeof(utf16bom))
return create_error(GetLastError());
stream->first_write = FALSE;
}
ret = WriteFile(stream->file, text, SysStringByteLen(text), &written, NULL);
return (ret && written == SysStringByteLen(text)) ? S_OK : create_error(GetLastError());
} else {
DWORD len = WideCharToMultiByte(CP_ACP, 0, text, SysStringLen(text), NULL, 0, NULL, NULL);
char *buffA;
HRESULT hr;
buffA = heap_alloc(len);
if (!buffA)
return E_OUTOFMEMORY;
WideCharToMultiByte(CP_ACP, 0, text, SysStringLen(text), buffA, len, NULL, NULL);
ret = WriteFile(stream->file, buffA, len, &written, NULL);
hr = (ret && written == len) ? S_OK : create_error(GetLastError());
heap_free(buffA);
return hr;
}
}
static HRESULT WINAPI textstream_Write(ITextStream *iface, BSTR text)
{
struct textstream *This = impl_from_ITextStream(iface);
FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
return E_NOTIMPL;
TRACE("(%p)->(%s)\n", This, debugstr_w(text));
if (textstream_check_iomode(This, IOWrite))
return CTL_E_BADFILEMODE;
return textstream_writestr(This, text);
}
static HRESULT textstream_writecrlf(struct textstream *stream)
{
static const WCHAR crlfW[] = {'\r','\n'};
static const char crlfA[] = {'\r','\n'};
DWORD written = 0, len;
const void *ptr;
BOOL ret;
if (stream->unicode) {
ptr = crlfW;
len = sizeof(crlfW);
}
else {
ptr = crlfA;
len = sizeof(crlfA);
}
ret = WriteFile(stream->file, ptr, len, &written, NULL);
return (ret && written == len) ? S_OK : create_error(GetLastError());
}
static HRESULT WINAPI textstream_WriteLine(ITextStream *iface, BSTR text)
{
struct textstream *This = impl_from_ITextStream(iface);
FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
return E_NOTIMPL;
HRESULT hr;
TRACE("(%p)->(%s)\n", This, debugstr_w(text));
if (textstream_check_iomode(This, IOWrite))
return CTL_E_BADFILEMODE;
hr = textstream_writestr(This, text);
if (SUCCEEDED(hr))
hr = textstream_writecrlf(This);
return hr;
}
static HRESULT WINAPI textstream_WriteBlankLines(ITextStream *iface, LONG lines)
......@@ -439,7 +510,7 @@ static const ITextStreamVtbl textstreamvtbl = {
textstream_Close
};
static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMode mode, ITextStream **ret)
static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMode mode, BOOL unicode, ITextStream **ret)
{
struct textstream *stream;
DWORD access = 0;
......@@ -466,6 +537,8 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod
stream->ITextStream_iface.lpVtbl = &textstreamvtbl;
stream->ref = 1;
stream->mode = mode;
stream->unicode = unicode;
stream->first_write = TRUE;
stream->file = CreateFileW(filename, access, 0, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL);
if (stream->file == INVALID_HANDLE_VALUE)
......@@ -3295,7 +3368,7 @@ static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR filename,
TRACE("%p %s %d %d %p\n", iface, debugstr_w(filename), overwrite, unicode, stream);
disposition = overwrite == VARIANT_TRUE ? CREATE_ALWAYS : CREATE_NEW;
return create_textstream(filename, disposition, ForWriting, stream);
return create_textstream(filename, disposition, ForWriting, !!unicode, stream);
}
static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename,
......@@ -3306,7 +3379,13 @@ static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename,
TRACE("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream);
disposition = create == VARIANT_TRUE ? OPEN_ALWAYS : OPEN_EXISTING;
return create_textstream(filename, disposition, mode, stream);
if (format == TristateUseDefault) {
FIXME("default format not handled, defaulting to unicode\n");
format = TristateTrue;
}
return create_textstream(filename, disposition, mode, format == TristateTrue, stream);
}
static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface,
......
......@@ -54,10 +54,10 @@ library Scripting
typedef enum Tristate
{
TristateTrue = 0xffffffff,
TristateFalse = 0,
TristateUseDefault = 0xfffffffe,
TristateMixed = 0xfffffffe
TristateTrue = -1,
TristateFalse = 0,
TristateUseDefault = -2,
TristateMixed = -2
} Tristate;
typedef enum FileAttribute
......
......@@ -192,6 +192,13 @@ static void test_textstream(void)
hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* try to write when open for reading */
hr = ITextStream_WriteLine(stream, name);
ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
hr = ITextStream_Write(stream, name);
ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
b = 10;
hr = ITextStream_get_AtEndOfStream(stream, &b);
todo_wine {
......@@ -1265,6 +1272,81 @@ static void test_CreateTextFile(void)
SysFreeString(nameW);
}
static void test_WriteLine(void)
{
static const WCHAR scrrunW[] = {'s','c','r','r','u','n','\\',0};
static const WCHAR testfileW[] = {'t','e','s','t','.','t','x','t',0};
static const WCHAR crlfW[] = {'\r','\n',0};
WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
WCHAR buffW[MAX_PATH], buff2W[MAX_PATH];
char buffA[MAX_PATH];
ITextStream *stream;
DWORD r, len;
HANDLE file;
BSTR nameW;
HRESULT hr;
BOOL ret;
GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
lstrcatW(pathW, scrrunW);
lstrcpyW(dirW, pathW);
lstrcatW(pathW, testfileW);
ret = CreateDirectoryW(dirW, NULL);
ok(ret, "got %d, %d\n", ret, GetLastError());
/* create as ASCII file first */
nameW = SysAllocString(pathW);
hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = ITextStream_WriteLine(stream, nameW);
ok(hr == S_OK, "got 0x%08x\n", hr);
ITextStream_Release(stream);
/* check contents */
file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
r = 0;
ret = ReadFile(file, buffA, sizeof(buffA), &r, NULL);
ok(ret && r, "read %d, got %d, %d\n", r, ret, GetLastError());
len = MultiByteToWideChar(CP_ACP, 0, buffA, r, buffW, sizeof(buffW)/sizeof(WCHAR));
buffW[len] = 0;
lstrcpyW(buff2W, nameW);
lstrcatW(buff2W, crlfW);
ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
CloseHandle(file);
DeleteFileW(nameW);
/* same for unicode file */
hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = ITextStream_WriteLine(stream, nameW);
ok(hr == S_OK, "got 0x%08x\n", hr);
ITextStream_Release(stream);
/* check contents */
file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
r = 0;
ret = ReadFile(file, buffW, sizeof(buffW), &r, NULL);
ok(ret && r, "read %d, got %d, %d\n", r, ret, GetLastError());
buffW[r/sizeof(WCHAR)] = 0;
buff2W[0] = 0xfeff;
buff2W[1] = 0;
lstrcatW(buff2W, nameW);
lstrcatW(buff2W, crlfW);
ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
CloseHandle(file);
DeleteFileW(nameW);
RemoveDirectoryW(dirW);
SysFreeString(nameW);
}
START_TEST(filesystem)
{
HRESULT hr;
......@@ -1294,6 +1376,7 @@ START_TEST(filesystem)
test_FileCollection();
test_DriveCollection();
test_CreateTextFile();
test_WriteLine();
IFileSystem3_Release(fs3);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment