1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use glib::translate::*;

glib::wrapper! {
    /// #SoupMessageBody represents the request or response body of a
    /// [`Message`][crate::Message].
    ///
    /// Note that while @length always reflects the full length of the
    /// message body, @data is normally [`None`], and will only be filled in
    /// after [`flatten()`][Self::flatten()] is called. For client-side
    /// messages, this automatically happens for the response body after it
    /// has been fully read. Likewise, for server-side
    /// messages, the request body is automatically filled in after being
    /// read.
    ///
    /// As an added bonus, when @data is filled in, it is always terminated
    /// with a `\0` byte (which is not reflected in @length).
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct MessageBody(Shared<ffi::SoupMessageBody>);

    match fn {
        ref => |ptr| ffi::soup_message_body_ref(ptr),
        unref => |ptr| ffi::soup_message_body_unref(ptr),
        type_ => || ffi::soup_message_body_get_type(),
    }
}

impl MessageBody {
    /// Creates a new #SoupMessageBody.
    ///
    /// [`Message`][crate::Message] uses this internally; you
    /// will not normally need to call it yourself.
    ///
    /// # Returns
    ///
    /// a new #SoupMessageBody.
    #[doc(alias = "soup_message_body_new")]
    pub fn new() -> MessageBody {
        assert_initialized_main_thread!();
        unsafe { from_glib_full(ffi::soup_message_body_new()) }
    }

    /// Appends the data from @buffer to @self.
    /// ## `buffer`
    /// a #GBytes
    #[doc(alias = "soup_message_body_append_bytes")]
    pub fn append_bytes(&self, buffer: &glib::Bytes) {
        unsafe {
            ffi::soup_message_body_append_bytes(self.to_glib_none().0, buffer.to_glib_none().0);
        }
    }

    /// Appends @length bytes from @data to @self.
    ///
    /// This function is exactly equivalent to `MessageBody::append()`
    /// with [`MemoryUse::Take`][crate::MemoryUse::Take] as second argument; it exists mainly for
    /// convenience and simplifying language bindings.
    /// ## `data`
    /// data to append
    #[doc(alias = "soup_message_body_append_take")]
    pub fn append_take(&self, data: &[u8]) {
        let length = data.len() as _;
        unsafe {
            ffi::soup_message_body_append_take(self.to_glib_none().0, data.to_glib_full(), length);
        }
    }

    /// Tags @self as being complete.
    ///
    /// Call this when using chunked encoding after you have appended the last chunk.
    #[doc(alias = "soup_message_body_complete")]
    pub fn complete(&self) {
        unsafe {
            ffi::soup_message_body_complete(self.to_glib_none().0);
        }
    }

    /// Fills in @self's data field with a buffer containing all of the
    /// data in @self.
    ///
    /// Adds an additional `\0` byte not counted by @self's
    /// length field.
    ///
    /// # Returns
    ///
    /// a #GBytes containing the same data as @self.
    ///   (You must `GLib::Bytes::unref()` this if you do not want it.)
    #[doc(alias = "soup_message_body_flatten")]
    pub fn flatten(&self) -> Option<glib::Bytes> {
        unsafe { from_glib_full(ffi::soup_message_body_flatten(self.to_glib_none().0)) }
    }

    /// Gets the accumulate flag on @self.
    ///
    /// See [`set_accumulate()`][Self::set_accumulate()]. for details.
    ///
    /// # Returns
    ///
    /// the accumulate flag for @self.
    #[doc(alias = "soup_message_body_get_accumulate")]
    #[doc(alias = "get_accumulate")]
    pub fn is_accumulate(&self) -> bool {
        unsafe { from_glib(ffi::soup_message_body_get_accumulate(self.to_glib_none().0)) }
    }

    /// Gets a [`glib::Bytes`][crate::glib::Bytes] containing data from @self starting at @offset.
    ///
    /// The size of the returned chunk is unspecified. You can iterate
    /// through the entire body by first calling
    /// [`chunk()`][Self::chunk()] with an offset of 0, and then on each
    /// successive call, increment the offset by the length of the
    /// previously-returned chunk.
    ///
    /// If @offset is greater than or equal to the total length of @self,
    /// then the return value depends on whether or not
    /// [`complete()`][Self::complete()] has been called or not; if it has,
    /// then [`chunk()`][Self::chunk()] will return a 0-length chunk
    /// (indicating the end of @self). If it has not, then
    /// [`chunk()`][Self::chunk()] will return [`None`] (indicating that
    /// @self may still potentially have more data, but that data is not
    /// currently available).
    /// ## `offset`
    /// an offset
    ///
    /// # Returns
    ///
    /// a #GBytes
    #[doc(alias = "soup_message_body_get_chunk")]
    #[doc(alias = "get_chunk")]
    pub fn chunk(&self, offset: i64) -> Option<glib::Bytes> {
        unsafe {
            from_glib_full(ffi::soup_message_body_get_chunk(
                self.to_glib_none().0,
                offset,
            ))
        }
    }

    /// Handles the #SoupMessageBody part of receiving a chunk of data from
    /// the network.
    ///
    /// Normally this means appending @chunk to @self, exactly as with
    /// [`append_bytes()`][Self::append_bytes()], but if you have set @self's accumulate
    /// flag to [`false`], then that will not happen.
    ///
    /// This is a low-level method which you should not normally need to
    /// use.
    /// ## `chunk`
    /// a #GBytes received from the network
    #[doc(alias = "soup_message_body_got_chunk")]
    pub fn got_chunk(&self, chunk: &glib::Bytes) {
        unsafe {
            ffi::soup_message_body_got_chunk(self.to_glib_none().0, chunk.to_glib_none().0);
        }
    }

    /// Sets or clears the accumulate flag on @self.
    ///
    /// (The default value is [`true`].) If set to [`false`], @self's data field will not
    /// be filled in after the body is fully sent/received, and the chunks that make
    /// up @self may be discarded when they are no longer needed.
    ///
    /// If you set the flag to [`false`] on the [`Message`][crate::Message] request_body of a
    /// client-side message, it will block the accumulation of chunks into
    /// @self's data field, but it will not normally cause the chunks to
    /// be discarded after being written like in the server-side
    /// [`Message`][crate::Message] response_body case, because the request body needs to
    /// be kept around in case the request needs to be sent a second time
    /// due to redirection or authentication.
    /// ## `accumulate`
    /// whether or not to accumulate body chunks in @self
    #[doc(alias = "soup_message_body_set_accumulate")]
    pub fn set_accumulate(&self, accumulate: bool) {
        unsafe {
            ffi::soup_message_body_set_accumulate(self.to_glib_none().0, accumulate.into_glib());
        }
    }

    /// Deletes all of the data in @self.
    #[doc(alias = "soup_message_body_truncate")]
    pub fn truncate(&self) {
        unsafe {
            ffi::soup_message_body_truncate(self.to_glib_none().0);
        }
    }

    /// Handles the #SoupMessageBody part of writing a chunk of data to the
    /// network.
    ///
    /// Normally this is a no-op, but if you have set @self's accumulate flag to
    /// [`false`], then this will cause @chunk to be discarded to free up memory.
    ///
    /// This is a low-level method which you should not need to use, and
    /// there are further restrictions on its proper use which are not
    /// documented here.
    /// ## `chunk`
    /// a #GBytes returned from [`chunk()`][Self::chunk()]
    #[doc(alias = "soup_message_body_wrote_chunk")]
    pub fn wrote_chunk(&self, chunk: &glib::Bytes) {
        unsafe {
            ffi::soup_message_body_wrote_chunk(self.to_glib_none().0, chunk.to_glib_none().0);
        }
    }
}

impl Default for MessageBody {
    fn default() -> Self {
        Self::new()
    }
}