fatfs/src/ff.c
TCHAR* f_gets (
	TCHAR* buff,	/* Pointer to the string buffer to read */
	int len,		/* Size of string buffer (items) */
	FIL* fp			/* Pointer to the file object */
)
{
	int nc = 0;
	TCHAR *p = buff;
	BYTE s[4];
	UINT rc;
	DWORD dc;
#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2
	WCHAR wc;
#endif
#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3
	UINT ct;
#endif

#if FF_USE_LFN && FF_LFN_UNICODE			/* With code conversion (Unicode API) */
	/* Make a room for the character and terminator  */
	if (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2;
	if (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4;
	if (FF_LFN_UNICODE == 3) len -= 1;
	while (nc < len) {
#if FF_STRF_ENCODE == 0		/* Read a character in ANSI/OEM */
		f_read(fp, s, 1, &rc);
		if (rc != 1) break;
		wc = s[0];
		if (dbc_1st((BYTE)wc)) {
			f_read(fp, s, 1, &rc);
			if (rc != 1 || !dbc_2nd(s[0])) continue;
			wc = wc << 8 | s[0];
		}
		dc = ff_oem2uni(wc, CODEPAGE);
		if (dc == 0) continue;
#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 	/* Read a character in UTF-16LE/BE */
		f_read(fp, s, 2, &rc);
		if (rc != 2) break;
		dc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];
		if (IsSurrogateL(dc)) continue;
		if (IsSurrogateH(dc)) {
			f_read(fp, s, 2, &rc);
			if (rc != 2) break;
			wc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];
			if (!IsSurrogateL(wc)) continue;
			dc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF);
		}
#else	/* Read a character in UTF-8 */
		f_read(fp, s, 1, &rc);
		if (rc != 1) break;
		dc = s[0];
		if (dc >= 0x80) {	/* Multi-byte character? */
			ct = 0;
			if ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; }	/* 2-byte? */
			if ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; }	/* 3-byte? */
			if ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; }	/* 4-byte? */
			if (ct == 0) continue;
			f_read(fp, s, ct, &rc);		/* Get trailing bytes */
			if (rc != ct) break;
			rc = 0;
			do {	/* Merge trailing bytes */
				if ((s[rc] & 0xC0) != 0x80) break;
				dc = dc << 6 | (s[rc] & 0x3F);
			} while (++rc < ct);
			if (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue;	/* Wrong encoding? */
		}
#endif
		if (FF_USE_STRFUNC == 2 && dc == '\r') continue;	/* Strip \r off if needed */
#if FF_LFN_UNICODE == 1	|| FF_LFN_UNICODE == 3	/* Output it in UTF-16/32 encoding */
		if (FF_LFN_UNICODE == 1 && dc >= 0x10000) {	/* Out of BMP at UTF-16? */
			*p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++;	/* Make and output high surrogate */
			dc = 0xDC00 | (dc & 0x3FF);		/* Make low surrogate */
		}
		*p++ = (TCHAR)dc; nc++;
		if (dc == '\n') break;	/* End of line? */
#elif FF_LFN_UNICODE == 2		/* Output it in UTF-8 encoding */
		if (dc < 0x80) {	/* 1-byte */
			*p++ = (TCHAR)dc;
			nc++;
			if (dc == '\n') break;	/* End of line? */
		} else {
			if (dc < 0x800) {		/* 2-byte */
				*p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F));
				*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));
				nc += 2;
			} else {
				if (dc < 0x10000) {	/* 3-byte */
					*p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F));
					*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));
					*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));
					nc += 3;
				} else {			/* 4-byte */
					*p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07));
					*p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F));
					*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));
					*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));
					nc += 4;
				}
			}
		}
#endif
	}

#else			/* Byte-by-byte without any conversion (ANSI/OEM API) */
	len -= 1;	/* Make a room for the terminator */
	while (nc < len) {
		f_read(fp, s, 1, &rc);
		if (rc != 1) break;
		dc = s[0];
		if (FF_USE_STRFUNC == 2 && dc == '\r') continue;
		*p++ = (TCHAR)dc; nc++;
		if (dc == '\n') break;
	}
#endif

	*p = 0;		/* Terminate the string */
	return nc ? buff : 0;	/* When no data read due to EOF or error, return with error. */
}
/*-----------------------------------------------------------------------*/
/* Get a String from the File                                            */
/*-----------------------------------------------------------------------*/
Get a String from the File
Get a String from the File
TCHAR* f_gets (
	TCHAR* buff,	
	int len,		
	FIL* fp			
)
{
	int nc = 0;
	TCHAR *p = buff;
	BYTE s[4];
	UINT rc;
	DWORD dc;
#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2
	WCHAR wc;
#endif
#if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3
	UINT ct;
#endif
#if FF_USE_LFN && FF_LFN_UNICODE			
	if (FF_LFN_UNICODE == 1) len -= (FF_STRF_ENCODE == 0) ? 1 : 2;
	if (FF_LFN_UNICODE == 2) len -= (FF_STRF_ENCODE == 0) ? 3 : 4;
	if (FF_LFN_UNICODE == 3) len -= 1;
	while (nc < len) {
#if FF_STRF_ENCODE == 0		
		f_read(fp, s, 1, &rc);
		if (rc != 1) break;
		wc = s[0];
		if (dbc_1st((BYTE)wc)) {
			f_read(fp, s, 1, &rc);
			if (rc != 1 || !dbc_2nd(s[0])) continue;
			wc = wc << 8 | s[0];
		}
		dc = ff_oem2uni(wc, CODEPAGE);
		if (dc == 0) continue;
#elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 	
		f_read(fp, s, 2, &rc);
		if (rc != 2) break;
		dc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];
		if (IsSurrogateL(dc)) continue;
		if (IsSurrogateH(dc)) {
			f_read(fp, s, 2, &rc);
			if (rc != 2) break;
			wc = (FF_STRF_ENCODE == 1) ? ld_word(s) : s[0] << 8 | s[1];
			if (!IsSurrogateL(wc)) continue;
			dc = ((dc & 0x3FF) + 0x40) << 10 | (wc & 0x3FF);
		}
#else	
		f_read(fp, s, 1, &rc);
		if (rc != 1) break;
		dc = s[0];
		if (dc >= 0x80) {	
			ct = 0;
			if ((dc & 0xE0) == 0xC0) { dc &= 0x1F; ct = 1; }	
			if ((dc & 0xF0) == 0xE0) { dc &= 0x0F; ct = 2; }	
			if ((dc & 0xF8) == 0xF0) { dc &= 0x07; ct = 3; }	
			if (ct == 0) continue;
			f_read(fp, s, ct, &rc);		
			if (rc != ct) break;
			rc = 0;
			do {	
				if ((s[rc] & 0xC0) != 0x80) break;
				dc = dc << 6 | (s[rc] & 0x3F);
			} while (++rc < ct);
			if (rc != ct || dc < 0x80 || IsSurrogate(dc) || dc >= 0x110000) continue;	
		}
#endif
		if (FF_USE_STRFUNC == 2 && dc == '\r') continue;	
#if FF_LFN_UNICODE == 1	|| FF_LFN_UNICODE == 3	
		if (FF_LFN_UNICODE == 1 && dc >= 0x10000) {	
			*p++ = (TCHAR)(0xD800 | ((dc >> 10) - 0x40)); nc++;	
			dc = 0xDC00 | (dc & 0x3FF);		
		}
		*p++ = (TCHAR)dc; nc++;
		if (dc == '\n') break;	
#elif FF_LFN_UNICODE == 2		
		if (dc < 0x80) {	
			*p++ = (TCHAR)dc;
			nc++;
			if (dc == '\n') break;	
		} else {
			if (dc < 0x800) {		
				*p++ = (TCHAR)(0xC0 | (dc >> 6 & 0x1F));
				*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));
				nc += 2;
			} else {
				if (dc < 0x10000) {	
					*p++ = (TCHAR)(0xE0 | (dc >> 12 & 0x0F));
					*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));
					*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));
					nc += 3;
				} else {			
					*p++ = (TCHAR)(0xF0 | (dc >> 18 & 0x07));
					*p++ = (TCHAR)(0x80 | (dc >> 12 & 0x3F));
					*p++ = (TCHAR)(0x80 | (dc >> 6 & 0x3F));
					*p++ = (TCHAR)(0x80 | (dc >> 0 & 0x3F));
					nc += 4;
				}
			}
		}
#endif
	}
#else			
	len -= 1;	
	while (nc < len) {
		f_read(fp, s, 1, &rc);
		if (rc != 1) break;
		dc = s[0];
		if (FF_USE_STRFUNC == 2 && dc == '\r') continue;
		*p++ = (TCHAR)dc; nc++;
		if (dc == '\n') break;
	}
#endif
	*p = 0;		
	return nc ? buff : 0;	
}
TCHAR * f_gets ( TCHAR * buff , int len , FIL * fp ) { int nc = 0 ; TCHAR * p = buff ; BYTE s [ 4 ] ; UINT rc ; DWORD dc ; #if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE <= 2 WCHAR wc ; #endif #if FF_USE_LFN && FF_LFN_UNICODE && FF_STRF_ENCODE == 3 UINT ct ; #endif #if FF_USE_LFN && FF_LFN_UNICODE if ( FF_LFN_UNICODE == 1 ) len -= ( FF_STRF_ENCODE == 0 ) ? 1 : 2 ; if ( FF_LFN_UNICODE == 2 ) len -= ( FF_STRF_ENCODE == 0 ) ? 3 : 4 ; if ( FF_LFN_UNICODE == 3 ) len -= 1 ; while ( nc < len ) { #if FF_STRF_ENCODE == 0 f_read ( fp , s , 1 , & rc ) ; if ( rc != 1 ) break ; wc = s [ 0 ] ; if ( dbc_1st ( ( BYTE ) wc ) ) { f_read ( fp , s , 1 , & rc ) ; if ( rc != 1 || ! dbc_2nd ( s [ 0 ] ) ) continue ; wc = wc << 8 | s [ 0 ] ; } dc = ff_oem2uni ( wc , CODEPAGE ) ; if ( dc == 0 ) continue ; #elif FF_STRF_ENCODE == 1 || FF_STRF_ENCODE == 2 f_read ( fp , s , 2 , & rc ) ; if ( rc != 2 ) break ; dc = ( FF_STRF_ENCODE == 1 ) ? ld_word ( s ) : s [ 0 ] << 8 | s [ 1 ] ; if ( IsSurrogateL ( dc ) ) continue ; if ( IsSurrogateH ( dc ) ) { f_read ( fp , s , 2 , & rc ) ; if ( rc != 2 ) break ; wc = ( FF_STRF_ENCODE == 1 ) ? ld_word ( s ) : s [ 0 ] << 8 | s [ 1 ] ; if ( ! IsSurrogateL ( wc ) ) continue ; dc = ( ( dc & 0x3FF ) + 0x40 ) << 10 | ( wc & 0x3FF ) ; } #else f_read ( fp , s , 1 , & rc ) ; if ( rc != 1 ) break ; dc = s [ 0 ] ; if ( dc >= 0x80 ) { ct = 0 ; if ( ( dc & 0xE0 ) == 0xC0 ) { dc &= 0x1F ; ct = 1 ; } if ( ( dc & 0xF0 ) == 0xE0 ) { dc &= 0x0F ; ct = 2 ; } if ( ( dc & 0xF8 ) == 0xF0 ) { dc &= 0x07 ; ct = 3 ; } if ( ct == 0 ) continue ; f_read ( fp , s , ct , & rc ) ; if ( rc != ct ) break ; rc = 0 ; do { if ( ( s [ rc ] & 0xC0 ) != 0x80 ) break ; dc = dc << 6 | ( s [ rc ] & 0x3F ) ; } while ( ++ rc < ct ) ; if ( rc != ct || dc < 0x80 || IsSurrogate ( dc ) || dc >= 0x110000 ) continue ; } #endif if ( FF_USE_STRFUNC == 2 && dc == ' \r ' ) continue ; #if FF_LFN_UNICODE == 1 || FF_LFN_UNICODE == 3 if ( FF_LFN_UNICODE == 1 && dc >= 0x10000 ) { * p ++ = ( TCHAR ) ( 0xD800 | ( ( dc >> 10 ) - 0x40 ) ) ; nc ++ ; dc = 0xDC00 | ( dc & 0x3FF ) ; } * p ++ = ( TCHAR ) dc ; nc ++ ; if ( dc == ' \n ' ) break ; #elif FF_LFN_UNICODE == 2 if ( dc < 0x80 ) { * p ++ = ( TCHAR ) dc ; nc ++ ; if ( dc == ' \n ' ) break ; } else { if ( dc < 0x800 ) { * p ++ = ( TCHAR ) ( 0xC0 | ( dc >> 6 & 0x1F ) ) ; * p ++ = ( TCHAR ) ( 0x80 | ( dc >> 0 & 0x3F ) ) ; nc += 2 ; } else { if ( dc < 0x10000 ) { * p ++ = ( TCHAR ) ( 0xE0 | ( dc >> 12 & 0x0F ) ) ; * p ++ = ( TCHAR ) ( 0x80 | ( dc >> 6 & 0x3F ) ) ; * p ++ = ( TCHAR ) ( 0x80 | ( dc >> 0 & 0x3F ) ) ; nc += 3 ; } else { * p ++ = ( TCHAR ) ( 0xF0 | ( dc >> 18 & 0x07 ) ) ; * p ++ = ( TCHAR ) ( 0x80 | ( dc >> 12 & 0x3F ) ) ; * p ++ = ( TCHAR ) ( 0x80 | ( dc >> 6 & 0x3F ) ) ; * p ++ = ( TCHAR ) ( 0x80 | ( dc >> 0 & 0x3F ) ) ; nc += 4 ; } } } #endif } #else len -= 1 ; while ( nc < len ) { f_read ( fp , s , 1 , & rc ) ; if ( rc != 1 ) break ; dc = s [ 0 ] ; if ( FF_USE_STRFUNC == 2 && dc == ' \r ' ) continue ; * p ++ = ( TCHAR ) dc ; nc ++ ; if ( dc == ' \n ' ) break ; } #endif * p = 0 ; return nc ? buff : 0 ; }
Get a String from the File
Get a String from the File
/* Pointer to the string buffer to read */ /* Size of string buffer (items) */ /* Pointer to the file object */ /* With code conversion (Unicode API) */ /* Make a room for the character and terminator  */ /* Read a character in ANSI/OEM */ /* Read a character in UTF-16LE/BE */ /* Read a character in UTF-8 */ /* Multi-byte character? */ /* 2-byte? */ /* 3-byte? */ /* 4-byte? */ /* Get trailing bytes */ /* Merge trailing bytes */ /* Wrong encoding? */ /* Strip \r off if needed */ /* Output it in UTF-16/32 encoding */ /* Out of BMP at UTF-16? */ /* Make and output high surrogate */ /* Make low surrogate */ /* End of line? */ /* Output it in UTF-8 encoding */ /* 1-byte */ /* End of line? */ /* 2-byte */ /* 3-byte */ /* 4-byte */ /* Byte-by-byte without any conversion (ANSI/OEM API) */ /* Make a room for the terminator */ /* Terminate the string */ /* When no data read due to EOF or error, return with error. */