File:  [parser3project] / parser3 / src / types / pa_vform.h
Revision 1.71: download - view: text, annotated - select for diffs - revision graph
Sat Apr 25 13:38:46 2026 UTC (2 months, 1 week ago) by moko
Branches: MAIN
CVS tags: HEAD
Copyright year updated, websites links changed to https://

/** @file
	Parser: @b form class decls.

	Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
	Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
*/

#ifndef PA_VFORM_H
#define PA_VFORM_H

#define IDENT_PA_VFORM_H "$Id: pa_vform.h,v 1.71 2026/04/25 13:38:46 moko Exp $"

// includes

#include "classes.h"
#include "pa_common.h"
#include "pa_value.h"
#include "pa_vhash.h"

// forwards

class Request_info;
class Request_charsets;

enum POST_CONTENT_TYPE {
	UNKNOWN,
	FORM_URLENCODED,
	MULTIPART_FORMDATA
};

/**
	derivates from VStateless_class so that :CLASS element referred to @a this.

	and users could do such tricks:
	@verbatim
		^rem{pass somebody something with elements}

		^rem{this time that would be elements of a form}
		^somebody[$form:CLASS]

		^rem{this time that would be elements of a table record}
		$news[^table:sql[select * from news]]
		^somebody[^news.record[]]
	@endverbatim
*/
class VForm: public VStateless_class {
public: // Value
	
	const char* type() const { return "form"; }
	
	// form: fields,tables,files,imap,method,field
	Value* get_element(const String& aname);
	Charset* get_body_charset();

	/// form: (field)=value
	override const VJunction* put_element(const String& name, Value* value);

public: // usage

	VForm(Request_charsets& acharsets, Request_info& arequest_info);
	
private:

	Request_charsets& fcharsets;
	Request_info& frequest_info;

	bool can_have_body;
	bool charset_detected;
	POST_CONTENT_TYPE post_content_type;

	char *strpart(const char* str, size_t len);
	char *getAttributeValue(const char* data,const char *attr,size_t len);
	void UnescapeChars(char **sp, const char* cp, size_t len);
	void ParseGetFormInput(const char* query_string, size_t length);
	void ParseFormInput(const char* data, size_t length, Charset* client_charset=0);
	void ParseMimeInput(char *content_type, const char* data, size_t length, Charset* client_charset=0);
	void AppendFormEntry(
		const char* cname_cstr, 
		const char* raw_cvalue_ptr, const size_t raw_cvalue_size, Charset* client_charset=0);
	void AppendFormFileEntry(
		const char* cname_cstr, 
		const char* raw_cvalue_ptr, const size_t raw_cvalue_size,
		const char* file_name_cstr, Charset* client_charset=0);

	bool should_refill_fields_tables_and_files();
	void refill_fields_tables_and_files();

	void detect_post_charset();
private:

	Charset* filled_source;
	Charset* filled_client;
	Charset* fpost_charset; // charset which was specified in content-type in incoming POST

	VHash vfields, vtables, vfiles, vimap, velements;
	HashStringValue &fields, &tables, &files, &imap, &elements;

private:

	String::C transcode(const char* client, size_t client_size, Charset* client_charset=0);

};

#endif

E-mail: