📄 read.c
字号:
else {
/* *p is CR, so must check next char for LF */
if (p < (char *)buf + bytes_read - 1) {
if (*(p+1) == LF) {
p += 2;
*q++ = LF; /* convert CR-LF to LF */
}
else
*q++ = *p++; /* store char normally */
}
else {
/* This is the hard part. We found a CR at end of
buffer. We must peek ahead to see if next char
is an LF. */
++p;
dosretval = 0;
if ( !ReadFile( (HANDLE)_osfhnd(fh), &peekchr, 1,
(LPDWORD)&os_read, NULL ) )
dosretval = GetLastError();
if (dosretval != 0 || os_read == 0) {
/* couldn't read ahead, store CR */
*q++ = CR;
}
else {
/*
* peekchr now has the extra character -- we now
* have several possibilities:
*
* 1. disk file and char is not LF; just seek
* back and copy CR
* 2. disk file and char is LF; seek back and
* discard CR
* 3. disk file, char is LF but this is a
* one-byte read: store LF, don't seek back
* 4. pipe/device and char is LF; store LF.
* 5. pipe/device and char isn't LF, store CR
* and put char in pipe lookahead buffer.
*/
if (_osfile(fh) & (FDEV|FPIPE)) {
/* non-seekable device */
if (peekchr == LF)
*q++ = LF;
else {
*q++ = CR;
_pipech(fh) = peekchr;
}
}
else {
/* disk file */
if (q == buf && peekchr == LF) {
/* nothing read yet; must make some
progress */
*q++ = LF;
}
else {
/* seek back */
filepos = _lseeki64_nolock(fh, -1i64, FILE_CURRENT);
if (peekchr != LF)
*q++ = CR;
}
}
}
}
}
}
/* we now change bytes_read to reflect the true number of chars
in the buffer */
bytes_read = (int)(q - (char *)buf);
if((tmode == __IOINFO_TM_UTF8) && (bytes_read != 0)) {
/* UTF8 reads need to be converted into UTF16 */
--q; /* q has gone beyond the last char */
/*
* If the last byte is a standalone UTF-8 char. We then
* take the whole buffer. Otherwise we skip back till we
* come to a lead byte. If the leadbyte forms a complete
* UTF-8 character will the remaining part of the buffer,
* then again we take the whole buffer. If not, we skip to
* one byte which should be the final trail byte of the
* previous UTF-8 char or a standalone UTF-8 character
*/
if(_utf8_is_independent(*q)) {
++q;
/*
* Final byte is standalone, we reset q, because we
* will now consider the full buffer which we have read
*/
}
else {
int ctr = 1;
int cnt_trailbytes;
while(!_utf8_is_leadbyte(*q) && ctr <= 4 && q >= (char *)buf) {
--q;
++ctr;
}
cnt_trailbytes = _utf8_no_of_trailbytes(*q);
if(cnt_trailbytes == 0) {
/*
* Should have exited the while by finding a lead
* byte else, the file has incorrect UTF-8 chars
*/
errno = EILSEQ;
retval = -1;
goto error_return;
}
if(cnt_trailbytes + 1 == ctr) {
/*
* The leadbyte + the remaining bytes form a full
* set
*/
q += ctr;
}
else {
/* Seek back */
if (_osfile(fh) & (FDEV|FPIPE)) {
/*
* non-seekable device. Put the extra chars in
* _pipech & _pipech2. We would have a maximum
* of 3 extra chars
*/
_pipech(fh) = *q;
++q;
if(ctr >= 2) {
_pipech2(fh)[0] = *q;
++q;
}
if(ctr == 3) {
_pipech2(fh)[1] = *q;
++q;
}
/*
* We need to point q back to beyond whatever
* we actually took in.
*/
q -= ctr;
}
else {
/* We have read extra chars, so we seek back */
filepos = _lseeki64_nolock(fh, -ctr, FILE_CURRENT);
}
}
}
bytes_read = (int)(q - (char *)buf);
bytes_read = MultiByteToWideChar(
CP_UTF8,
0,
buf,
bytes_read,
inputbuf,
inputsize/2);
if(!bytes_read) {
_dosmaperr(GetLastError());
retval = -1;
goto error_return;
}
_utf8translations(fh) = (bytes_read != (int)(q - (char *)buf));
/* MultiByteToWideChar returns no of wchar_t's. Double it */
bytes_read = bytes_read*2;
}
}
else {
/* set CRLF flag to indicate LF at beginning of buffer */
if ( (os_read != 0) && (*(wchar_t *)buf == LF) )
_osfile(fh) |= FCRLF;
else
_osfile(fh) &= ~FCRLF;
/* convert chars in the buffer: pu is src, qu is dest */
pu = qu = (wchar_t *)buf;
while ((char *)pu < (char *)buf + bytes_read) {
if (*pu == CTRLZ) {
/* if fh is not a device, set ctrl-z flag */
if ( !(_osfile(fh) & FDEV) )
_osfile(fh) |= FEOFLAG;
else
*qu++ = *pu++;
break; /* stop translating */
}
else if (*pu != CR)
*qu++ = *pu++;
else {
/* *pu is CR, so must check next wchar_t for LF */
if ((char *)pu < (char *)buf + bytes_read - 2) {
if (*(pu+1) == LF) {
pu += 2;
*qu++ = LF; /* convert CR-LF to LF */
}
else
*qu++ = *pu++; /* store char normally */
}
else {
/* This is the hard part. We found a CR at end of
buffer. We must peek ahead to see if next
wchar_t is an LF. */
++pu;
dosretval = 0;
if ( !ReadFile( (HANDLE)_osfhnd(fh), &wpeekchr, 2,
(LPDWORD)&os_read, NULL ) )
dosretval = GetLastError();
if (dosretval != 0 || os_read == 0) {
/* couldn't read ahead, store CR */
*qu++ = CR;
}
else {
/*
* peekchr now has the extra character -- we
* now have several possibilities:
* 1. wchar_t is not LF; just seek back and
* copy CR
* 2. wchar_t is LF; seek back and discard CR
* 3. disk file, wchar_t is LF but this is a
* one-byte read: store LF, don't seek back.
*/
if (_osfile(fh) & (FDEV|FPIPE)) {
/* non-seekable device */
if (wpeekchr == LF)
*qu++ = LF;
else {
char * pwpeekchr = (char *)&wpeekchr;
*qu++ = CR;
_pipech(fh) = *pwpeekchr;
++pwpeekchr;
_pipech2(fh)[0] = *pwpeekchr;
_pipech2(fh)[1] = LF; /* Mark as empty */
}
}
else {
if ((char *)qu == buf && wpeekchr == LF) {
/* nothing read yet; must make some
progress */
*qu++ = LF;
}
else {
/* seek back */
filepos = _lseeki64_nolock(fh, -2, FILE_CURRENT);
if (wpeekchr != LF)
*qu++ = CR;
}
}
}
}
}
}
/* we now change bytes_read to reflect the true number of chars
in the buffer */
bytes_read = (int)((char *)qu - (char *)buf);
}
}
error_return:
if(buf != inputbuf) {
free(buf);
}
return (retval == -2) ? bytes_read : retval ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -