⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wwwapi.cpp

📁 一个功能强大的内存数据库源代码,c++编写,有详细的注释
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-< WWWAPI.CPP >----------------------------------------------------*--------*// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *// (Main Memory Database Management System)                          *   /\|  *//                                                                   *  /  \  *//                          Created:     27-Mar-99    K.A. Knizhnik  * / [] \ *//                          Last update:  1-Jul-99    K.A. Knizhnik  * GARRET *//-------------------------------------------------------------------*--------*// Implementation of WWWapi class//-------------------------------------------------------------------*--------*#define INSIDE_FASTDB#include "wwwapi.h"#include <ctype.h>const size_t init_reply_buffer_size = 4*1024;inline unsigned string_hash_function(const char* name){     unsigned h = 0, g;    while(*name) { 	h = (h << 4) + *name++;	if ((g = h & 0xF0000000) != 0) { 	    h ^= g >> 24;	}	h &= ~g;    }    return h;}#define ERROR_TEXT(x) \"HTTP/1.1 " x "\r\n\Connection: close\r\n\r\n\<HTML><HEAD><TITLE>Invalid request to the database</TITLE>\r\n\</HEAD><BODY>\n\r\<H1>" x "</H1>\n\r\</BODY></HTML>\r\n\r\n"WWWconnection::WWWconnection(){    memset(hash_table, 0, sizeof hash_table);    sock = NULL;    reply_buf = new char[init_reply_buffer_size];    reply_buf_size = init_reply_buffer_size;    free_pairs = NULL;    peer = NULL;    userData = NULL;}WWWconnection::~WWWconnection(){    reset();    name_value_pair *nvp, *next;    for (nvp = free_pairs; nvp != NULL; nvp = next) { 	next = nvp->next;	delete nvp;    }    delete[] reply_buf;    delete[] peer;}inline char* WWWconnection::extendBuffer(size_t inc){    if (reply_buf_used + inc >= reply_buf_size) { 	reply_buf_size = reply_buf_size*2 > reply_buf_used + inc	    ? reply_buf_size*2 : reply_buf_used + inc;	char* new_buf = new char[reply_buf_size];	memcpy(new_buf, reply_buf, reply_buf_used);	delete[] reply_buf;	reply_buf = new_buf;    }         reply_buf_used += inc;    return reply_buf;}bool WWWconnection::terminatedBy(char const* str) const{    size_t len = strlen(str);    if (len > reply_buf_used - 4) { 	return false;    }    return memcmp(reply_buf + reply_buf_used - len, str, len) == 0;}WWWconnection& WWWconnection::append(char const* str) {    int pos = reply_buf_used;    char* dst = extendBuffer(strlen(str));    unsigned char ch;    switch (encoding) {      case TAG:	strcpy(dst + pos, str);	encoding = HTML;	break;      case HTML:	encoding = TAG;	while (true) { 	    switch(ch = *str++) { 	      case '<':		dst = extendBuffer(3);		dst[pos++] = '&';		dst[pos++] = 'l';		dst[pos++] = 't';		dst[pos++] = ';';		break;	      case '>':		dst = extendBuffer(3);		dst[pos++] = '&';		dst[pos++] = 'g';		dst[pos++] = 't';		dst[pos++] = ';';		break;	      case '&':		dst = extendBuffer(4);		dst[pos++] = '&';		dst[pos++] = 'a';		dst[pos++] = 'm';		dst[pos++] = 'p';		dst[pos++] = ';';		break;	      case '"':		dst = extendBuffer(5);		dst[pos++] = '&';		dst[pos++] = 'q';		dst[pos++] = 'u';		dst[pos++] = 'o';		dst[pos++] = 't';		dst[pos++] = ';';		break;	      case '\0':		dst[pos] = '\0';		return *this;	      default:		dst[pos++] = ch;	    }	}      case URL:	encoding = TAG;	while (true) { 	    ch = *str++;	    if (ch == '\0') { 		dst[pos] = '\0';		return *this;	    } else if (ch == ' ') { 		dst[pos++] = '+';	    } else if (!isalnum(ch)) { 		dst = extendBuffer(2);		dst[pos++] = '%';		dst[pos++] = (ch >> 4) >= 10 		    ? (ch >> 4) + 'A' - 10 : (ch >> 4) + '0';		dst[pos++] = (ch & 0xF) >= 10		    ? (ch & 0xF) + 'A' - 10 : (ch & 0xF) + '0';	    } else { 		dst[pos++] = ch;	    }	}    }    return *this;}void WWWconnection::reset(){    reply_buf_used = 0;    encoding = TAG;    for (int i = items(hash_table); --i >= 0;) { 	name_value_pair *nvp, *next;	for (nvp = hash_table[i]; nvp != NULL; nvp = next) { 	    next = nvp->next;	    nvp->next = free_pairs;	    free_pairs = nvp;	}	hash_table[i] = NULL;    }	    }void WWWconnection::addPair(char const* name, char const* value){    name_value_pair* nvp;    if (free_pairs != NULL) { 	nvp = free_pairs;	free_pairs = nvp->next;    } else { 	nvp = new name_value_pair;    }    unsigned hash_code = string_hash_function(name);    nvp->hash_code = hash_code;    hash_code %= hash_table_size;    nvp->next = hash_table[hash_code];    hash_table[hash_code] = nvp;    nvp->value = value;    nvp->name = name;}char* WWWconnection::unpack(char* body, size_t length){    char *src = body, *end = body + length;    while (src < end) { 	char* name = src;	char ch; 	char* dst = src;	while (src < end && (ch = *src++) != '=') { 	    if (ch == '+') {		ch = ' ';	    } else if (ch == '%') { 		ch = ((src[0] >= 'A' ? src[0] - 'A'+ 10 : src[0] - '0') << 4) |		     (src[1] >= 'A' ? src[1] - 'A'+ 10 : src[1] - '0');		src += 2;	    }	    *dst++ = ch;	}	*dst = '\0';	char* value = dst = src;	while (src < end && (ch = *src++) != '&') { 	    if (ch == '+') {		ch = ' ';	    } else if (ch == '%') { 		ch = ((src[0] >= 'A' ? src[0] - 'A'+ 10 : src[0] - '0') << 4) |		     (src[1] >= 'A' ? src[1] - 'A'+ 10 : src[1] - '0');		src += 2;	    }	    *dst++ = ch;	}	*dst = '\0';	addPair(name, value);    }    stub = get("stub");    return get("page");}char* WWWconnection::get(char const* name, int n){    unsigned hash_code = string_hash_function(name);    name_value_pair* nvp;    for (nvp = hash_table[hash_code % hash_table_size];	 nvp != NULL; 	 nvp = nvp->next)    {	if (nvp->hash_code == hash_code && strcmp(nvp->name, name) == 0) { 	    if (n == 0) { 		return (char*)nvp->value;	    }	    n -= 1;	}    }    return NULL;}    //--------------------------------------------------WWWapi::WWWapi(dbDatabase& dbase, int n_handlers, dispatcher* dispatch_table): db(dbase){    memset(hash_table, 0, sizeof hash_table);    sock = NULL;    address = NULL;    dispatcher* disp = dispatch_table;    while (--n_handlers >= 0) { 	unsigned hash_code = string_hash_function(disp->page);	disp->hash_code = hash_code;	hash_code %= hash_table_size;	disp->collision_chain = hash_table[hash_code];	hash_table[hash_code] = disp;	disp += 1;    }}bool WWWapi::open(char const* socket_address, 		  socket_t::socket_domain domain, 		  int listen_queue){    if (sock != NULL) { 	close();    }    address = new char[strlen(socket_address) + 1];    strcpy(address, socket_address);    sock = domain != socket_t::sock_global_domain 	? socket_t::create_local(socket_address, listen_queue)	: socket_t::create_global(socket_address, listen_queue);    canceled = false;    if (!sock->is_ok()) { 	char buf[64];	sock->get_error_text(buf, sizeof buf);	fprintf(stderr, "WWWapi::open: create socket failed: %s\n", buf);	return false;    }    return true;	}bool WWWapi::connect(WWWconnection& con){    assert(sock != NULL);    con.reset();    delete con.sock;    con.sock = sock->accept();    con.address = address;    if (con.sock == NULL) { 	if (!canceled) { 	    char buf[64];	    sock->get_error_text(buf, sizeof buf);	    fprintf(stderr, "WWWapi::connect: accept failed: %s\n", buf);	}	return false;    }    return true;}void WWWapi::cancel(){    canceled = true;    sock->cancel_accept();}void WWWapi::close(){    delete sock;    delete[] address;    sock = NULL;}bool WWWapi::dispatch(WWWconnection& con, char* page){    unsigned hash_code = string_hash_function(page);    for (dispatcher* disp = hash_table[hash_code % hash_table_size];	 disp != NULL; 	 disp = disp->collision_chain)    {	if (disp->hash_code == hash_code && strcmp(disp->page, page) == 0)	{ 	    bool result = disp->func(con);	    db.commit();	    return result;	}    }    return true;}void URL2ASCII(char* src){    char* dst = src;    char ch;    while ((ch = *src++) != '\0') { 	if (ch == '%') { 	    *dst++ = ((src[0] - '0') << 8) | (src[1] - '0');	} else if (ch == '+') {	    *dst++ = ' ';	} else if (ch == '.' && *src == '.') {	    // for security reasons do not allow access to parent directory	    break;	} else { 	    *dst++ = ch;	}    }    *dst = '\0';}bool CGIapi::serve(WWWconnection& con){    nat4 length;    con.reset();    if ((size_t)con.sock->read(&length, sizeof length, sizeof length) 	!= sizeof(length))     {	return true;    }    int size = length - sizeof length;    char* buf = new char[size];    if (con.sock->read(buf, size, size) != size) {	return true;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -