最近由于项目原因,需要将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 left
currentByte <<= numBits;
// Clear the space for new bits
uint8_t mask = ~(0xFF << numBits);
currentByte &= mask;
// Insert the new bits
value &= 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 space
byteString.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
对象的特定位的值并输出
下面是执行结果: