First, class definition class cBitbuffer {private: longlong m_llens; // Cached size, unit (bit). BYTE * m_pbegin; // Cached start pointer, byte pointer, point to the first byte of the cache. BYTE * m_pend; // Cached end pointer, byte pointer, point to the next byte of the last byte of the cache. Byte * m_pcurbyte; // Cached current pointer, byte pointer, point to the current byte. BYTE M_NCUROFFSET; // From the start of the bit offset from the current byte, the value range is 0-7. Bool m_blocked; // The cache is locked, when you create a cache, the cache is unlocked before the release, cannot re-assay the header pointer and the cache size. // Note: m_pcurbyte is combined with m_ncuroffset to form a bit pointer to point to the current bit. Public: // [Status]: bool islocked (); // Whether or not to lock the status for the cache. Bool isbytealigned (); // Whether the current bit pointer is aligned by the byte. // [Input Output]: // Write the current bit to '0', the bit pointer automatically moves one bit. Void writebit0 (); // Write the current bit to '1', the bit pointer automatically moves one bit. Void writebit1 (); // From the current bit pointer to the NCOUNT bit, convert it into an integer output, the bit pointer is automatically moved. // (in / out) NCOUNT: The number of bits read. // Note: This value range is 0-32, and ensure that the read value does not base when using this function, // Does any check in the function body, considering that the user is not careful. INT read (Byte Ncount); // Write a string of binary numbers from the current bit pointer, the number is input in the form of string, and the bit pointer is automatically moved. // Parameter example: "0011 1011 0111 1111", the space will be ignored. // "* 000 1111 1111 * 111", the position in the asterisk will be slightly reached and not written. Void WriteBinary (CHAR * PBINSTR); // Write a 16-based number from the current paragraph pointer, the number is input as a string, and the bit pointer is automatically shifted and the bit offset is 0. // Parameter example: "00 01 ba", the space will be ignored, and there is no "0x" character in the string, and the letters are capitalized. // Note: Before using this function, it must be ensured that the byte is aligned, no "0x", the letter is capitalized, etc., there is no verification in the function! Void WriteHex (CHAR * PHEXSTR); // Writes from the current bit pointer to NCOUNT bit, this NCOUNT bit corresponds to a specified value, which can be entered with a decimal or hexadecimal input. Void WriteDecimal (uint ndata, int ncount); // Copy a data to the current cache, start writing from the current paragraph pointer, the bit pointer automatically moves, bit offset 0. // (in) psubbuff: The head pointer of the source data. // (in / out) NCOUNT: The length of the copy, pay attention is the number of bytes. // Actually Write Doublete Count. The Count May Be Less Than ncount if The // end of buffer (byte * psubbuff, int & ncount);
// [Position related]: // acquire the start pointer of the cache. Byte * getBegin ();
// Number of cache, the pointer points to the next byte of the cache. BYTE * getend ();
// Get the current pointer. Byte * getcurbyte ();
// obtain the bit offset of the current bit pointer in the current byte. Byte getcuroffset ();
// Set the size of the cache, the unit is "bit", but must ensure that 8 is multiple. // Before setting the cache size, you need to make sure that the cache start pointer has been set. / / Returns the last set cache size, if it is set, return 0. // If the cache has been locked, the size cannot be reset, and the return -1 means failure. // (in) Lllen: The cache size, the unit is "bit", and is the multiple of 8, preferably in the form of 1024 * 8. Longlong setlength (longlong lllen); // get the size of the cache, the unit is "bit", should be a multiple of 8. LONGLONG GETLENGTH (); / / Mobile The current bit pointer to the end of the cache, actually pointing the first bit of the next byte of the cached last byte. // Returns the size of the cache, the unit is "bit", should be a multiple of 8. Longlong seektoend ();
/ / Move the current bit pointer to the beginning of the cache, actually point to the first bit of the first byte of the cache. Void seektobegin ();
/ / Move the current bit pointer a specified numerical offset, the offset is moved at the end, and the offset is moved to the start, and "bit" when the offset unit is moved. / / Returns the offset of the current bit pointer relative to the start address, when "bit", the return value is fails if it is a negative number. // (in) LLOFF: Offset, unit "bit". Longlong seek (longlong lloff); // [Constructor]: / / The default constructor does not set a cache and its size, etc., pay attention to set the relevant content before use. CBitBuffer (); // This constructor sets a cache and its size. The cache is default 0. // Cache default is 0, you must set the correct cache size before actual use. // Note: It is best not to use this constructor, it is recommended to use the ShareBuffer () function. CBitbuffer (Byte * Pbegin, Longlong Lllen = 0);
// This function reset the start address of the cache and the size of the cache, and calculates the end address. // If you don't set the size of the cache, the default will be set to 0, and the correct value must be set before use. // If there is already a data area, you want to use CBitBuffer to manage, it is recommended to use this function to initialize. // Note: // If the memory allocated elsewhere is managed using CBitBuffer, the release of the memory is not the responsibility of the cbitbuffer. // If the CBitBuffer object has created a cache using the Create () function, you cannot reset the cache before calling the Release () function is released. // If the CBitBuffer object already has a cache, and it is also set to use this function, you can use this function to set a new cache again. // The cache set by this function is not locked, so you can reset the cache and size. // When using this function, if the cache has been locked, it will return FALSE to indicate failed. // (in) PBEGIN: The first address of the managed data area refers to the address of the first byte. // (in) Lllen: The size of the data area is managed, the unit "bit", must be a multiple of 8, it is recommended to use 1024 * 8 input. Bool ShareBuffer (BYTE * PBEGIN, LONGLONG LLLEN = 0); // Creating a cache using the size of the input, the cache size is "bit", must be a multiple of 8, it is recommended to use 1024 * 8 input. // Cache creation successfully returns true, failed to return false. // Note: After using this function to create a cache, the cache is locked; when the function is called, if the cache has been locked, the creation will fail. // If you determine that it is no longer needed, remember to call the release () function solution lock and release the cache. BOOL CREATE (LONGLONG LLLEN); // Release the cache lock and release the cache created by the create () function. Void release (); virtual ~ cBitbuffer ();
Second, the class realizes #include "bitbuffer.h" #include "math.h" #define bytebits 8 //// Construction / destruction // cbitbustbuffer :: cbitbuffer () {m_llens = 0; // the count in bits of bufferm_pbegin = NULL; // The beginning pointer of buffer, the last byte.m_pEnd = NULL; // The ending pointer of bufferm_pCurByte = NULL; // The current pointer in byte of bufferm_nCurOffset = 0; // The offset in bits from current pointerm_bLocked = FALSE; // Whether the buffer is locked} CBitBuffer :: CBitBuffer (bYTE * pBegin, LONGLONG llLen) {m_llLength = llLen; // The count in bits of bufferm_pBegin = pBegin; // The beginning pointer of buffer, the last byte .m_pCurByte = pBegin; // The current pointer in byte of bufferm_nCurOffset = 0; // The offset in bits from current pointerm_pEnd = pBegin llLen / BYTEBITS; // The ending pointer of bufferm_bLocked = FALSE; // Whether the buffer is locked } Cbitbuffer :: ~ cbitbuffer () {} // review to the ending of buffer} {m_pcurbyete () {m_pcurbyte = M_pEnd; m_nCurOffset = 0; return m_llLength;} // Seek to the beginning of buffervoid CBitBuffer :: SeekToBegin () {m_pCurByte = m_pBegin; m_nCurOffset = 0;} // Seek from current pointer in bits // Return the new bit offset from the beginning of the buffer // (in) llOff: The offset in bits from current pointer in bitsLONGLONG CBitBuffer :: Seek (LONGLONG llOff) {LONGLONG pos = (m_pCurByte - m_pBegin) * BYTEBITS m_nCurOffset; pos = llOff; if (POS <0 || POS> M_LLLENGTH) RETURN-1; m_pcurbyte = m_pbegin pos / bytebits; m_ncuroffset = POS% Bytebits; Return Pos;} longlong cbitbuffer :: getLENGTH () {Return m_llens;
} LONGLONG CBitBuffer :: SetLength (LONGLONG llLen) {if (m_bLocked) return -1; LONGLONG temp = m_llLength; m_pEnd = m_pBegin llLen / BYTEBITS; if (m_pCurByte> m_pEnd) {m_pCurByte = NULL; m_nCurOffset = 0;} m_llLength = llLen; return temp;} BOOL CBitBuffer :: ShareBuffer (BYTE * pBegin, LONGLONG llLen) {if (m_bLocked || pBegin == NULL) return FALSE; m_llLength = llLen; // The count in bits of bufferm_pBegin = pBegin; // The beginning pointer of buffer, the last byte.m_pCurByte = pBegin; // The current pointer in byte of bufferm_nCurOffset = 0; // The offset in bits from current pointerm_pEnd = pBegin llLen / BYTEBITS; // The ending pointer of bufferm_bLocked = FALSE; // Whether the buffer is lockedreturn TRUE;} BOOL CBitBuffer :: Create (LONGLONG llLen) {if (m_bLocked) return FALSE; m_pBegin = (BYTE *) malloc (llLen / BYTEBITS); if (m_pBegin == NULL) return False; m_pcurbyte = llen; m_ncuroffset = 0; m_pend = m_pbegin lllen / bytebits; m_blocked = true; return true;} void cbitbuffer :: release () {ix (m_bl Ocked && m_pbegin) {free (m_pbegin); m_pbegin = null; m_pcurbyte = null; m_ncuroffset = 0; m_pnd = null; m_blocked = false;} else if (m_blocked == false)
{m_pbegin = null; m_ncuroffset = 0; m_pnd = null;}} int cbitbuffer :: read (Byte ncount) {dWord64 D64 = * ((DWORD64 *) m_pcurbyte); D64 = (D64 >> 8 * 0 << (64-8)) | (D64 >> 8 * 1 << (64-8) >> (8 * 1)) | (D64 >> 8 * 2 << (64-8) >> (8) * 2) | (D64 >> 8 * 3 << (64-8) >> (8 * 3)) | (D64 >> 8 * 4 << (64-8) >> (8 * 4)) | (D64 >> 8 * 5 << (64-8) >> (8 * 5)) | (D64 >> 8 * 6 << (64-8) >> (8 * 6)) | (D64> > 8 * 7 << (64-8) >> (8 * 7));
INT RE = (int) (D64 << m_ncuroffset >> (64-ncount)); m_pcurbyte = (m_ncuroffset ncount) / 8; m_ncuroffset = (m_ncuroffset ncount)% 8; return re;} void cbitbuffer :: writebinary (CHAR * PBINSTR) {INT LEN = Strlen (PBINSTR); for (int i = 0; i {IF (Pbinstr [i] == '1') {Writebit1 ();} else IF (Pbinstr [i] == '0') {WriteBit0 (); Else IF (pbinstr [i] == '*') {seek (1);}}} void cbitbuffer :: writehex (char * phexstr) {// before use this function you SHOULD Make Sure Byte Aligned and Capital Letter .// Here Do Not Verify Anything Function.int Len = Strlen (PhexStr); Int Iactuallen = 0; INTH; For (INT i = 0; i { IF (PhexStr [I]> = '0' && PhexSTR [i] <= '9') {IF (IACTUALLEN )% 2 == 0) H = PhexSTR [I] - '0'; Else {* m_pcurbyte = H * 16 PhexStr [I] - '0'; m_pcurbyte ;}} else f (PhexStr [i]> = 'a' && PhexStr [i] <= 'f') {IF ((Iactuallen )% 2 == 0) H = PhexSTR [I] - 'a' 10; Else {* m_pcurbyte = h * 16 PhexStr [I] - 'a' 10; m_pcurbyte ;}} else} (PhexStr [i]> = 'a '&& PhexStr [I] <=' f ') {IF (Iactuallen )% 2 == 0) H = PhexStr [I] -' A ' 10; Else {* M_pcurbyte = h * 16 PhexStr [I] - 'a' 10; m_pcurbyte ;}}}} f (Iactuallen% 2 == 1) {* m_pcurbyte = * m_pcurbyte & 0x0f | ((byte) h) << 4 ); m_nCurOffset = 4;}} BOOL CBitBuffer :: IsByteAligned () {if (m_nCurOffset == 0) return TRUE; elsereturn FALSE;} void CBitBuffer :: WriteDecimal (UINT nData, int nCount) {// !! nCount <=
32int nByteCountNeed = (m_nCurOffset nCount - 1) / BYTEBITS 1; // Head: DWORD64 head = (* m_pCurByte) >> (BYTEBITS-m_nCurOffset) << (BYTEBITS-m_nCurOffset) 7 * BYTEBITS; // Bottom: int B = bytebits- (nbytecountneed * 8-m_ncuroffset-ncount); dword64 bottom = (DWORD64) ((byte) (* (m_pcurbyte nbytecountneed-1) << (BYTEBITS-B)) >> b) << (64- NByteCountNeed * 8); byte test = * (m_pcurbyte nbytecountneed-1) << (Bytebits-b); test = test >> b; // center: dword64 center = (dword64) NData << (64-m_ncuroffset-ncount ); // result; dword64 resu = head | center | bottom