v2.9.0: MBMNET Shop (eigene App, auf Wunsch installierbar)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d264cd93cd
commit
ca77952a9d
@@ -0,0 +1,73 @@
|
||||
// HTTP über den Systemdienst http:C. Alles läuft über den MBMNET-Server (einfaches HTTP),
|
||||
// der Katalog, Symbole und Downloads von Universal-DB und GitHub holt.
|
||||
#include <3ds.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "net.h"
|
||||
|
||||
#define CHUNK (128 * 1024)
|
||||
|
||||
static Result open_request(httpcContext *ctx, const char *url, u32 *status)
|
||||
{
|
||||
Result rc = httpcOpenContext(ctx, HTTPC_METHOD_GET, url, 1);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
httpcAddRequestHeaderField(ctx, "User-Agent", "MBMNET-Shop/" APP_VERSION);
|
||||
httpcSetKeepAlive(ctx, HTTPC_KEEPALIVE_DISABLED);
|
||||
if (R_SUCCEEDED(rc = httpcBeginRequest(ctx)))
|
||||
rc = httpcGetResponseStatusCodeTimeout(ctx, status, 30ULL * 1000 * 1000 * 1000);
|
||||
if (R_FAILED(rc)) httpcCloseContext(ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
u32 net_stream(const char *url, NetSink sink, void *ctx, Result *rcOut)
|
||||
{
|
||||
httpcContext http;
|
||||
u32 status = 0, total = 0, got;
|
||||
Result rc = open_request(&http, url, &status);
|
||||
if (rcOut) *rcOut = rc;
|
||||
if (R_FAILED(rc)) return 0;
|
||||
if (status != 200) { httpcCloseContext(&http); return status; }
|
||||
|
||||
httpcGetDownloadSizeState(&http, NULL, &total);
|
||||
u8 *buf = malloc(CHUNK);
|
||||
if (!buf) { httpcCloseContext(&http); if (rcOut) *rcOut = -2; return 0; }
|
||||
do {
|
||||
got = 0;
|
||||
rc = httpcDownloadData(&http, buf, CHUNK, &got);
|
||||
if (got && !sink(ctx, buf, got, total)) { rc = -3; break; } // -3 = Empfänger hat abgebrochen
|
||||
} while (rc == (Result)HTTPC_RESULTCODE_DOWNLOADPENDING);
|
||||
free(buf);
|
||||
httpcCloseContext(&http);
|
||||
if (rcOut) *rcOut = rc;
|
||||
return R_SUCCEEDED(rc) ? 200 : 0;
|
||||
}
|
||||
|
||||
typedef struct { u8 *data; u32 size, cap, max; } MemSink;
|
||||
|
||||
static bool to_memory(void *p, const u8 *data, u32 len, u32 total)
|
||||
{
|
||||
MemSink *m = p;
|
||||
if (m->size + len > m->max) return false;
|
||||
if (m->size + len > m->cap) {
|
||||
u32 cap = m->cap ? m->cap : (total && total <= m->max ? total : 64 * 1024);
|
||||
while (cap < m->size + len) cap *= 2;
|
||||
u8 *bigger = realloc(m->data, cap);
|
||||
if (!bigger) return false;
|
||||
m->data = bigger;
|
||||
m->cap = cap;
|
||||
}
|
||||
memcpy(m->data + m->size, data, len);
|
||||
m->size += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 net_get(const char *url, u8 **out, u32 *size, u32 max, Result *rc)
|
||||
{
|
||||
MemSink m = { NULL, 0, 0, max };
|
||||
u32 status = net_stream(url, to_memory, &m, rc);
|
||||
if (status != 200) { free(m.data); m.data = NULL; m.size = 0; }
|
||||
*out = m.data;
|
||||
*size = m.size;
|
||||
return status;
|
||||
}
|
||||
Reference in New Issue
Block a user