📄 stream.cpp
字号:
// stream.cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "msc.h"
#include "stream.h"
// 僼傽僀儖僗僩儕乕儉偲暥帤楍傪摨偠僗僩儕乕儉偲偟偰張棟偡傞偨傔偺儔僀僽儔儕
// for Stream->Flag
#define IS_PREVMODE_TEXT 1
#if ! defined _MSC_VER || _MSC_VER < 1300
static int __cdecl vscprintf ( const char *format, va_list args ) ;
#else
#define vscprintf _vscprintf
#endif
////////////////////////////////////////////
// 暥帤楍梡峔憿懱 //
////////////////////////////////////////////
typedef struct {
const char *Current ; // 暥帤楍億僀儞僞偺尰嵼偺埵抲
const char *Start ; // 暥帤楍偺愭摢
const char *End ; // 暥帤楍偺枛旜 (Start+nLength)
int CharSize ; // 暥帤偺僒僀僘
int Flags ; // STRING_READ or STRING_WRITE
} STRINGINFO ;
// for StringInfo->Flags
#define STRING_READ 1
#define STRING_WRITE 2
#define STRING_ERROR 0x10
////////////////////////////////////////////
// 暥帤楍梡娭悢 //
////////////////////////////////////////////
// 曉傝抣偼 fgetc() 偵摨偠
static int __cdecl StringRead ( STRINGINFO *StringInfo ) {
if ( StringInfo->Flags & ( STRING_WRITE | STRING_ERROR ) ) return EOF ;
if ( StringInfo->Current >= StringInfo->End ) return EOF ;
int C = (unsigned char) *( StringInfo->Current ) ;
StringInfo->Current ++ ;
return C ;
}
// 曉傝抣偼 fputc() 偵摨偠
static int __cdecl StringWrite ( int C, STRINGINFO *StringInfo ) {
if ( StringInfo->Flags & ( STRING_READ | STRING_ERROR ) ) return EOF ;
if ( StringInfo->Current >= StringInfo->End ) { StringInfo->Flags |= STRING_ERROR ; return EOF ; }
*( (char*) StringInfo->Current ) = (unsigned char) C ;
StringInfo->Current ++ ;
return (unsigned char) C ;
}
// 曉傝抣偼 fputc() 偵摨偠
static int __cdecl StringWriteOnlyCount ( int C, STRINGINFO *StringInfo ) {
if ( StringInfo->Flags & ( STRING_READ | STRING_ERROR ) ) return EOF ;
StringInfo->Current ++ ;
return (unsigned char) C ;
}
// 曉傝抣偼 fputs() 偵摨偠
static int __cdecl StringWriteString ( const char *szString, STRINGINFO *StringInfo ) {
if ( StringInfo->Flags & ( STRING_READ | STRING_ERROR ) ) return EOF ;
size_t nLength = strlen ( szString ) ;
if ( StringInfo->Current + nLength > StringInfo->End ) { StringInfo->Flags |= STRING_ERROR ; return EOF ; }
memmove ( (char*) StringInfo->Current, szString, nLength ) ;
StringInfo->Current += nLength ;
return 0 ;
}
// 曉傝抣偼 fputs() 偵摨偠
static int __cdecl StringWriteStringOnlyCount ( const char *szString, STRINGINFO *StringInfo ) {
if ( StringInfo->Flags & ( STRING_READ | STRING_ERROR ) ) return EOF ;
StringInfo->Current += strlen ( szString ) ;
return 0 ;
}
// 曉傝抣偼 vfprintf() 偵摨偠
static int __cdecl StringWriteFormat ( STRINGINFO *StringInfo, const char *format, va_list args ) {
if ( StringInfo->Flags & ( STRING_READ | STRING_ERROR ) ) return EOF ;
size_t nMaxLen = StringInfo->End - StringInfo->Current ;
int nResult = vsnprintf ( (char*) StringInfo->Current, nMaxLen, format, args ) ;
if ( nResult < 0 || (unsigned) nResult > nMaxLen ) { StringInfo->Flags |= STRING_ERROR ; return EOF ; }
StringInfo->Current += nResult ;
return nResult ;
}
// 曉傝抣偼 vfprintf() 偵摨偠
static int __cdecl StringWriteFormatOnlyCount ( STRINGINFO *StringInfo, const char *format, va_list args ) {
if ( StringInfo->Flags & ( STRING_READ | STRING_ERROR ) ) return EOF ;
int nResult = vscprintf ( format, args ) ;
if ( nResult < 0 ) { StringInfo->Flags |= STRING_ERROR ; return EOF ; }
StringInfo->Current += nResult ;
return nResult ;
}
// 曉傝抣偼 fseek() 偵摨偠
static int __cdecl StringSeek ( STRINGINFO *StringInfo, intptr_t nOffset, int nOrigin ) {
if ( StringInfo->Flags & STRING_ERROR ) return EOF ;
if ( nOrigin == SEEK_SET ) {
if ( nOffset < 0 || nOffset > StringInfo->End - StringInfo->Start ) return 1 ;
StringInfo->Current = StringInfo->Start + nOffset ;
return 0 ;
}
else if ( nOrigin == SEEK_END ) {
if ( nOffset < StringInfo->End - StringInfo->Start || nOffset > 0 ) return 1 ;
StringInfo->Current = StringInfo->End + nOffset ;
return 0 ;
}
else if ( nOrigin == SEEK_CUR ) {
if ( nOffset < StringInfo->Start - StringInfo->Current || nOffset > StringInfo->End - StringInfo->Current ) return 1 ;
StringInfo->Current += nOffset ;
return 0 ;
}
return 1 ;
}
// 曉傝抣偼 ferror() 偵摨偠
static int __cdecl StringError ( STRINGINFO *StringInfo ) {
if ( StringInfo->Flags & STRING_ERROR ) return EOF ;
return 0 ;
}
////////////////////////////////////////////
// 嫟捠娭悢 //
////////////////////////////////////////////
// fgetc() 偵憡摉
// 撈帺偺撉傒栠偟僶僢僼傽傪帩偮
int StreamRead ( STREAM *Stream ) {
if ( ! Stream->UnreadCurrent ) return Stream->Read ( Stream->File ) ;
Stream->UnreadCurrent -- ;
return (unsigned char) *( Stream->UnreadBuffer + Stream->UnreadCurrent ) ;
}
// ungetc() 偵憡摉
// 撈帺偺撉傒栠偟僶僢僼傽傪帩偮
int StreamUnread ( int C, STREAM *Stream ) {
if ( C == EOF ) return EOF ;
if ( Stream->UnreadCurrent >= STREAM_UNREAD_BUFFER_SIZE ) return EOF ;
*( Stream->UnreadBuffer + Stream->UnreadCurrent ) = (unsigned char) C ;
Stream->UnreadCurrent ++ ;
return (unsigned char) C ;
}
// fread() 偵憡摉
// 撉傒弌偟偨僶僀僩悢傪曉偡
// 枛旜偵僰儖暥帤傪晅壛偟側偄
int StreamReadString ( char *szBuffer, int nSize, STREAM *Stream ) {
int nCurrentSize = 0 ;
while ( nCurrentSize < nSize ) {
int C = StreamRead ( Stream ) ;
if ( C == EOF ) break ;
*szBuffer = (unsigned char) C ;
szBuffer ++ ;
nCurrentSize ++ ;
}
return nCurrentSize ;
}
// fprintf() 偵憡摉
// 彂偒崬傫偩僶僀僩悢傪曉偡
int __cdecl StreamWriteFormat ( STREAM *Stream, const char *format,... ) {
va_list args ;
va_start ( args, format ) ;
int result = Stream->WriteFormat ( Stream->File, format, args ) ;
va_end ( args ) ;
return result ;
}
// fseek() 偵憡摉
// 僐儞僜乕儖丒僷僀僾偼僔乕僋偱偒側偄丄儕僟僀儗僋僩偼僔乕僋偱偒傞
int StreamSeek ( STREAM *Stream, intptr_t nOffset, int nOrigin ) {
Stream->UnreadCurrent = 0 ;
if ( Stream->Read == fgetc ) return fseek64 ( Stream->File, nOffset, nOrigin ) ;
else return StringSeek ( (STRINGINFO*) Stream->File, nOffset, nOrigin ) ;
}
////////////////////////////////////////////
// 廔椆乮僼傽僀儖乯 //
////////////////////////////////////////////
static inline int IsStdDevice ( FILE *File ) ;
// 惉岟偟偨傜 0 傪曉偡
// 幐攕偟偨傜 EOF 傪曉偡
static int CloseFileStream ( STREAM *Stream, size_t *pSize ) {
int nResult = 0 ;
if ( ! Stream ) return EOF ;
if ( ! IsStdDevice ( Stream->File ) ) {
if ( pSize ) *pSize = (size_t) ftell64 ( Stream->File ) ;
if ( fclose ( Stream->File ) ) nResult = EOF ;
}
else {
if ( pSize ) *pSize = 0 ;
if ( Stream->File != stdin && fflush ( Stream->File ) ) nResult = EOF ;
if ( StreamError ( Stream ) ) nResult = EOF ;
if ( Stream->Flag & IS_PREVMODE_TEXT ) fsetmode ( Stream->File, _O_TEXT ) ;
}
free ( Stream ) ;
return nResult ;
}
// 昗弨擖弌椡側傜 0 埲奜傪曉偡
static inline int IsStdDevice ( FILE *File ) {
if ( (unsigned) _fileno ( File ) <= 2 ) return 1 ;
return 0 ;
}
////////////////////////////////////////////
// 廔椆乮暥帤楍乯 //
////////////////////////////////////////////
static int TerminateStringStream ( STREAM *Stream, size_t *pSize ) ;
// 惉岟偟偨傜 0 傪曉偡
// 幐攕偟偨傜 EOF 傪曉偡
static int CloseStringStream ( STREAM *Stream, size_t *pSize ) {
if ( ! Stream ) return EOF ;
int nResult = TerminateStringStream ( Stream, pSize ) ;
free ( Stream->File ) ;
free ( Stream ) ;
return nResult ;
}
// 暥帤楍傪僰儖暥帤偱廔椆偝偣傞
// 惉岟偟偨傜 0 傪曉偡
// 僄儔乕傪専弌偟偨傜 EOF 傪曉偡
// 挿偝偑廫暘偱側偗傟偽丄暥帤楍傪抁弅偟偰僰儖暥帤傪壛偊丄EOF 傪曉偡
static int TerminateStringStream ( STREAM *Stream, size_t *pSize ) {
STRINGINFO *StringInfo = (STRINGINFO *) Stream->File ;
if ( StringInfo->Flags & STRING_WRITE ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -