⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pinstm.cxx

📁 使用stl技术,(还没看,是听说的)
💻 CXX
字号:
/*
 *
 *  C++ Portable Types Library (PTypes)
 *  Version 1.8.3  Released 25-Aug-2003
 *
 *  Copyright (c) 2001, 2002, 2003 Hovik Melikyan
 *
 *  http://www.melikyan.com/ptypes/
 *  http://ptypes.sourceforge.net/
 *
 */

#include <errno.h>
#include <string.h>
#include <limits.h>

#ifdef WIN32
#  include <windows.h>
#else
#  include <unistd.h>
#endif

#include "pstreams.h"


PTYPES_BEGIN


instm::instm(int ibufsize): iobase(ibufsize) 
{
}


instm::~instm() 
{
}


int instm::classid()
{
    return CLASS_INSTM;
}


int instm::dorawread(char* buf, int count)
{
    if (handle == invhandle)
	return -1;
#ifdef WIN32
    unsigned long ret;
    if (!ReadFile(HANDLE(handle), buf, count, &ret, nil)) 
#else
    int ret;
    if ((ret = ::read(handle, buf, count)) < 0)
#endif
    {
        int e = uerrno();
        if (e == EPIPE)
            ret = 0;
        else
            error(e, "Couldn't read");
    }
    return ret;
}


int instm::rawread(char* buf, int count) 
{
    if (!active)
        errstminactive();
    try 
    {
        int ret = dorawread(buf, count);
        if (ret <= 0) {
            ret = 0;
            eof = true;
            chstat(IO_EOF);
        }
        else 
        {
            abspos += ret;
            chstat(IO_READING);
        }
        return ret;
    }
    catch (estream*) 
    {
        eof = true;
        chstat(IO_EOF);
        throw;
    }
}


int instm::tell() 
{
    return abspos - bufend + bufpos;
}


void instm::bufvalidate() 
{
    if (!active)
        errstminactive();
    if (bufsize == 0)
        errbufrequired();
    bufclear();
    bufend = rawread(bufdata, bufsize);
}


int instm::seek(int newpos, ioseekmode mode) 
{
    if (bufsize != 0 && mode != IO_END) 
    {
        int pos;
        if (mode == IO_BEGIN)
            pos = newpos;
        else
            pos = tell() + newpos;
        pos -= abspos - bufend;
        if (pos >= 0 && pos <= bufend) 
        {
            bufpos = pos;
            eof = false;
            return tell();
        }
    }
    return iobase::seek(newpos, mode);
}


bool instm::get_eof() 
{
    if (!eof && bufsize != 0 && bufpos >= bufend)
        bufvalidate();
    return eof;
}


int instm::get_dataavail()
{
    get_eof();
    return bufend - bufpos;
}


char instm::preview() 
{
    if (!eof && bufpos >= bufend)
        bufvalidate();
    if (eof)
        return eofchar;
    return bufdata[bufpos];
}


void instm::putback()
{
    if (!active)
        errstminactive();
    if (bufpos == 0)
        fatal(CRIT_FIRST + 14, "putback() failed");
    bufpos--;
    eof = false;
}


bool instm::get_eol() 
{
    char c = preview();
    return (eof || c == 10 || c == 13);
}


void instm::skipeol() 
{
    switch (preview()) 
    {
    case 10: 
        get(); 
        break;
    case 13:
        get();
        if (preview() == 10)
            get();
        break;
    }
}


char instm::get() 
{
    char ret = preview();
    if (!eof)
        bufpos++;
    return ret;
}


string instm::token(const cset& chars, int limit) 
{
    if (bufsize == 0)
        errbufrequired();
    string ret;
    while (!get_eof()) 
    {
        char* b = bufdata + bufpos;
        char* e = bufdata + bufend;
        char* p = b;
        while (p < e && (*p & chars))
            p++;
        int n = p - b;
        limit -= n;
        if (limit < 0)
        {
            bufpos += n + limit;
            error(ERANGE, "Token too long");
        }
        concat(ret, b, n);
        bufpos += n;
        if (p < e)
            break;
    }
    return ret;
}


string instm::token(const cset& chars) 
{
    return token(chars, INT_MAX);
}


static cset linechars = cset("*") - cset("~0a~0d");


string instm::line(int limit) 
{
    string ret = token(linechars, limit);
    skipeol();
    return ret;
}


string instm::line()
{
    string ret = token(linechars, INT_MAX);
    skipeol();
    return ret;
}


int instm::token(const cset& chars, char* buf, int count) 
{
    if (bufsize == 0)
        errbufrequired();
    int ret = 0;
    while (count > 0 && !get_eof()) 
    {
        char* b = bufdata + bufpos;
        char* e = b + imin(count, bufend - bufpos);
        char* p = b;
        while (p < e && (*p & chars))
            p++;
        int n = p - b;
        memcpy(buf, b, n);
        buf += n;
        ret += n;
        count -= n;
        bufpos += n;
        if (p < e)
            break;
    }
    return ret;
}


int instm::line(char* buf, int size, bool eateol) 
{
    int ret = token(linechars, buf, size);
    if (eateol)
        skipeol();
    return ret;
}


int instm::read(void* buf, int count) 
{
    int ret = 0;
    if (bufsize == 0) 
        ret = rawread(pchar(buf), count);
    else 
    {
        while (count > 0 && !get_eof()) 
        {
            int n = imin(count, bufend - bufpos);
            memcpy(buf, bufdata + bufpos, n);
            buf = pchar(buf) + n;
            ret += n;
            count -= n;
            bufpos += n;
        }
    }
    return ret;
}


int instm::skip(int count) 
{
    int ret = 0;
    if (bufsize == 0)
        errbufrequired();
    else
        while (count > 0 && !get_eof()) 
        {
            int n = imin(count, bufend - bufpos);
            ret += n;
            count -= n;
            bufpos += n;
        }
    return ret;
}


int instm::skiptoken(const cset& chars) 
{
    int ret = 0;
    if (bufsize == 0)
        errbufrequired();
    while (!get_eof()) {
        char* b = bufdata + bufpos;
        char* e = bufdata + bufend;
        char* p = b;
        while (p < e && (*p & chars))
            p++;
        int n = p - b;
        bufpos += n;
        ret += n;
        if (p < e)
            break;
    }
    return ret;
}


void instm::skipline(bool eateol) 
{
    if (!get_eol())
        skiptoken(linechars);
    if (eateol)
        skipeol();
}


PTYPES_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -