Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}