diff options
Diffstat (limited to 'tcp.c')
-rw-r--r-- | tcp.c | 103 |
1 files changed, 93 insertions, 10 deletions
@@ -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); |