介绍见前一篇 https://blog.csdn.net/lin_strong/article/details/88236566
文章目录
通用类
common.h
#ifndef D_common_H
#define D_common_H
#ifndef BOOL
#define BOOL int
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#endif
Container
Container.h
/*
*******************************************************************************************
*
* Parent Class for All Container
*
* File : Container.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. Container is defined here as a storage space which hold elements.
* b. A container has limited capacity(for linked-list,maybe UINT_MAX).
* c. The capacity may change(e.g. for dynamic-array) according to implementation.
* d. Container can be 0-capacity, if so, the container is empty and full simultaneously.
* e. A NULL Container is 0-capacity, 0-count, empty and not-full.
* f. empty is defined as count == 0.
* g. full is defined as count >= capacity.
* h. the class is to be the basic class for all container, so it holds the destroy
* func.
*******************************************************************************************
*/
#ifndef _CONTAINER_H
#define _CONTAINER_H
#include <stddef.h>
#include <stdint.h>
#include "common.h"
/*
*******************************************************************************************
* DATA TYPE
*******************************************************************************************
*/
typedef struct CONTAINER_STRUCT * Container;
/*
*******************************************************************************************
* INTERFACE
*******************************************************************************************
*/
// return: capacity of the container ct
// 0 when ct == NULL
unsigned int Container_getCapacity(Container ct);
// return: element count of the container ct
// 0 when ct == NULL
unsigned int Container_getCount(Container ct);
// return: whether the container ct is empty
// TRUE when ct == NULL
BOOL Container_isEmpty(Container ct);
// return: whether the container ct is full
// FALSE when ct == NULL
BOOL Container_isFull(Container ct);
// destroy the container ct
void Container_Destroy(Container ct);
#include "ContainerPrivate.h"
#endif
ContainerPrivate.h
/*
*******************************************************************************************
*
* Parent Class for All Container
*
* File : ContainerPrivate.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. this file is only for the developer, user shouldn't use any in this file.
* b. to inherit from parent class in C:
*
* #include "ParentClass.h"
* typedef struct CHILDCLASS_STRUCT{
* PARENTCLASS_STRUCT parent;
* SOMETYPE memberofchild;
* ...
* } * ChildClass;
*
* to use the interface of ParentClass, e.g:
*
* ChildClass child = ChildClass_Create();
* PARENTCLASS_METHOD((ParentClass)child,...);
* c. developer should implement the whole vtable, none of the interfaces in the
* vtable can be left NULL. isEmpty and isFull is implemented by calling
* getCapacity and getCount, so you should implement these two interfaces correctly.
* d. destroy interface can be left NULL.
*******************************************************************************************
*/
#include "Container.h"
// destroy function signature
typedef void (* OBJECTINTERFACE_VOID)(void * obj);
typedef unsigned int (* CONTAINERINTERFACE_RETURNUINT)(Container ct);
typedef struct CONTAINER_INTERFACE{
CONTAINERINTERFACE_RETURNUINT getCapacity; // return the capacity of the buffer(no need for NULL check)
CONTAINERINTERFACE_RETURNUINT getCount; // return the elements count of the buffer(no need for NULL check)
}CONTAINER_INTERFACE;
typedef const struct CONTAINER_INTERFACE * CONTAINER_INTERFACE_TABLE;
// members of a container
typedef struct CONTAINER_STRUCT{
OBJECTINTERFACE_VOID destroy; // destroy method register
CONTAINER_INTERFACE_TABLE vtable;
}CONTAINER_STRUCT;
// destroy method member of the container(internal, no NULL check)
#define _Container_fDestroy(ct) (((Container)(ct))->destroy)
#define _Container_mVtable(ct) (((Container)(ct))->vtable)
#define _Container_fgetCapacity(ct) (((Container)(ct))->vtable->getCapacity)
#define _Container_fgetCount(ct) (((Container)(ct))->vtable->getCount)
// initialize an instance of Container,you should implement all the interface, except for Destroy
//(internal, no NULL check)
// void _Container_Init(Container ct,OBJECTINTERFACE_VOID fDestroy,CONTAINER_INTERFACE_TABLE vtable);
#define _Container_Init(ct,fDestroy,vtable) \
{_Container_fDestroy(ct) = fDestroy; \
_Container_mVtable(ct) = vtable;}
// get the capacity of the container(internal, no NULL check)
unsigned int _Container_getCapacity(Container ct);
// get the count of the container(internal, no NULL check)
unsigned int _Container_getCount(Container ct);
// whether the container ct is empty(internal, no NULL check)
BOOL _Container_isEmpty(Container ct);
// whether the container ct is full(internal, no NULL check)
BOOL _Container_isFull(Container ct);
BOOL _Container_isNullorEmpty(Container ct);
BOOL _Container_isNullorFull(Container ct);
// and simple destroyer prepared for those who just need to call free(obj)
void _Destroy_JustCallFree(void * obj);
Container.c
/*
*******************************************************************************************
*
* Interface Implementation for All Container
*
* File : Container.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s):
*******************************************************************************************
*/
#include <stdlib.h>
#include "Container.h"
// void _Container_Init(Container ct,OBJECTINTERFACE_VOID fDestroy,CONTAINER_INTERFACE_TABLE vtable){
// ct->destroy = fDestroy;
// ct->vtable = vtable;
// }
unsigned int Container_getCapacity(Container ct){
if(ct)
return _Container_getCapacity(ct);
return 0;
}
unsigned int Container_getCount(Container ct){
if(ct)
return _Container_getCount(ct);
return 0;
}
BOOL Container_isEmpty(Container ct){
if(ct)
return _Container_isEmpty(ct);
return TRUE;
}
BOOL Container_isFull(Container ct){
if(ct)
return _Container_isFull(ct);
return FALSE;
}
void Container_Destroy(Container ct){
if(ct && ct->destroy)
ct->destroy(ct);
}
unsigned int _Container_getCapacity(Container ct){
return _Container_fgetCapacity(ct)(ct);
}
unsigned int _Container_getCount(Container ct){
return _Container_fgetCount(ct)(ct);
}
BOOL _Container_isEmpty(Container ct){
return _Container_getCount(ct) == 0;
}
BOOL _Container_isFull(Container ct){
return _Container_getCount(ct) >= _Container_getCapacity(ct);
}
BOOL _Container_isNullorEmpty(Container ct){
return ct == NULL || _Container_isEmpty(ct);
}
BOOL _Container_isNullorFull(Container ct){
return ct == NULL || _Container_isFull(ct);
}
void _Destroy_JustCallFree(void * buf){
if(buf == NULL)
return;
free(buf);
}
Buffer
Buffer.h
/*
*******************************************************************************************
*
* Parent Class for All Buffer
*
* File : Buffer.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. Buffer is defined here as a double-ended container, which has a front element
* and a back element, and is able to insert and remove element at front and back.
*******************************************************************************************
*/
#ifndef _BUFFER_H
#define _BUFFER_H
#include "Container.h"
/*
*******************************************************************************************
* DATA TYPE
*******************************************************************************************
*/
typedef struct BUFFER_STRUCT * Buffer;
typedef struct BUFFERUINT8_STRUCT * BufferUINT8;
typedef struct BUFFERUINT16_STRUCT * BufferUINT16;
typedef struct BUFFERUINT32_STRUCT * BufferUINT32;
typedef void (* BUFFERINTERFACE_VOID)(Buffer);
typedef void (* BUFFERUINT8INTERFACE_VOID)(BufferUINT8);
typedef void (* BUFFERUINT16INTERFACE_VOID)(BufferUINT16);
typedef void (* BUFFERUINT32INTERFACE_VOID)(BufferUINT32);
typedef void (* BUFFERUINT8INTERFACE_TAKEELEMENT)(BufferUINT8,uint8_t);
typedef void (* BUFFERUINT16INTERFACE_TAKEELEMENT)(BufferUINT16,uint16_t);
typedef void (* BUFFERUINT32INTERFACE_TAKEELEMENT)(BufferUINT32,uint32_t);
typedef uint8_t (* BUFFERUINT8INTERFACE_RETURNELEMENT)(BufferUINT8);
typedef uint16_t (* BUFFERUINT16INTERFACE_RETURNELEMENT)(BufferUINT16);
typedef uint32_t (* BUFFERUINT32INTERFACE_RETURNELEMENT)(BufferUINT32);
/*
*******************************************************************************************
* CONSTANT
*******************************************************************************************
*/
#define BUFFER_WHENERR_ELEMENTRETURN -1
/*
*******************************************************************************************
* INTERFACE FOR ALL BUFFER CLASS
*******************************************************************************************
*/
// unsigned int Buffer_getCapacity(Buffer buf);
// return: capacity of the Buffer buf
// 0 when buf == NULL
#define Buffer_getCapacity(buf) Container_getCapacity((Container)(buf))
// unsigned int Buffer_getCount(Buffer buf);
// return: element count of the Buffer buf
// 0 when buf == NULL
#define Buffer_getCount(buf) Container_getCount((Container)(buf))
// BOOL Buffer_isEmpty(Buffer buf);
// return: whether the Buffer buf is empty
// TRUE when buf == NULL
#define Buffer_isEmpty(buf) Container_isEmpty((Container)(buf))
// BOOL Buffer_isFull(Buffer buf);
// return: whether the Buffer buf is full
// FALSE when buf == NULL
#define Buffer_isFull(buf) Container_isFull((Container)(buf))
// void Buffer_Destroy(Buffer buf);
// destroy the Buffer buf
#define Buffer_Destroy(buf) Container_Destroy((Container)(buf))
// cleanup the Buffer buf
void Buffer_Cleanup(Buffer buf);
/*
*******************************************************************************************
* INTERFACE FOR UINT8 BUFFER
*******************************************************************************************
*/
// unsigned int BufferUINT8_getCapacity(BufferUINT8 buf);
#define BufferUINT8_getCapacity(buf) Buffer_getCapacity((Buffer)buf)
// unsigned int BufferUINT8_geyCount(BufferUINT8 buf);
#define BufferUINT8_getCount(buf) Buffer_getCount((Buffer)buf)
// BOOL BufferUINT8_isEmpty(BufferUINT8 buf);
#define BufferUINT8_isEmpty(buf) Buffer_isEmpty((Buffer)buf)
// BOOL BufferUINT8_isFull(BufferUINT8 buf);
#define BufferUINT8_isFull(buf) Buffer_isFull((Buffer)buf)
// void BufferUINT8_Destroy(BufferUINT8 buf);
#define BufferUINT8_Destroy(buf) Buffer_Destroy((Buffer)buf)
// return the front element while the element still in the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint8_t BufferUINT8_Front (BufferUINT8 buf);
// return the back element while the element still in the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint8_t BufferUINT8_Back (BufferUINT8 buf);
// put an element at the front of the buffer.
// if container is full, the behavior depends on the implementation.
void BufferUINT8_FrontIn (BufferUINT8 buf,uint8_t element);
// put an element at the back of the buffer.
// if container is full, the behavior depends on the implementation.
void BufferUINT8_BackIn (BufferUINT8 buf,uint8_t element);
// pick an element from the front of the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint8_t BufferUINT8_FrontOut(BufferUINT8 buf);
// pick an element from the back of the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint8_t BufferUINT8_BackOut (BufferUINT8 buf);
// void BufferUINT8_Cleanup(BufferUINT8 buf);
// cleanup the Buffer buf
#define BufferUINT8_Cleanup(buf) Buffer_Cleanup((Buffer)buf)
/*
*******************************************************************************************
* INTERFACE FOR UINT16 BUFFER
*******************************************************************************************
*/
// unsigned int BufferUINT16_getCapacity(BufferUINT16 buf);
#define BufferUINT16_getCapacity(buf) Buffer_getCapacity((Buffer)buf)
// unsigned int BufferUINT16_getCount(BufferUINT16 buf);
#define BufferUINT16_getCount(buf) Buffer_getCount((Buffer)buf)
// BOOL BufferUINT16_isEmpty(BufferUINT16 buf);
#define BufferUINT16_isEmpty(buf) Buffer_isEmpty((Buffer)buf)
// BOOL BufferUINT16_isFull(BufferUINT16 buf);
#define BufferUINT16_isFull(buf) Buffer_isFull((Buffer)buf)
// void BufferUINT16_Destroy(BufferUINT16 buf);
#define BufferUINT16_Destroy(buf) Buffer_Destroy((Buffer)buf)
// return the front element while the element still in the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint16_t BufferUINT16_Front (BufferUINT16 buf);
// return the back element while the element still in the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint16_t BufferUINT16_Back (BufferUINT16 buf);
// put an element at the front of the buffer.
// if container is full, the behavior depends on the implementation.
void BufferUINT16_FrontIn (BufferUINT16 buf,uint16_t element);
// put an element at the back of the buffer.
// if container is full, the behavior depends on the implementation.
void BufferUINT16_BackIn (BufferUINT16 buf,uint16_t element);
// pick an element from the front of the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint16_t BufferUINT16_FrontOut(BufferUINT16 buf);
// pick an element from the back of the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint16_t BufferUINT16_BackOut (BufferUINT16 buf);
// void BufferUINT16_Cleanup(BufferUINT16 buf);
// cleanup the Buffer buf
#define BufferUINT16_Cleanup(buf) Buffer_Cleanup((Buffer)buf)
/*
*******************************************************************************************
* INTERFACE FOR UINT32 BUFFER
*******************************************************************************************
*/
// unsigned int BufferUINT32_getCapacity(BufferUINT32 buf);
#define BufferUINT32_getCapacity(buf) Buffer_getCapacity((Buffer)buf)
// unsigned int BufferUINT32_getCount(BufferUINT32 buf);
#define BufferUINT32_getCount(buf) Buffer_getCount((Buffer)buf)
// BOOL BufferUINT32_isEmpty(BufferUINT32 buf);
#define BufferUINT32_isEmpty(buf) Buffer_isEmpty((Buffer)buf)
// BOOL BufferUINT32_isFull(BufferUINT32 buf);
#define BufferUINT32_isFull(buf) Buffer_isFull((Buffer)buf)
// void BufferUINT32_Destroy(BufferUINT32 buf);
#define BufferUINT32_Destroy(buf) Buffer_Destroy((Buffer)buf)
// return the front element while the element still in the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint32_t BufferUINT32_Front (BufferUINT32 buf);
// return the back element while the element still in the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint32_t BufferUINT32_Back (BufferUINT32 buf);
// put an element at the front of the buffer.
// if container is full, the behavior depends on the implementation.
void BufferUINT32_FrontIn (BufferUINT32 buf,uint32_t element);
// put an element at the back of the buffer.
// if container is full, the behavior depends on the implementation.
void BufferUINT32_BackIn (BufferUINT32 buf,uint32_t element);
// pick an element from the front of the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint32_t BufferUINT32_FrontOut(BufferUINT32 buf);
// pick an element from the back of the buffer.
// return BUFFER_WHENERR_ELEMENTRETURN when any error
uint32_t BufferUINT32_BackOut (BufferUINT32 buf);
// void BufferUINT32_Cleanup(BufferUINT32 buf);
// cleanup the Buffer buf
#define BufferUINT32_Cleanup(buf) Buffer_Cleanup((Buffer)buf)
#include "BufferPrivate.h"
#endif
BufferPrivate.h
/*
*******************************************************************************************
*
* Parent Class for All Buffer
*
* File : BufferPrivate.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. this file is only for the developer, user shouldn't use any in this file.
* b. to inherit from parent class in C:
*
* #include "ParentClass.h"
* typedef struct CHILDCLASS_STRUCT{
* PARENTCLASS_STRUCT parent;
* SOMETYPE memberofchild;
* ...
* } * ChildClass;
*
* to use the interface of ParentClass, e.g:
*
* ChildClass child = ChildClass_Create();
* PARENTCLASS_METHOD((ParentClass)child,...);
*
* c. Main purpose of this class is to provide common interface for Buffer of all
* type. All Buffer Objects have the same shape interfaces (in the virtual
* table) following the exact same order below:
*
* ElementType BufferXXXX_Front (Buffer buf);
* ElementType BufferXXXX_Back (Buffer buf);
* void BufferXXXX_FrontIn (Buffer buf,ElementType element);
* void BufferXXXX_BackIn (Buffer buf,ElementType element);
* ElementType BufferXXXX_FrontIn (Buffer buf);
* ElementType BufferXXXX_BackOut (Buffer buf);
* void BufferXXXX_Cleanup (Buffer buf);
*
* Different ElementTypes lead to different function signatures, however, due to
* the exact same order, we know which one is the "front" function of all function.
* d. If you want to add a Buffer Class of new ElementType, you need to implement
* some methods to guide compiler to correct function signatures, just like
* uint8_t BufferUINT8_Front(BufferUINT8 buf);
* do. You can use Implementations of BufferUINT8 Interface as a template to
* create yours.
* e. If you want to write an implementation for BufferUINT8 Class, for example.
* the main work you should do is to inherit from the Buffer Class, implement
* the CONTAINER_INTERFACE and BUFFER_INTERFACE. And when creating the instance,
* assign the virtual table.
* Then, when user call the interface, the corresponding interface will be called,
* there is no need for NULL check in your interface implementation.
* f. To reduce redundancy, it's recommended to adapt from the exist Buffer Class,
* whose element type take the same space as your new type, rather than create
* interfaces for new type. e.g,BufferChar can be adapted from BufferUINT8.
* g. developer should implement the whole vtable, none of the interfaces in the
* vtable can be left NULL. There will be no NULL check for vtable.
* h. !!! the manners of front, back, frontOut and backOut when buffer is empty,!!!
* !!! and of frontIn and frontOut when buffer is full, are not defined. !!!
*******************************************************************************************
*/
#include "Buffer.h"
/*
*******************************************************************************************
* PROTECTED INTERFACES
*******************************************************************************************
*/
typedef const struct BUFFER_INTERFACE * BUFFER_INTERFACE_TABLE;
typedef const struct BUFFERUINT8_INTERFACE * BUFFERUINT8_INTERFACE_TABLE;
typedef const struct BUFFERUINT16_INTERFACE * BUFFERUINT16_INTERFACE_TABLE;
typedef const struct BUFFERUINT32_INTERFACE * BUFFERUINT32_INTERFACE_TABLE;
typedef struct BUFFER_STRUCT{
CONTAINER_STRUCT parent;
union{
BUFFER_INTERFACE_TABLE v;
BUFFERUINT8_INTERFACE_TABLE uint8;
BUFFERUINT16_INTERFACE_TABLE uint16;
BUFFERUINT32_INTERFACE_TABLE uint32;
} vtable;
}BUFFER_STRUCT;
#define _Buffer_mVtable(buf) (((Buffer)(buf))->vtable.v)
#define _Buffer_fFront(buf) (_Buffer_mVtable(buf)->front)
#define _Buffer_fBack(buf) (_Buffer_mVtable(buf)->back)
#define _Buffer_fFrontIn(buf) (_Buffer_mVtable(buf)->frontIn)
#define _Buffer_fBackIn(buf) (_Buffer_mVtable(buf)->backIn)
#define _Buffer_fFrontOut(buf) (_Buffer_mVtable(buf)->frontOut)
#define _Buffer_fBackOut(buf) (_Buffer_mVtable(buf)->backOut)
#define _Buffer_fCleanup(buf) (_Buffer_mVtable(buf)->cleanup)
typedef struct BUFFERUINT8_STRUCT{
BUFFER_STRUCT member;
}BUFFERUINT8_STRUCT;
#define _BufferUINT8_mVtable(buf) (((Buffer)(buf))->vtable.uint8)
#define _BufferUINT8_fFront(buf) (_BufferUINT8_mVtable(buf)->front)
#define _BufferUINT8_fBack(buf) (_BufferUINT8_mVtable(buf)->back)
#define _BufferUINT8_fFrontIn(buf) (_BufferUINT8_mVtable(buf)->frontIn)
#define _BufferUINT8_fBackIn(buf) (_BufferUINT8_mVtable(buf)->backIn)
#define _BufferUINT8_fFrontOut(buf) (_BufferUINT8_mVtable(buf)->frontOut)
#define _BufferUINT8_fBackOut(buf) (_BufferUINT8_mVtable(buf)->backOut)
#define _BufferUINT8_fCleanup(buf) (_BufferUINT8_mVtable(buf)->cleanup)
typedef struct BUFFERUINT16_STRUCT{
BUFFER_STRUCT member;
}BUFFERUINT16_STRUCT;
#define _BufferUINT16_mVtable(buf) (((Buffer)(buf))->vtable.uint16)
#define _BufferUINT16_fFront(buf) (_BufferUINT16_mVtable(buf)->front)
#define _BufferUINT16_fBack(buf) (_BufferUINT16_mVtable(buf)->back)
#define _BufferUINT16_fFrontIn(buf) (_BufferUINT16_mVtable(buf)->frontIn)
#define _BufferUINT16_fBackIn(buf) (_BufferUINT16_mVtable(buf)->backIn)
#define _BufferUINT16_fFrontOut(buf) (_BufferUINT16_mVtable(buf)->frontOut)
#define _BufferUINT16_fBackOut(buf) (_BufferUINT16_mVtable(buf)->backOut)
#define _BufferUINT16_fCleanup(buf) (_BufferUINT16_mVtable(buf)->cleanup)
typedef struct BUFFERUINT32_STRUCT{
BUFFER_STRUCT member;
}BUFFERUINT32_STRUCT;
#define _BufferUINT32_mVtable(buf) (((Buffer)(buf))->vtable.uint32)
#define _BufferUINT32_fFront(buf) (_BufferUINT32_mVtable(buf)->front)
#define _BufferUINT32_fBack(buf) (_BufferUINT32_mVtable(buf)->back)
#define _BufferUINT32_fFrontIn(buf) (_BufferUINT32_mVtable(buf)->frontIn)
#define _BufferUINT32_fBackIn(buf) (_BufferUINT32_mVtable(buf)->backIn)
#define _BufferUINT32_fFrontOut(buf) (_BufferUINT32_mVtable(buf)->frontOut)
#define _BufferUINT32_fBackOut(buf) (_BufferUINT32_mVtable(buf)->backOut)
#define _BufferUINT32_fCleanup(buf) (_BufferUINT32_mVtable(buf)->cleanup)
typedef void (* BUFFERINTERFACE_POINTER)(void);
typedef struct BUFFER_INTERFACE{
BUFFERINTERFACE_POINTER front; // the buf passed in is assured not NULL
BUFFERINTERFACE_POINTER back; // the buf passed in is assured not NULL
BUFFERINTERFACE_POINTER frontIn; // the buf passed in is assured not NULL
BUFFERINTERFACE_POINTER backIn; // the buf passed in is assured not NULL
BUFFERINTERFACE_POINTER frontOut; // the buf passed in is assured not NULL
BUFFERINTERFACE_POINTER backOut; // the buf passed in is assured not NULL
BUFFERINTERFACE_VOID cleanup; // the buf passed in is assured not NULL
}BUFFER_INTERFACE;
// if don't implement any interface, just leave it NULL
typedef struct BUFFERUINT8_INTERFACE{
BUFFERUINT8INTERFACE_RETURNELEMENT front; // the buf passed in is assured not NULL
BUFFERUINT8INTERFACE_RETURNELEMENT back; // the buf passed in is assured not NULL
BUFFERUINT8INTERFACE_TAKEELEMENT frontIn; // the buf passed in is assured not NULL
BUFFERUINT8INTERFACE_TAKEELEMENT backIn; // the buf passed in is assured not NULL
BUFFERUINT8INTERFACE_RETURNELEMENT frontOut; // the buf passed in is assured not NULL
BUFFERUINT8INTERFACE_RETURNELEMENT backOut; // the buf passed in is assured not NULL
BUFFERUINT8INTERFACE_VOID cleanup; // the buf passed in is assured not NULL
}BUFFERUINT8_INTERFACE;
// if don't implement any interface, just leave it NULL
typedef struct BUFFERUINT16_INTERFACE{
BUFFERUINT16INTERFACE_RETURNELEMENT front; // the buf passed in is assured not NULL
BUFFERUINT16INTERFACE_RETURNELEMENT back; // the buf passed in is assured not NULL
BUFFERUINT16INTERFACE_TAKEELEMENT frontIn; // the buf passed in is assured not NULL
BUFFERUINT16INTERFACE_TAKEELEMENT backIn; // the buf passed in is assured not NULL
BUFFERUINT16INTERFACE_RETURNELEMENT frontOut; // the buf passed in is assured not NULL
BUFFERUINT16INTERFACE_RETURNELEMENT backOut; // the buf passed in is assured not NULL
BUFFERUINT16INTERFACE_VOID cleanup; // the buf passed in is assured not NULL
}BUFFERUINT16_INTERFACE;
typedef struct BUFFERUINT32_INTERFACE{
BUFFERUINT32INTERFACE_RETURNELEMENT front; // the buf passed in is assured not NULL
BUFFERUINT32INTERFACE_RETURNELEMENT back; // the buf passed in is assured not NULL
BUFFERUINT32INTERFACE_TAKEELEMENT frontIn; // the buf passed in is assured not NULL
BUFFERUINT32INTERFACE_TAKEELEMENT backIn; // the buf passed in is assured not NULL
BUFFERUINT32INTERFACE_RETURNELEMENT frontOut; // the buf passed in is assured not NULL
BUFFERUINT32INTERFACE_RETURNELEMENT backOut; // the buf passed in is assured not NULL
BUFFERUINT32INTERFACE_VOID cleanup; // the buf passed in is assured not NULL
}BUFFERUINT32_INTERFACE;
/*
*******************************************************************************************
* PROTECTED MEMBER AND METHOD
*******************************************************************************************
*/
// initialize a Buffer instance(internal, no NULL check)
// void _Buffer_Init(Buffer buf,OBJECTINTERFACE_VOID fDestroy,CONTAINER_INTERFACE_TABLE c_vtable,
// BUFFER_INTERFACE_TABLE vtable);
#define _Buffer_Init(buf,fDestroy,c_vtable,vtable) \
{ _Container_Init(buf,fDestroy,c_vtable); \
_Buffer_mVtable(buf) = vtable; }
// destroy method member of the buffer(internal, no NULL check)
#define _Buffer_fDestroy(buf) (_Container_fDestroy((Container)(buf)))
#define _Buffer_getCapacity(buf) _Container_getCapacity((Container)(buf))
#define _Buffer_getCount(buf) _Container_getCount((Container)(buf))
// whether the buffer is empty(internal, no NULL check)
#define _Buffer_isEmpty(buf) _Container_isEmpty((Container)(buf))
// whether the buffer is full(internal, no NULL check)
#define _Buffer_isFull(buf) _Container_isFull((Container)(buf))
//BOOL _Buffer_isNullorEmpty(Buffer buf);
#define _Buffer_isNullorEmpty(buf) _Container_isNullorEmpty((Container)(buf))
//BOOL _Buffer_isNullorFull(Buffer buf);
#define _Buffer_isNullorFull(buf) _Container_isNullorFull((Container)(buf))
/*
*******************************************************************************************
* PROTECTED INTERFACE METHODS
*******************************************************************************************
*/
// offset of each interface in the vtable
#define _BufferInterface_offset_Front 0
#define _BufferInterface_offset_Back 1
#define _BufferInterface_offset_FrontIn 2
#define _BufferInterface_offset_BackIn 3
#define _BufferInterface_offset_FrontOut 4
#define _BufferInterface_offset_BackOut 5
#define _BufferInterface_offset_Cleanup 6
#define _BufferInterface_byOffset(buf,offset) \
(((BUFFERINTERFACE_POINTER *)_Buffer_mVtable(buf))[offset])
// will check whether buf is NULL , whether buf->vtable is NULL
BUFFERINTERFACE_POINTER _BufferInterface_getByOffset(Buffer buf,unsigned int offset);
BUFFERINTERFACE_POINTER _BufferInterface_getByOffsetIfCanReturnElement(Buffer buf,unsigned int offset);
BUFFERINTERFACE_POINTER _BufferInterface_getByOffsetIfCanTakeElement(Buffer buf,unsigned int offset);
Buffer.c
/*
*******************************************************************************************
*
* Common Methods for All Buffer Class and implementations for UINT8, UINT16, UINT32
*
* File : Buffer.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s):
*******************************************************************************************
*/
#include "Buffer.h"
// void _Buffer_Init(Buffer buf,OBJECTINTERFACE_VOID fDestroy,CONTAINER_INTERFACE_TABLE c_vtable,
// BUFFER_INTERFACE_TABLE vtable){
// _Container_Init((Container)buf,(OBJECTINTERFACE_VOID)fDestroy,c_vtable);
// _Buffer_mVtable(buf) = vtable;
// }
void Buffer_Cleanup(Buffer buf){
BUFFERINTERFACE_VOID _interface;
if(buf == NULL)
return;
_interface = (BUFFERINTERFACE_VOID)_BufferInterface_getByOffset(buf,_BufferInterface_offset_Cleanup);
_interface(buf);
}
BUFFERINTERFACE_POINTER _BufferInterface_getByOffset(Buffer buf,unsigned int offset){
// if(buf && _Buffer_mVtable(buf)) we assume every buffer should implement the (whole) vtable.
return _BufferInterface_byOffset(buf,offset);
}
BUFFERINTERFACE_POINTER _BufferInterface_getByOffsetIfCanTakeElement(Buffer buf,unsigned int offset){
if(!_Buffer_isFull(buf))
return _BufferInterface_getByOffset(buf,offset);
return NULL;
}
BUFFERINTERFACE_POINTER _BufferInterface_getByOffsetIfCanReturnElement(Buffer buf,unsigned int offset){
if(!_Buffer_isEmpty(buf))
return _BufferInterface_getByOffset(buf,offset);
return NULL;
}
static uint8_t BufferUINT8Interface_ReturnElement(BufferUINT8 buf,unsigned int offset){
BUFFERUINT8INTERFACE_RETURNELEMENT _interface;
if(buf == NULL)
return BUFFER_WHENERR_ELEMENTRETURN;
_interface = (BUFFERUINT8INTERFACE_RETURNELEMENT)_BufferInterface_getByOffset((Buffer)buf,offset);
return _interface(buf);
}
static void BufferUINT8Interface_TakeElement(BufferUINT8 buf,unsigned int offset,uint8_t element){
BUFFERUINT8INTERFACE_TAKEELEMENT _interface;
if(buf == NULL)
return;
_interface = (BUFFERUINT8INTERFACE_TAKEELEMENT)_BufferInterface_getByOffset((Buffer)buf,offset);
_interface(buf,element);
}
uint8_t BufferUINT8_Front(BufferUINT8 buf){
return BufferUINT8Interface_ReturnElement(buf,_BufferInterface_offset_Front);
}
uint8_t BufferUINT8_Back(BufferUINT8 buf){
return BufferUINT8Interface_ReturnElement(buf,_BufferInterface_offset_Back);
}
void BufferUINT8_FrontIn(BufferUINT8 buf,uint8_t element){
BufferUINT8Interface_TakeElement(buf,_BufferInterface_offset_FrontIn,element);
}
void BufferUINT8_BackIn(BufferUINT8 buf,uint8_t element){
BufferUINT8Interface_TakeElement(buf,_BufferInterface_offset_BackIn,element);
}
uint8_t BufferUINT8_FrontOut(BufferUINT8 buf){
return BufferUINT8Interface_ReturnElement(buf,_BufferInterface_offset_FrontOut);
}
uint8_t BufferUINT8_BackOut(BufferUINT8 buf){
return BufferUINT8Interface_ReturnElement(buf,_BufferInterface_offset_BackOut);
}
static uint16_t BufferUINT16Interface_ReturnElement(BufferUINT16 buf,unsigned int offset){
BUFFERUINT16INTERFACE_RETURNELEMENT _interface;
if(buf == NULL)
return BUFFER_WHENERR_ELEMENTRETURN;
_interface = (BUFFERUINT16INTERFACE_RETURNELEMENT)_BufferInterface_getByOffset((Buffer)buf,offset);
return _interface(buf);
}
static void BufferUINT16Interface_TakeElement(BufferUINT16 buf,unsigned int offset,uint16_t element){
BUFFERUINT16INTERFACE_TAKEELEMENT _interface;
if(buf == NULL)
return;
_interface = (BUFFERUINT16INTERFACE_TAKEELEMENT)_BufferInterface_getByOffset((Buffer)buf,offset);
_interface(buf,element);
}
uint16_t BufferUINT16_Front(BufferUINT16 buf){
return BufferUINT16Interface_ReturnElement(buf,_BufferInterface_offset_Front);
}
uint16_t BufferUINT16_Back(BufferUINT16 buf){
return BufferUINT16Interface_ReturnElement(buf,_BufferInterface_offset_Back);
}
void BufferUINT16_FrontIn(BufferUINT16 buf,uint16_t element){
BufferUINT16Interface_TakeElement(buf,_BufferInterface_offset_FrontIn,element);
}
void BufferUINT16_BackIn(BufferUINT16 buf,uint16_t element){
BufferUINT16Interface_TakeElement(buf,_BufferInterface_offset_BackIn,element);
}
uint16_t BufferUINT16_FrontOut(BufferUINT16 buf){
return BufferUINT16Interface_ReturnElement(buf,_BufferInterface_offset_FrontOut);
}
uint16_t BufferUINT16_BackOut(BufferUINT16 buf){
return BufferUINT16Interface_ReturnElement(buf,_BufferInterface_offset_BackOut);
}
static uint32_t BufferUINT32Interface_ReturnElement(BufferUINT32 buf,unsigned int offset){
BUFFERUINT32INTERFACE_RETURNELEMENT _interface;
if(buf == NULL)
return BUFFER_WHENERR_ELEMENTRETURN;
_interface = (BUFFERUINT32INTERFACE_RETURNELEMENT)_BufferInterface_getByOffset((Buffer)buf,offset);
return _interface(buf);
}
static void BufferUINT32Interface_TakeElement(BufferUINT32 buf,unsigned int offset,uint32_t element){
BUFFERUINT32INTERFACE_TAKEELEMENT _interface;
if(buf == NULL)
return;
_interface = (BUFFERUINT32INTERFACE_TAKEELEMENT)_BufferInterface_getByOffset((Buffer)buf,offset);
_interface(buf,element);
}
uint32_t BufferUINT32_Front(BufferUINT32 buf){
return BufferUINT32Interface_ReturnElement(buf,_BufferInterface_offset_Front);
}
uint32_t BufferUINT32_Back(BufferUINT32 buf){
return BufferUINT32Interface_ReturnElement(buf,_BufferInterface_offset_Back);
}
void BufferUINT32_FrontIn(BufferUINT32 buf,uint32_t element){
BufferUINT32Interface_TakeElement(buf,_BufferInterface_offset_FrontIn,element);
}
void BufferUINT32_BackIn(BufferUINT32 buf,uint32_t element){
BufferUINT32Interface_TakeElement(buf,_BufferInterface_offset_BackIn,element);
}
uint32_t BufferUINT32_FrontOut(BufferUINT32 buf){
return BufferUINT32Interface_ReturnElement(buf,_BufferInterface_offset_FrontOut);
}
uint32_t BufferUINT32_BackOut(BufferUINT32 buf){
return BufferUINT32Interface_ReturnElement(buf,_BufferInterface_offset_BackOut);
}
BufferIndexed
BufferIndexed.h
/*
*******************************************************************************************
*
* Parent Class for All Indexed Buffer
*
* File : BufferIndexed.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. Indexed Buffer is defined here as a buffer whose element can be accessed by index.
* b. Index here is 0-based, 0-index element is the front element, 1-index element
* is the second-front element, and so on; the count-1 element is the back element.
* c. For a BufferIndexed instance, for example, an BufferUINT8Indexed instance.you can:
* // assign 30 to the second element in the buffer
* BufferUINT8Indexed_set(buf,1,30);
* // get the value of the second element in the buffer(still in the buffer)
* i = BufferUINT8Indexed_get(buf,1);
* you need to make sure the index between 0 and count-1.
*******************************************************************************************
*/
#ifndef _BUFFERINDEXED_H
#define _BUFFERINDEXED_H
#include "Buffer.h"
typedef struct BUFFERINDEXED_STRUCT
* BufferIndexed,
* BufferUINT8Indexed,
* BufferUINT16Indexed,
* BufferUINT32Indexed;
// user should make sure that index between 0 and count - 1, or bad thing may happen.
void BufferUINT8Indexed_set (BufferUINT8Indexed buf,unsigned int index,uint8_t element);
uint8_t BufferUINT8Indexed_get(BufferUINT8Indexed buf,unsigned int index);
void BufferUINT16Indexed_set(BufferUINT16Indexed buf,unsigned int index,uint16_t element);
uint16_t BufferUINT16Indexed_get(BufferUINT16Indexed buf,unsigned int index);
void BufferUINT32Indexed_set(BufferUINT32Indexed buf,unsigned int index,uint32_t element);
uint32_t BufferUINT32Indexed_get(BufferUINT32Indexed buf,unsigned int index);
#include "BufferIndexedPrivate.h"
#endif
BufferIndexedPrivate.h
/*
*******************************************************************************************
*
* Parent Class for All Indexed Array Buffer
*
* File : BufferIndexedPrivate.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. this file is only for the developer, user shouldn't use any in this file.
* b. to inherit from parent class in C:
*
* #include "ParentClass.h"
* typedef struct CHILDCLASS_STRUCT{
* PARENTCLASS_STRUCT parent;
* SOMETYPE memberofchild;
* ...
* } * ChildClass;
*
* to use the interface of ParentClass, e.g:
*
* ChildClass child = ChildClass_Create();
* PARENTCLASS_METHOD((ParentClass)child,...);
* c. Main purpose of this class is to provide common interface for Indexed Buffer
* of all type. All Buffer Objects have the same shape interfaces (in the virtual
* table) following the exact same order below:
*
* void INDEXER_SET (Buffer buf,unsigned int index, ElementType element);
* ElementType INDEXER_GET (Buffer buf,unsigned int index);
*
* Different ElementTypes lead to different function signatures, however, due to
* the exact same order, we know which one is the "set" indexer of all function.
* d. children class should implement indexer as described below:
* 1) when index == 0, the value of the front element will be set or get.
* 2) when index == 1, the value of the second-front element. and so on.
* 3) when index == count - 1, the value of the back element.
* 4) there is no need to protect from the wrong index, this will make the indexer
* a common indexer. The correctness or the index is the responsibility of
* the user.
* e. If you want to add a Buffer Class of new ElementType, you need to implement
* some methods to guide compiler to correct function signatures, just like
*
* void BufferUINT8Indexed_set(BufferUINT8Indexed buf,unsigned int index,uint8_t element);
* uint8_t BufferUINT8Indexed_get(BufferUINT8Indexed buf,unsigned int index);
*
* do. You can use Implementations of BufferUINT8Indexed Interface as a template
* to create yours.
* f. If you want to write an implementation for BufferUINT8Indexed Class, for
* example. the main work you should do is to inherit from the BufferIndexed Class
* , implement the CONTAINER_INTERFACE ,BUFFER_INTERFACE and BUFFERINDEXED_INTERFACE.
* And when creating the instance, assign the virtual table.
* Then, when user call the interface, the corresponding interface will be called,
* there is no need for NULL check in your interface implementation.
* g. To reduce redundancy, it's recommended to adapt from the exist BufferIndexed Class,
* whose element type take the same space as your new type, rather than create
* interfaces for new type. e.g,BufferChar can be adapted from BufferUINT8.
* h. developer should implement the whole vtable, none of the interfaces in the
* vtable can be left NULL. There will be no NULL check for vtable.
*******************************************************************************************
*/
#include "BufferIndexed.h"
typedef void (* BUFFERUINT8INDEXEDINTERFACE_SET)
(BufferUINT8Indexed buf,unsigned int index,uint8_t element);
typedef uint8_t (* BUFFERUINT8INDEXEDINTERFACE_GET)
(BufferUINT8Indexed buf,unsigned int index);
typedef void (* BUFFERUINT16INDEXEDINTERFACE_SET)
(BufferUINT16Indexed buf,unsigned int index,uint16_t element);
typedef uint16_t (* BUFFERUINT16INDEXEDINTERFACE_GET)
(BufferUINT16Indexed buf,unsigned int index);
typedef void (* BUFFERUINT32INDEXEDINTERFACE_SET)
(BufferUINT32Indexed buf,unsigned int index,uint32_t element);
typedef uint32_t (* BUFFERUINT32INDEXEDINTERFACE_GET)
(BufferUINT32Indexed buf,unsigned int index);
typedef struct BUFFERINDEXED_INTERFACE {
BUFFERINTERFACE_POINTER set;
BUFFERINTERFACE_POINTER get;
}BUFFERINDEXED_INTERFACE;
typedef BUFFERINDEXED_INTERFACE const * BUFFERINDEXED_INTERFACE_TABLE;
// compatible to all BUFFERXXX_STRUCT,due to the size of
// all BUFFERXXXXINTERFACE_TABLE are the same(one pointer).
typedef struct BUFFERINDEXED_STRUCT{
BUFFER_STRUCT parent;
BUFFERINDEXED_INTERFACE_TABLE vtable;
}BUFFERINDEXED_STRUCT;
// all private methods don't has NULL check.
#define _BufferIndexed_mVtable(buf) (((BufferIndexed)(buf))->vtable)
#define _BufferIndexed_fSet(buf) (_BufferIndexed_mVtable(buf)->set)
#define _BufferIndexed_fGet(buf) (_BufferIndexed_mVtable(buf)->get)
void _BufferUINT8Indexed_set (BufferUINT8Indexed buf,unsigned int index,uint8_t element);
uint8_t _BufferUINT8Indexed_get(BufferUINT8Indexed buf,unsigned int index);
void _BufferUINT16Indexed_set (BufferUINT16Indexed buf,unsigned int index,uint16_t element);
uint16_t _BufferUINT16Indexed_get(BufferUINT16Indexed buf,unsigned int index);
void _BufferUINT32Indexed_set (BufferUINT32Indexed buf,unsigned int index,uint32_t element);
uint32_t _BufferUINT32Indexed_get(BufferUINT32Indexed buf,unsigned int index);
// initialize a BufferIndexed instance,you should implement all the interface,
// except for Destroy(internal, no NULL check)
// void _BufferIndexed_Init(BufferIndexed buf,OBJECTINTERFACE_VOID fDestroy,
// CONTAINER_INTERFACE_TABLE c_vtable,BUFFER_INTERFACE_TABLE vtable,
// BUFFERINDEXED_INTERFACE_TABLE i_vtable);
#define _BufferIndexed_Init(buf, fDestroy, c_vtable, vtable, i_vtable) \
{_Buffer_Init((Buffer)buf, fDestroy, c_vtable, vtable);\
_BufferIndexed_mVtable(buf) = i_vtable;}
BufferIndexed.c
/*
*******************************************************************************************
*
* Interface Implementation for All Indexed Buffer
*
* File : BufferIndexed.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s):
*******************************************************************************************
*/
#include "BufferIndexed.h"
/*void _BufferIndexed_Init(BufferIndexed buf,OBJECTINTERFACE_VOID fDestroy,
CONTAINER_INTERFACE_TABLE c_vtable,BUFFER_INTERFACE_TABLE vtable,
BUFFERINDEXED_INTERFACE_TABLE i_vtable){
_Buffer_Init((Buffer)buf, fDestroy, c_vtable, vtable);
_BufferIndexed_mVtable(buf) = i_vtable;
} // */
void BufferUINT8Indexed_set (BufferUINT8Indexed buf,unsigned int index,uint8_t element){
if(buf)
_BufferUINT8Indexed_set(buf,index,element);
}
uint8_t BufferUINT8Indexed_get(BufferUINT8Indexed buf,unsigned int index){
if(buf)
return _BufferUINT8Indexed_get(buf,index);
return BUFFER_WHENERR_ELEMENTRETURN;
}
void BufferUINT16Indexed_set(BufferUINT16Indexed buf,unsigned int index,uint16_t element){
if(buf)
_BufferUINT16Indexed_set(buf,index,element);
}
uint16_t BufferUINT16Indexed_get(BufferUINT16Indexed buf,unsigned int index){
if(buf)
return _BufferUINT16Indexed_get(buf,index);
return BUFFER_WHENERR_ELEMENTRETURN;
}
void BufferUINT32Indexed_set(BufferUINT32Indexed buf,unsigned int index,uint32_t element){
if(buf)
_BufferUINT32Indexed_set(buf,index,element);
}
uint32_t BufferUINT32Indexed_get(BufferUINT32Indexed buf,unsigned int index){
if(buf)
return _BufferUINT32Indexed_get(buf,index);
return BUFFER_WHENERR_ELEMENTRETURN;
}
void _BufferUINT8Indexed_set (BufferUINT8Indexed buf,unsigned int index,uint8_t element){
((BUFFERUINT8INDEXEDINTERFACE_SET)_BufferIndexed_fSet(buf))(buf,index,element);
}
uint8_t _BufferUINT8Indexed_get(BufferUINT8Indexed buf,unsigned int index){
return ((BUFFERUINT8INDEXEDINTERFACE_GET)_BufferIndexed_fGet(buf))(buf,index);
}
void _BufferUINT16Indexed_set (BufferUINT16Indexed buf,unsigned int index,uint16_t element){
((BUFFERUINT16INDEXEDINTERFACE_SET)_BufferIndexed_fSet(buf))(buf,index,element);
}
uint16_t _BufferUINT16Indexed_get(BufferUINT16Indexed buf,unsigned int index){
return ((BUFFERUINT16INDEXEDINTERFACE_GET)_BufferIndexed_fGet(buf))(buf,index);
}
void _BufferUINT32Indexed_set (BufferUINT32Indexed buf,unsigned int index,uint32_t element){
((BUFFERUINT32INDEXEDINTERFACE_SET)_BufferIndexed_fSet(buf))(buf,index,element);
}
uint32_t _BufferUINT32Indexed_get(BufferUINT32Indexed buf,unsigned int index){
return ((BUFFERUINT32INDEXEDINTERFACE_GET)_BufferIndexed_fGet(buf))(buf,index);
}
BufferArrayShare
BufferArrayShare.h
/*
*******************************************************************************************
*
* Share Parent Class for All Indexed Array Buffer
*
* File : BufferArrayShare.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. this class include the protected members and the corresponding methods that
* share for Buffers that implemented with numerically indexed array.
*******************************************************************************************
*/
#ifndef _BUFFERARRAYSHARE_H
#define _BUFFERARRAYSHARE_H
#include "BufferIndexed.h"
typedef struct BUFFERARRAYSHARE_STRUCT
* BufferArrayShare;
#include "BufferArraySharePrivate.h"
#endif
BufferArraySharePrivate.h
/*
*******************************************************************************************
*
* Share Parent Class for All Indexed Array Buffer
*
* File : BufferArraySharePrivate.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. this file is only for the developer, user shouldn't use any in this file.
* b. to inherit from parent class in C:
*
* #include "ParentClass.h"
* typedef struct CHILDCLASS_STRUCT{
* PARENTCLASS_STRUCT parent;
* SOMETYPE memberofchild;
* ...
* } * ChildClass;
*
* to use the interface of ParentClass, e.g:
*
* ChildClass child = ChildClass_Create();
* PARENTCLASS_METHOD((ParentClass)child,...);
*
* !!!!! the "index" below refers to the internal(actual) index, not the index for indexer !!!!!
*
* a. I assume most developer would like to use an circle-indexed array or something
* similar to implement the Buffer. So here provide the share members and methods.
* the use of 'capacity' and 'count' is obvious. 'front' and 'back' are the internal
* index for front-element and back-element respectively. 'front'
* refers to the actual position front-element at.
* b. Index here is 0-based and up to buffer's capacity - 1 .
* _BufferArrayShare_Inc/decXXXIndex will treat front or back index as circle.
* c. compatible to all BUFFERUINTXXX_STRUCT,due to the size of all INTERFACE_TABLE
* are the same(one pointer).
* d. this class assumes add element at front will cause frontIndex to decrease,
* and add element at back will cause backIndex to increase.
* so _BufferIndexed_Init will init frontIndex bigger than backIndex by 1
*******************************************************************************************
*/
#include "BufferArrayShare.h"
typedef struct BUFFERARRAYSHARE_STRUCT{
BUFFERINDEXED_STRUCT parent; // compatible to all BUFFERXXX_STRUCT,due to the size of
// all BUFFERXXXXINTERFACE_TABLE are the same(one pointer).
unsigned int capacity; // the capacity
unsigned int count; // count of elements
unsigned int front; // index of the front element in the array
unsigned int back; // index of the back element in the array
}BUFFERARRAYSHARE_STRUCT;
// common container interface for all
extern const CONTAINER_INTERFACE _ContainerInterface_ArrayShare;
// all private methods don't has NULL check.
#define _BufferArrayShare_mCapacity(buf) (((BufferArrayShare)(buf))->capacity)
#define _BufferArrayShare_mCount(buf) (((BufferArrayShare)(buf))->count)
#define _BufferArrayShare_mFront(buf) (((BufferArrayShare)(buf))->front)
#define _BufferArrayShare_mBack(buf) (((BufferArrayShare)(buf))->back)
// initialize a BufferIndexed instance, count is assumed to be initialized to 0
// and frontIndex will bigger than backIndex by 1 (internal, no NULL check)
void _BufferArrayShare_Init(BufferArrayShare buf,OBJECTINTERFACE_VOID fDestroy,
CONTAINER_INTERFACE_TABLE c_vtable, BUFFER_INTERFACE_TABLE vtable,
BUFFERINDEXED_INTERFACE_TABLE indexer, unsigned int capacity);
// operation on index front
void _BufferArrayShare_IncFrontIndex(BufferArrayShare buf);
// operation on index front
void _BufferArrayShare_DecFrontIndex(BufferArrayShare buf);
// operation on index back
void _BufferArrayShare_IncBackIndex(BufferArrayShare buf);
// operation on index back
void _BufferArrayShare_DecBackIndex(BufferArrayShare buf);
// Common cleanup Interface implementation for all Indexed Array Buffer
// just care about front, back and count members. Used by the implementations below.
void _BufferArrayShare_Cleanup(BufferArrayShare buf);
// Common Interface implementations for all Buffers which use indexed array as internal storage.
// In these implementations:
// When buffer is empty, front, back, frontOut and back will return BUFFER_WHENERR_ELEMENTRETURN.
// When buffer is full, frontIn and backOut will just ignore the call.
// if you use these interface, just make sure you implement the indexer correctly, then Buffer should
// work properly.
extern const BUFFER_INTERFACE _BufferInterface_ArrayUint8;
extern const BUFFER_INTERFACE _BufferInterface_ArrayUint16;
extern const BUFFER_INTERFACE _BufferInterface_ArrayUint32;
// calculate the internal(actual) index by relative index
// very useful for implementations which use an array for storage.
unsigned int _BufferArrayShare_calInternalIndex(BufferArrayShare buf,unsigned int relativeIndex);
BufferArrayShare.c
/*
*******************************************************************************************
*
* Common Implementation for All Indexed Array Buffer
*
* File : BufferArrayShare.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s):
*******************************************************************************************
*/
#include "BufferArrayShare.h"
void _BufferArrayShare_Init(BufferArrayShare buf,OBJECTINTERFACE_VOID fDestroy,
CONTAINER_INTERFACE_TABLE c_vtable, BUFFER_INTERFACE_TABLE vtable,
BUFFERINDEXED_INTERFACE_TABLE indexer, unsigned int capacity){
_BufferIndexed_Init((BufferIndexed)buf, fDestroy, c_vtable,vtable,indexer);
_BufferArrayShare_Cleanup(buf);
_BufferArrayShare_mCapacity(buf) = capacity;
}
void _BufferArrayShare_IncFrontIndex(BufferArrayShare buf){
if(++_BufferArrayShare_mFront(buf) >= _BufferArrayShare_mCapacity(buf))
_BufferArrayShare_mFront(buf) = 0;
}
void _BufferArrayShare_DecFrontIndex(BufferArrayShare buf){
if(_BufferArrayShare_mFront(buf)-- == 0)
_BufferArrayShare_mFront(buf) = _BufferArrayShare_mCapacity(buf) - 1;
}
void _BufferArrayShare_IncBackIndex(BufferArrayShare buf){
if(++_BufferArrayShare_mBack(buf) >= _BufferArrayShare_mCapacity(buf))
_BufferArrayShare_mBack(buf) = 0;
}
void _BufferArrayShare_DecBackIndex(BufferArrayShare buf){
if(_BufferArrayShare_mBack(buf)-- == 0)
_BufferArrayShare_mBack(buf) = _BufferArrayShare_mCapacity(buf) - 1;
}
void _BufferArrayShare_Cleanup(BufferArrayShare buf){
_BufferArrayShare_mFront(buf) = 1;
_BufferArrayShare_mBack(buf) = 0;
_BufferArrayShare_mCount(buf) = 0;
}
// share container-interface for indexed array
static unsigned int _getCapacity(Container ct){
return _BufferArrayShare_mCapacity(ct);
}
static unsigned int _getCount(Container ct){
return _BufferArrayShare_mCount(ct);
}
const CONTAINER_INTERFACE _ContainerInterface_ArrayShare = {_getCapacity,_getCount};
unsigned int _BufferArrayShare_calInternalIndex(BufferArrayShare buf,unsigned int relativeIndex){
// here has a bug, if the capacity is big enough, _BufferArrayShare_mFront(buf) + relativeIndex
// may exceed the UINT_MAX, however, I don't think you will need a buffer so big.
unsigned int internalIndex;
internalIndex = _BufferArrayShare_mFront(buf) + relativeIndex;
if(internalIndex >= _BufferArrayShare_mCapacity(buf))
internalIndex -= _BufferArrayShare_mCapacity(buf);
return internalIndex;
}
#define incFrontIndex(buf) _BufferArrayShare_IncFrontIndex((BufferArrayShare)buf)
#define decFrontIndex(buf) _BufferArrayShare_DecFrontIndex((BufferArrayShare)buf)
#define incBackIndex(buf) _BufferArrayShare_IncBackIndex((BufferArrayShare)buf)
#define decBackIndex(buf) _BufferArrayShare_DecBackIndex((BufferArrayShare )buf)
static uint8_t _Front_uint8(BufferUINT8 buf);
static uint8_t _Back_uint8(BufferUINT8 buf);
static void _FrontIn_uint8(BufferUINT8 buf,uint8_t element);
static void _BackIn_uint8(BufferUINT8 buf,uint8_t element);
static uint8_t _FrontOut_uint8(BufferUINT8 buf);
static uint8_t _BackOut_uint8(BufferUINT8 buf);
const BUFFER_INTERFACE _BufferInterface_ArrayUint8 = {
(BUFFERINTERFACE_POINTER)_Front_uint8,
(BUFFERINTERFACE_POINTER)_Back_uint8,
(BUFFERINTERFACE_POINTER)_FrontIn_uint8,
(BUFFERINTERFACE_POINTER)_BackIn_uint8,
(BUFFERINTERFACE_POINTER)_FrontOut_uint8,
(BUFFERINTERFACE_POINTER)_BackOut_uint8,
(BUFFERINTERFACE_VOID)_BufferArrayShare_Cleanup
};
static uint16_t _Front_uint16(BufferUINT16 buf);
static uint16_t _Back_uint16(BufferUINT16 buf);
static void _FrontIn_uint16(BufferUINT16 buf,uint16_t element);
static void _BackIn_uint16(BufferUINT16 buf,uint16_t element);
static uint16_t _FrontOut_uint16(BufferUINT16 buf);
static uint16_t _BackOut_uint16(BufferUINT16 buf);
const BUFFER_INTERFACE _BufferInterface_ArrayUint16 = {
(BUFFERINTERFACE_POINTER)_Front_uint16,
(BUFFERINTERFACE_POINTER)_Back_uint16,
(BUFFERINTERFACE_POINTER)_FrontIn_uint16,
(BUFFERINTERFACE_POINTER)_BackIn_uint16,
(BUFFERINTERFACE_POINTER)_FrontOut_uint16,
(BUFFERINTERFACE_POINTER)_BackOut_uint16,
(BUFFERINTERFACE_VOID)_BufferArrayShare_Cleanup
};
static uint32_t _Front_uint32(BufferUINT32 buf);
static uint32_t _Back_uint32(BufferUINT32 buf);
static void _FrontIn_uint32(BufferUINT32 buf,uint32_t element);
static void _BackIn_uint32(BufferUINT32 buf,uint32_t element);
static uint32_t _FrontOut_uint32(BufferUINT32 buf);
static uint32_t _BackOut_uint32(BufferUINT32 buf);
const BUFFER_INTERFACE _BufferInterface_ArrayUint32 = {
(BUFFERINTERFACE_POINTER)_Front_uint32,
(BUFFERINTERFACE_POINTER)_Back_uint32,
(BUFFERINTERFACE_POINTER)_FrontIn_uint32,
(BUFFERINTERFACE_POINTER)_BackIn_uint32,
(BUFFERINTERFACE_POINTER)_FrontOut_uint32,
(BUFFERINTERFACE_POINTER)_BackOut_uint32,
(BUFFERINTERFACE_VOID)_BufferArrayShare_Cleanup
};
static uint8_t _Front_uint8(BufferUINT8 buf){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
return _BufferUINT8Indexed_get((BufferUINT8Indexed)buf,0);
}
static uint8_t _Back_uint8(BufferUINT8 buf){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
return _BufferUINT8Indexed_get((BufferUINT8Indexed)buf,cnt - 1);
}
static void _FrontIn_uint8(BufferUINT8 buf,uint8_t element){
if(_Buffer_isFull(buf))
return;
decFrontIndex(buf);
++_BufferArrayShare_mCount(buf);
_BufferUINT8Indexed_set((BufferUINT8Indexed)buf,0,element);
}
static void _BackIn_uint8(BufferUINT8 buf,uint8_t element){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(_Buffer_isFull(buf))
return;
incBackIndex(buf);
++_BufferArrayShare_mCount(buf);
_BufferUINT8Indexed_set((BufferUINT8Indexed)buf,cnt,element);
}
static uint8_t _FrontOut_uint8(BufferUINT8 buf){
uint8_t rst;
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
rst = _BufferUINT8Indexed_get((BufferUINT8Indexed)buf,0);
incFrontIndex(buf);
--_BufferArrayShare_mCount(buf);
return rst;
}
static uint8_t _BackOut_uint8(BufferUINT8 buf){
uint8_t rst;
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
rst = _BufferUINT8Indexed_get((BufferUINT8Indexed)buf,cnt - 1);
decBackIndex(buf);
--_BufferArrayShare_mCount(buf);
return rst;
}
static uint16_t _Front_uint16(BufferUINT16 buf){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
return _BufferUINT16Indexed_get((BufferUINT16Indexed)buf,0);
}
static uint16_t _Back_uint16(BufferUINT16 buf){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
return _BufferUINT16Indexed_get((BufferUINT16Indexed)buf,cnt - 1);
}
static void _FrontIn_uint16(BufferUINT16 buf,uint16_t element){
if(_Buffer_isFull(buf))
return;
decFrontIndex(buf);
++_BufferArrayShare_mCount(buf);
_BufferUINT16Indexed_set((BufferUINT16Indexed)buf,0,element);
}
static void _BackIn_uint16(BufferUINT16 buf,uint16_t element){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(_Buffer_isFull(buf))
return;
incBackIndex(buf);
++_BufferArrayShare_mCount(buf);
_BufferUINT16Indexed_set((BufferUINT16Indexed)buf,cnt,element);
}
static uint16_t _FrontOut_uint16(BufferUINT16 buf){
uint16_t rst;
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
rst = _BufferUINT16Indexed_get((BufferUINT16Indexed)buf,0);
incFrontIndex(buf);
--_BufferArrayShare_mCount(buf);
return rst;
}
static uint16_t _BackOut_uint16(BufferUINT16 buf){
uint16_t rst;
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
rst = _BufferUINT16Indexed_get((BufferUINT16Indexed)buf,cnt - 1);
decBackIndex(buf);
--_BufferArrayShare_mCount(buf);
return rst;
}
static uint32_t _Front_uint32(BufferUINT32 buf){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
return _BufferUINT32Indexed_get((BufferUINT32Indexed)buf,0);
}
static uint32_t _Back_uint32(BufferUINT32 buf){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
return _BufferUINT32Indexed_get((BufferUINT32Indexed)buf,cnt - 1);
}
static void _FrontIn_uint32(BufferUINT32 buf,uint32_t element){
if(_Buffer_isFull(buf))
return;
decFrontIndex(buf);
++_BufferArrayShare_mCount(buf);
_BufferUINT32Indexed_set((BufferUINT32Indexed)buf,0,element);
}
static void _BackIn_uint32(BufferUINT32 buf,uint32_t element){
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(_Buffer_isFull(buf))
return;
incBackIndex(buf);
++_BufferArrayShare_mCount(buf);
_BufferUINT32Indexed_set((BufferUINT32Indexed)buf,cnt,element);
}
static uint32_t _FrontOut_uint32(BufferUINT32 buf){
uint32_t rst;
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
rst = _BufferUINT32Indexed_get((BufferUINT32Indexed)buf,0);
incFrontIndex(buf);
--_BufferArrayShare_mCount(buf);
return rst;
}
static uint32_t _BackOut_uint32(BufferUINT32 buf){
uint32_t rst;
unsigned int cnt = _BufferArrayShare_mCount(buf);
if(cnt == 0)
return BUFFER_WHENERR_ELEMENTRETURN;
rst = _BufferUINT32Indexed_get((BufferUINT32Indexed)buf,cnt - 1);
decBackIndex(buf);
--_BufferArrayShare_mCount(buf);
return rst;
}
BufferArray
BufferArray.h
/*
*******************************************************************************************
*
* Parent Class for All Indexed Array Buffer with normal pointer
*
* File : BufferArray.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. This class provide the pointer members for Buffers which use a (near) numerically
* indexed array internal. And the indexer for UINT8, UINT16 and UINT32 Buffer.
*******************************************************************************************
*/
#ifndef _BUFFERARRAY_H
#define _BUFFERARRAY_H
#include "BufferArrayShare.h"
typedef struct BUFFERARRAY_STRUCT
* BufferArray,
* BufferUINT8Array,
* BufferUINT16Array,
* BufferUINT32Array;
#include "BufferArrayPrivate.h"
#endif
BufferArrayPrivate.h
/*
*******************************************************************************************
*
* Parent Class for All Indexed Array Buffer with normal pointer
*
* File : BufferArrayPrivate.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. This class provide the pointer members for Buffers which use a (near) numerically
* indexed array internal. And the indexer for UINT8, UINT16 and UINT32 Buffer.
* b. Generally, to implement an indexed array buffer, developer just need to implement
* a Create method, which allocates space for BUFFERARRAY_STRUCT and use the Init
* method in this file to initialize it, plus the corresponding destroy method;
* then everything will go right.
*******************************************************************************************
*/
#include "BufferArray.h"
typedef struct BUFFERARRAY_STRUCT{
BUFFERARRAYSHARE_STRUCT parent;
union{
uint8_t * uint8;
uint16_t * uint16;
uint32_t * uint32;
void * ptr;
}ptr;
} BUFFERARRAY_STRUCT;
#define _BufferArray_ptrUint8(buf) (((BufferUINT8Array )buf)->ptr.uint8)
#define _BufferArray_ptrUint16(buf) (((BufferUINT16Array)buf)->ptr.uint16)
#define _BufferArray_ptrUint32(buf) (((BufferUINT32Array)buf)->ptr.uint32)
#define _BufferArray_ptr(buf) (((BufferArray )buf)->ptr.ptr)
// common indexer interface for normal array, use the indexer to access internal element.
// so you should implement the indexer correctly as description.
extern const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayUint8;
extern const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayUint16;
extern const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayUint32;
void _BufferArray_Init(BufferArray buf,void *ptr,unsigned int capacity,
OBJECTINTERFACE_VOID fDestroy, BUFFER_INTERFACE_TABLE vtable,
BUFFERINDEXED_INTERFACE_TABLE i_vtable);
#define _BufferUINT8Array_Init(buf,ptr,capacity,fDestroy) \
_BufferArray_Init(buf,ptr,capacity,fDestroy,&_BufferInterface_ArrayUint8,\
&_BufferIndexedInterface_ArrayUint8);
#define _BufferUINT16Array_Init(buf,ptr,capacity,fDestroy) \
_BufferArray_Init(buf,ptr,capacity,fDestroy,&_BufferInterface_ArrayUint16,\
&_BufferIndexedInterface_ArrayUint16);
#define _BufferUINT32Array_Init(buf,ptr,capacity,fDestroy) \
_BufferArray_Init(buf,ptr,capacity,fDestroy,&_BufferInterface_ArrayUint32,\
&_BufferIndexedInterface_ArrayUint32);
BufferArray.c
/*
*******************************************************************************************
*
* Parent Class for All Indexed Array Buffer with normal pointer
*
* File : BufferArray.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s):
*******************************************************************************************
*/
#include "BufferArray.h"
void _BufferArray_Init(BufferArray buf,void *ptr,unsigned int capacity,
OBJECTINTERFACE_VOID fDestroy, BUFFER_INTERFACE_TABLE vtable,BUFFERINDEXED_INTERFACE_TABLE i_vtable){
_BufferArrayShare_Init((BufferArrayShare)buf,fDestroy,
&_ContainerInterface_ArrayShare,vtable,i_vtable,capacity);
_BufferArray_ptr(buf) = ptr;
}
uint8_t *_BufferIndexer_ArrayUint8(BufferIndexed buf,unsigned int index){
return _BufferArray_ptrUint8(buf) + _BufferArrayShare_calInternalIndex((BufferArrayShare)buf,index);
}
uint16_t *_BufferIndexer_ArrayUint16(BufferIndexed buf,unsigned int index){
return _BufferArray_ptrUint16(buf) + _BufferArrayShare_calInternalIndex((BufferArrayShare)buf,index);
}
uint32_t *_BufferIndexer_ArrayUint32(BufferIndexed buf,unsigned int index){
return _BufferArray_ptrUint32(buf) + _BufferArrayShare_calInternalIndex((BufferArrayShare)buf,index);
}
static void _Uint8Setter(BufferUINT8Indexed buf,unsigned int index,uint8_t element){
* _BufferIndexer_ArrayUint8(buf,index) = element;
}
static uint8_t _Uint8Getter(BufferUINT8Indexed buf,unsigned int index){
return * _BufferIndexer_ArrayUint8(buf,index);
}
static void _Uint16Setter(BufferUINT16Indexed buf,unsigned int index,uint16_t element){
* _BufferIndexer_ArrayUint16(buf,index) = element;
}
static uint16_t _Uint16Getter(BufferUINT16Indexed buf,unsigned int index){
return * _BufferIndexer_ArrayUint16(buf,index);
}
static void _Uint32Setter(BufferUINT32Indexed buf,unsigned int index,uint32_t element){
* _BufferIndexer_ArrayUint32(buf,index) = element;
}
static uint32_t _Uint32Getter(BufferUINT32Indexed buf,unsigned int index){
return * _BufferIndexer_ArrayUint32(buf,index);
}
const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayUint8 = {
(BUFFERINTERFACE_POINTER)_Uint8Setter,
(BUFFERINTERFACE_POINTER)_Uint8Getter
};
const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayUint16 = {
(BUFFERINTERFACE_POINTER)_Uint16Setter,
(BUFFERINTERFACE_POINTER)_Uint16Getter
};
const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayUint32 = {
(BUFFERINTERFACE_POINTER)_Uint32Setter,
(BUFFERINTERFACE_POINTER)_Uint32Getter
};
BufferExternalArray
BufferExternalArray.h
/*
*******************************************************************************************
*
* An Implementation for BufferArray
*
* File : BufferExternalArray.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. An implementation for BufferArray, which manage the array passed by user.
* b. Inheritance tree: Container -> BufferTYPE -> BufferTYPEIndexed ->
* BufferTYPEArrayShare -> BufferTYPEArray
* where TYPE can be UINT8, UINT16, UINT32 ......
* See the header file of each class to figure out which it can do.
*******************************************************************************************
*/
#ifndef _BUFFER_EXTERNAL_ARRAY_H
#define _BUFFER_EXTERNAL_ARRAY_H
/*
*******************************************************************************************
* INCLUDES
*******************************************************************************************
*/
#include "BufferArray.h"
/*
*******************************************************************************************
* FUNCTIONS
*******************************************************************************************
*/
// description: Create an instance of BufferArray
// parameters : arr the array to be managed by the BufferArray
// capacity the size of the array
// return : the instance created.
// NULL if anything wrong.
// note : in the lifetime of the instance, you should never touch the array, just
// think it as the private property of the instance
BufferUINT8Array BufferUINT8ExternalArray_Create (uint8_t * arr, unsigned int capacity);
BufferUINT16Array BufferUINT16ExternalArray_Create(uint16_t * arr, unsigned int capacity);
BufferUINT32Array BufferUINT32ExternalArray_Create(uint32_t * arr, unsigned int capacity);
#endif
BufferExternalArray.c
/*
*******************************************************************************************
*
* An Implementation for BufferArray
*
* File : BufferExternalArray.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. An implementation for BufferArray, which use the array passed by user.
* b. Inheritance tree: Container -> BufferTYPE -> BufferTYPEIndexed ->
* BufferTYPEArrayShare -> BufferTYPEArray
* where TYPE can be UINT8, UINT16, UINT32 ......
* See the header file of each class to figure out which it can do.
*******************************************************************************************
*/
#include <stdlib.h>
#include "BufferExternalArray.h"
BufferUINT8Array BufferUINT8ExternalArray_Create (uint8_t * arr, unsigned int capacity){
BufferUINT8Array buf = (BufferUINT8Array)malloc(sizeof(BUFFERARRAY_STRUCT));
if(buf)
_BufferUINT8Array_Init(buf, arr,capacity,_Destroy_JustCallFree);
return buf;
}
BufferUINT16Array BufferUINT16ExternalArray_Create (uint16_t * arr, unsigned int capacity){
BufferUINT16Array buf = (BufferUINT16Array)malloc(sizeof(BUFFERARRAY_STRUCT));
if(buf)
_BufferUINT16Array_Init(buf, arr,capacity,_Destroy_JustCallFree);
return buf;
}
BufferUINT32Array BufferUINT32ExternalArray_Create (uint32_t * arr, unsigned int capacity){
BufferUINT32Array buf = (BufferUINT32Array)malloc(sizeof(BUFFERARRAY_STRUCT));
if(buf)
_BufferUINT32Array_Init(buf, arr,capacity,_Destroy_JustCallFree);
return buf;
}
BufferMallocArray
BufferMallocArray.h
/*
*******************************************************************************************
*
* A Common Implementation for BufferArray
*
* File : BufferMallocArray.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. A common implementation for BufferArray, which use malloc to allocate space
* b. Inheritance tree: Container -> BufferTYPE -> BufferTYPEIndexed ->
* BufferTYPEArrayShare -> BufferTYPEArray
* where TYPE can be UINT8, UINT16 or UINT32.
* See the header file of each class to figure out which it can do.
*******************************************************************************************
*/
#ifndef _BUFFER_MALLOC_ARRAY_H
#define _BUFFER_MALLOC_ARRAY_H
/*
*******************************************************************************************
* INCLUDES
*******************************************************************************************
*/
#include "BufferArray.h"
/*
*******************************************************************************************
* FUNCTIONS
*******************************************************************************************
*/
BufferUINT8Array BufferUINT8MallocArray_Create(unsigned int capacity);
BufferUINT16Array BufferUINT16MallocArray_Create(unsigned int capacity);
BufferUINT32Array BufferUINT32MallocArray_Create(unsigned int capacity);
#endif
BufferMallocArray.c
/*
*******************************************************************************************
*
* A Common Implementation for BufferArray
*
* File : BufferMallocArray.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. A common implementation for BufferArray, which use malloc to allocate space
* b. Inheritance tree: Container -> BufferTYPE -> BufferTYPEIndexed ->
* BufferTYPEArrayShare -> BufferTYPEArray
* where TYPE can be UINT8, UINT16 or UINT32.
* See the header file of each class to figure out which it can do.
*******************************************************************************************
*/
#include <stdlib.h>
#include "BufferMallocArray.h"
#ifndef UINT_MAX
#define UINT_MAX ((unsigned int)-1)
#endif
static void _Destroy(void * buf);
static BufferArray _BufferMallocArray_Create(unsigned int arrSize,unsigned int capacity,
BUFFER_INTERFACE_TABLE vtable,BUFFERINDEXED_INTERFACE_TABLE indexer);
BufferUINT8Array BufferUINT8MallocArray_Create(unsigned int capacity){
return (BufferUINT8Array)_BufferMallocArray_Create
(capacity,capacity,&_BufferInterface_ArrayUint8,&_BufferIndexedInterface_ArrayUint8);
}
BufferUINT16Array BufferUINT16MallocArray_Create(unsigned int capacity){
if(capacity > (UINT_MAX >> 1))
return NULL;
return (BufferUINT16Array)_BufferMallocArray_Create
(capacity << 1,capacity,&_BufferInterface_ArrayUint16,&_BufferIndexedInterface_ArrayUint16);
}
BufferUINT32Array BufferUINT32MallocArray_Create(unsigned int capacity){
if(capacity > (UINT_MAX >> 2))
return NULL;
return (BufferUINT32Array)_BufferMallocArray_Create
(capacity << 2,capacity,&_BufferInterface_ArrayUint32,&_BufferIndexedInterface_ArrayUint32);
}
static BufferArray _BufferMallocArray_Create(unsigned int arrSize,unsigned int capacity,
BUFFER_INTERFACE_TABLE vtable,BUFFERINDEXED_INTERFACE_TABLE indexer){
uint8_t * ptr = NULL;
BufferArray buf;
if(capacity != 0 && (ptr = (uint8_t *)malloc(arrSize)) == NULL)
return NULL;
if((buf = (BufferArray)malloc(sizeof(BUFFERARRAY_STRUCT))) == NULL){
if(ptr)
free(ptr);
return NULL;
}
_BufferArray_Init(buf,ptr,capacity, _Destroy,vtable,indexer);
return buf;
}
static void _Destroy(void * buf){
if(buf == NULL)
return;
if(_BufferArray_ptr(buf))
free(_BufferArray_ptr(buf));
free(buf);
}
BufferArrayR
BufferArrayR.h
注意:要使用这个模块得宏定义CODEWARRIOR,否则效果和BufferArray一样。
/*
*******************************************************************************************
*
* Parent Class for All Indexed Array Buffer with rpage pointer
*
* File : BufferArrayR.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. This class provide the pointer members for Buffers which use a RPAGE numerically
* indexed array internal. And the indexer for UINT8, UINT16 and UINT32 Buffer.
* b. To use this module, #define CODEWARRIOR marco (maybe in your complier option)
* or it will act same as the BufferArray.
*******************************************************************************************
*/
#ifndef _BUFFERARRAYR_H
#define _BUFFERARRAYR_H
#include "BufferArrayShare.h"
typedef struct BUFFERARRAYR_STRUCT
* BufferArrayR,
* BufferUINT8ArrayR,
* BufferUINT16ArrayR,
* BufferUINT32ArrayR;
#include "BufferArrayRPrivate.h"
#endif
BufferArrayRPrivate.h
/*
*******************************************************************************************
*
* Parent Class for All RPAGE Indexed Array Buffer
*
* File : BufferArrayRPrivate.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. This class provide the pointer members for Buffers which use a RPAGE numerically
* indexed array internal. And the indexer for UINT8, UINT16 and UINT32 Buffer.
* b. Generally, to implement an indexed array buffer, developer just need to implement
* a Create method, which allocates space for BUFFERARRAYR_STRUCT and use the Init
* method in this file to initialize it, plus the corresponding destroy method;
* then everything will go right.
*******************************************************************************************
*/
#include "BufferArrayR.h"
#ifdef CODEWARRIOR
#define __RPTR __rptr
#else
#define __RPTR
#endif
typedef struct BUFFERARRAYR_STRUCT{
BUFFERARRAYSHARE_STRUCT parent;
union{
uint8_t * __RPTR uint8;
uint16_t * __RPTR uint16;
uint32_t * __RPTR uint32;
void * __RPTR ptr;
}ptr;
} BUFFERARRAYR_STRUCT;
#define _BufferArrayR_ptrUint8(buf) (((BufferUINT8ArrayR )buf)->ptr.uint8)
#define _BufferArrayR_ptrUint16(buf) (((BufferUINT16ArrayR)buf)->ptr.uint16)
#define _BufferArrayR_ptrUint32(buf) (((BufferUINT32ArrayR)buf)->ptr.uint32)
#define _BufferArrayR_ptr(buf) (((BufferArrayR )buf)->ptr.ptr)
// common indexer interface for rpaged array, use the indexer to access internal element.
// so you should implement the indexer correctly as description.
extern const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayRUint8;
extern const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayRUint16;
extern const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayRUint32;
void _BufferArrayR_Init(BufferArrayR buf,void * __RPTR ptr,unsigned int capacity,
OBJECTINTERFACE_VOID fDestroy, BUFFER_INTERFACE_TABLE vtable,
BUFFERINDEXED_INTERFACE_TABLE i_vtable);
// void _BufferUINT8ArrayR_Init(BufferUINT8ArrayR buf,uint8_t * __rptr ptr,unsigned int capacity, OBJECTINTERFACE_VOID fDestroy);
#define _BufferUINT8ArrayR_Init(buf,ptr,capacity,fDestroy) \
_BufferArrayR_Init(buf,ptr,capacity,fDestroy,&_BufferInterface_ArrayUint8,\
&_BufferIndexedInterface_ArrayRUint8);
// void _BufferUINT16ArrayR_Init(BufferUINT16ArrayR buf,uint16_t * __rptr ptr,unsigned int capacity, OBJECTINTERFACE_VOID fDestroy);
#define _BufferUINT16ArrayR_Init(buf,ptr,capacity,fDestroy) \
_BufferArrayR_Init(buf,ptr,capacity,fDestroy,&_BufferInterface_ArrayUint16,\
&_BufferIndexedInterface_ArrayRUint16);
// void _BufferUINT32ArrayR_Init(BufferUINT32ArrayR buf,uint32_t * __rptr ptr,unsigned int capacity, OBJECTINTERFACE_VOID fDestroy);
#define _BufferUINT32ArrayR_Init(buf,ptr,capacity,fDestroy) \
_BufferArrayR_Init(buf,ptr,capacity,fDestroy,&_BufferInterface_ArrayUint32,\
&_BufferIndexedInterface_ArrayRUint32);
BufferArrayR.c
/*
*******************************************************************************************
*
* Parent Class for All Indexed Array Buffer with rpage pointer
*
* File : BufferArrayR.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s):
*******************************************************************************************
*/
#include "BufferArrayR.h"
void _BufferArrayR_Init(BufferArrayR buf,void *__RPTR ptr,unsigned int capacity, OBJECTINTERFACE_VOID fDestroy,
BUFFER_INTERFACE_TABLE vtable,BUFFERINDEXED_INTERFACE_TABLE i_vtable){
_BufferArrayShare_Init((BufferArrayShare)buf,fDestroy,
&_ContainerInterface_ArrayShare,vtable,i_vtable,capacity);
_BufferArrayR_ptr(buf) = ptr;
}
uint8_t * __RPTR _BufferIndexer_ArrayRUint8(BufferIndexed buf,unsigned int index){
return _BufferArrayR_ptrUint8(buf) + _BufferArrayShare_calInternalIndex((BufferArrayShare)buf,index);
}
uint16_t * __RPTR _BufferIndexer_ArrayRUint16(BufferIndexed buf,unsigned int index){
return _BufferArrayR_ptrUint16(buf) + _BufferArrayShare_calInternalIndex((BufferArrayShare)buf,index);
}
uint32_t * __RPTR _BufferIndexer_ArrayRUint32(BufferIndexed buf,unsigned int index){
return _BufferArrayR_ptrUint32(buf) + _BufferArrayShare_calInternalIndex((BufferArrayShare)buf,index);
}
static void _Uint8Setter(BufferUINT8Indexed buf,unsigned int index,uint8_t element){
* _BufferIndexer_ArrayRUint8(buf,index) = element;
}
static uint8_t _Uint8Getter(BufferUINT8Indexed buf,unsigned int index){
return * _BufferIndexer_ArrayRUint8(buf,index);
}
static void _Uint16Setter(BufferUINT16Indexed buf,unsigned int index,uint16_t element){
* _BufferIndexer_ArrayRUint16(buf,index) = element;
}
static uint16_t _Uint16Getter(BufferUINT16Indexed buf,unsigned int index){
return * _BufferIndexer_ArrayRUint16(buf,index);
}
static void _Uint32Setter(BufferUINT32Indexed buf,unsigned int index,uint32_t element){
* _BufferIndexer_ArrayRUint32(buf,index) = element;
}
static uint32_t _Uint32Getter(BufferUINT32Indexed buf,unsigned int index){
return * _BufferIndexer_ArrayRUint32(buf,index);
}
const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayRUint8 = {
(BUFFERINTERFACE_POINTER)_Uint8Setter,
(BUFFERINTERFACE_POINTER)_Uint8Getter
};
const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayRUint16 = {
(BUFFERINTERFACE_POINTER)_Uint16Setter,
(BUFFERINTERFACE_POINTER)_Uint16Getter
};
const BUFFERINDEXED_INTERFACE _BufferIndexedInterface_ArrayRUint32 = {
(BUFFERINTERFACE_POINTER)_Uint32Setter,
(BUFFERINTERFACE_POINTER)_Uint32Getter
};
BufferExternalArrayR
BufferExternalArrayR.h
/*
*******************************************************************************************
*
* An Implementation for BufferArrayR
*
* File : BufferExternalArrayR.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. An implementation for BufferArrayR, which manage the array passed by user.
* b. Inheritance tree: Container -> BufferTYPE -> BufferTYPEIndexed ->
* BufferTYPEArrayShare -> BufferTYPEArrayR
* where TYPE can be UINT8, UINT16, UINT32 ......
* See the header file of each class to figure out which it can do.
*******************************************************************************************
*/
#ifndef _BUFFER_EXTERNAL_ARRAYR_H
#define _BUFFER_EXTERNAL_ARRAYR_H
/*
*******************************************************************************************
* INCLUDES
*******************************************************************************************
*/
#include "BufferArrayR.h"
/*
*******************************************************************************************
* FUNCTIONS
*******************************************************************************************
*/
// description: Create an instance of BufferArrayR
// parameters : arr the array to be managed by the BufferArray
// capacity the size of the array
// return : the instance created.
// NULL if anything wrong.
// note : in the lifetime of the instance, you should never touch the array, just
// think it as the private property of the instance
BufferUINT8ArrayR BufferUINT8ExternalArrayR_Create (uint8_t * __RPTR arr, unsigned int capacity);
BufferUINT16ArrayR BufferUINT16ExternalArrayR_Create(uint16_t * __RPTR arr, unsigned int capacity);
BufferUINT32ArrayR BufferUINT32ExternalArrayR_Create(uint32_t * __RPTR arr, unsigned int capacity);
#endif
BufferExternalArrayR.c
/*
*******************************************************************************************
*
* An Implementation for BufferArray
*
* File : BufferExternalArrayR.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): a. An implementation for BufferArray, which use the array passed by user.
* b. Inheritance tree: Container -> BufferTYPE -> BufferTYPEIndexed ->
* BufferTYPEArrayShare -> BufferTYPEArrayR
* where TYPE can be UINT8, UINT16, UINT32 ......
* See the header file of each class to figure out which it can do.
*******************************************************************************************
*/
#include <stdlib.h>
#include "BufferExternalArrayR.h"
BufferUINT8ArrayR BufferUINT8ExternalArrayR_Create(uint8_t * __RPTR arr, unsigned int capacity){
BufferUINT8ArrayR buf = (BufferUINT8ArrayR)malloc(sizeof(BUFFERARRAYR_STRUCT));
if(buf)
_BufferUINT8ArrayR_Init(buf, arr,capacity,_Destroy_JustCallFree);
return buf;
}
BufferUINT16ArrayR BufferUINT16ExternalArrayR_Create(uint16_t * __RPTR arr, unsigned int capacity){
BufferUINT16ArrayR buf = (BufferUINT16ArrayR)malloc(sizeof(BUFFERARRAYR_STRUCT));
if(buf)
_BufferUINT16ArrayR_Init(buf, arr,capacity,_Destroy_JustCallFree);
return buf;
}
BufferUINT32ArrayR BufferUINT32ExternalArrayR_Create (uint32_t * __RPTR arr, unsigned int capacity){
BufferUINT32ArrayR buf = (BufferUINT32ArrayR)malloc(sizeof(BUFFERARRAYR_STRUCT));
if(buf)
_BufferUINT32ArrayR_Init(buf, arr,capacity,_Destroy_JustCallFree);
return buf;
}
BufferChar
BufferChar.h
示例了怎么适配其他类型元素的缓冲区,由于直接使用的宏,不需要.c文件。
/*
*******************************************************************************************
*
* Buffer for char type
*
* File : BufferChar.h
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date: 2019/01/08
* version: V1.0
* History:
* NOTE(s): Adapt BufferChar from BufferUINT8Array
*******************************************************************************************
*/
#ifndef _BUFFERCHAR_H
#define _BUFFERCHAR_H
/*
*******************************************************************************************
* INCLUDES
*******************************************************************************************
*/
#include "BufferMallocArray.h"
#include "BufferExternalArray.h"
/*
*******************************************************************************************
* DATA TYPE 数据类型
*******************************************************************************************
*/
typedef BufferUINT8 BufferChar;
/*
*******************************************************************************************
* FUNCTION PROTOTYPE
*******************************************************************************************
*/
// BufferChar BufferChar_Create(unsigned int capacity);
#define BufferChar_Create(capacity) \
((BufferChar)BufferUINT8MallocArray_Create(capacity))
// BufferChar BufferChar_CreateEx(char * arr,unsigned int capacity);
#define BufferChar_CreateEx(arr,capacity) \
((BufferChar)BufferUINT8ExternalArray_Create((uint8_t *)(arr),capacity))
// unsigned int BufferChar_getCapacity(BufferChar buf);
#define BufferChar_getCapacity(buf) BufferUINT8_getCapacity(buf)
// unsigned int BufferChar_getCount(BufferChar buf);
#define BufferChar_getCount(buf) BufferUINT8_getCount(buf)
// BOOL BufferChar_isEmpty(BufferChar buf);
#define BufferChar_isEmpty(buf) BufferUINT8_isEmpty(buf)
// BOOL BufferChar_isFull(BufferChar buf);
#define BufferChar_isFull(buf) BufferUINT8_isFull(buf)
// char BufferChar_Front(BufferChar buf);
#define BufferChar_Front(buf) ((char)BufferUINT8_Front(buf))
// char BufferChar_Back(BufferChar buf);
#define BufferChar_Back(buf) ((char)BufferUINT8_Back(buf))
// void BufferChar_FrontIn(BufferChar buf,char element);
#define BufferChar_FrontIn(buf,element) BufferUINT8_FrontIn(buf,(uint8_t)element)
// void BufferChar_BackIn(BufferChar buf,char element);
#define BufferChar_BackIn(buf,element) BufferUINT8_BackIn(buf,(uint8_t)element)
// char BufferChar_FrontOut(BufferChar buf);
#define BufferChar_FrontOut(buf) ((char)BufferUINT8_FrontOut(buf))
// char BufferChar_BackOut(BufferChar buf);
#define BufferChar_BackOut(buf) ((char)BufferUINT8_BackOut(buf))
// char BufferChar_Cleanup(BufferChar buf);
#define BufferChar_Cleanup(buf) BufferUINT8_Cleanup(buf)
// void BufferChar_Destroy(BufferChar buf);
#define BufferChar_Destroy(buf) BufferUINT8_Destroy(buf)
#endif