return message_sub_part_by_idx(parts, idx);
}
+
+bool message_part_is_equal(const struct message_part *p1,
+ const struct message_part *p2)
+{
+ /* This cannot be p1 && p2, because then we would return
+ TRUE when either part is NULL, and we should return FALSE */
+ while (p1 != NULL || p2 != NULL) {
+ /* If either part is NULL, return false */
+ if ((p1 != NULL) != (p2 != NULL))
+ return FALSE;
+
+ /* Expect that both either have children, or both
+ do not have children */
+ if ((p1->children != NULL) != (p2->children != NULL))
+ return FALSE;
+
+ /* If there are children, ensure they are equal */
+ if (p1->children != NULL) {
+ if (!message_part_is_equal(p1->children, p2->children))
+ return FALSE;
+ }
+
+ /* If any of these properties differ, then parts are not equal */
+ if (p1->physical_pos != p2->physical_pos ||
+ p1->header_size.physical_size != p2->header_size.physical_size ||
+ p1->header_size.virtual_size != p2->header_size.virtual_size ||
+ p1->header_size.lines != p2->header_size.lines ||
+ p1->body_size.physical_size != p2->body_size.physical_size ||
+ p1->body_size.virtual_size != p2->body_size.virtual_size ||
+ p1->body_size.lines != p2->body_size.lines ||
+ p1->children_count != p2->children_count ||
+ p1->flags != p2->flags)
+ return FALSE;
+
+ /* Move forward */
+ p1 = p1->next;
+ p2 = p2->next;
+ }
+
+ /* Parts are equal */
+ return TRUE;
+}
struct message_part *
message_part_by_idx(struct message_part *parts, unsigned int idx);
+/* Returns TRUE when message parts are considered equal. Equality is determined
+ to be TRUE, when
+
+ - both parts are NULL
+ - both parts are not NULL, and
+ - both parts children are equal
+ - both parts have same position, sizes, line counts and flags. */
+bool message_part_is_equal(const struct message_part *p1,
+ const struct message_part *p2) ATTR_NULL(1, 2);
+
#endif