Шаг 13 - Разработка класса CGIContent

Код получения параметров во многих скриптах CGI одинаков и кочует от одного скрипта к другому практически без изменений. Поэтому стоит написать библиотеку классов для работы с CGI и подключать ее при разработке нового скрипта.

Прежде чем разработать какую-либо программу надо поставить себе цель, поэтому давайте ее наметим. Естественно самое главное, что должны обеспечивать классы - это простоту работы с ними. Потом любой скрипт должен уметь получать данные большого размера, при этом обеспечивая их удобное размещение в памяти и маленький размер.

До сих пор мы просто выделяли кусок памяти и целиком помещали в него все переданные данные. Из-за этого при передаче огромного количества данных скрипт мог зависнуть. Кроме того наши данные никогда не декодировались и хранились закодированными, что сильно тратило нашу память и содержимое параметров могло занимать в три раза больше, чем на самом деле.

Первое, что нам потребуется для разработки нашего класса - это класс для хранения больших объемов данных. Самым простым способом хранения помоему является список. Поэтому создадим класс CGIContentItem, который будет элементом списка управляемого классом CGIContent:

class CGIContent;

class CGIContentItem{
friend CGIContent;
	char *Content;
	CGIContentItem *Next;
public:
	CGIContentItem();
	~CGIContentItem();
};
Простой элемент списка у нас будет содержать текстовую строку Content и указывать на следующий элемент. Реализация деструктора и конструктора тоже просты:
CGIContentItem::CGIContentItem(){
	Content=NULL;
	Next=NULL;
};

CGIContentItem::~CGIContentItem(){
	if (Content!=NULL) free(Content);
	if (Next!=NULL) delete Next;
};
Для всех классов элементы нашей ячейки скрыты, поэтому класс CGIContent, который является управляющей оболочкой для списка описан как дружественный.

Теперь требуется реализовать сам этот класс, чтобы получить полнофункциональный список со всякими возможностями.

class CGIContent{
public:
	CGIContentItem *Content;
	CGIContent();
	~CGIContent();
	CGIContentItem* Add(char *Buffer);
	int Write(FILE *f_out);
};
Самое главное в списке это указатель на его начало, эту функцию у нас выполняет указатель Content. Для начала нам потребуется только функция добавления в список Add() и вывода Write(). Для возможности вывода содержимого списка в любое место в функции Write() надо использовать указатель типа FILE, вместо которого можно будет поставлять поток stdout или любой другой открытый файл. Вот реализация методов этого класса:
CGIContent::CGIContent(){
	Content=NULL;
};

CGIContent::~CGIContent(){
	if (Content!=NULL) delete Content;
};

CGIContentItem* CGIContent::Add(char *Buffer){
	CGIContentItem *temp,*p;

	temp=new CGIContentItem();
	temp->Content=strdup(Buffer);

	if (Content==NULL){
		Content=temp;
	} else {
		p=Content;
		while (p->Next!=NULL) p=p->Next;
		p->Next=temp;
	};
	return temp;
};

int CGIContent::Write(FILE *f_out){
	CGIContentItem *temp=Content;
	while (temp!=NULL){
		fprintf(f_out,"%s",temp->Content);
		temp=temp->Next;
	};
	return 0;
};

Теперь у нас готов полнофункциональный класс способный хранить в себе большие массивы информации.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Кузин Андрей.