pbuf_stream.h

来自「AMLOGIC DPF source code」· C头文件 代码 · 共 232 行

H
232
字号
/*******************************************************************
 * 
 *  Copyright C 2004 by Amlogic, Inc. All Rights Reserved.
 *
 *  Description: Allows a chain of pbufs to be treated as a stream
 *               of bytes
 *
 * Created: Wed Oct 20 12:33:49 2004, Eric Knudstrup
 *
 *******************************************************************/

#ifndef PBUF_STREAM_H
#define PBUF_STREAM_H

#include <lwip/debug.h>
#include <lwip/pbuf.h>

#include <debug_dump.h>

typedef struct {
    struct pbuf *buf_head;  /* List of input pbufs */
    struct pbuf *buf_last;
} PBUFStream;

#define pbuf_stream_len(buf) (((buf)->buf_head) ? (buf)->buf_head->tot_len : 0)

static inline void pbuf_stream_dump(char *caller, PBUFStream *buf)
{
    struct pbuf *q;

    if(buf->buf_head) {
        LWIP_DEBUGF(PBUF_STREAM_DEBUG, 1, ("******************************************\n"));
        LWIP_DEBUGF(PBUF_STREAM_DEBUG, 1, ("%s: %u bytes\n", caller, 
                                           (unsigned) buf->buf_head->tot_len));
        for(q = buf->buf_head; q != NULL; q = q->next) {
            debug_dump(q->payload, q->len);
        }
        LWIP_DEBUGF(PBUF_STREAM_DEBUG, 1, ("******************************************\n"));
    } else {
        LWIP_DEBUGF(PBUF_STREAM_DEBUG, 1, ("************* STREAM EMPTY\n"));
    }
}

static inline void pbuf_stream_add(PBUFStream *buf, 
                                   struct pbuf *p)
{
    struct pbuf *p_last;

    /* The new PBUF might be a chain.  Find its last link. */
    for(p_last = p; p_last->next; p_last = p_last->next)
        ;

    if(buf->buf_head) {
        /* Add the new one to the end of the queue */
        buf->buf_last->next = p;
        buf->buf_last = p_last;

        buf->buf_head->tot_len += p->tot_len;
    } else {
        buf->buf_head = p;
        buf->buf_last = p_last;
    }
}

/* Remove and return the first pbuf */
static inline struct pbuf *pbuf_stream_get(PBUFStream *buf)
{
    struct pbuf *first = buf->buf_head;

    if(first) {
        buf->buf_head = buf->buf_head->next;

        if(first == buf->buf_last) {
            buf->buf_last = NULL;
        } else {
            buf->buf_head->tot_len = 
                first->tot_len - first->len;
        }

        first->next = NULL;
        first->tot_len = first->len;
    }

    return first;
}

/* Remove and free the first pbuf */
static inline void pbuf_stream_dechain(PBUFStream *buf)
{
    struct pbuf *first = pbuf_stream_get(buf);

    if(first) {
        pbuf_free(first);
    }
}

void static inline pbuf_stream_flush(PBUFStream *buf)
{
    while(buf->buf_head) {
        pbuf_stream_dechain(buf);
    }
}

/* 
 * Copy len bytes from PBUFStream buf into unsigned char buffer inbuf 
 * but don't move any pointers
 */
static inline char pbuf_stream_getch(PBUFStream *buf)
{
    char i = '\0';

    if(pbuf_stream_len(buf)) {
        i = *PBUF_PAYLOAD_CHAR(buf->buf_head);

        buf->buf_head->len--;
        buf->buf_head->tot_len--;
        PBUF_PAYLOAD_INC(buf->buf_head, 1);

        if(!buf->buf_head->len) {
            pbuf_stream_dechain(buf);
        }
    }

    return i;
}

/* 
 * Copy len bytes from PBUFStream buf into unsigned char buffer inbuf 
 * but don't move any pointers
 */
static inline char pbuf_stream_peek_char(PBUFStream *buf)
{
    char i = '\0';

    if(pbuf_stream_len(buf)) {
        i = *PBUF_PAYLOAD_CHAR(buf->buf_head);
    }

    return i;
}


/* 
 * Copy len bytes from PBUFStream buf into unsigned char buffer inbuf 
 * but don't move any pointers
 */
static inline int pbuf_stream_peek(PBUFStream *buf, char *inbuf, int len)
{
    struct pbuf *pbuf = buf->buf_head;
    int i;

    for(i = 0; (i < len && pbuf); ) {
        int pbuf_len   = pbuf->len;
        int bytes = MIN(pbuf_len, (len - i));

        memcpy((inbuf+i), pbuf->payload, bytes);

        i += bytes;

        if(bytes == pbuf_len) {
            /* We cleaned out the pbuf */
            pbuf = pbuf->next;
        } else {
            /* The caller asked for fewer bytes
               than we have in this pbuf */
            break;
        }
    }

    return i;
}

/* Consume len bytes from stream buf */
static inline int pbuf_stream_consume(PBUFStream *buf, int len)
{
    int i;

    for(i = 0; (i < (len) && buf->buf_head); ) {
        int pbuf_len   = buf->buf_head->len;
        int bytes = MIN(pbuf_len, (len - i));

        i += bytes;

        LWIP_DEBUGF(PBUF_STREAM_DEBUG, 1, 
                    ("consuming %d bytes cumulative %d pbuf len %d\n", 
                     bytes, i, pbuf_len));

        if(bytes < pbuf_len) {
            buf->buf_head->len -= bytes;
            buf->buf_head->tot_len -= bytes;
            PBUF_PAYLOAD_INC(buf->buf_head, bytes);
        } else {
            /* The first pbuf is empty now */
            pbuf_stream_dechain(buf);
        }
    }

    return i;
}

/* Copy len bytes from PBUFStream buf into unsigned char buffer inbuf */
static inline int pbuf_stream_copy_in(PBUFStream *buf, u8_t *inbuf, int len)
{
    int i;

    for(i = 0; (i < (len) && buf->buf_head); ) {
        int pbuf_len   = buf->buf_head->len;
        int bytes = MIN(pbuf_len, (len - i));

        memcpy((inbuf+i), buf->buf_head->payload, bytes);

        i += bytes;

        LWIP_DEBUGF(PBUF_STREAM_DEBUG, 1, 
                    ("pbuf_stream_copy_in %d bytes cumulative %d pbuf len %d\n", 
                     bytes, i, pbuf_len));

        if(bytes < pbuf_len) {
            buf->buf_head->len -= bytes;
            buf->buf_head->tot_len -= bytes;
            PBUF_PAYLOAD_INC(buf->buf_head, bytes);
        } else {
            /* The first pbuf is empty now */
            pbuf_stream_dechain(buf);
        }
    }

    return i;
}

#endif

⌨️ 快捷键说明

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