1 module soup.MultipartInputStream; 2 3 private import gio.AsyncResultIF; 4 private import gio.Cancellable; 5 private import gio.FilterInputStream; 6 private import gio.InputStream; 7 private import gio.PollableInputStreamIF; 8 private import gio.PollableInputStreamT; 9 private import glib.ConstructionException; 10 private import glib.ErrorG; 11 private import glib.GException; 12 private import gobject.ObjectG; 13 private import soup.Message; 14 private import soup.MessageHeaders; 15 private import soup.c.functions; 16 public import soup.c.types; 17 18 19 /** 20 * This adds support for the multipart responses. For handling the 21 * multiple parts the user needs to wrap the #GInputStream obtained by 22 * sending the request with a #SoupMultipartInputStream and use 23 * soup_multipart_input_stream_next_part() before reading. Responses 24 * which are not wrapped will be treated like non-multipart responses. 25 * 26 * Note that although #SoupMultipartInputStream is a #GInputStream, 27 * you should not read directly from it, and the results are undefined 28 * if you do. 29 * 30 * Since: 2.40 31 */ 32 public class MultipartInputStream : FilterInputStream, PollableInputStreamIF 33 { 34 /** the main Gtk struct */ 35 protected SoupMultipartInputStream* soupMultipartInputStream; 36 37 /** Get the main Gtk struct */ 38 public SoupMultipartInputStream* getMultipartInputStreamStruct(bool transferOwnership = false) 39 { 40 if (transferOwnership) 41 ownedRef = false; 42 return soupMultipartInputStream; 43 } 44 45 /** the main Gtk struct as a void* */ 46 protected override void* getStruct() 47 { 48 return cast(void*)soupMultipartInputStream; 49 } 50 51 /** 52 * Sets our main struct and passes it to the parent class. 53 */ 54 public this (SoupMultipartInputStream* soupMultipartInputStream, bool ownedRef = false) 55 { 56 this.soupMultipartInputStream = soupMultipartInputStream; 57 super(cast(GFilterInputStream*)soupMultipartInputStream, ownedRef); 58 } 59 60 // add the PollableInputStream capabilities 61 mixin PollableInputStreamT!(SoupMultipartInputStream); 62 63 64 /** */ 65 public static GType getType() 66 { 67 return soup_multipart_input_stream_get_type(); 68 } 69 70 /** 71 * Creates a new #SoupMultipartInputStream that wraps the 72 * #GInputStream obtained by sending the #SoupRequest. Reads should 73 * not be done directly through this object, use the input streams 74 * returned by soup_multipart_input_stream_next_part() or its async 75 * counterpart instead. 76 * 77 * Params: 78 * msg = the #SoupMessage the response is related to. 79 * baseStream = the #GInputStream returned by sending the request. 80 * 81 * Returns: a new #SoupMultipartInputStream 82 * 83 * Since: 2.40 84 * 85 * Throws: ConstructionException GTK+ fails to create the object. 86 */ 87 public this(Message msg, InputStream baseStream) 88 { 89 auto __p = soup_multipart_input_stream_new((msg is null) ? null : msg.getMessageStruct(), (baseStream is null) ? null : baseStream.getInputStreamStruct()); 90 91 if(__p is null) 92 { 93 throw new ConstructionException("null returned by new"); 94 } 95 96 this(cast(SoupMultipartInputStream*) __p, true); 97 } 98 99 /** 100 * Obtains the headers for the part currently being processed. Note 101 * that the #SoupMessageHeaders that are returned are owned by the 102 * #SoupMultipartInputStream and will be replaced when a call is made 103 * to soup_multipart_input_stream_next_part() or its async 104 * counterpart, so if keeping the headers is required, a copy must be 105 * made. 106 * 107 * Note that if a part had no headers at all an empty #SoupMessageHeaders 108 * will be returned. 109 * 110 * Returns: a #SoupMessageHeaders 111 * containing the headers for the part currently being processed or 112 * %NULL if the headers failed to parse. 113 * 114 * Since: 2.40 115 */ 116 public MessageHeaders getHeaders() 117 { 118 auto __p = soup_multipart_input_stream_get_headers(soupMultipartInputStream); 119 120 if(__p is null) 121 { 122 return null; 123 } 124 125 return ObjectG.getDObject!(MessageHeaders)(cast(SoupMessageHeaders*) __p); 126 } 127 128 /** 129 * Obtains an input stream for the next part. When dealing with a 130 * multipart response the input stream needs to be wrapped in a 131 * #SoupMultipartInputStream and this function or its async 132 * counterpart need to be called to obtain the first part for 133 * reading. 134 * 135 * After calling this function, 136 * soup_multipart_input_stream_get_headers() can be used to obtain the 137 * headers for the first part. A read of 0 bytes indicates the end of 138 * the part; a new call to this function should be done at that point, 139 * to obtain the next part. 140 * 141 * Params: 142 * cancellable = a #GCancellable 143 * 144 * Returns: a new #GInputStream, or 145 * %NULL if there are no more parts 146 * 147 * Since: 2.40 148 * 149 * Throws: GException on failure. 150 */ 151 public InputStream nextPart(Cancellable cancellable) 152 { 153 GError* err = null; 154 155 auto __p = soup_multipart_input_stream_next_part(soupMultipartInputStream, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 156 157 if (err !is null) 158 { 159 throw new GException( new ErrorG(err) ); 160 } 161 162 if(__p is null) 163 { 164 return null; 165 } 166 167 return ObjectG.getDObject!(InputStream)(cast(GInputStream*) __p, true); 168 } 169 170 /** 171 * Obtains a #GInputStream for the next request. See 172 * soup_multipart_input_stream_next_part() for details on the 173 * workflow. 174 * 175 * Params: 176 * ioPriority = the I/O priority for the request. 177 * cancellable = a #GCancellable. 178 * callback = callback to call when request is satisfied. 179 * data = data for @callback 180 * 181 * Since: 2.40 182 */ 183 public void nextPartAsync(int ioPriority, Cancellable cancellable, GAsyncReadyCallback callback, void* data) 184 { 185 soup_multipart_input_stream_next_part_async(soupMultipartInputStream, ioPriority, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, data); 186 } 187 188 /** 189 * Finishes an asynchronous request for the next part. 190 * 191 * Params: 192 * result = a #GAsyncResult. 193 * 194 * Returns: a newly created 195 * #GInputStream for reading the next part or %NULL if there are no 196 * more parts. 197 * 198 * Since: 2.40 199 * 200 * Throws: GException on failure. 201 */ 202 public InputStream nextPartFinish(AsyncResultIF result) 203 { 204 GError* err = null; 205 206 auto __p = soup_multipart_input_stream_next_part_finish(soupMultipartInputStream, (result is null) ? null : result.getAsyncResultStruct(), &err); 207 208 if (err !is null) 209 { 210 throw new GException( new ErrorG(err) ); 211 } 212 213 if(__p is null) 214 { 215 return null; 216 } 217 218 return ObjectG.getDObject!(InputStream)(cast(GInputStream*) __p, true); 219 } 220 }