static int httpserver_handle_get_mmap(struct mg_connection* conn, void* cbdata) { static const char* hexdigits = "0123456789ABCDEF"; const struct mg_request_info* req = mg_get_request_info(conn); const char* comma = ""; rarch_system_info_t* system; const struct retro_memory_map* mmaps; const struct retro_memory_descriptor* mmap; unsigned id; uLong buflen; Bytef* buffer; if (strcmp(req->request_method, "GET")) { return httpserver_error(conn, 405, "Unimplemented method in %s: %s", __FUNCTION__, req->request_method); } if (sscanf(req->request_uri, "/mmaps/%u", &id) != 1) { return httpserver_error(conn, 500, "Malformed request in %s: %s", __FUNCTION__, req->request_uri); } if (!runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system)) { return httpserver_error(conn, 500, "Could not get system information in %s", __FUNCTION__); } mmaps = &system->mmaps; if (id >= mmaps->num_descriptors) { return httpserver_error(conn, 404, "Invalid memory map id in %s: %u", __FUNCTION__, id); } mmap = mmaps->descriptors + id; buflen = compressBound(mmap->len); buffer = (Bytef*)malloc(((buflen + 3) / 4) * 5); if (buffer == NULL) { return httpserver_error(conn, 500, "Out of memory in %s", __FUNCTION__); } if (compress2(buffer, &buflen, (Bytef*)mmap->ptr, mmap->len, Z_BEST_COMPRESSION) != Z_OK) { free((void*)buffer); return httpserver_error(conn, 500, "Error during compression in %s", __FUNCTION__); } buffer[buflen] = 0; buffer[buflen + 1] = 0; buffer[buflen + 2] = 0; httpserver_z85_encode_inplace(buffer, (buflen + 3) & ~3); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"); mg_printf(conn, "{" "\"length\":" STRING_REP_UINT64 "," "\"compressedLength\":" STRING_REP_ULONG "," "\"bytesZ85\":\"%s\"" "}", mmap->len, (size_t)buflen, (char*)buffer ); free((void*)buffer); return 1; }
static int httpserver_handle_get_mmap(struct mg_connection* conn, void* cbdata) { size_t start, length; unsigned id; uLong buflen; const struct mg_request_info * req = mg_get_request_info(conn); const char * comma = ""; const struct retro_memory_map* mmaps = NULL; const struct retro_memory_descriptor* mmap = NULL; const char* param = NULL; Bytef* buffer = NULL; rarch_system_info_t *system = runloop_get_system_info(); if (strcmp(req->request_method, "GET")) return httpserver_error(conn, 405, "Unimplemented method in %s: %s", __FUNCTION__, req->request_method); if (sscanf(req->request_uri, "/" MEMORY_MAP "/%u", &id) != 1) return httpserver_error(conn, 500, "Malformed request in %s: %s", __FUNCTION__, req->request_uri); mmaps = &system->mmaps; if (id >= mmaps->num_descriptors) return httpserver_error(conn, 404, "Invalid memory map id in %s: %u", __FUNCTION__, id); mmap = mmaps->descriptors + id; start = 0; length = mmap->len; if (req->query_string != NULL) { param = strstr(req->query_string, "start="); if (param != NULL) start = atoll(param + 6); param = strstr(req->query_string, "length="); if (param != NULL) length = atoll(param + 7); } if (start >= mmap->len) start = mmap->len - 1; if (length > mmap->len - start) length = mmap->len - start; buflen = compressBound(length); buffer = (Bytef*)malloc(((buflen + 3) / 4) * 5); if (buffer == NULL) return httpserver_error(conn, 500, "Out of memory in %s", __FUNCTION__); if (compress2(buffer, &buflen, (Bytef*)mmap->ptr + start, length, Z_BEST_COMPRESSION) != Z_OK) { free((void*)buffer); return httpserver_error(conn, 500, "Error during compression in %s", __FUNCTION__); } buffer[buflen] = 0; buffer[buflen + 1] = 0; buffer[buflen + 2] = 0; httpserver_z85_encode_inplace(buffer, (buflen + 3) & ~3); mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"); mg_printf(conn, "{" "\"start\":" STRING_REP_ULONG "," "\"length\":" STRING_REP_ULONG "," "\"compression\":\"deflate\"," "\"compressedLength\":" STRING_REP_ULONG "," "\"encoding\":\"Z85\"," "\"data\":\"%s\"" "}", start, length, (size_t)buflen, (char*)buffer ); free((void*)buffer); return 1; }