Encode query with C

From WABI

Jump to: navigation, search

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;
}

Link

Japanese page

Personal tools