| 866 | |
| 867 | |
| 868 | void CECSocket::SendCachedBodyResponse(uint8_t opcode, |
| 869 | const std::vector<std::shared_ptr<const std::vector<unsigned char> > > &blobs) |
| 870 | { |
| 871 | if (SocketRealError()) { |
| 872 | OnError(); |
| 873 | return; |
| 874 | } |
| 875 | |
| 876 | // Remember where in the output queue our bytes start, so the |
| 877 | // length-patch at the end touches the right CQueuedData. |
| 878 | std::list<CQueuedData*>::iterator outputStart = m_output_queue.begin(); |
| 879 | uint32 outputQueueSize = m_output_queue.size(); |
| 880 | for (uint32 i = 1; i < outputQueueSize; i++) { |
| 881 | ++outputStart; |
| 882 | } |
| 883 | |
| 884 | // Sum the pre-serialized body length. Used both for the local-ZLIB- |
| 885 | // bypass decision and as a budget hint — the actual on-wire length |
| 886 | // is computed from the queue after FlushBuffers below. |
| 887 | uint32 body_bytes = 0; |
| 888 | for (size_t i = 0; i < blobs.size(); ++i) { |
| 889 | if (blobs[i]) { |
| 890 | body_bytes += (uint32)blobs[i]->size(); |
| 891 | } |
| 892 | } |
| 893 | |
| 894 | // Same flag-byte logic as WritePacket. Cached blobs were |
| 895 | // serialized assuming UTF-8 numbers + LARGE_TAG_COUNT, so both |
| 896 | // bits must end up in the wire flag; we OR them in unconditionally |
| 897 | // and then mask against m_my_flags — callers should only invoke |
| 898 | // this method on connections that negotiated both capabilities. |
| 899 | uint32_t flags = 0x20; |
| 900 | const bool local_bypass_zlib = m_isLocalPeer |
| 901 | && body_bytes <= kLocalPeerZlibBypassMax; |
| 902 | if (body_bytes > EC_MAX_UNCOMPRESSED |
| 903 | && ((m_my_flags & EC_FLAG_ZLIB) > 0) |
| 904 | && !local_bypass_zlib) { |
| 905 | flags |= EC_FLAG_ZLIB; |
| 906 | } |
| 907 | flags |= EC_FLAG_UTF8_NUMBERS; |
| 908 | flags |= EC_FLAG_LARGE_TAG_COUNT; |
| 909 | flags &= m_my_flags; |
| 910 | m_tx_flags = flags; |
| 911 | |
| 912 | if (flags & EC_FLAG_ZLIB) { |
| 913 | m_z.zalloc = Z_NULL; |
| 914 | m_z.zfree = Z_NULL; |
| 915 | m_z.opaque = Z_NULL; |
| 916 | m_z.avail_in = 0; |
| 917 | m_z.next_in = &m_in_ptr[0]; |
| 918 | int zerror = deflateInit(&m_z, EC_COMPRESSION_LEVEL); |
| 919 | if (zerror != Z_OK) { |
| 920 | flags &= ~EC_FLAG_ZLIB; |
| 921 | ShowZError(zerror, &m_z); |
| 922 | } |
| 923 | } |
| 924 | |
| 925 | uint32_t tmp_flags = ENDIAN_HTONL(flags); |
nothing calls this directly
no test coverage detected