最近由于项目原因,需要将Java项目中的ByteArray类用C++实现一遍,于是琢磨了一下,下面是该类中部分已实现方法的使用说明:
// 添加一个字节到ByteArray中。
void addByte(uint8_t byte);
// 添加多个字节到ByteArray中
void addBytes(const std::vector<uint8_t>& bytes)
// 获取指定索引位置的字节。
uint8_t getByte(int index) const;
// 设置指定索引位置的字节值。
void setByte(int index, uint8_t value);
//获取所有字节
std::vector<uint8_t> getBytes();
// 获取ByteArray的长度(字节数)。
int length() const;
// 从字节字符串创建一个ByteArray对象。
static ByteArray fromByteString(const std::string& byteString);
// 将ByteArray转换为二进制字符串。
std::string toBinaryString() const;
// 从二进制字符串创建一个ByteArray对象。
static ByteArray fromBinaryString(const std::string& binaryString);
// 从长整型值创建一个ByteArray对象。
static ByteArray fromLongValue(uint64_t value);
// 将ByteArray转换为ASCII字符串。
std::string toASCII() const;
// 从ByteArray中提取指定位范围的子字节字段。
ByteArray subByteField(int startBit, int numBits) const;
// 反转ByteArray中的字节顺序。
void reverse();
下面几个是计划添加但还没实现的函数:
// 获取ByteArray的字节数据。
const std::vector<uint8_t>& getData() const;
// 根据索引获取ByteArray的字节数据。
uint8_t operator[](int index) const;
// 根据索引设置ByteArray的字节数据。
uint8_t& operator[](int index);
// 比较两个ByteArray是否相等。
bool operator==(const ByteArray& other) const;
// 比较两个ByteArray是否不相等。
bool operator!=(const ByteArray& other) const;
下面是完整的实现代码:
#include "stdafx.h"#include <iostream>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <iomanip>class ByteArray {
private:std::vector<uint8_t> data;public:ByteArray() {}ByteArray(const std::vector<uint8_t>& bytes) : data(bytes) {}void addByte(uint8_t byte) {data.push_back(byte);}void addBytes(const std::vector<uint8_t>& bytes) {data.insert(data.end(), bytes.begin(), bytes.end());}uint8_t getByte(int index) {if (index < 0 || index >= data.size()) {throw std::out_of_range("Index out of range");}return data[index];}void setByte(int index, uint8_t byte) {if (index < 0 || index >= data.size()) {throw std::out_of_range("Index out of range");}data[index] = byte;}int length() {return data.size();}std::vector<uint8_t> getBytes() {return data;}std::string toString() {std::string result(data.begin(), data.end());return result;}bool equals(const ByteArray& other) {if (data.size() != other.data.size()) {return false;}for (int i = 0; i < data.size(); i++) {if (data[i] != other.data[i]) {return false;}}return true;}static ByteArray fromByteString(const std::string& byteString) {std::vector<uint8_t> bytes;std::istringstream iss(byteString);std::string byte;while (iss >> std::setw(2) >> byte) {uint8_t value = std::stoi(byte, nullptr, 16);bytes.push_back(value);}return ByteArray(bytes);}static ByteArray fromBinaryString(const std::string& binaryString) {std::vector<uint8_t> bytes;std::string byte;for (int i = 0; i < binaryString.length(); i += 8) {byte = binaryString.substr(i, 8);uint8_t value = std::stoi(byte, nullptr, 2);bytes.push_back(value);}return ByteArray(bytes);}static ByteArray fromLongValue(uint64_t value) {std::vector<uint8_t> bytes(sizeof(value));for (int i = sizeof(value) - 1; i >= 0; i--) {bytes[i] = value & 0xFF;value >>= 8;}return ByteArray(bytes);}uint8_t get(int index) {return getByte(index);}void insertBits(int index, uint8_t value, int numBits) {if (index < 0 || index > length() || numBits < 0 || numBits > 8) {throw std::out_of_range("Index or number of bits out of range");}uint8_t currentByte = getByte(index);// Shift existing bits to the leftcurrentByte <<= numBits;// Clear the space for new bitsuint8_t mask = ~(0xFF << numBits);currentByte &= mask;// Insert the new bitsvalue &= mask;currentByte |= value;setByte(index, currentByte);}uint8_t getBit(int index, int bitPosition) {if (index < 0 || index >= length() || bitPosition < 0 || bitPosition > 7) {throw std::out_of_range("Index or bit position out of range");}uint8_t currentByte = getByte(index);return (currentByte >> bitPosition) & 0x01;}std::string ByteArray::toByteString() {std::stringstream ss;ss << std::hex << std::setfill('0');for (int i = 0; i < length(); i++) {ss << std::setw(2) << static_cast<int>(data[i]) << " ";}std::string byteString = ss.str();// Remove trailing spacebyteString.pop_back();return byteString;}int size() {return length() * 8;}std::string toBinaryString() {std::stringstream ss;for (int i = 0; i < length(); i++) {uint8_t currentByte = getByte(i);for (int j = 7; j >= 0; j--) {ss << ((currentByte >> j) & 0x01);}}return ss.str();}uint64_t toLongValue() {if (length() > sizeof(uint64_t)) {throw std::out_of_range("ByteArray size too large for uint64_t conversion");}uint64_t value = 0;for (int i = 0; i < length(); i++) {value <<= 8;value |= getByte(i);}return value;}std::string toASCII() {std::string result = "";for (int i = 0; i < length(); i++) {char character = static_cast<char>(getByte(i));result += character;}return result;}ByteArray ByteArray::subByteField(int startBit, int numBits) {if (startBit < 0 || startBit >= size() || numBits < 1 || numBits > size() - startBit) {throw std::out_of_range("Invalid start bit or number of bits");}int startByte = startBit / 8;int startBitIndex = startBit % 8;int endBit = startBit + numBits - 1;int endByte = endBit / 8;int endBitIndex = endBit % 8;std::vector<uint8_t> subBytes;if (startByte == endByte) {uint8_t startByteValue = getByte(startByte);uint8_t mask = static_cast<uint8_t>((1 << numBits) - 1);uint8_t subByteValue = (startByteValue >> (8 - startBitIndex - numBits)) & mask;subBytes.push_back(subByteValue);}else {uint8_t startByteValue = getByte(startByte);uint8_t mask = static_cast<uint8_t>((1 << (8 - startBitIndex)) - 1);uint8_t subByteValue = (startByteValue >> (8 - startBitIndex)) & mask;subBytes.push_back(subByteValue);for (int i = startByte + 1; i < endByte; i++) {uint8_t byteValue = getByte(i);subBytes.push_back(byteValue);}uint8_t endByteValue = getByte(endByte);uint8_t mask2 = static_cast<uint8_t>((1 << (endBitIndex + 1)) - 1);uint8_t subByteValue2 = (endByteValue >> (8 - endBitIndex - 1)) & mask2;subBytes.push_back(subByteValue2);}return ByteArray(subBytes);}void reverse() {std::reverse(data.begin(), data.end());}void set(int index, uint8_t value) {setByte(index, value);}void setBit(int index, int bitPosition, uint8_t bitValue) {if (index < 0 || index >= length() || bitPosition < 0 || bitPosition > 7 || (bitValue != 0 && bitValue != 1)) {throw std::out_of_range("Index, bit position, or bit value out of range");}uint8_t currentByte = getByte(index);uint8_t mask = ~(0x01 << bitPosition);currentByte &= mask;currentByte |= (bitValue << bitPosition);setByte(index, currentByte);}
};
下面是使用示例:
int main() {ByteArray byteArray;byteArray.addByte(0x55);byteArray.addByte(0xAA);byteArray.addByte(0xFF);std::cout << "ByteArray as hex string: " << byteArray.toString() << std::endl;std::string byteString = byteArray.toByteString();std::cout << "ByteArray as byte string: " << byteString << std::endl;ByteArray byteArrayFromByteString = ByteArray::fromByteString(byteString);std::cout << "ByteArray from byte string: " << byteArrayFromByteString.toString() << std::endl;std::string binaryString = byteArray.toBinaryString();std::cout << "ByteArray as binary string: " << binaryString << std::endl;ByteArray byteArrayFromBinaryString = ByteArray::fromBinaryString(binaryString);std::cout << "ByteArray from binary string: " << byteArrayFromBinaryString.toString() << std::endl;uint64_t longValue = 0xFFAA55;ByteArray byteArrayFromLongValue = ByteArray::fromLongValue(longValue);std::cout << "ByteArray from long value: " << byteArrayFromLongValue.toString() << std::endl;std::string asciiString = byteArray.toASCII();std::cout << "ByteArray as ASCII string: " << asciiString << std::endl;std::cout << "ByteArray size: " << byteArray.length() << std::endl;ByteArray subBytes = byteArray.subByteField(4, 12);std::cout << "Sub-byte field: " << subBytes.toString() << std::endl;byteArray.reverse();std::cout << "Reversed ByteArray: " << byteArray.toString() << std::endl;byteArray.setByte(1, 0xBB);std::cout << "Updated ByteArray: " << byteArray.toString() << std::endl;byteArray.setBit(0, 2, 1);std::cout << "Updated ByteArray: " << byteArray.toString() << std::endl;return 0;
}
在主函数中,我们创建了一个 ByteArray
对象并执行了以下操作:
- 向
ByteArray
对象中添加字节 - 将
ByteArray
对象转换为十六进制字符串并输出 - 将
ByteArray
对象转换为字节字符串并输出 - 使用
fromByteString
方法将字节字符串转换回ByteArray
对象并输出 - 将
ByteArray
对象转换为二进制字符串并输出 - 使用
fromBinaryString
方法将二进制字符串转换回ByteArray
对象并输出 - 使用
fromLongValue
方法将长整型值转换为ByteArray
对象并输出 - 将
ByteArray
对象转换为 ASCII 字符串并输出 - 获取
ByteArray
对象的长度并输出 - 从
ByteArray
对象中提取子字节字段并输出 - 反转
ByteArray
对象的字节反序并输出 - 更新
ByteArray
对象的字节值并输出 - 更新
ByteArray
对象的特定位的值并输出
下面是执行结果: