Encode query with C
From WABI
Contents |
Summary
Result may not be able to be retrieved normally, if query including non alphanumeric character is used with C.
Description
You have to encode your query. If qPath is a query to be encoded, please do as follows.
int replaceChar(unsigned char c){
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') || c == '@' || c == '*' ||
c == '-' || c == '.' || c == '_') return 0;
return 1;
}
void URLEncode(unsigned char *input, unsigned char *output) {
const unsigned char chars[] = "0123456789ABCDEF";
while (*input != '\0') {
if (replaceChar(*input)) {
*output++ = '%';
*output++ = chars[*input >> 4];
*output++ = chars[*input & 0x0F];
} else {
*output++ = *input;
}
input++;
}
*output = '\0';
}
int main(){
char qPath[] = "/ENTRY/DDBJ/feature-table/feature/f_key=='rRNA' AND (/ENTRY/DDBJ/feature-table/feature{/f_key=='rRNA' AND /f_quals/qualifier{/q_name=='product' AND /q_value='16S ribosomal RNA'}}) ";
char encodedQpath[500];
URLEncode(qPath,encodedQpath);
}
Sample program
Following is a sample code that search entries with the condition of Feature Key is 'rRNA', Qualifier name is 'product' and Qualifier value is '16S ribosomal RNA' by using ARSA searchByXMLPath method.
Download this program
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h> /* snprintf */
#include <ctype.h> /* isalnum */
#define MAX_CONTENT_LENGTH 4096
#define WHITE_SPACE ' '
#define MINUS '-'
#define UNDERBAR '_'
#define PERIOD '.'
#define BUF_LEN 256
int replaceChar(unsigned char c){
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') || c == '@' || c == '*' ||
c == '-' || c == '.' || c == '_') return 0;
return 1;
}
void URLEncode(unsigned char *input, unsigned char *output) {
const unsigned char chars[] = "0123456789ABCDEF";
while (*input != '\0') {
if (replaceChar(*input)) {
*output++ = '%';
*output++ = chars[*input >> 4];
*output++ = chars[*input & 0x0F];
} else {
*output++ = *input;
}
input++;
}
*output = '\0';
}
int main(){
int s;
struct hostent *servhost;
struct sockaddr_in server;
struct servent *service;
char send_buf[MAX_CONTENT_LENGTH * 3 + 1];
//host name
char host[] = "xml.nig.ac.jp";
//path
char path[] = "/rest/Invoke";
//port number
unsigned short port = 80;
char query[MAX_CONTENT_LENGTH] = "service=ARSA&method=searchByXMLPath&queryPath=";
char encodedQpath[MAX_CONTENT_LENGTH * 3 + 1];
char encodedRpath[MAX_CONTENT_LENGTH * 3 + 1];
char qPath[] = "/ENTRY/DDBJ/feature-table/feature/f_key=='rRNA' AND (/ENTRY/DDBJ/feature-table/feature{/f_key=='rRNA' AND /f_quals/qualifier{/q_name=='product' AND /q_value='16S ribosomal RNA'}}) ";
char rPath[] = "/ENTRY/DDBJ/primary-accession,/ENTRY/DDBJ/definition";
char offset[5] = "1";
char limit[5] = "10";
URLEncode(qPath,encodedQpath);
URLEncode(rPath,encodedRpath);
strcat(query,encodedQpath);
strcat(query,"&returnPath=");
strcat(query,encodedRpath);
strcat(query,"&offset=");
strcat(query,offset);
strcat(query,"&count=");
strcat(query,limit);
//get IP adddres from host
servhost = gethostbyname(host);
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
bcopy(servhost->h_addr, &server.sin_addr, servhost->h_length);
server.sin_port = htons(port);
//make socket
s = socket(AF_INET, SOCK_STREAM, 0);
//make connection
connect(s, (struct sockaddr *)&server, sizeof(server));
//send data
sprintf(send_buf, "POST %s HTTP/1.0\n", path);
write(s, send_buf, strlen(send_buf));
sprintf(send_buf, "Host: %s:%d\n", host, port);
write(s, send_buf, strlen(send_buf));
sprintf(send_buf, "User-Agent: c/socket\n");
write(s, send_buf, strlen(send_buf));
sprintf(send_buf, "Content-Type: application/x-www-form-urlencoded\n");
write(s, send_buf, strlen(send_buf));
sprintf(send_buf, "Content-Length: %d \n\n", strlen(query));
write(s, send_buf, strlen(send_buf));
sprintf(send_buf, "%s", query);
write(s, send_buf, strlen(send_buf));
//get your result
while (1){
char buf[BUF_LEN];
int read_size;
read_size = read(s, buf, BUF_LEN);
if ( read_size > 0 ){
write(1, buf, read_size);
} else {
break;
}
}
close(s);
return 0;
}
