📄 write.c
字号:
}
}
if (bCR) {
size = 1;
mboutbuf[0] = CR;
if (WriteFile((HANDLE)_osfhnd(fh),
mboutbuf,
size,
(LPDWORD)&written,
NULL) ) {
if (written < size)
break;
lfcount ++;
charcount++;
} else {
dosretval = GetLastError();
break;
}
}
}
else if ( tmode == __IOINFO_TM_UTF8 || tmode == __IOINFO_TM_UTF16LE)
{
if ( _putwch_nolock(tmpchar) == tmpchar )
{
charcount+=2;
}
else
{
dosretval = GetLastError();
break;
}
if (bCR) /* emit carriage return */
{
size = 1;
tmpchar = CR;
if ( _putwch_nolock(tmpchar) == tmpchar )
{
charcount++;
lfcount++;
}
else
{
dosretval = GetLastError();
break;
}
}
}
}
} else if ( _osfile(fh) & FTEXT ) {
/* text mode, translate LF's to CR/LF's on output */
dosretval = 0; /* no OS error yet */
if(tmode == __IOINFO_TM_ANSI) {
char ch; /* current character */
char *p = NULL, *q = NULL; /* pointers into buf and lfbuf resp. */
char lfbuf[BUF_SIZE];
p = (char *)buf; /* start at beginning of buffer */
while ( (unsigned)(p - (char *)buf) < cnt ) {
q = lfbuf; /* start at beginning of lfbuf */
/* fill the lf buf, except maybe last char */
while ( q - lfbuf < sizeof(lfbuf) - 1 &&
(unsigned)(p - (char *)buf) < cnt ) {
ch = *p++;
if ( ch == LF ) {
++lfcount;
*q++ = CR;
}
*q++ = ch;
}
/* write the lf buf and update total */
if ( WriteFile( (HANDLE)_osfhnd(fh),
lfbuf,
(int)(q - lfbuf),
(LPDWORD)&written,
NULL) )
{
charcount += written;
if (written < q - lfbuf)
break;
}
else {
dosretval = GetLastError();
break;
}
}
} else if ( tmode == __IOINFO_TM_UTF16LE ){
char lfbuf[BUF_SIZE];
wchar_t wch; /* current wide char */
wchar_t *pu = (wchar_t *)buf;
wchar_t *qu = NULL;
while ( (unsigned)((char *)pu - (char *)buf) < cnt ) {
qu = (wchar_t *)lfbuf; /* start at beginning of lfbuf */
/* fill the lf buf, except maybe last wchar_t */
while ( (((char *)qu - lfbuf) < (sizeof(lfbuf) - 2)) &&
((unsigned)((char *)pu - (char *)buf) < cnt )) {
wch = *pu++;
if ( wch == LF ) {
lfcount+=2;
*qu++ = CR;
}
*qu++ = wch;
}
/* write the lf buf and update total */
if ( WriteFile( (HANDLE)_osfhnd(fh),
lfbuf,
(int)((char*)qu - lfbuf),
(LPDWORD)&written,
NULL) )
{
charcount += written;
if (written < ((char *)qu - lfbuf))
break;
}
else {
dosretval = GetLastError();
break;
}
}
} else {
/*
* Let's divide the lfbuf in 1:2 wher 1 is for storing
* widecharacters and 2 if for converting it to UTF8. This takes
* into account the worst case scenario where all the UTF8
* characters are 4 byte long.
*/
char utf8_buf[(BUF_SIZE*2)/3];
wchar_t utf16_buf[BUF_SIZE/6];
wchar_t wch; /* current wide char */
wchar_t *pu = (wchar_t *)buf;
wchar_t *qu = NULL;
pu = (wchar_t *)buf;
while ((unsigned)((char *)pu - (char *)buf) < cnt) {
int bytes_converted = 0;
qu = utf16_buf; /* start at beginning of lfbuf */
while ( (((char *)qu - (char *)utf16_buf) <
(sizeof(utf16_buf) - 2)) &&
((unsigned)((char *)pu - (char *)buf) < cnt )) {
wch = *pu++;
if ( wch == LF ) {
/* no need to count the linefeeds here: we calculate the written chars in another way */
*qu++ = CR;
}
*qu++ = wch;
}
bytes_converted = WideCharToMultiByte(
CP_UTF8,
0,
utf16_buf,
((int)((char *)qu - (char *)utf16_buf))/2,
utf8_buf,
sizeof(utf8_buf),
NULL,
NULL);
if (bytes_converted == 0) {
dosretval = GetLastError();
break;
} else {
/*
* Here we need to make every attempt to write all the
* converted characters. The resaon behind this is,
* incase half the bytes of a UTF8 character is
* written, it may currupt whole of the stream or file.
*
* The loop below will make sure we exit only if all
* the bytes converted are written (which makes sure no
* partial MBCS is written) or there was some error in
* the stream.
*/
int bytes_written = 0;
do {
if (WriteFile(
(HANDLE)_osfhnd(fh),
utf8_buf + bytes_written,
bytes_converted - bytes_written,
&written,
NULL)) {
bytes_written += written;
} else {
dosretval = GetLastError();
break;
}
} while ( bytes_converted > bytes_written);
/*
* Only way the condition below could be true is if
* there was en error. In case of error we need to
* break this loop as well.
*/
if (bytes_converted > bytes_written) {
break;
}
/* if this chunk has been committed successfully, update charcount */
charcount = (int)((char *)pu - (char *)buf);
}
}
}
}
else {
/* binary mode, no translation */
if ( WriteFile( (HANDLE)_osfhnd(fh),
(LPVOID)buf,
cnt,
(LPDWORD)&written,
NULL) )
{
dosretval = 0;
charcount = written;
}
else
dosretval = GetLastError();
}
if (charcount == 0) {
/* If nothing was written, first check if an o.s. error,
otherwise we return -1 and set errno to ENOSPC,
unless a device and first char was CTRL-Z */
if (dosretval != 0) {
/* o.s. error happened, map error */
if (dosretval == ERROR_ACCESS_DENIED) {
/* wrong read/write mode should return EBADF, not
EACCES */
errno = EBADF;
_doserrno = dosretval;
}
else
_dosmaperr(dosretval);
return -1;
}
else if ((_osfile(fh) & FDEV) && *(char *)buf == CTRLZ)
return 0;
else {
errno = ENOSPC;
_doserrno = 0; /* no o.s. error */
return -1;
}
}
else
/* return adjusted bytes written */
return charcount - lfcount;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -