From 9f245a3f79cadc6fd1e4bf7d06fc7c9feaa7a2b6 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sat, 13 Apr 2019 23:25:02 -0500 Subject: [PATCH] Parse and display the list of disks. --- diskbrowser.c | 69 ++++++++++++++++++++++++++++++++++++++++++------- diskbrowser.rez | 2 +- httptest.c | 12 ++++++++- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/diskbrowser.c b/diskbrowser.c index 802599b..ef7bee8 100644 --- a/diskbrowser.c +++ b/diskbrowser.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -22,6 +24,8 @@ #include "http.h" #include "readtcp.h" #include "tcpconnection.h" +#include "json.h" +#include "jsonutil.h" static char menuTitle[] = "\pArchive.org Disk Browser\xC9"; static char windowTitle[] = "\p Archive.org Disk Browser "; @@ -63,10 +67,13 @@ boolean gsDisksOnly = true; struct diskListEntry { char *memPtr; Byte memFlag; + char *idPtr; }; struct diskListEntry diskList[DISK_LIST_LENGTH]; +int diskListPos = 0; + static struct MountURLRec mountURLRec = {sizeof(struct MountURLRec)}; Session sess = {0}; @@ -75,6 +82,11 @@ Session sess = {0}; /* See Prog. Ref. for System 6.0, page 20. */ static NDASysWindRecord sysWindRecord; +/* Buffer for data received from network */ +char *netBuf = NULL; + +json_value *json = NULL; + void InstallMenuItem(void) { static MenuItemTemplate menuItem = { /* .version = */ 0x8000, /* show dividing line */ @@ -127,6 +139,14 @@ void CloseBrowserWindow(void) { CloseResourceFile(resourceFileID); resourceFileOpened = false; } + + free(netBuf); + netBuf = NULL; + + if (json) { + json_value_free(json); + json = NULL; + } } #pragma databank 0 @@ -162,11 +182,28 @@ boolean DoLEEdit (int editAction) { return ((id == searchLine) || (id == pageNumberLine)); } +boolean processDoc(json_value *docObj) { + if (diskListPos >= DISK_LIST_LENGTH) + return false; + + if (docObj == NULL || docObj->type != json_object) + return false; + json_value *id = findEntryInObject(docObj, "identifier", json_string); + json_value *title = findEntryInObject(docObj, "title", json_string); + if (id == NULL || title == NULL) + return true; + diskList[diskListPos].idPtr = id->u.string.ptr; + diskList[diskListPos++].memPtr = title->u.string.ptr; + return true; +} + /* Do a search */ void DoSearch(void) { static char searchURL[] = "http://archive.org/advancedsearch.php?q=emulator%3Aapple3&fl%5B%5D=identifier&fl%5B%5D=title&rows=3&page=1&output=json"; enum NetDiskError result; + WaitCursor(); + result = SetURL(&sess, searchURL, FALSE, FALSE); //TODO enable this once we have real code to build the URL //if (result != OPERATION_SUCCESSFUL) @@ -180,26 +217,38 @@ void DoSearch(void) { if (sess.contentLength == 0 || sess.contentLength > 0xffff) sess.contentLength = 0xffff; - char *buf = malloc(sess.contentLength + 1); - if (buf == NULL) + free(netBuf); + netBuf = malloc(sess.contentLength + 1); + if (netBuf == NULL) goto errorReturn; - InitReadTCP(&sess, sess.contentLength, buf); + InitReadTCP(&sess, sess.contentLength, netBuf); while (TryReadTCP(&sess) == rsWaiting) /* keep reading */ ; - *(buf + (sess.contentLength - sess.readCount)) = 0; + sess.contentLength -= sess.readCount; + *(netBuf + (sess.contentLength)) = 0; - //TODO + json = json_parse(netBuf, sess.contentLength); + if (json == NULL) + goto errorReturn; + + json_value *response = findEntryInObject(json, "response", json_object); + if (response == NULL) + goto errorReturn; + + diskListPos = 0; + json_value *docs = findEntryInObject(response, "docs", json_array); + processArray(docs, json_object, processDoc); + for (int i = 0; i < DISK_LIST_LENGTH; i++) { - diskList[i].memPtr = buf; diskList[i].memFlag = 0; } - + /* Update state of controls once disk list is available */ CtlRecHndl disksListHandle = GetCtlHandleFromID(window, disksList); HiliteControl(noHilite, disksListHandle); NewList2(NULL, 1, (Ref) diskList, refIsPointer, - DISK_LIST_LENGTH, (Handle)disksListHandle); + diskListPos, (Handle)disksListHandle); SetCtlMoreFlags( GetCtlMoreFlags(disksListHandle) | fCtlCanBeTarget | fCtlWantEvents, @@ -213,12 +262,14 @@ void DoSearch(void) { ShowControl(GetCtlHandleFromID(window, nextPageButton)); EndTCPConnection(&sess); + InitCursor(); return; errorReturn: EndTCPConnection(&sess); + InitCursor(); // TODO show error message - //SysBeep(); + SysBeep(); } /* Handle an event after TaskMasterDA processing */ diff --git a/diskbrowser.rez b/diskbrowser.rez index 42f5db4..6f1a91d 100644 --- a/diskbrowser.rez +++ b/diskbrowser.rez @@ -133,7 +133,7 @@ resource rControlTemplate (disksList) { $0000, /* List Type */ 0, /* List Start */ 10, /* ListMemHeight */ - 5, /* List Mem Size */ + 9, /* List Mem Size */ 0, /* List Ref */ 0 /* Color Ref */ }}; diff --git a/httptest.c b/httptest.c index 0e8d2ec..83ad8cf 100644 --- a/httptest.c +++ b/httptest.c @@ -70,7 +70,17 @@ int main(int argc, char **argv) { while (TryReadTCP(&sess) == rsWaiting) /* keep reading */ ; - printf("Read %lu bytes\n", sess.contentLength - sess.readCount); + //printf("sess.contentLength = %lu\n", sess.contentLength); + //printf("sess.readCount = %lu\n", sess.readCount); + + sess.contentLength -= sess.readCount; + + printf("Read %lu bytes:\n", sess.contentLength); + + for (unsigned long i = 0; i < sess.contentLength; i++) { + putchar(buf[i]); + } + putchar('\n'); cleanup: EndTCPConnection(&sess);