mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-23 20:36:53 +01:00
249 lines
8.9 KiB
JavaScript
249 lines
8.9 KiB
JavaScript
/*************************************************************************/
|
|
/* library_pandemonium_fetch.js */
|
|
/*************************************************************************/
|
|
/* This file is part of: */
|
|
/* GODOT ENGINE */
|
|
/* https://godotengine.org */
|
|
/*************************************************************************/
|
|
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
/* a copy of this software and associated documentation files (the */
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
/* the following conditions: */
|
|
/* */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/*************************************************************************/
|
|
|
|
const PandemoniumFetch = {
|
|
$PandemoniumFetch__deps: ['$IDHandler', '$PandemoniumRuntime'],
|
|
$PandemoniumFetch: {
|
|
|
|
onread: function(id, result) {
|
|
const obj = IDHandler.get(id);
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
if (result.value) {
|
|
obj.chunks.push(result.value);
|
|
}
|
|
obj.reading = false;
|
|
obj.done = result.done;
|
|
},
|
|
|
|
onresponse: function(id, response) {
|
|
const obj = IDHandler.get(id);
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
let chunked = false;
|
|
response.headers.forEach(function(value, header) {
|
|
const v = value.toLowerCase().trim();
|
|
const h = header.toLowerCase().trim();
|
|
if (h === 'transfer-encoding' && v === 'chunked') {
|
|
chunked = true;
|
|
}
|
|
});
|
|
obj.status = response.status;
|
|
obj.response = response;
|
|
obj.reader = response.body.getReader();
|
|
obj.chunked = chunked;
|
|
},
|
|
|
|
onerror: function(id, err) {
|
|
PandemoniumRuntime.error(err);
|
|
const obj = IDHandler.get(id);
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
obj.error = err;
|
|
},
|
|
|
|
create: function(method, url, headers, body) {
|
|
const obj = {
|
|
request: null,
|
|
response: null,
|
|
reader: null,
|
|
error: null,
|
|
done: false,
|
|
reading: false,
|
|
status: 0,
|
|
chunks: [],
|
|
bodySize: -1,
|
|
};
|
|
const id = IDHandler.add(obj);
|
|
const init = {
|
|
method: method,
|
|
headers: headers,
|
|
body: body,
|
|
};
|
|
obj.request = fetch(url, init);
|
|
obj.request.then(PandemoniumFetch.onresponse.bind(null, id)).catch(PandemoniumFetch.onerror.bind(null, id));
|
|
return id;
|
|
},
|
|
|
|
free: function(id) {
|
|
const obj = IDHandler.get(id);
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
IDHandler.remove(id);
|
|
if (!obj.request) {
|
|
return;
|
|
}
|
|
// Try to abort
|
|
obj.request.then(function(response) {
|
|
response.abort();
|
|
}).catch(function(e) {
|
|
/* nothing to do */
|
|
});
|
|
},
|
|
|
|
read: function(id) {
|
|
const obj = IDHandler.get(id);
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
if (obj.reader && !obj.reading) {
|
|
if (obj.done) {
|
|
obj.reader = null;
|
|
return;
|
|
}
|
|
obj.reading = true;
|
|
obj.reader.read().then(PandemoniumFetch.onread.bind(null, id)).catch(PandemoniumFetch.onerror.bind(null, id));
|
|
}
|
|
},
|
|
},
|
|
|
|
pandemonium_js_fetch_create__sig: 'iiiiiii',
|
|
pandemonium_js_fetch_create: function(p_method, p_url, p_headers, p_headers_size, p_body, p_body_size) {
|
|
const method = PandemoniumRuntime.parseString(p_method);
|
|
const url = PandemoniumRuntime.parseString(p_url);
|
|
const headers = PandemoniumRuntime.parseStringArray(p_headers, p_headers_size);
|
|
const body = p_body_size ? PandemoniumRuntime.heapSlice(HEAP8, p_body, p_body_size) : null;
|
|
return PandemoniumFetch.create(method, url, headers.map(function(hv) {
|
|
const idx = hv.indexOf(':');
|
|
if (idx <= 0) {
|
|
return [];
|
|
}
|
|
return [
|
|
hv.slice(0, idx).trim(),
|
|
hv.slice(idx + 1).trim(),
|
|
];
|
|
}).filter(function(v) {
|
|
return v.length === 2;
|
|
}), body);
|
|
},
|
|
|
|
pandemonium_js_fetch_state_get__sig: 'ii',
|
|
pandemonium_js_fetch_state_get: function(p_id) {
|
|
const obj = IDHandler.get(p_id);
|
|
if (!obj) {
|
|
return -1;
|
|
}
|
|
if (obj.error) {
|
|
return -1;
|
|
}
|
|
if (!obj.response) {
|
|
return 0;
|
|
}
|
|
if (obj.reader) {
|
|
return 1;
|
|
}
|
|
if (obj.done) {
|
|
return 2;
|
|
}
|
|
return -1;
|
|
},
|
|
|
|
pandemonium_js_fetch_http_status_get__sig: 'ii',
|
|
pandemonium_js_fetch_http_status_get: function(p_id) {
|
|
const obj = IDHandler.get(p_id);
|
|
if (!obj || !obj.response) {
|
|
return 0;
|
|
}
|
|
return obj.status;
|
|
},
|
|
|
|
pandemonium_js_fetch_read_headers__sig: 'iiii',
|
|
pandemonium_js_fetch_read_headers: function(p_id, p_parse_cb, p_ref) {
|
|
const obj = IDHandler.get(p_id);
|
|
if (!obj || !obj.response) {
|
|
return 1;
|
|
}
|
|
const cb = PandemoniumRuntime.get_func(p_parse_cb);
|
|
const arr = [];
|
|
obj.response.headers.forEach(function(v, h) {
|
|
arr.push(`${h}:${v}`);
|
|
});
|
|
const c_ptr = PandemoniumRuntime.allocStringArray(arr);
|
|
cb(arr.length, c_ptr, p_ref);
|
|
PandemoniumRuntime.freeStringArray(c_ptr, arr.length);
|
|
return 0;
|
|
},
|
|
|
|
pandemonium_js_fetch_read_chunk__sig: 'iiii',
|
|
pandemonium_js_fetch_read_chunk: function(p_id, p_buf, p_buf_size) {
|
|
const obj = IDHandler.get(p_id);
|
|
if (!obj || !obj.response) {
|
|
return 0;
|
|
}
|
|
let to_read = p_buf_size;
|
|
const chunks = obj.chunks;
|
|
while (to_read && chunks.length) {
|
|
const chunk = obj.chunks[0];
|
|
if (chunk.length > to_read) {
|
|
PandemoniumRuntime.heapCopy(HEAP8, chunk.slice(0, to_read), p_buf);
|
|
chunks[0] = chunk.slice(to_read);
|
|
to_read = 0;
|
|
} else {
|
|
PandemoniumRuntime.heapCopy(HEAP8, chunk, p_buf);
|
|
to_read -= chunk.length;
|
|
chunks.pop();
|
|
}
|
|
}
|
|
if (!chunks.length) {
|
|
PandemoniumFetch.read(p_id);
|
|
}
|
|
return p_buf_size - to_read;
|
|
},
|
|
|
|
pandemonium_js_fetch_body_length_get__sig: 'ii',
|
|
pandemonium_js_fetch_body_length_get: function(p_id) {
|
|
const obj = IDHandler.get(p_id);
|
|
if (!obj || !obj.response) {
|
|
return -1;
|
|
}
|
|
return obj.bodySize;
|
|
},
|
|
|
|
pandemonium_js_fetch_is_chunked__sig: 'ii',
|
|
pandemonium_js_fetch_is_chunked: function(p_id) {
|
|
const obj = IDHandler.get(p_id);
|
|
if (!obj || !obj.response) {
|
|
return -1;
|
|
}
|
|
return obj.chunked ? 1 : 0;
|
|
},
|
|
|
|
pandemonium_js_fetch_free__sig: 'vi',
|
|
pandemonium_js_fetch_free: function(id) {
|
|
PandemoniumFetch.free(id);
|
|
},
|
|
};
|
|
|
|
autoAddDeps(PandemoniumFetch, '$PandemoniumFetch');
|
|
mergeInto(LibraryManager.library, PandemoniumFetch); |