From 09d777261f4249ccdba5bef44d794742f4e3237a Mon Sep 17 00:00:00 2001 From: hyzboy Date: Thu, 10 Oct 2024 01:20:29 +0800 Subject: [PATCH] Added BitsArray.h/.cpp --- inc/hgl/type/BitsArray.h | 82 +++++++ src/CMakeLists.txt | 21 +- src/Type/BitsArray.cpp | 493 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 589 insertions(+), 7 deletions(-) create mode 100644 inc/hgl/type/BitsArray.h create mode 100644 src/Type/BitsArray.cpp diff --git a/inc/hgl/type/BitsArray.h b/inc/hgl/type/BitsArray.h new file mode 100644 index 0000000..0ea851f --- /dev/null +++ b/inc/hgl/type/BitsArray.h @@ -0,0 +1,82 @@ +#pragma once +#include +namespace hgl +{ + namespace io + { + class DataInputStream; + class DataOutputStream; + }//namespace io + + /** + * 位队列用于处理需要按位保存的数据,它可以按位读取和写入 + */ + class BitsArray ///位数据阵列 + { + bool mapping; + + int byte_size; + int count,pos; + + uint8 *data; + + public: + + int GetCount()const noexcept{return count;} + void SetCount(int); + + int GetByteSize()const noexcept{return byte_size;} + + int GetPos()const noexcept{return pos;} + void SetPos(int); + + uint8 * GetData() {return data;} + const uint8 * GetData()const {return data;} + + public: + + BitsArray(int=0); + BitsArray(void *,int,bool=true); + virtual ~BitsArray(); + + void Create(int); ///<创建数据区 + void MapData(void *,int); ///<映射数据 + void Clear(); ///<清除所有数据 + + void Fill(bool); ///<填充数据 + + bool WriteZero(); ///<写入一位0 + bool WriteOne(); ///<写入一位1 + + bool WriteTrue(){return WriteOne();} ///<写入一位真(即1) + bool WriteFalse(){return WriteZero();} ///<写入一位假(即0) + + bool WriteBit(bool bit) ///<写入一位数据 + {return(bit?WriteOne():WriteZero());} + bool WriteBytes(uint8 *,int); ///<按字节写入数据 + + bool ReadBit(bool &); ///<读取一位 + + bool FlipBit(); ///<翻转一位 + bool FlipBitAt(int o) ///<翻转指定位 + {SetPos(o);return(FlipBit());} + + bool ReadAt( int o,bool &bit)const; ///<读取指定位 + bool WriteAt( int o,bool bit); ///<写入一位数据 + + bool SaveToStream(io::DataOutputStream *); ///<保存当前位阵列数据到流 + bool LoadFromStream(io::DataInputStream *); ///<从流中读取位阵列数据 + + public: //操作符重载 + + BitsArray & operator =(const BitsArray &); ///<=号重载 + + BitsArray & operator +=(const BitsArray &); ///<+ + BitsArray & operator -=(const BitsArray &); ///<- + BitsArray & operator *=(const BitsArray &); ///<* + + bool operator == (const BitsArray &) const; + bool operator != (const BitsArray &rhs) const {return !operator==(rhs);} + };//class BitsArray +}//namespace hgl + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 84f86b3..2d9ca47 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,8 @@ SET(CORE_PLATFORM_HEADER_FILES ${CORE_PLATFORM_INCLUDE_PATH}/Platform.h) +SET(TYPE_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type) + FILE(GLOB CORE_PLATFORM_OS_FILES ${CORE_PLATFORM_INCLUDE_PATH}/os/*.h) FILE(GLOB CORE_PLATFORM_COMPILER_FILES ${CORE_PLATFORM_INCLUDE_PATH}/compiler/*.h) @@ -13,11 +15,14 @@ SET(CORE_PLATFORM_HEADER_FILES ${CORE_PLATFORM_HEADER_FILES} ${CORE_PLATFORM_OS_FILES} ${CORE_PLATFORM_COMPILER_FILES}) -SET(TYPE_INFO_FILE ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/TypeInfo.h) +SET(TYPE_INFO_FILE ${TYPE_INCLUDE_PATH}/TypeInfo.h) SOURCE_GROUP("DataType" FILES ${TYPE_INFO_FILE}) -SET(TYPE_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type) +SET(BITS_ARRAY_FILES ${TYPE_INCLUDE_PATH}/BitsArray.h + Type/BitsArray.cpp) + +SOURCE_GROUP("DataType\\BitsArray" FILES ${BITS_ARRAY_FILES}) SET(TYPE_IDNAME_HEADER_FILES ${TYPE_INCLUDE_PATH}/ConstStringSet.h ${TYPE_INCLUDE_PATH}/IDName.h) @@ -52,11 +57,11 @@ SET(SYSTEM_INFO_SOURCE ${CORE_PLATFORM_INCLUDE_PATH}/SystemInfo.h SET(MATH_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/math) -SET(BASE_OBJECT_HEADER_FILES ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/ObjectBaseInfo.h - ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/Object.h - ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/ObjectAllocator.h - ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/ObjectManager.h - ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/DefaultCreateObject.h) +SET(BASE_OBJECT_HEADER_FILES ${TYPE_INCLUDE_PATH}/object/ObjectBaseInfo.h + ${TYPE_INCLUDE_PATH}/object/Object.h + ${TYPE_INCLUDE_PATH}/object/ObjectAllocator.h + ${TYPE_INCLUDE_PATH}/object/ObjectManager.h + ${TYPE_INCLUDE_PATH}/object/DefaultCreateObject.h) SET(BASE_OBJECT_SOURCE_FILES Object/Object.cpp Object/ObjectManager.cpp @@ -254,6 +259,8 @@ add_cm_library(CMCore "CM" ${CORE_PLATFORM_HEADER_FILES} ${BASE_OBJECT_HEADER_FILES} ${BASE_OBJECT_SOURCE_FILES} + ${BITS_ARRAY_FILES} + ${COLOR_HEADER_FILES} ${COLOR_SOURCE_FILES} diff --git a/src/Type/BitsArray.cpp b/src/Type/BitsArray.cpp new file mode 100644 index 0000000..6ef8597 --- /dev/null +++ b/src/Type/BitsArray.cpp @@ -0,0 +1,493 @@ +#include +#include +#include + +namespace hgl +{ + /** + * 本类构造函数,并创建指定长度的数据空间 + * @param bitsize 位长度 + */ + BitsArray::BitsArray(int bitsize) + { + data=nullptr; + + Create(bitsize); + } + + /** + * 本类构造函数,并传入部分数据,做为已有的数据 + * @param bytedata 原有的数据 + * @param size 数据字节数 + * @param 是否是映射的其它数据区,如果为true,则在本类被清除时不会释放数据区 + */ + BitsArray::BitsArray(void *bytedata,int size,bool map) + { + if(size>0) + { + byte_size=size; + count=byte_size<<3; + pos=0; + + mapping=map; + + if(mapping) + { + data=(uint8 *)bytedata; + } + else + { + data=(uint8 *)hgl_malloc(byte_size); + memcpy(data,bytedata,size); + } + } + else + { + byte_size=0; + count=0; + pos=0; + + data=nullptr; + + mapping=false; + } + } + + BitsArray::~BitsArray() + { + Clear(); + } + + void BitsArray::MapData(void *bytedata,int size) + { + Clear(); + + if(size>0) + { + byte_size=size; + count=byte_size<<3; + pos=0; + + mapping=true; + data=(uint8 *)bytedata; + } + } + + void BitsArray::Clear() + { + if(data) + { + if(!mapping) + hgl_free(data); + + data=nullptr; + } + + mapping=false; + + count=0; + pos=0; + byte_size=0; + } + + /** + * 创建指定长度的数据空间 + * @param bitsize 位长度 + */ + void BitsArray::Create(int bitsize) + { + Clear(); + + if(bitsize>0) + { + byte_size=(bitsize+7)>>3; + count=bitsize; + + data=(uint8 *)hgl_malloc(byte_size); + memset(data,0,byte_size); + } + else + { + byte_size=0; + count=0; + + data=nullptr; + } + + pos=0; + } + + void BitsArray::SetCount(int newcount) + { + if(newcount==count)return; + if(newcount<=0) + { + Clear(); + return; + } + + int new_size=(newcount+7)>>3; + + if(byte_size==0) + { + byte_size=new_size; + count=newcount; + pos=0; + + data=(uint8 *)hgl_malloc(byte_size); + } + else + { + if(byte_size!=new_size) + { + byte_size=new_size; + + data=(uint8 *)hgl_realloc(data,new_size); + } + + count=newcount; + if(pos>count)pos=count; + } + } + + void BitsArray::SetPos(int npos) + { + if(npos<0)pos=0;else + if(npos>count)pos=count;else + pos=npos; + } + + /** + * 全部填充成指定数据 + */ + void BitsArray::Fill(bool v) + { + if(data) + memset(data,v?255:0,byte_size); + } + + #define ONE_AT_BIT(_bit_off) (1<<_bit_off) + #define ZERO_AT_BIT(_bit_off) (0xff^(1<<_bit_off)) + + /** + * 向位队列中写入一位0 + */ + bool BitsArray::WriteZero() + { + if(!data)return(false); + + int byte_offset; + int bit_offset; + + if(pos==count) + count++; + + byte_offset=pos>>3; //除8 + bit_offset=pos&7; //取最后3位,最大是7 + + data[byte_offset]&=ZERO_AT_BIT(bit_offset); + + pos++; + return(true); + } + + /** + * 向位队列中写入一位1 + */ + bool BitsArray::WriteOne() + { + if(!data)return(false); + + int byte_offset; + int bit_offset; + + if(pos==count) + count++; + + byte_offset=pos>>3; //除8 + bit_offset=pos&7; //取最后3位,最大是7 + + data[byte_offset]|=ONE_AT_BIT(bit_offset); + + pos++; + return(true); + } + + /** + * 向位队列中写入一位数据 + * @param off 位置 + * @param bit 数据 + * @return 是否写入成功 + */ + bool BitsArray::WriteAt(int off,bool bit) + { + if(!data)return(false); + + int byte_offset; + int bit_offset; + + byte_offset=off>>3; //除8 + bit_offset=off&7; //取最后3位,最大是7 + + if(bit) + data[byte_offset]|=ONE_AT_BIT(bit_offset); + else + data[byte_offset]&=ZERO_AT_BIT(bit_offset); + + return(true); + } + + /** + * 按字节向队列写入数据 + * @param bytedata 字节数据 + * @param size 字节长度 + */ + bool BitsArray::WriteBytes(uint8 *bytedata,int size) + { + if(!data)return(false); + + int byte_offset,n; + int bit_offset; + + if(pos+(size<<3)>count) + count=pos+(size<<3); + + byte_offset=pos>>3; + bit_offset=pos&7; + + pos+=size<<3; + + if(bit_offset==0) //当位正好对齐时直接复制数据 + { + memcpy(data+byte_offset,bytedata,size); + } + else + { + while(size--) + { + n=0; + do + { + if(*bytedata&(1<>3; //除8 + bit_offset=pos&7; //取最后3位,最大是7 + + pos++; + + bit=data[byte_offset]&(ONE_AT_BIT(bit_offset)); + + return(true); + } + + /** + * 从位队列中读取一位 + * @param off 位置 + * @param bit 读取出来的位数据 + * @return 是否读取成功 + */ + bool BitsArray::ReadAt(int off,bool &bit)const + { + if(!data)return(false); + + int byte_offset; + int bit_offset; + + byte_offset=off>>3; //除8 + bit_offset=off&7; //取最后3位,最大是7 + + bit=data[byte_offset]&(ONE_AT_BIT(bit_offset)); + + return(true); + } + + /** + * 翻转一位数据,将指0变1,1变0 + * @return 翻转后的数据 + */ + bool BitsArray::FlipBit() + { + int byte_offset; + int bit_offset; + + byte_offset=pos; //除8 + bit_offset=pos; //取最后3位,最大是7 + + pos++; + + data[byte_offset]^=(ONE_AT_BIT(bit_offset)); + + return(data[byte_offset]&(ONE_AT_BIT(bit_offset))); + } + + BitsArray &BitsArray::operator =(const BitsArray &rhs) + { + if(this!=&rhs) + { + Clear(); + + if(rhs.count>0) + { + byte_size=rhs.byte_size; + count=rhs.count; + + data=(uint8 *)hgl_malloc(byte_size); + + memcpy(data,rhs.data,byte_size); + + pos=0; + mapping=false; + } + } + + return *this; + } + + BitsArray &BitsArray::operator +=(const BitsArray &rhs) + { + int n=count; + int n8; + uint8 bit=1; + + if(rhs.count>3; + + for(int i=0;i>3; + + for(int i=0;i>3; + + for(int i=0;i>3; + uint8 bit=1; + + const uint8 *rhs_data=rhs.GetData(); + + if(memcmp(data,rhs_data,n8)==0) + { + for(int i=n8<<3;iWriteInt32(count)) + if(str->Write(data,byte_size)) + return(true); + + return(false); + } + + bool BitsArray::LoadFromStream(io::DataInputStream *str) + { + Clear(); + + int tcount; + + if(str->ReadInt32(tcount)) + { + Create(tcount); + + if(str->Read(data,byte_size)) + return(true); + } + + return(false); + } +}//namespace hgl