182 lines
5.0 KiB
C
182 lines
5.0 KiB
C
|
|
|
|
#include <HByteStack.h>
|
|
|
|
|
|
#ifndef LogD
|
|
#define LogD(...)
|
|
#endif
|
|
|
|
|
|
static void InitStack(HByteType *stackData) {
|
|
if ((stackData[0] & kHByteStackNeedInit) == 0) {
|
|
return;
|
|
}
|
|
|
|
// 初始化, 需要纠正长度数据, 因多字节时候存在大小端问题
|
|
_HByteStackBase *base = (_HByteStackBase *)stackData;
|
|
base->flag &= ~kHByteStackNeedInit;
|
|
uint8_t *len = (uint8_t *)&base->len;
|
|
base->len = _HBYTE_STACK_INIT_SIZE_INIT(len);
|
|
len = (uint8_t *)&base->useLen;
|
|
base->useLen = _HBYTE_STACK_INIT_SIZE_INIT(len);
|
|
}
|
|
|
|
// 获取栈类型
|
|
static uint8_t GetStackType(const HByteType *stackData) {
|
|
InitStack((HByteType *)stackData);
|
|
_HByteStackBase *base = (_HByteStackBase *)stackData;
|
|
return base->flag & kHByteStackFlagAllMask;
|
|
}
|
|
|
|
static HByteDataType GetStackData(const HByteType *stackData, HByteLenType pos) {
|
|
switch (GetStackType(stackData)) {
|
|
case kHByteStackFlag8: return ((const _HByteStack8 *)stackData)->data[pos]; break;
|
|
case kHByteStackFlag16: return ((const _HByteStack16 *)stackData)->data[pos]; break;
|
|
case kHByteStackFlag32: return ((const _HByteStack32 *)stackData)->data[pos]; break;
|
|
}
|
|
|
|
return HBYTE_STACK_ERROR;
|
|
}
|
|
|
|
static void SetStackData(HByteType *stackData, HByteLenType pos, HByteDataType data) {
|
|
switch (GetStackType(stackData)) {
|
|
case kHByteStackFlag8: ((_HByteStack8 *)stackData)->data[pos] = (uint8_t)data; break;
|
|
case kHByteStackFlag16: ((_HByteStack16 *)stackData)->data[pos] = (uint16_t)data; break;
|
|
case kHByteStackFlag32: ((_HByteStack32 *)stackData)->data[pos] = (uint32_t)data; break;
|
|
}
|
|
}
|
|
|
|
// 获取栈长度
|
|
static HByteLenType GetStackLen(const HByteType *stackData) {
|
|
const _HByteStackBase *base = (const _HByteStackBase *)stackData;
|
|
InitStack((HByteType *)stackData);
|
|
|
|
if ((base->flag & kHByteStackFlagAllMask) == 0) {
|
|
LogD("error flag[%d]", base->flag);
|
|
return 0;
|
|
}
|
|
|
|
return base->len;
|
|
}
|
|
|
|
static HByteLenType GetStackUseLen(const HByteType *stackData) {
|
|
const _HByteStackBase *base = (const _HByteStackBase *)stackData;
|
|
InitStack((HByteType *)stackData);
|
|
|
|
if ((base->flag & kHByteStackFlagAllMask) == 0) {
|
|
LogD("error flag[%d]", base->flag);
|
|
return 0;
|
|
}
|
|
|
|
return base->useLen;
|
|
}
|
|
|
|
static void SetStackUseLen(HByteType *stackData, HByteLenType len) {
|
|
_HByteStackBase *base = (_HByteStackBase *)stackData;
|
|
InitStack((HByteType *)stackData);
|
|
|
|
if ((base->flag & kHByteStackFlagAllMask) == 0) {
|
|
LogD("error flag[%d]", base->flag);
|
|
return ;
|
|
}
|
|
|
|
base->useLen = len;
|
|
}
|
|
|
|
uint8_t HByteStackPush(HByteType *stackData, HByteDataType value) {
|
|
if (GetStackUseLen(stackData) >= GetStackLen(stackData)) {
|
|
return 0;
|
|
}
|
|
|
|
HByteLenType len = GetStackUseLen(stackData);
|
|
SetStackData(stackData, len, value);
|
|
SetStackUseLen(stackData, len + 1);
|
|
return 1;
|
|
}
|
|
|
|
HByteDataType HByteStackPop(HByteType *stackData) {
|
|
if (HByteStackEmpty(stackData)) {
|
|
return HBYTE_STACK_ERROR;
|
|
}
|
|
|
|
HByteLenType len = GetStackUseLen(stackData) - 1;
|
|
SetStackUseLen(stackData, len);
|
|
return GetStackData(stackData, len);
|
|
}
|
|
|
|
HByteDataType HByteStackTop(const HByteType *stackData) {
|
|
if (HByteStackEmpty(stackData)) {
|
|
return HBYTE_STACK_ERROR;
|
|
}
|
|
|
|
return GetStackData(stackData, GetStackUseLen(stackData) - 1);
|
|
}
|
|
|
|
// 返回指定位置数据, 失败返回 HBYTE_STACK_ERROR
|
|
HByteDataType HByteStackGetPos(const HByteType *stackData, HByteLenType pos) {
|
|
if (pos >= GetStackUseLen(stackData)) {
|
|
return HBYTE_STACK_ERROR;
|
|
}
|
|
|
|
return GetStackData(stackData, pos);
|
|
}
|
|
|
|
HByteLenType HByteStackLen(const HByteType *stackData) {
|
|
return GetStackLen(stackData);
|
|
}
|
|
|
|
uint8_t HByteStackEmpty(const HByteType *stackData) {
|
|
return GetStackUseLen(stackData) == 0;
|
|
}
|
|
|
|
void HByteStackClear(HByteType *stackData) {
|
|
SetStackUseLen(stackData, 0);
|
|
}
|
|
|
|
HByteLenType HByteStackFind(const HByteType *stackData, HByteDataType value) {
|
|
return HByteStackFindEx(stackData, value, 0);
|
|
}
|
|
|
|
HByteLenType HByteStackFindEx(const HByteType *stackData, HByteDataType value, HByteLenType endPos) {
|
|
if (endPos >= GetStackUseLen(stackData)) {
|
|
return HBYTE_STACK_ERROR;
|
|
}
|
|
|
|
for (HByteLenType i = GetStackUseLen(stackData); i-- > endPos;) {
|
|
if (GetStackData(stackData, i) == value) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return HBYTE_STACK_ERROR;
|
|
}
|
|
|
|
HByteLenType HByteStackGetUseLen(const HByteType *stackData) {
|
|
return GetStackUseLen(stackData);
|
|
}
|
|
|
|
void HByteStackSetUseLen(HByteType *stackData, HByteLenType pos) {
|
|
if (pos >= HByteStackGetUseLen(stackData)) {
|
|
LogD("error pos[%d], useLen[%d]", pos, HByteStackGetUseLen(stackData));
|
|
return;
|
|
}
|
|
|
|
SetStackUseLen(stackData, pos);
|
|
}
|
|
|
|
HByteLenType HByteStackCount(const HByteType *stackData, HByteDataType value) {
|
|
if (HByteStackEmpty(stackData)) {
|
|
return 0;
|
|
}
|
|
|
|
HByteType count = 0;
|
|
for (HByteType i = GetStackUseLen(stackData); i-- > 0;) {
|
|
if (GetStackData(stackData, i) == value) {
|
|
++count;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|