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

📄 nlinebuffer.h

📁 奇迹世界公用文件源代码,研究网络游戏的朋友可以研究下
💻 H
字号:
#ifndef N_LINEBUFFER_H
#define N_LINEBUFFER_H
//------------------------------------------------------------------------------
/**
    @brief A ring buffer for strings.

    @author
    - RadonLabs GmbH 

    @since
    - 2005.6.30
    @remarks
    - 瘤肯 眠啊 
*/

#include "../ProgramCommon/Define.h"

//------------------------------------------------------------------------------
class nLineBuffer 
{
public:
    /// constructor
    nLineBuffer();
    /// destructor
    ~nLineBuffer();
    /// write string to line buffer
    void Put(const char*);
    /// return pointer to line defined by line number
    const char *GetLine(int) const;
    /// get line number of first line
    int GetHeadLine() const;
    /// get line number of last line
    int GetTailLine() const;
    /// get line number of previous line
    int GetNextLine(int) const;
    /// get line number of next line
    int GetPrevLine(int) const;
    /// fill a user provided array with pointers to lines
    int GetLines(const char** array, int arraySize) const;

private:
    /// get next line number
    int nextLine(int) const;
    /// get previus line number
    int prevLine(int) const;

    /// private class to keep track of lines in buffer
    class nLine
    {
        friend class nLineBuffer;

        /// constructor
        nLine();
        /// set line pointer to external storage space
        void Set(char* p, int len);
        /// reset line pointer
        void Reset();
        /// append string to line
        const char* Append(const char* s);
        
        int line_len;
        int act_pos;
        char *line;
    };

    enum 
    {
        N_LINE_LEN  = 80,
        N_NUM_LINES = 256,
    };
    char *c_buf;        
    nLine line_array[N_NUM_LINES];
    int tail_line;
    int head_line;      

};

//------------------------------------------------------------------------------
/**
*/
inline
nLineBuffer::nLine::nLine() :
    line(0),
    line_len(0),
    act_pos(0)
{
    // empty
}

//------------------------------------------------------------------------------
/**
*/
inline
void
nLineBuffer::nLine::Set(char* p, int len)
{
    ASSERT(p);
    this->line = p;
    this->line[0] = 0;
    this->line_len = len;
    this->act_pos = 0;
}

//------------------------------------------------------------------------------
/**
*/
inline
void
nLineBuffer::nLine::Reset()
{
    ASSERT(this->line);
    this->line[0] = 0;
    this->act_pos = 0;
}

//------------------------------------------------------------------------------
/**
    Appends string until line full, new line or end of string is reached.

    If new line, a pointer to the next char is returned, otherwise NULL.
    A '\r' in the string rewinds the cursor to the start of the line. If
    the string buffer is full, a 0 is appended in any case. Newlines are 
    not copied.
*/
inline
const char*
nLineBuffer::nLine::Append(const char *s) 
{
    ASSERT(s);

    char c;
    bool running = true;
    do 
    {
        // Zeile voll?
        c = *s++;
        if (act_pos >= (line_len-1)) 
        {
            line[line_len - 1] = 0;
            running = false;
            s--;
        } 
        else 
        {
            if (c == '\n') 
            {
                line[act_pos] = 0;
                running = false;
            } 
            else if (c == '\r') 
            {
                act_pos       = 0;
                line[act_pos] = 0;
            } 
            else if (c == 0) 
            {
                line[act_pos] = 0;
                s = NULL;
                running = false;
            } 
            else 
            {
                line[act_pos++] = c;
            }
        }
    } while (running);
    return s;
}

//------------------------------------------------------------------------------
/**
*/
inline 
nLineBuffer::nLineBuffer()
{
    int i;
    this->c_buf = (char *) n_calloc(N_LINE_LEN, N_NUM_LINES);
    ASSERT(this->c_buf);
    for (i = 0; i < N_NUM_LINES; i++) 
    {
        this->line_array[i].Set((this->c_buf + i*N_LINE_LEN), N_LINE_LEN);
    }
    this->tail_line = 0;
    this->head_line = 0;
}

//------------------------------------------------------------------------------
/**
*/
inline 
nLineBuffer::~nLineBuffer()
{
    if (this->c_buf) 
    {
        free(this->c_buf);
    }
}

//------------------------------------------------------------------------------
/**
*/
inline 
int nLineBuffer::nextLine(int l) const
{
    l++;
    if (l >= N_NUM_LINES) l = 0;
    return l;
}

//------------------------------------------------------------------------------
/**
*/
inline 
int nLineBuffer::prevLine(int l) const
{
    l--;
    if (l < 0) l = N_NUM_LINES - 1;
    return l;
}

//------------------------------------------------------------------------------
/**
*/
inline 
void 
nLineBuffer::Put(const char *s)
{
    const char *cont = s;
    while (cont && (*cont) && (cont = this->line_array[this->head_line].Append(cont))) 
    {
        // Line ends with a newline (\n) so switch to next line
        this->head_line = this->nextLine(this->head_line);
        if (this->head_line == this->tail_line) 
        {
            this->tail_line = this->nextLine(this->tail_line);
        }
        this->line_array[this->head_line].Reset();
    }
}

//------------------------------------------------------------------------------
/**
*/
inline 
const char*
nLineBuffer::GetLine(int l) const
{
    ASSERT(l >= 0);
    ASSERT(l < N_NUM_LINES);
    return this->line_array[l].line;
}

//------------------------------------------------------------------------------
/**
*/
inline 
int 
nLineBuffer::GetHeadLine() const
{
    return this->head_line;
}

//------------------------------------------------------------------------------
/**
*/
inline 
int 
nLineBuffer::GetTailLine() const
{
    return this->tail_line;
}

//------------------------------------------------------------------------------
/**
*/
inline 
int 
nLineBuffer::GetNextLine(int l) const
{
    if (l == this->head_line) return -1;
    return nextLine(l);
}

//------------------------------------------------------------------------------
/**
*/
inline 
int 
nLineBuffer::GetPrevLine(int l) const
{
    if (l == this->tail_line) return -1;
    return prevLine(l);
}

//------------------------------------------------------------------------------
/**
    Fills the user provided char pointer array with pointers to the N 
    latest lines in the line buffer. Return number of valid lines.

    @param  array       an char pointer array to fill with pointers
    @param  arraySize   the size of the char pointer array
    @return             number of valid lines
*/
inline
int
nLineBuffer::GetLines(const char** array, int arraySize) const
{
    int i;
    int numLines = 0;
    for (i = this->GetHeadLine();
         (i != -1) && (numLines < arraySize);
         i = this->GetPrevLine(i))
    {
        const char *l = this->GetLine(i);
        if (l) 
        {
            if (*l) array[numLines++] = l;
        } 
        else break;
    }
    return numLines;
}

//------------------------------------------------------------------------------
#endif

⌨️ 快捷键说明

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