109 lines
2.6 KiB
C++
109 lines
2.6 KiB
C++
#pragma once
|
||
|
||
#include <google/protobuf/arena.h>
|
||
#include <QVector>
|
||
#include <QDebug>
|
||
#include <algorithm>
|
||
#include "tool.h"
|
||
#include "BZStruct.h"
|
||
|
||
class OrderBookParser {
|
||
public:
|
||
OrderBookParser() {
|
||
}
|
||
|
||
bool parse(const char* data, int size, OrderBookData& output) {
|
||
// 创建Response消息并解析
|
||
google::protobuf::Arena arena;
|
||
auto* response = new Qot_UpdateOrderBook::Response;
|
||
if (!response->ParseFromArray(data, size)) {
|
||
return false;
|
||
}
|
||
|
||
// 检查响应状态 (0表示成功)
|
||
if (response->rettype() != 0) {
|
||
arena.Reset();
|
||
return false;
|
||
}
|
||
|
||
// 检查是否存在有效数据
|
||
if (!response->has_s2c()) {
|
||
arena.Reset();
|
||
return true;
|
||
}
|
||
|
||
const auto& s2c = response->s2c();
|
||
output.clear();
|
||
|
||
output.name = QString(s2c.name().c_str());
|
||
output.code = QString(s2c.security().code().c_str());
|
||
output.askTime = QString(s2c.svrrecvtimeask().c_str());
|
||
output.bidTime = QString(s2c.svrrecvtimebid().c_str());
|
||
|
||
// 处理买盘订单簿 (bids)
|
||
if (s2c.orderbookbidlist_size() > 0) {
|
||
parseOrderBookList(s2c.orderbookbidlist(), output.bids);
|
||
}
|
||
|
||
// 处理卖盘订单簿 (asks)
|
||
if (s2c.orderbookasklist_size() > 0) {
|
||
parseOrderBookList(s2c.orderbookasklist(), output.asks);
|
||
}
|
||
|
||
arena.Reset(); // 重置内存池供下次使用
|
||
return true;
|
||
}
|
||
|
||
|
||
private:
|
||
void parseOrderBookList(
|
||
const google::protobuf::RepeatedPtrField<Qot_Common::OrderBook>& pbList,
|
||
QVector<OrderBookEntry>& output)
|
||
{
|
||
output.clear();
|
||
const int itemCount = pbList.size();
|
||
if (itemCount == 0) return;
|
||
|
||
// 预分配输出内存
|
||
output.reserve(itemCount);
|
||
|
||
// 第一遍:计算最大明细数量
|
||
int maxDetails = 0;
|
||
for (int i = 0; i < itemCount; ++i) {
|
||
maxDetails = std::max(maxDetails, pbList.Get(i).detaillist_size());
|
||
}
|
||
|
||
// 第二遍:填充数据(使用局部缓冲区)
|
||
for (int i = 0; i < itemCount; ++i) {
|
||
const auto& pb_item = pbList.Get(i);
|
||
const int detailCount = pb_item.detaillist_size();
|
||
|
||
// 为当前条目创建独立的明细缓冲区
|
||
QVector<OrderDetail> detailsBuffer;
|
||
detailsBuffer.reserve(detailCount); // 按实际需求预分配
|
||
|
||
// 安全解析明细
|
||
try {
|
||
for (int j = 0; j < detailCount; ++j) {
|
||
const auto& pb_detail = pb_item.detaillist(j);
|
||
OrderDetail detail;
|
||
detail.orderId = pb_detail.orderid();
|
||
detail.volume = pb_detail.volume();
|
||
detailsBuffer.append(detail);
|
||
}
|
||
}
|
||
catch (const std::exception& e) {
|
||
detailsBuffer.clear(); // 清除非法数据
|
||
}
|
||
|
||
// 构造 OrderBookEntry(直接移动缓冲区)
|
||
OrderBookEntry item;
|
||
item.price = pb_item.price();
|
||
item.volume = pb_item.volume();
|
||
item.orderCount = pb_item.oredercount();
|
||
item.details = detailCount > 0 ? std::move(detailsBuffer) : QVector<OrderDetail>{};
|
||
output.append(item);
|
||
}
|
||
}
|
||
};
|