1 module awebview.wrapper.resourceinterceptor;
2 
3 import awebview.wrapper.webstring,
4        awebview.wrapper.weburl,
5        awebview.wrapper.cpp,
6        awebview.wrapper.weakref;
7 
8 import awebview.wrapper.webstring : WebString;
9 import awebview.wrapper.weburl : WebURL;
10 
11 import std.conv : to;
12 import std.traits : isSomeString;
13 import core.exception;
14 
15 struct UploadElement
16 {
17     this(inout(CppObj) obj) inout pure nothrow @safe @nogc
18     {
19         _cppObj = obj;
20     }
21 
22 
23     inout(CppObj) cppObj() inout pure nothrow @safe @nogc @property
24     {
25         return _cppObj;
26     }
27 
28 
29     @property
30     bool isFilePath() const nothrow @nogc
31     {
32         return UEM.IsFilePath(_cppObj);
33     }
34 
35 
36     @property
37     bool isBytes() const nothrow @nogc
38     {
39         return UEM.IsBytes(_cppObj);
40     }
41 
42 
43     @property
44     const(ubyte)[] bytes() const nothrow @nogc
45     {
46         return (cast(const(ubyte)*)UEM.bytes(_cppObj))[0 .. UEM.num_bytes(_cppObj)];
47     }
48 
49 
50     @property
51     S filePath(S = string)() const nothrow @nogc
52     {
53         WebString str;
54         UEM.file_path(_cppObj, str.cppObj);
55         return str.to!string;
56     }
57 
58 
59   private:
60     alias CppObj = Awesomium.UploadElement;
61     alias UEM = Awesomium4D.UploadElementMember;
62 
63     CppObj _cppObj;
64 }
65 
66 
67 struct ResourceRequest
68 {
69     this(inout(CppObj) cppObj) inout pure nothrow @safe @nogc
70     {
71         _cppObj = cppObj;
72     }
73 
74 
75     inout(CppObj) cppObj() inout pure nothrow @safe @nogc @property
76     {
77         return _cppObj;
78     }
79 
80 
81     void cancel() @nogc
82     {
83         RReqMmb.Cancel(_cppObj);
84     }
85 
86 
87     @property
88     int originProcessId() const nothrow @nogc
89     {
90         return RReqMmb.origin_process_id(_cppObj);
91     }
92 
93 
94     @property
95     int originRoutingId() const nothrow @nogc
96     {
97         return RReqMmb.origin_routing_id(_cppObj);
98     }
99 
100 
101     @property
102     WebURL url() const nothrow @nogc
103     {
104         WebURL dst;
105         RReqMmb.url(_cppObj, dst.cppObj);
106         return dst;
107     }
108 
109 
110     @property
111     S method(S = string)() const nothrow
112     if(isSomeString!S)
113     {
114         WebStringCpp str;
115         RReqMmb.method(_cppObj, str.cppObj);
116         return str.to!S;
117     }
118 
119 
120     @property
121     void method(S)(in S m) nothrow @nogc
122     if(isSomeString!S)
123     {
124         auto ws = WebStringCpp(m);
125         RReqMmb.set_method(_cppObj, m.cppObj);
126     }
127 
128 
129     @property
130     S referrer(S = string)() const nothrow
131     if(isSomeString!S)
132     {
133         WebStringCpp dst;
134         RReqMmb.referrer(_cppObj, dst.cppObj);
135         return dst.to!S;
136     }
137 
138 
139     @property
140     void referrer(S)(in S s) nothrow @nogc
141     {
142         auto ws = WebStringCpp(s);
143         RReqMmb.set_referrer(_cppObj, ws.cppObj);
144     }
145 
146 
147     @property
148     S extraHandlers(S = string)() const nothrow
149     {
150         WebStringCpp dst;
151         RReqMmb.extra_headers(_cppObj, dst.cppObj);
152         return dst.to!S;
153     }
154 
155 
156     @property
157     void extraHeaders(S)(in S s) nothrow @nogc
158     if(isSomeString!S)
159     {
160         auto ws = WebStringCpp(s);
161         RReqMmb.set_extra_headers(_cppObj, eh);
162     }
163 
164 
165     void appendExtraHeader(S)(in S name, in S value)
166     if(isSomeString!S)
167     {
168         auto n = WebStringCpp(name),
169              v = WebStringCpp(value);
170 
171         RReqMmb.AppendExtraHeader(_cppObj, n.cppObj, v.cppObj);
172     }
173 
174 
175     @property
176     uint numUploadElements() const nothrow @nogc
177     {
178         return RReqMmb.num_upload_elements(_cppObj);
179     }
180 
181 
182     const(UploadElement) getUploadElement(uint idx) const nothrow @nogc
183     {
184         return const(UploadElement)(cast(const(Awesomium.UploadElement))RReqMmb.GetUploadElement(_cppObj, idx));
185     }
186 
187 
188     @property
189     auto uploadElements() const nothrow @nogc
190     {
191         static struct UploadElementsResult()
192         {
193             @property
194             const(UploadElement) front() const nothrow
195             {
196                 if(this.length)
197                     return _parent.getUploadElement(_sIdx);
198                 else
199                     onRangeError();
200 
201                 assert(0);
202             }
203 
204 
205             @property
206             const(UploadElement) back() const nothrow
207             {
208                 if(this.length)
209                     return _parent.getUploadElement(_bIdx - 1);
210                 else
211                     onRangeError();
212 
213                 assert(0);
214             }
215 
216 
217             const(UploadElement) opIndex(uint i) const nothrow
218             {
219                 if(i < this.length)
220                     return _parent.getUploadElement(_sIdx + i);
221                 else
222                     onRangeError();
223 
224                 assert(0);
225             }
226 
227 
228             void popFront() pure nothrow @safe @nogc
229             {
230                 if(_sIdx != size_t.max) ++_sIdx;
231             }
232 
233 
234             void popBack() pure nothrow @safe @nogc
235             {
236                 if(_bIdx) --_bIdx;
237             }
238 
239 
240             @property
241             bool empty() const pure nothrow @safe @nogc
242             {
243                 return _sIdx >= _bIdx;
244             }
245 
246 
247             UploadElementsResult save() const pure nothrow @safe @nogc
248             {
249                 return this;
250             }
251 
252 
253             @property
254             uint length() const pure nothrow @safe @nogc
255             {
256                 if(this.empty)
257                     return 0;
258                 else
259                     return _bIdx - _sIdx;
260             }
261 
262 
263             UploadElementsResult opSlice() const pure nothrow @safe @nogc
264             {
265                 return this;
266             }
267 
268 
269             UploadElementsResult opSlice(uint i, uint j) const pure nothrow @safe
270             {
271                 if(i > j || j > this.length)
272                     onRangeError();
273                 else
274                     return UploadElementsResult(_parent, _sIdx + i, _sIdx + j - i);
275 
276                 assert(0);
277             }
278 
279 
280             alias opDollar = length;
281 
282 
283           private:
284             const(ResourceRequest) _parent;
285             uint _sIdx;
286             uint _bIdx;
287         }
288 
289 
290         return UploadElementsResult!()(this, 0, this.numUploadElements);
291     }
292 
293 
294     void clearUploadElements() nothrow @nogc
295     {
296         RReqMmb.ClearUploadElements(_cppObj);
297     }
298 
299 
300     void appendUploadFilePath(S)(in S path) nothrow @nogc
301     if(isSomeString!S)
302     {
303         auto ws = WebStringCpp(path);
304         RReqMmb.AppendUploadFilePath(_cppObj, ws.cppObj);
305     }
306 
307 
308     void appendUploadBytes(in ubyte[] bytes) nothrow @nogc
309     {
310         RReqMmb.AppendUploadBytes(_cppObj, cast(const(char)*)(bytes.ptr), cast(uint)bytes.length);
311     }
312 
313 
314     @property
315     void ignoreDataSourceHandler(bool ignore) nothrow @nogc
316     {
317         RReqMmb.set_ignore_data_source_handler(_cppObj, ignore);
318     }
319 
320 
321   private:
322     alias RReqMmb = Awesomium4D.ResourceRequestMember;
323     alias CppObj = Awesomium.ResourceRequest;
324 
325     CppObj _cppObj;
326 }
327 
328 
329 struct ResourceResponse
330 {
331     this(inout(CppObj) cppObj) inout
332     {
333         _cppObj = cppObj;
334     }
335 
336 
337     this(S)(const(ubyte)[] buffer, in S mimeType)
338     {
339         auto ws = WebStringCpp(mimeType);
340         this(Awesomium4D.ResourceResponseMember.Create(cast(uint)buffer.length, buffer.ptr, ws.cppObj));
341     }
342 
343 
344     this(S)(in S path)
345     {
346         auto ws = WebStringCpp(path);
347         this(Awesomium4D.ResourceResponseMember.Create(ws.cppObj));
348     }
349 
350 
351     inout(CppObj) cppObj() inout pure nothrow @safe @nogc @property
352     {
353         return _cppObj;
354     }
355 
356 
357   private:
358     alias CppObj = Awesomium.ResourceResponse;
359 
360     CppObj _cppObj;
361 }
362 
363 
364 final class ResourceInterceptorCpp
365 {
366     this()
367     {
368         _cppObj = RIM.newCtor();
369     }
370 
371 
372     //~this()
373     //{
374     //    RIM.deleteDtor(_cppObj);
375     //    _cppObj = null;
376     //}
377 
378 
379     inout(CppObj) cppObj() inout pure nothrow @safe @nogc @property
380     {
381         return _cppObj;
382     }
383 
384 
385     ResourceResponse onRequest(ResourceRequest req)
386     {
387         return ResourceResponse(RIM.OnRequest(_cppObj, req.cppObj));
388     }
389 
390 
391     bool onFilterNavigation(S)(int opid, int orid, in S method, WebURL url, bool isMainFrame)
392     if(isSomeString!S)
393     {
394         WebStringCpp m = method;
395 
396         return RIM.OnFilterNavigation(_cppObj, opid, orid, m.cppObj, url.cppObj, isMainFrame);
397     }
398 
399 
400     void onWillDownload(int opid, int orid, WebURL url)
401     {
402         return RIM.OnWillDownload(_cppObj, opid, orid, url.cppObj);
403     }
404 
405 
406   private:
407     alias CppObj = Awesomium.ResourceInterceptor;
408     alias RIM = Awesomium4D.ResourceInterceptorMember;
409 
410     CppObj _cppObj;
411 }
412 
413 
414 class ResourceInterceptor : IResourceInterceptorD
415 {
416     this()
417     {
418         _cppRI = new ResourceInterceptorCpp();
419 
420         auto id = MemoryManager.instance.register(cast(void*)this);
421         _d2cppObj = Awesomium4D.ResourceInterceptorD2CppMember.newCtor(this, id);
422     }
423 
424 
425     //~this()
426     //{
427     //    ResourceInterceptorD2CppMember.deleteDtor(_d2cppObj);
428     //    _d2cppObj = null;
429     //}
430 
431 
432     final
433     inout(D2CppObj) cppObj() inout pure nothrow @safe @nogc @property
434     {
435         return _d2cppObj;
436     }
437 
438 
439     ResourceResponse onRequest(ResourceRequest req)
440     {
441         return _cppRI.onRequest(req);
442     }
443 
444 
445     bool onFilterNavigation(int opid, int orid, const(char)[] method, WebURL url, bool is_main_frame)
446     {
447         return _cppRI.onFilterNavigation(opid, orid, method, url, is_main_frame);
448     }
449 
450 
451     void onWillDownload(int opid, int orid, WebURL url)
452     {
453         return _cppRI.onWillDownload(opid, orid, url);
454     }
455 
456 
457   extern(C++)
458   {
459     Awesomium.ResourceResponse onRequest(Awesomium.ResourceRequest req)
460     {
461         return this.onRequest(ResourceRequest(req)).cppObj;
462     }
463 
464 
465     bool onFilterNavigation(int opid, int orid,
466                             const(Awesomium.WebString) method,
467                             const(Awesomium.WebURL) url,
468                             bool is_main_frame)
469     {
470         WebURL u = url;
471         return this.onFilterNavigation(opid, orid, method.weakRef!WebStringCpp.to!string, u, is_main_frame);
472     }
473 
474 
475     void onWillDownload(int opid, int orid,
476                         const(Awesomium.WebURL) url)
477     {
478         WebURL u = url;
479         this.onWillDownload(opid, orid, u);
480     }
481   }
482 
483 
484   private:
485     alias D2CppObj = Awesomium4D.ResourceInterceptorD2Cpp;
486 
487     ResourceInterceptorCpp _cppRI;
488     D2CppObj _d2cppObj;
489 }