bool get_header_names_from_handle(JSContext *cx, uint32_t handle, Mode mode,
                                  HandleObject backing_map) {
  RootedString name(cx);
  RootedValue name_val(cx);
  OwnedHostCallBuffer buffer;

  MULTI_VALUE_HOSTCALL(
      {
        int result;
        if (mode == Mode::ProxyToRequest) {
          RequestHandle request = {handle};
          result = xqd_req_header_names_get(request, buffer.get(), HEADER_MAX_LEN, cursor,
                                            &ending_cursor, &nwritten);
        } else {
          ResponseHandle response = {handle};
          result = xqd_resp_header_names_get(response, buffer.get(), HEADER_MAX_LEN, cursor,
                                             &ending_cursor, &nwritten);
        }

        if (!HANDLE_RESULT(cx, result))
          return false;
      },
      {
        uint32_t offset = 0;
        for (size_t i = 0; i < nwritten; i++) {
          if (buffer.get()[i] != '\0') {
            continue;
          }

          name = JS_NewStringCopyN(cx, buffer.get() + offset, i - offset);
          if (!name)
            return false;

          name_val.setString(name);
          JS::MapSet(cx, backing_map, name_val, JS::NullHandleValue);

          offset = i + 1;
        }
      })

  return true;
}
bool get_header_names_from_handle(JSContext *cx, uint32_t handle, Mode mode,
                                  HandleObject backing_map) {
  RootedString name(cx);
  RootedValue name_val(cx);
  OwnedHostCallBuffer buffer;

  MULTI_VALUE_HOSTCALL(
      {
        int result;
        if (mode == Mode::ProxyToRequest) {
          RequestHandle request = {handle};
          result = xqd_req_header_names_get(request, buffer.get(), HEADER_MAX_LEN, cursor,
                                            &ending_cursor, &nwritten);
        } else {
          ResponseHandle response = {handle};
          result = xqd_resp_header_names_get(response, buffer.get(), HEADER_MAX_LEN, cursor,
                                             &ending_cursor, &nwritten);
        }

        if (!HANDLE_RESULT(cx, result))
          return false;
      },
      {
        uint32_t offset = 0;
        for (size_t i = 0; i < nwritten; i++) {
          if (buffer.get()[i] != '\0') {
            continue;
          }

          name = JS_NewStringCopyN(cx, buffer.get() + offset, i - offset);
          if (!name)
            return false;

          name_val.setString(name);
          JS::MapSet(cx, backing_map, name_val, JS::NullHandleValue);

          offset = i + 1;
        }
      })

  return true;
}