1 module soup.MessageBody;
2 
3 private import glib.ConstructionException;
4 private import glib.MemorySlice;
5 private import glib.Str;
6 private import gobject.ObjectG;
7 private import soup.Buffer;
8 private import soup.c.functions;
9 public  import soup.c.types;
10 
11 
12 /**
13  * #SoupMessageBody represents the request or response body of a
14  * #SoupMessage.
15  * 
16  * In addition to #SoupMessageBody, libsoup also defines a "smaller"
17  * data buffer type, #SoupBuffer, which is primarily used as a
18  * component of #SoupMessageBody. In particular, when using chunked
19  * encoding to transmit or receive a message, each chunk is
20  * represented as a #SoupBuffer.
21  */
22 public final class MessageBody
23 {
24 	/** the main Gtk struct */
25 	protected SoupMessageBody* soupMessageBody;
26 	protected bool ownedRef;
27 
28 	/** Get the main Gtk struct */
29 	public SoupMessageBody* getMessageBodyStruct(bool transferOwnership = false)
30 	{
31 		if (transferOwnership)
32 			ownedRef = false;
33 		return soupMessageBody;
34 	}
35 
36 	/** the main Gtk struct as a void* */
37 	protected void* getStruct()
38 	{
39 		return cast(void*)soupMessageBody;
40 	}
41 
42 	/**
43 	 * Sets our main struct and passes it to the parent class.
44 	 */
45 	public this (SoupMessageBody* soupMessageBody, bool ownedRef = false)
46 	{
47 		this.soupMessageBody = soupMessageBody;
48 		this.ownedRef = ownedRef;
49 	}
50 
51 	~this ()
52 	{
53 		if ( ownedRef )
54 			soup_message_body_free(soupMessageBody);
55 	}
56 
57 
58 	/**
59 	 * the data
60 	 */
61 	public @property string data()
62 	{
63 		return Str.toString(soupMessageBody.data);
64 	}
65 
66 	/** Ditto */
67 	public @property void data(string value)
68 	{
69 		soupMessageBody.data = Str.toStringz(value);
70 	}
71 
72 	/**
73 	 * length of @data
74 	 */
75 	public @property long length()
76 	{
77 		return soupMessageBody.length;
78 	}
79 
80 	/** Ditto */
81 	public @property void length(long value)
82 	{
83 		soupMessageBody.length = value;
84 	}
85 
86 	/** */
87 	public static GType getType()
88 	{
89 		return soup_message_body_get_type();
90 	}
91 
92 	/**
93 	 * Creates a new #SoupMessageBody. #SoupMessage uses this internally; you
94 	 * will not normally need to call it yourself.
95 	 *
96 	 * Returns: a new #SoupMessageBody.
97 	 *
98 	 * Throws: ConstructionException GTK+ fails to create the object.
99 	 */
100 	public this()
101 	{
102 		auto __p = soup_message_body_new();
103 
104 		if(__p is null)
105 		{
106 			throw new ConstructionException("null returned by new");
107 		}
108 
109 		this(cast(SoupMessageBody*) __p);
110 	}
111 
112 	/**
113 	 * Appends @length bytes from @data to @body according to @use.
114 	 *
115 	 * Params:
116 	 *     use = how to use @data
117 	 *     data = data to append
118 	 */
119 	public void append(SoupMemoryUse use, ubyte[] data)
120 	{
121 		soup_message_body_append(soupMessageBody, use, data.ptr, cast(size_t)data.length);
122 	}
123 
124 	/**
125 	 * Appends the data from @buffer to @body. (#SoupMessageBody uses
126 	 * #SoupBuffers internally, so this is normally a constant-time
127 	 * operation that doesn't actually require copying the data in
128 	 * @buffer.)
129 	 *
130 	 * Params:
131 	 *     buffer = a #SoupBuffer
132 	 */
133 	public void appendBuffer(Buffer buffer)
134 	{
135 		soup_message_body_append_buffer(soupMessageBody, (buffer is null) ? null : buffer.getBufferStruct());
136 	}
137 
138 	/**
139 	 * Appends @length bytes from @data to @body.
140 	 *
141 	 * This function is exactly equivalent to soup_message_body_append()
142 	 * with %SOUP_MEMORY_TAKE as second argument; it exists mainly for
143 	 * convenience and simplifying language bindings.
144 	 *
145 	 * Params:
146 	 *     data = data to append
147 	 *
148 	 * Since: 2.32
149 	 */
150 	public void appendTake(char[] data)
151 	{
152 		soup_message_body_append_take(soupMessageBody, data.ptr, cast(size_t)data.length);
153 	}
154 
155 	/**
156 	 * Tags @body as being complete; Call this when using chunked encoding
157 	 * after you have appended the last chunk.
158 	 */
159 	public void complete()
160 	{
161 		soup_message_body_complete(soupMessageBody);
162 	}
163 
164 	/**
165 	 * Fills in @body's data field with a buffer containing all of the
166 	 * data in @body (plus an additional '\0' byte not counted by @body's
167 	 * length field).
168 	 *
169 	 * Returns: a #SoupBuffer containing the same data as @body.
170 	 *     (You must free this buffer if you do not want it.)
171 	 */
172 	public Buffer flatten()
173 	{
174 		auto __p = soup_message_body_flatten(soupMessageBody);
175 
176 		if(__p is null)
177 		{
178 			return null;
179 		}
180 
181 		return ObjectG.getDObject!(Buffer)(cast(SoupBuffer*) __p, true);
182 	}
183 
184 	/**
185 	 * Frees @body. You will not normally need to use this, as
186 	 * #SoupMessage frees its associated message bodies automatically.
187 	 */
188 	public void free()
189 	{
190 		soup_message_body_free(soupMessageBody);
191 		ownedRef = false;
192 	}
193 
194 	/**
195 	 * Gets the accumulate flag on @body; see
196 	 * soup_message_body_set_accumulate() for details.
197 	 *
198 	 * Returns: the accumulate flag for @body.
199 	 *
200 	 * Since: 2.24
201 	 */
202 	public bool getAccumulate()
203 	{
204 		return soup_message_body_get_accumulate(soupMessageBody) != 0;
205 	}
206 
207 	/**
208 	 * Gets a #SoupBuffer containing data from @body starting at @offset.
209 	 * The size of the returned chunk is unspecified. You can iterate
210 	 * through the entire body by first calling
211 	 * soup_message_body_get_chunk() with an offset of 0, and then on each
212 	 * successive call, increment the offset by the length of the
213 	 * previously-returned chunk.
214 	 *
215 	 * If @offset is greater than or equal to the total length of @body,
216 	 * then the return value depends on whether or not
217 	 * soup_message_body_complete() has been called or not; if it has,
218 	 * then soup_message_body_get_chunk() will return a 0-length chunk
219 	 * (indicating the end of @body). If it has not, then
220 	 * soup_message_body_get_chunk() will return %NULL (indicating that
221 	 * @body may still potentially have more data, but that data is not
222 	 * currently available).
223 	 *
224 	 * Params:
225 	 *     offset = an offset
226 	 *
227 	 * Returns: a #SoupBuffer, or %NULL.
228 	 */
229 	public Buffer getChunk(long offset)
230 	{
231 		auto __p = soup_message_body_get_chunk(soupMessageBody, offset);
232 
233 		if(__p is null)
234 		{
235 			return null;
236 		}
237 
238 		return ObjectG.getDObject!(Buffer)(cast(SoupBuffer*) __p, true);
239 	}
240 
241 	/**
242 	 * Handles the #SoupMessageBody part of receiving a chunk of data from
243 	 * the network. Normally this means appending @chunk to @body, exactly
244 	 * as with soup_message_body_append_buffer(), but if you have set
245 	 * @body's accumulate flag to %FALSE, then that will not happen.
246 	 *
247 	 * This is a low-level method which you should not normally need to
248 	 * use.
249 	 *
250 	 * Params:
251 	 *     chunk = a #SoupBuffer received from the network
252 	 *
253 	 * Since: 2.24
254 	 */
255 	public void gotChunk(Buffer chunk)
256 	{
257 		soup_message_body_got_chunk(soupMessageBody, (chunk is null) ? null : chunk.getBufferStruct());
258 	}
259 
260 	/**
261 	 * Sets or clears the accumulate flag on @body. (The default value is
262 	 * %TRUE.) If set to %FALSE, @body's %data field will not be filled in
263 	 * after the body is fully sent/received, and the chunks that make up
264 	 * @body may be discarded when they are no longer needed.
265 	 *
266 	 * In particular, if you set this flag to %FALSE on an "incoming"
267 	 * message body (that is, the #SoupMessage:response_body of a
268 	 * client-side message, or #SoupMessage:request_body of a server-side
269 	 * message), this will cause each chunk of the body to be discarded
270 	 * after its corresponding #SoupMessage::got_chunk signal is emitted.
271 	 * (This is equivalent to setting the deprecated
272 	 * %SOUP_MESSAGE_OVERWRITE_CHUNKS flag on the message.)
273 	 *
274 	 * If you set this flag to %FALSE on the #SoupMessage:response_body of
275 	 * a server-side message, it will cause each chunk of the body to be
276 	 * discarded after its corresponding #SoupMessage::wrote_chunk signal
277 	 * is emitted.
278 	 *
279 	 * If you set the flag to %FALSE on the #SoupMessage:request_body of a
280 	 * client-side message, it will block the accumulation of chunks into
281 	 * @body's %data field, but it will not normally cause the chunks to
282 	 * be discarded after being written like in the server-side
283 	 * #SoupMessage:response_body case, because the request body needs to
284 	 * be kept around in case the request needs to be sent a second time
285 	 * due to redirection or authentication. However, if you set the
286 	 * %SOUP_MESSAGE_CAN_REBUILD flag on the message, then the chunks will
287 	 * be discarded, and you will be responsible for recreating the
288 	 * request body after the #SoupMessage::restarted signal is emitted.
289 	 *
290 	 * Params:
291 	 *     accumulate = whether or not to accumulate body chunks in @body
292 	 *
293 	 * Since: 2.24
294 	 */
295 	public void setAccumulate(bool accumulate)
296 	{
297 		soup_message_body_set_accumulate(soupMessageBody, accumulate);
298 	}
299 
300 	/**
301 	 * Deletes all of the data in @body.
302 	 */
303 	public void truncate()
304 	{
305 		soup_message_body_truncate(soupMessageBody);
306 	}
307 
308 	/**
309 	 * Handles the #SoupMessageBody part of writing a chunk of data to the
310 	 * network. Normally this is a no-op, but if you have set @body's
311 	 * accumulate flag to %FALSE, then this will cause @chunk to be
312 	 * discarded to free up memory.
313 	 *
314 	 * This is a low-level method which you should not need to use, and
315 	 * there are further restrictions on its proper use which are not
316 	 * documented here.
317 	 *
318 	 * Params:
319 	 *     chunk = a #SoupBuffer returned from soup_message_body_get_chunk()
320 	 *
321 	 * Since: 2.24
322 	 */
323 	public void wroteChunk(Buffer chunk)
324 	{
325 		soup_message_body_wrote_chunk(soupMessageBody, (chunk is null) ? null : chunk.getBufferStruct());
326 	}
327 }