Commit 94e36475 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcrt: Added support for unicode mode in write function.

parent 617bf861
...@@ -2586,89 +2586,170 @@ int CDECL _wutime(const MSVCRT_wchar_t* path, struct MSVCRT___utimbuf32 *t) ...@@ -2586,89 +2586,170 @@ int CDECL _wutime(const MSVCRT_wchar_t* path, struct MSVCRT___utimbuf32 *t)
*/ */
int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count) int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count)
{ {
DWORD num_written; DWORD num_written;
HANDLE hand = msvcrt_fdtoh(fd); ioinfo *info = msvcrt_get_ioinfo(fd);
HANDLE hand = info->handle;
/* Don't trace small writes, it gets *very* annoying */ /* Don't trace small writes, it gets *very* annoying */
#if 0 #if 0
if (count > 32) if (count > 32)
TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count); TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count);
#endif #endif
if (hand == INVALID_HANDLE_VALUE) if (hand == INVALID_HANDLE_VALUE)
{ {
*MSVCRT__errno() = MSVCRT_EBADF; *MSVCRT__errno() = MSVCRT_EBADF;
return -1; return -1;
}
if (((info->exflag&EF_UTF8) || (info->exflag&EF_UTF16)) && count&1)
{
*MSVCRT__errno() = MSVCRT_EINVAL;
return -1;
} }
/* If appending, go to EOF */ /* If appending, go to EOF */
if (msvcrt_get_ioinfo(fd)->wxflag & WX_APPEND) if (info->wxflag & WX_APPEND)
MSVCRT__lseek(fd, 0, FILE_END); MSVCRT__lseek(fd, 0, FILE_END);
if (!(msvcrt_get_ioinfo(fd)->wxflag & WX_TEXT)) if (!(info->wxflag & WX_TEXT))
{ {
if (WriteFile(hand, buf, count, &num_written, NULL) if (WriteFile(hand, buf, count, &num_written, NULL)
&& (num_written == count)) && (num_written == count))
return num_written; return num_written;
TRACE("WriteFile (fd %d, hand %p) failed-last error (%d)\n", fd, TRACE("WriteFile (fd %d, hand %p) failed-last error (%d)\n", fd,
hand, GetLastError()); hand, GetLastError());
*MSVCRT__errno() = MSVCRT_ENOSPC; *MSVCRT__errno() = MSVCRT_ENOSPC;
} }
else else
{ {
unsigned int i, j, nr_lf; unsigned int i, j, nr_lf, size;
char *p = NULL; char *p = NULL;
const char *q; const char *q;
const char *s = buf, *buf_start = buf; const char *s = buf, *buf_start = buf;
/* find number of \n ( without preceding \r ) */
for ( nr_lf=0,i = 0; i <count; i++)
{
if (s[i]== '\n')
{
nr_lf++;
/*if ((i >1) && (s[i-1] == '\r')) nr_lf--; */
}
}
if (nr_lf)
{
if ((q = p = MSVCRT_malloc(count + nr_lf)))
{
for (s = buf, i = 0, j = 0; i < count; i++)
{
if (s[i]== '\n')
{
p[j++] = '\r';
/*if ((i >1) && (s[i-1] == '\r'))j--;*/
}
p[j++] = s[i];
}
}
else
{
FIXME("Malloc failed\n");
nr_lf =0;
q = buf;
}
}
else
q = buf;
if ((WriteFile(hand, q, count+nr_lf, &num_written, NULL) == 0 ) || (num_written != count+nr_lf)) if (!(info->exflag & (EF_UTF8|EF_UTF16)))
{ {
TRACE("WriteFile (fd %d, hand %p) failed-last error (%d), num_written %d\n", /* find number of \n */
fd, hand, GetLastError(), num_written); for (nr_lf=0, i=0; i<count; i++)
*MSVCRT__errno() = MSVCRT_ENOSPC; if (s[i] == '\n')
if(nr_lf) nr_lf++;
MSVCRT_free(p); if (nr_lf)
return s - buf_start; {
} size = count+nr_lf;
else if ((q = p = MSVCRT_malloc(size)))
{ {
if(nr_lf) for (s = buf, i = 0, j = 0; i < count; i++)
MSVCRT_free(p); {
return count; if (s[i] == '\n')
} p[j++] = '\r';
} p[j++] = s[i];
return -1; }
}
else
{
FIXME("Malloc failed\n");
nr_lf = 0;
size = count;
q = buf;
}
}
else
{
size = count;
q = buf;
}
}
else if (info->exflag & EF_UTF16)
{
for (nr_lf=0, i=0; i<count; i+=2)
if (s[i]=='\n' && s[i+1]==0)
nr_lf += 2;
if (nr_lf)
{
size = count+nr_lf;
if ((q = p = MSVCRT_malloc(size)))
{
for (s=buf, i=0, j=0; i<count; i++)
{
if (s[i]=='\n' && s[i+1]==0)
{
p[j++] = '\r';
p[j++] = 0;
}
p[j++] = s[i++];
p[j++] = s[i];
}
}
else
{
FIXME("Malloc failed\n");
nr_lf = 0;
size = count;
q = buf;
}
}
else
{
size = count;
q = buf;
}
}
else
{
DWORD conv_len;
for(nr_lf=0, i=0; i<count; i+=2)
if (s[i]=='\n' && s[i+1]==0)
nr_lf++;
conv_len = WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)buf, count/2, NULL, 0, NULL, NULL);
if(!conv_len) {
msvcrt_set_errno(GetLastError());
MSVCRT_free(p);
return -1;
}
size = conv_len+nr_lf;
if((p = MSVCRT_malloc(count+nr_lf*2+size)))
{
for (s=buf, i=0, j=0; i<count; i++)
{
if (s[i]=='\n' && s[i+1]==0)
{
p[j++] = '\r';
p[j++] = 0;
}
p[j++] = s[i++];
p[j++] = s[i];
}
q = p+count+nr_lf*2;
WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)p, count/2+nr_lf,
p+count+nr_lf*2, conv_len+nr_lf, NULL, NULL);
}
else
{
FIXME("Malloc failed\n");
nr_lf = 0;
size = count;
q = buf;
}
}
if (!WriteFile(hand, q, size, &num_written, NULL))
num_written = -1;
if(p)
MSVCRT_free(p);
if (num_written != size)
{
TRACE("WriteFile (fd %d, hand %p) failed-last error (%d), num_written %d\n",
fd, hand, GetLastError(), num_written);
*MSVCRT__errno() = MSVCRT_ENOSPC;
return s - buf_start;
}
return count;
}
return -1;
} }
/********************************************************************* /*********************************************************************
......
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