2010-07-12 31 views
19

Tôi muốn so sánh hai Thông báo hoặc (hai thông số phụ) của Google protocol buffers. Tôi không tìm thấy API để đạt được nó.Bộ đệm giao thức Google so sánh

Bất kỳ ý tưởng nào?

+0

Bạn có thể chỉ định chính xác bạn muốn so sánh: cấu trúc thông báo, giá trị trường của tin nhắn hoặc cả hai cùng một lúc? –

Trả lời

-1

Điều này có thể không phải là giải pháp lý tưởng, nhưng tôi nghĩ rằng nó có thể được thực hiện bằng cách:

messageA.DebugString() == messageB.DebugString(); 

Khác hơn thế, tôi nghĩ rằng giải pháp duy nhất là tạo cho riêng lớp Message con quý vị và thực hiện một bool operator==(const Message&) .

+0

+1 tốt đẹp thử :) Trên thực tế tôi cần nó được nhanh chóng – dimba

+0

@idimba Tks. Nhưng sau đó tôi đoán bạn nên chỉnh sửa câu hỏi của bạn và đề cập đến điều tốc độ ;-). Nhưng sau đó, tôi đoán, lựa chọn duy nhất thực sự là tự mình thực hiện toán tử so sánh. – Gianni

+0

+1 cho nhà điều hành ==, đây là cách chính xác để làm .. – Yousf

0

Vâng, bộ đệm giao thức chỉ là định dạng tuần tự hóa cho một số loại đối tượng. Tại sao không sử dụng bộ đệm giao thức để tái tạo lại các đối tượng ban đầu, và sau đó cho phép các đối tượng đó so sánh bản thân, sử dụng bất kỳ logic so sánh nào mà bạn đã xây dựng trong lớp?

8

Thay vì sử dụng message.DebugString bạn cũng có thể làm

std::string strMsg; 
message.SerializeToString(&strMsg); 

với cả hai thông điệp và sau đó so sánh hai chuỗi (nhị phân). Tôi đã không kiểm tra hiệu suất nhưng tôi cho rằng nó nhanh hơn so với chuỗi thông điệp có thể đọc được của con người được trả về bởi .DebugString(). + Bạn có thể làm điều đó với thư viện protobuf-lite (trong khi cho message.DebugString bạn cần phiên bản đầy đủ).

+1

Việc tuần tự hóa không được đảm bảo nhất quán trên các tệp nhị phân và theo thời gian. Ví dụ, các phần mở rộng chưa được biết đến nhị phân sẽ được tuần tự hóa lần cuối (như các trường không xác định), sau các phần mở rộng đã biết. Vì vậy, việc serialization sẽ phụ thuộc vào những gì descriptors có sẵn tại thời điểm serialization. So sánh các thông điệp tuần tự do đó là một xấu là để kiểm tra bình đẳng. MessageDifferencer là đúng cách để làm điều này. –

-3

Bạn có thể so sánh con trỏ của bộ mô tả (siêu nhanh):

if (mMessages[i]->body()->GetDescriptor() == T::descriptor()) 

mMessages đó là một vũng điệp mạng với tiêu đề và crypto mà tạo ra một gói với cơ thể protobuf (google :: protobuf :: Nội dung *).

vì vậy, để nhận đúng loại thông báo tôi so sánh con trỏ hằng số mô tả giống nhau cho mọi loại thông điệp (không phải% 100 chắc chắn nhưng tôi chưa gặp bất kỳ sự cố nào).

Đó sẽ là cách nhanh nhất để so sánh Thư thông báo trước khi sử dụng phải sử dụng so sánh chuỗi, theo cách bạn lấy tên kiểu từ bộ mô tả. :-)

+0

Yêu câu trả lời của tôi đã được bình chọn như thế nào, nhưng đó là cách phù hợp để so sánh tin nhắn. – KukoBits

+5

Điều đó sẽ đúng nếu bạn muốn so sánh các loại, nhưng câu hỏi này dường như là về so sánh nội dung, điều này chắc chắn nhất không làm. Đây là lý do tại sao bạn có downvote, tôi muốn đảm bảo. –

17

Bạn có thể sử dụng lớp google::protobuf::util::MessageDifferencer cho việc này. Tôi nghĩ rằng nó chỉ có sẵn từ v3.0.2:

Giới thiệu chức năng tiện ích mới/classes trong thư mục/protobuf/util thư mục google:

  • MessageDifferencer: so sánh hai thông điệp proto và báo cáo khác biệt của họ.

MessageDifferencer::Equals(msg1, msg2);

+1

Để thêm: MessageDifferencer có sẵn cho C++ chỉ – deddebme

+0

tùy thuộc vào việc các trường trong loại Tin nhắn của bạn có thể có giá trị mặc định hay không, bạn có thể muốn xem xét 'MessageDifferencer :: Equivalent' thay vì' Equals' – pestophagous

4

Bạn có thể dựa vào thực tế là tất cả các thông điệp protobuf bạn kế thừa từ các loại google::protobuf::MesageLite, mà lần lượt có mọi thứ bạn cần phải so sánh bất kỳ hai thông điệp protobuf, bất kể nếu họ thậm chí cùng loại có nguồn gốc:

bool operator==(const google::protobuf::MessageLite& msg_a, 
       const google::protobuf::MessageLite& msg_b) { 
    return (msg_a.GetTypeName() == msg_b.GetTypeName()) && 
     (msg_a.SerializeAsString() == msg_b.SerializeAsString()); 
} 
+0

Wow. Đây sẽ là câu trả lời hoàn hảo cho câu hỏi của người dùng này! Bravo! – Peaches491

Các vấn đề liên quan