#pragma once #include #include #include #include #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& pbList, QVector& 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 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{}; output.append(item); } } };