|  | @@ -60,6 +60,96 @@ void FillMetadataMap(grpc_metadata_array* arr,
 | 
	
		
			
				|  |  |  grpc_metadata* FillMetadataArray(
 | 
	
		
			
				|  |  |      const std::multimap<grpc::string, grpc::string>& metadata);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/// Per-message write options.
 | 
	
		
			
				|  |  | +class WriteOptions {
 | 
	
		
			
				|  |  | + public:
 | 
	
		
			
				|  |  | +  WriteOptions() : flags_(0) {}
 | 
	
		
			
				|  |  | +  WriteOptions(const WriteOptions& other) : flags_(other.flags_) {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Clear all flags.
 | 
	
		
			
				|  |  | +  inline void Clear() {
 | 
	
		
			
				|  |  | +    flags_ = 0;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Returns raw flags bitset.
 | 
	
		
			
				|  |  | +  inline gpr_uint32 flags() const {
 | 
	
		
			
				|  |  | +    return flags_;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Sets flag for the disabling of compression for the next message write.
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// \sa GRPC_WRITE_NO_COMPRESS
 | 
	
		
			
				|  |  | +  inline WriteOptions& set_no_compression() {
 | 
	
		
			
				|  |  | +    SetBit(GRPC_WRITE_NO_COMPRESS);
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Clears flag for the disabling of compression for the next message write.
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// \sa GRPC_WRITE_NO_COMPRESS
 | 
	
		
			
				|  |  | +  inline WriteOptions& clear_no_compression() {
 | 
	
		
			
				|  |  | +    ClearBit(GRPC_WRITE_NO_COMPRESS);
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Get value for the flag indicating whether compression for the next
 | 
	
		
			
				|  |  | +  /// message write is forcefully disabled.
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// \sa GRPC_WRITE_NO_COMPRESS
 | 
	
		
			
				|  |  | +  inline bool get_no_compression() const {
 | 
	
		
			
				|  |  | +    return GetBit(GRPC_WRITE_NO_COMPRESS);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Sets flag indicating that the write may be buffered and need not go out on
 | 
	
		
			
				|  |  | +  /// the wire immediately.
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// \sa GRPC_WRITE_BUFFER_HINT
 | 
	
		
			
				|  |  | +  inline WriteOptions& set_buffer_hint() {
 | 
	
		
			
				|  |  | +    SetBit(GRPC_WRITE_BUFFER_HINT);
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Clears flag indicating that the write may be buffered and need not go out
 | 
	
		
			
				|  |  | +  /// on the wire immediately.
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// \sa GRPC_WRITE_BUFFER_HINT
 | 
	
		
			
				|  |  | +  inline WriteOptions& clear_buffer_hint() {
 | 
	
		
			
				|  |  | +    ClearBit(GRPC_WRITE_BUFFER_HINT);
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /// Get value for the flag indicating that the write may be buffered and need
 | 
	
		
			
				|  |  | +  /// not go out on the wire immediately.
 | 
	
		
			
				|  |  | +  ///
 | 
	
		
			
				|  |  | +  /// \sa GRPC_WRITE_BUFFER_HINT
 | 
	
		
			
				|  |  | +  inline bool get_buffer_hint() const {
 | 
	
		
			
				|  |  | +    return GetBit(GRPC_WRITE_BUFFER_HINT);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  WriteOptions& operator=(const WriteOptions& rhs) {
 | 
	
		
			
				|  |  | +    if (this == &rhs) {
 | 
	
		
			
				|  |  | +      return *this;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    flags_ = rhs.flags_;
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | + private:
 | 
	
		
			
				|  |  | +  void SetBit(const gpr_int32 mask) {
 | 
	
		
			
				|  |  | +    flags_ |= mask;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  void ClearBit(const gpr_int32 mask) {
 | 
	
		
			
				|  |  | +    flags_ &= ~mask;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  bool GetBit(const gpr_int32 mask) const {
 | 
	
		
			
				|  |  | +    return flags_ & mask;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  gpr_uint32 flags_;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /// Default argument for CallOpSet. I is unused by the class, but can be
 | 
	
		
			
				|  |  |  /// used for generating multiple names for the same thing.
 | 
	
		
			
				|  |  |  template <int I>
 | 
	
	
		
			
				|  | @@ -104,6 +194,12 @@ class CallOpSendMessage {
 | 
	
		
			
				|  |  |   public:
 | 
	
		
			
				|  |  |    CallOpSendMessage() : send_buf_(nullptr), own_buf_(false) {}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  /// Send \a message using \a options for the write. The \a options are cleared
 | 
	
		
			
				|  |  | +  /// after use.
 | 
	
		
			
				|  |  | +  template <class M>
 | 
	
		
			
				|  |  | +  Status SendMessage(const M& message,
 | 
	
		
			
				|  |  | +                     const WriteOptions& options) GRPC_MUST_USE_RESULT;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    template <class M>
 | 
	
		
			
				|  |  |    Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -112,8 +208,10 @@ class CallOpSendMessage {
 | 
	
		
			
				|  |  |      if (send_buf_ == nullptr) return;
 | 
	
		
			
				|  |  |      grpc_op* op = &ops[(*nops)++];
 | 
	
		
			
				|  |  |      op->op = GRPC_OP_SEND_MESSAGE;
 | 
	
		
			
				|  |  | -    op->flags = 0;
 | 
	
		
			
				|  |  | +    op->flags = write_options_.flags();
 | 
	
		
			
				|  |  |      op->data.send_message = send_buf_;
 | 
	
		
			
				|  |  | +    // Flags are per-message: clear them after use.
 | 
	
		
			
				|  |  | +    write_options_.Clear();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    void FinishOp(bool* status, int max_message_size) {
 | 
	
		
			
				|  |  |      if (own_buf_) grpc_byte_buffer_destroy(send_buf_);
 | 
	
	
		
			
				|  | @@ -122,14 +220,22 @@ class CallOpSendMessage {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |   private:
 | 
	
		
			
				|  |  |    grpc_byte_buffer* send_buf_;
 | 
	
		
			
				|  |  | +  WriteOptions write_options_;
 | 
	
		
			
				|  |  |    bool own_buf_;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <class M>
 | 
	
		
			
				|  |  | -Status CallOpSendMessage::SendMessage(const M& message) {
 | 
	
		
			
				|  |  | +Status CallOpSendMessage::SendMessage(const M& message,
 | 
	
		
			
				|  |  | +                                      const WriteOptions& options) {
 | 
	
		
			
				|  |  | +  write_options_ = options;
 | 
	
		
			
				|  |  |    return SerializationTraits<M>::Serialize(message, &send_buf_, &own_buf_);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +template <class M>
 | 
	
		
			
				|  |  | +Status CallOpSendMessage::SendMessage(const M& message) {
 | 
	
		
			
				|  |  | +  return SendMessage(message, WriteOptions());
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  template <class R>
 | 
	
		
			
				|  |  |  class CallOpRecvMessage {
 | 
	
		
			
				|  |  |   public:
 |