summaryrefslogtreecommitdiff
path: root/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c103
1 files changed, 93 insertions, 10 deletions
diff --git a/tcp.c b/tcp.c
index 65da79d..8ed6060 100644
--- a/tcp.c
+++ b/tcp.c
@@ -123,15 +123,7 @@ i64 tcp_read_ok(int sock,const char *tag){
return success?0:-1;
}
-TcpList* tcp_read_list(int sock,const char *tag){
- char *buf=NULL;
- i64 bufsz=0;
- i64 ret=tcp_read_line(sock,&buf,&bufsz);
- if(ret==-1){
- if(buf!=NULL)free(buf);
- return NULL;
- }
-
+static TcpList* interpret_list(char *buf,const char *tag){
char *walker=buf;
char *word1=strsep(&walker," ");
char *word2=strsep(&walker," ");
@@ -144,7 +136,7 @@ TcpList* tcp_read_list(int sock,const char *tag){
return NULL;
}
char *endp;
- i64 word3i=strtol(word3,&endp,10);
+ i64 word3i=strtoll(word3,&endp,10);
if(word3[0]=='\0'||*endp!='\0'||word3i!=nitems){
free(buf);
return NULL;
@@ -161,12 +153,103 @@ TcpList* tcp_read_list(int sock,const char *tag){
return list;
}
+TcpList* tcp_read_list(int sock,const char *tag){
+ char *buf=NULL;
+ i64 bufsz=0;
+ i64 ret=tcp_read_line(sock,&buf,&bufsz);
+ if(ret==-1){
+ if(buf!=NULL)free(buf);
+ return NULL;
+ }
+
+ TcpList *list=interpret_list(buf,tag);
+ free(buf);
+ return list;
+}
+
void tcp_list_destroy(TcpList *list){
free(list->items);
free(list);
}
+TcpResponse* tcp_read_response(int sock,const char *tag){
+ char *buf=NULL;
+ i64 bufsz=0;
+ i64 ret=tcp_read_line(sock,&buf,&bufsz);
+ if(ret==-1){
+ if(buf!=NULL)free(buf);
+ return NULL;
+ }
+
+ char *walker=buf;
+ char *word1=strsep(&walker," ");
+ char *word2=strsep(&walker," ");
+ if(word1==NULL||word2==NULL||strcmp(word2,tag)!=0){
+ free(buf);
+ return NULL;
+ }
+
+ TcpResponseType type;
+ i64 intvalue;
+ TcpList *listvalue=NULL;
+ char *errorvalue=NULL;
+ if(strcmp(word1,"ok")==0&&walker==NULL){
+ type=TCP_OK;
+ } else if(strcmp(word1,"error")==0){
+ type=TCP_ERROR;
+ if(walker==NULL){
+ free(buf);
+ return NULL;
+ }
+ errorvalue=walker;
+ } else if(strcmp(word1,"int")==0){
+ type=TCP_INT;
+ char *token=strsep(&walker," ");
+ if(walker!=NULL||token==NULL){
+ free(buf);
+ return NULL;
+ }
+ char *endp;
+ intvalue=strtoll(token,&endp,10);
+ if(token[0]=='\0'||*endp!='\0'){
+ free(buf);
+ return NULL;
+ }
+ } else if(strcmp(word1,"list")==0){
+ type=TCP_LIST;
+ listvalue=interpret_list(buf,tag);
+ if(listvalue==NULL){
+ free(buf);
+ return NULL;
+ }
+ } else {
+ free(buf);
+ return NULL;
+ }
+
+ TcpResponse *res=malloc(1,TcpResponse);
+ res->type=type;
+ switch(type){
+ case TCP_OK: break;
+ case TCP_ERROR: res->eval=errorvalue; break;
+ case TCP_INT: res->ival=intvalue; break;
+ case TCP_LIST: res->lval=listvalue; break;
+ }
+ return res;
+}
+
+void tcp_response_destroy(TcpResponse *res){
+ switch(res->type){
+ case TCP_OK: break;
+ case TCP_ERROR: free(res->eval); break;
+ case TCP_INT: break;
+ case TCP_LIST: tcp_list_destroy(res->lval); break;
+ }
+ free(res);
+}
+
+
static const char* itoa(int n){
static char buf[64];
sprintf(buf,"%d",n);