Mercurial
diff postdog/main.c @ 112:d6d578b49a19
[PostDog] Got CRUD working.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Sun, 04 Jan 2026 11:38:44 -0800 |
| parents | 48f260576059 |
| children | e2a73e64e8e6 |
line wrap: on
line diff
--- a/postdog/main.c Sun Jan 04 06:39:16 2026 -0800 +++ b/postdog/main.c Sun Jan 04 11:38:44 2026 -0800 @@ -14,37 +14,26 @@ #define SCREEN_WIDTH 1280 #define SCREEN_HEIGHT 780 #define TEXT_SIZE 10 -#define LINE_HEIGHT 15 -#define GENERIC_PADDING 15 - -#define SIDEBAR_WIDTH 200 -#define SIDEBAR_PADDING_GENERAL 5 -#define SIDEBAR_AREA_PADDING_X 10 -#define SIDEBAR_AREA_PADDING_Y 10 -#define SIDEBAR_REFERSH_BUTTON_WIDTH 90 -#define SIDEBAR_REFERSH_BUTTON_HEIGHT 20 -#define SIDEBAR_HISTORY_ITEM_HEIGHT 45 - -#define URL_INPUT_HEIGHT 40 - -#define TAB_LEN 3 -#define METHOD_BUTTON_WIDTH 100 -#define METHOD_BUTTON_HEIGHT 40 -#define SEND_BUTTON_WIDTH 100 -#define SEND_BUTTON_HEIGHT 40 #define JSON_INPUT_BUFFER_LEN 8192 #define HEADER_INPUT_BUFFER_LEN 4096 #define PARAM_INPUT_BUFFER_LEN 4096 #define MAX_HISTORY_ITEMS 100 -// Structure to hold response data +#define HEADER_BUFFER_LENGTH 1024 * 4 +#define DEFAULT_TEXT_BUFFER_LENGTH 1024 * 4 +#define URL_TEXT_BUFFER 1024 * 10 +#define BODY_BUFFER_LENGTH 1024 * 1025 * 5 +#define RESULT_BUFFER_LENGTH 1024 * 1025 * 5 +#define AREANA_BUFFER_LENGTH 1024 * 1025 * 15 + +typedef Dowa_KV(char*, char*) INPUT_HASHMAP; + typedef struct { char *data; size_t size; } ResponseBuffer; -// Structure to hold history item typedef struct { char filename[256]; char displayName[128]; @@ -52,11 +41,16 @@ time_t timestamp; } HistoryItem; -typedef enum { - ActiveTab_JSON = 0, - ActiveTab_Headers, - ActiveTab_Params, -} ActiveTab; +char *PostDog_Enum_To_String(int active_enum) +{ + switch(active_enum) + { + case 0: return "GET"; + case 1: return "POST"; + case 2: return "PUT"; + case 3: return "DELETE"; + } +} static size_t Postdog_Curl_Callback(void *contents, size_t size, size_t nmemb, void *userp) { @@ -78,13 +72,19 @@ return real_size; } -int PostDog_Make_HttpRequest(const char *url, const char *method, const char *headers, - const char *body, char *response, size_t responseSize) +int PostDog_Make_HttpRequest( + const char *url, + const char *method, + const char *headers, + const char *body, + char *response, size_t responseSize) { CURL *curl; CURLcode res; ResponseBuffer buffer = { .data = malloc(1), .size = 0 }; + response[0] = '\n'; + if (buffer.data == NULL) { snprintf(response, responseSize, "Error: Failed to allocate memory"); @@ -180,8 +180,77 @@ typedef struct { Rectangle rectangle; char *label; + bool active; } TabItem; +typedef enum { + TAB_HEADER = 0, + TAB_BODY, + TAB_GET_PARAMS, + TAB_BAR, +} PostDog_Tab_Enum; + +void PostDog_Update_URL(char **p_url_input_text, char* get_params) +{ + char *url_input_text = *p_url_input_text; + + // Reset + char *question_mark = strchr(url_input_text, '?'); + if (question_mark) + *question_mark = '\0'; + + int get_params_length = (int)strlen(get_params) ; + if (get_params_length == 0) + return; + + char *separator = "?"; + + Dowa_Arena *arena = Dowa_Arena_Create(1024*1024); + char **lines = Dowa_String_Split(get_params, "\n", get_params_length, 1, arena); + + size_t url_len = strlen(url_input_text); + size_t url_capacity = URL_TEXT_BUFFER; + + for (int i = 0; i < Dowa_Array_Length(lines); i++) + { + char *line = lines[i]; + char **key_value = Dowa_String_Split(line, " ", (int)strlen(line), 1, arena); + + if (Dowa_Array_Length(key_value) < 2) + continue; // Skip this line, not break entire loop + + // Check buffer capacity before each append + size_t needed = url_len + strlen(separator) + strlen(key_value[0]) + 1 + 10; // +10 for "=" and safety + if (needed >= url_capacity) break; + + strcat(url_input_text, separator); + strcat(url_input_text, key_value[0]); + strcat(url_input_text, "="); + url_len = strlen(url_input_text); + + for (int i = 1; i < Dowa_Array_Length(key_value); i++) + { + if (!key_value[i] || key_value[i][0] == '\0') + break; + + size_t value_len = strlen(key_value[i]); + needed = url_len + value_len + 4; // +4 for "%20" if needed + if (needed >= url_capacity) break; + + printf("\n\n------\n\n"); + printf("key_value[%i]: %s, p = %p\n", i, key_value[i], key_value[i]); + printf("\n\n------\n\n"); + + if (i > 1) strcat(url_input_text, "%20"); + strcat(url_input_text, key_value[i]); + url_len = strlen(url_input_text); + } + separator = "&"; + } + + Dowa_Arena_Free(arena); +} + int main() { // -- initizlied --// @@ -189,7 +258,7 @@ SetWindowState(FLAG_WINDOW_RESIZABLE); SetTargetFPS(60); - Dowa_Arena *arena = Dowa_Arena_Create(1024 * 1025 * 10); + Dowa_Arena *arena = Dowa_Arena_Create(AREANA_BUFFER_LENGTH); // -- Starting pos ---// float side_bar_x = 10; @@ -200,36 +269,44 @@ Rectangle url_area = { 0 }; Rectangle textBounds = { 0 }; Rectangle url_input_bounds = { 0 }; + bool url_input_bool = false; Rectangle url_text_bounds = { 0 }; Rectangle url_enter_button = { 0 }; + Rectangle method_dropdown = { 0 }; - char *input_text = (char *)Dowa_Arena_Allocate(arena, 1024 * 4); + char *url_input_text = (char *)Dowa_Arena_Allocate(arena, URL_TEXT_BUFFER); + snprintf(url_input_text, URL_TEXT_BUFFER, "https://httpbin.org/get"); + + INPUT_HASHMAP *url_body_map = NULL; + Dowa_HashMap_Push_Arena(url_body_map, "Header", (char *)Dowa_Arena_Allocate(arena, HEADER_BUFFER_LENGTH), arena); + Dowa_HashMap_Push_Arena(url_body_map, "Body", (char *)Dowa_Arena_Allocate(arena, BODY_BUFFER_LENGTH), arena); + Dowa_HashMap_Push_Arena(url_body_map, "Get Param", (char *)Dowa_Arena_Allocate(arena, DEFAULT_TEXT_BUFFER_LENGTH), arena); + Dowa_HashMap_Push_Arena(url_body_map, "Bar", (char *)Dowa_Arena_Allocate(arena, DEFAULT_TEXT_BUFFER_LENGTH), arena); + + snprintf(url_body_map[0].value, HEADER_BUFFER_LENGTH, "Content-Type: application/json"); + snprintf(url_body_map[1].value, HEADER_BUFFER_LENGTH, ""); + + char *url_result_text = (char *)Dowa_Arena_Allocate(arena, RESULT_BUFFER_LENGTH); + + int active_method_dropdown = 0; + bool method_edit = false; + int sendRequest; + // -- input --// Rectangle input_area = { 0 }; Rectangle input_tab = { 0 }; - TabItem input_tab_items[4] = { - { - .rectangle={0}, .label="body" - }, - { - .rectangle={0}, .label="header" - }, - { - .rectangle={0}, .label="foo" - }, - { - .rectangle={0}, .label="bar" - }, - }; + Rectangle input_tab_item = { 0 }; Rectangle input_body = { 0 }; + bool input_body_bool = false; + // -- result --// Rectangle result_area = { 0 }; Rectangle result_body = { 0 }; // General styling. int padding = 10; // TODO make it % based? - + int active_input_tab = 0; while (!WindowShouldClose()) { @@ -260,6 +337,11 @@ url_enter_button.width = (url_area.width - padding) * 0.1; url_enter_button.height = TEXT_SIZE * 2; + method_dropdown.x = url_enter_button.x + url_enter_button.width + padding; + method_dropdown.y = (url_area.height) / 2; + method_dropdown.width = (url_area.width - padding) * 0.1; + method_dropdown.height = TEXT_SIZE * 2; + // -- Input Area --// input_area.x = (side_bar_x + history_sidebar.width); input_area.y = (side_bar_y + url_area.height); @@ -270,12 +352,8 @@ input_tab.y = (side_bar_y + url_area.height) + padding; input_tab.width = url_area.width * 0.49 - padding; input_tab.height = input_area.height * 0.1; - for (int pos = 0; pos < 4; pos++) - { - input_tab_items[pos].rectangle = input_tab; - input_tab_items[pos].rectangle.x = input_tab.x + (pos * input_tab.width / 4); - input_tab_items[pos].rectangle.width = input_tab.width / 4; - } + input_tab_item = input_tab; + input_tab_item.width = input_tab.width / 4; input_body.x = input_tab.x; input_body.y = input_tab.y + input_tab.height; @@ -302,21 +380,34 @@ // URL area Rect GuiDrawText("URL: ", url_text_bounds, TEXT_ALIGN_CENTER, RED); DrawRectangleRec(url_area, Fade(RED, 0.1f)); - GuiTextBox(url_input_bounds, input_text, 1024 * 4, true); + if (GuiTextBox(url_input_bounds, url_input_text, DEFAULT_TEXT_BUFFER_LENGTH, url_input_bool)) + url_input_bool = !url_input_bool; sendRequest = GuiButton(url_enter_button, "ENTER"); + if (sendRequest) + PostDog_Make_HttpRequest( + url_input_text, + PostDog_Enum_To_String(active_method_dropdown), + url_body_map[0].value, + url_body_map[1].value, + url_result_text, + RESULT_BUFFER_LENGTH + ); + if (GuiDropdownBox(method_dropdown, "GET;POST;PUT;DELETE", &active_method_dropdown, method_edit)) + method_edit = !method_edit; // Input Tabs Rect DrawRectangleRec(input_area, Fade(BLUE, 0.1f)); DrawRectangleRec(input_tab, Fade(DARKBLUE, 0.1f)); - for (int pos = 0; pos < 4; pos++) - { - JUNE_GuiButton(input_tab_items[pos].rectangle, input_tab_items[pos].label, 0, Fade(DARKBLUE, 0.1f)); - } - JUNE_GuiTextBox(input_body, input_text, 1024 * 4, true); + GuiSetStyle(TOGGLE, GROUP_PADDING, 0); + if (JUNE_GuiTextBox(input_body, url_body_map[active_input_tab].value, DEFAULT_TEXT_BUFFER_LENGTH, input_body_bool)) + input_body_bool = !input_body_bool; + GuiToggleGroup(input_tab_item, "Header;Body;Get Param;Bar", &active_input_tab); + PostDog_Update_URL(&url_input_text, url_body_map[TAB_GET_PARAMS].value); // Result Rect DrawRectangleRec(result_area, Fade(GREEN, 0.1f)); DrawRectangleRec(result_body, Fade(DARKGREEN, 0.1f)); + GuiTextBoxMulti(result_body, url_result_text, RESULT_BUFFER_LENGTH, false); EndDrawing(); } CloseWindow();