+ case eioOPAQUE:
+ {
+ if (item == nullptr && nitem > 0)
+ {
+ gmx_fatal(FARGS, "Null pointer provided for non-zero length XDR opaque data.");
+ }
+
+ if (nitem > 0)
+ {
+ // We need to support very large opaque data objects although the default
+ // XDR interface only uses integers for the size field, since gromacs-2020
+ // e.g. embeds the entire TPR body as a single such object, which would break all
+ // TPR files larger than 2GB unless we handle it as a special case.
+ // To avoid inserting extra padding, we calculate the chunk size as:
+ // - The max value of a signed integer + 1
+ // - Subtract 4 (the XDR object size) to get a size within the range of the signed int.
+ const std::size_t maxChunk =
+ static_cast<std::size_t>(std::numeric_limits<int>::max()) + 1 - 4;
+
+ for (res = 1; res > 0 && nitem > 0;)
+ {
+ std::size_t thisChunk = std::min(maxChunk, nitem);
+ res = xdr_opaque(fio->xdr, reinterpret_cast<char*>(item), thisChunk);
+ nitem -= thisChunk;
+ }
+ }
+ else
+ {
+ res = 1;
+ }
+ break;
+ }