用C++实现Java的ByteArray类(字节数组)

文章介绍了一个C++实现的ByteArray类,包括添加、获取和设置字节,以及转换为不同格式字符串的功能。还展示了从字节字符串、二进制字符串和长整型创建ByteArray对象的方法,并提供了部分未实现的成员函数。在主函数中,展示了ByteArray对象的使用,如添加字节、转换为各种字符串、提取子字节字段和反向字节顺序等操作。
摘要由CSDN通过智能技术生成

最近由于项目原因,需要将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 对象的特定位的值并输出

下面是执行结果: 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen Roson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值