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

📄 imapparser.hpp

📁 MIME解析的代码
💻 HPP
📖 第 1 页 / 共 5 页
字号:
					else					{						++pos;						++len;					}				}			}			if (len != 0)			{				m_value.resize(len);				std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin());				*currentPos = pos;			}			else			{				throw exceptions::invalid_response("", makeResponseLine("text", line, pos));			}		}	private:		string m_value;		const bool m_allow8bits;		const char m_except;	public:		const string& value() const { return (m_value); }	};	class text8 : public text	{	public:		text8() : text(true)		{		}	};	template <char C>	class text_except : public text	{	public:		text_except() : text(false, C)		{		}	};	template <char C>	class text8_except : public text	{	public:		text8_except() : text(true, C)		{		}	};	//	// QUOTED_CHAR     ::= <any TEXT_CHAR except quoted_specials> / "\" quoted_specials	// quoted_specials ::= <"> / "\"	// TEXT_CHAR       ::= <any CHAR except CR and LF>	// CHAR            ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f>	//	class QUOTED_CHAR : public component	{	public:		void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("quoted_char");			string::size_type pos = *currentPos;			const unsigned char c = static_cast <unsigned char>(pos < line.length() ? line[pos] : 0);			if (c >= 0x01 && c <= 0x7f &&   // 0x01 - 0x7f			    c != '"' && c != '\\' &&    // quoted_specials			    c != '\r' && c != '\n')     // CR and LF			{				m_value = c;				*currentPos = pos + 1;			}			else if (c == '\\' && pos + 1 < line.length() &&			         (line[pos + 1] == '"' || line[pos + 1] == '\\'))			{				m_value = line[pos + 1];				*currentPos = pos + 2;			}			else			{				throw exceptions::invalid_response("", makeResponseLine("QUOTED_CHAR", line, pos));			}		}	private:		char m_value;	public:		char value() const { return (m_value); }	};	//	// quoted          ::= <"> *QUOTED_CHAR <">	// QUOTED_CHAR     ::= <any TEXT_CHAR except quoted_specials> / "\" quoted_specials	// quoted_specials ::= <"> / "\"	// TEXT_CHAR       ::= <any CHAR except CR and LF>	// CHAR            ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f>	//	class quoted_text : public component	{	public:		void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("quoted_text");			string::size_type pos = *currentPos;			string::size_type len = 0;			bool valid = false;			m_value.reserve(line.length() - pos);			for (bool end = false, quoted = false ; !end && pos < line.length() ; )			{				const unsigned char c = line[pos];				if (quoted)				{					if (c == '"' || c == '\\')						m_value += c;					else					{						m_value += '\\';						m_value += c;					}					quoted = false;					++pos;					++len;				}				else				{					if (c == '\\')					{						quoted = true;						++pos;						++len;					}					else if (c == '"')					{						valid = true;						end = true;					}					else if (c >= 0x01 && c <= 0x7f &&  // CHAR					         c != 0x0a && c != 0x0d)    // CR and LF					{						m_value += c;						++pos;						++len;					}					else					{						valid = false;						end = true;					}				}			}			if (valid)			{				*currentPos = pos;			}			else			{				throw exceptions::invalid_response("", makeResponseLine("quoted_text", line, pos));			}		}	private:		string m_value;	public:		const string& value() const { return (m_value); }	};	//	// nil  ::= "NIL"	//	class NIL : public component	{	public:		void go(IMAPParser& parser, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("NIL");			string::size_type pos = *currentPos;			parser.checkWithArg <special_atom>(line, &pos, "nil");			*currentPos = pos;		}	};	//	// string          ::= quoted / literal    ----> named 'xstring'	//	// nil             ::= "NIL"	// quoted          ::= <"> *QUOTED_CHAR <">	// QUOTED_CHAR     ::= <any TEXT_CHAR except quoted_specials> / "\" quoted_specials	// quoted_specials ::= <"> / "\"	// TEXT_CHAR       ::= <any CHAR except CR and LF>	// CHAR            ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f>	// literal         ::= "{" number "}" CRLF *CHAR8	//                     ;; Number represents the number of CHAR8 octets	// CHAR8           ::= <any 8-bit octet except NUL, 0x01 - 0xff>	//	class xstring : public component	{	public:		xstring(const bool canBeNIL = false, component* comp = NULL, const int data = 0)			: m_canBeNIL(canBeNIL), m_component(comp), m_data(data)		{		}		void go(IMAPParser& parser, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("string");			string::size_type pos = *currentPos;			if (m_canBeNIL &&			    parser.checkWithArg <special_atom>(line, &pos, "nil", true))			{				// NIL			}			else			{				pos = *currentPos;				// quoted ::= <"> *QUOTED_CHAR <">				if (parser.check <one_char <'"'> >(line, &pos, true))				{					utility::auto_ptr <quoted_text> text(parser.get <quoted_text>(line, &pos));					parser.check <one_char <'"'> >(line, &pos);					if (parser.m_literalHandler != NULL)					{						literalHandler::target* target =							parser.m_literalHandler->targetFor(*m_component, m_data);						if (target != NULL)						{							m_value = "[literal-handler]";							const string::size_type length = text->value().length();							utility::progressListener* progress = target->progressListener();							if (progress)							{								progress->start(length);							}							target->putData(text->value());							if (progress)							{								progress->progress(length, length);								progress->stop(length);							}							delete (target);						}						else						{							m_value = text->value();						}					}					else					{						m_value = text->value();					}					DEBUG_FOUND("string[quoted]", "<length=" << m_value.length() << ", value='" << m_value << "'>");				}				// literal ::= "{" number "}" CRLF *CHAR8				else				{					parser.check <one_char <'{'> >(line, &pos);					number* num = parser.get <number>(line, &pos);					const string::size_type length = num->value();					delete (num);					parser.check <one_char <'}'> >(line, &pos);					parser.check <CRLF>(line, &pos);					if (parser.m_literalHandler != NULL)					{						literalHandler::target* target =							parser.m_literalHandler->targetFor(*m_component, m_data);						if (target != NULL)						{							m_value = "[literal-handler]";							parser.m_progress = target->progressListener();							parser.readLiteral(*target, length);							parser.m_progress = NULL;							delete (target);						}						else						{							literalHandler::targetString target(NULL, m_value);							parser.readLiteral(target, length);						}					}					else					{						literalHandler::targetString target(NULL, m_value);						parser.readLiteral(target, length);					}					line += parser.readLine();					DEBUG_FOUND("string[literal]", "<length=" << length << ", value='" << m_value << "'>");				}			}			*currentPos = pos;		}	private:		bool m_canBeNIL;		string m_value;		component* m_component;		const int m_data;	public:		const string& value() const { return (m_value); }	};	//	// nstring         ::= string / nil	//	class nstring : public xstring	{	public:		nstring(component* comp = NULL, const int data = 0)			: xstring(true, comp, data)		{		}	};	//	// astring ::= atom / string	//	class astring : public component	{	public:		void go(IMAPParser& parser, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("astring");			string::size_type pos = *currentPos;			xstring* str = NULL;			if ((str = parser.get <xstring>(line, &pos, true)))			{				m_value = str->value();				delete (str);			}			else			{				atom* at = parser.get <atom>(line, &pos);				m_value = at->value();				delete (at);			}			*currentPos = pos;		}	private:		string m_value;	public:		const string& value() const { return (m_value); }	};	//	// atom            ::= 1*ATOM_CHAR	//	// ATOM_CHAR       ::= <any CHAR except atom_specials>	// atom_specials   ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / quoted_specials	// CHAR            ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f>	// CTL             ::= <any ASCII control character and DEL, 0x00 - 0x1f, 0x7f>	// list_wildcards  ::= "%" / "*"	// quoted_specials ::= <"> / "\"	// SPACE           ::= <ASCII SP, space, 0x20>	//	class atom : public component	{	public:		void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("atom");			string::size_type pos = *currentPos;			string::size_type len = 0;			for (bool end = false ; !end && pos < line.length() ; )			{				const unsigned char c = line[pos];				switch (c)				{				case '(':				case ')':				case '{':				case 0x20:  // SPACE				case '%':   // list_wildcards				case '*':   // list_wildcards				case '"':   // quoted_specials				case '\\':  // quoted_specials				case '[':				case ']':   // for "special_atom"					end = true;					break;				default:					if (c <= 0x1f || c >= 0x7f)						end = true;					else					{						++pos;						++len;					}				}			}			if (len != 0)			{				m_value.resize(len);				std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin());				*currentPos = pos;			}			else			{				throw exceptions::invalid_response("", makeResponseLine("atom", line, pos));			}		}	private:		string m_value;	public:		const string& value() const { return (m_value); }	};	//	// special atom (eg. "CAPABILITY", "FLAGS", "STATUS"...)	//	//  " Except as noted otherwise, all alphabetic characters are case-	//    insensitive. The use of upper or lower case characters to define	//    token strings is for editorial clarity only. Implementations MUST	//    accept these strings in a case-insensitive fashion. "	//	class special_atom : public atom	{	public:		special_atom(const char* str)			: m_string(str)   // 'string' must be in lower-case		{		}		void go(IMAPParser& parser, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT(string("special_atom(") + m_string + ")");			string::size_type pos = *currentPos;			atom::go(parser, line, &pos);			const char* cmp = value().c_str();			const char* with = m_string;			bool ok = true;			while (ok && *cmp && *with)			{				ok = (std::tolower(*cmp, std::locale()) == *with);				++cmp;				++with;			}			if (!ok || *cmp || *with)			{				throw exceptions::invalid_response("", makeResponseLine(string("special_atom <") + m_string + ">", line, pos));			}			else			{				*currentPos = pos;			}		}	private:		const char* m_string;	};	//	// text_mime2 ::= "=?" <charset> "?" <encoding> "?" <encoded-text> "?="	//                ;; Syntax defined in [MIME-HDRS]	//	class text_mime2 : public component	{	public:		void go(IMAPParser& parser, string& line, string::size_type* currentPos)		{			DEBUG_ENTER_COMPONENT("text_mime2");			string::size_type pos = *currentPos;			atom* theCharset = NULL, *theEncoding = NULL;			text* theText = NULL;			try			{				parser.check <one_char <'='> >(line, &pos);				parser.check <one_char <'?'> >(line, &pos);				theCharset = parser.get <atom>(line, &pos);				parser.check <one_char <'?'> >(line, &pos);				theEncoding = parser.get <atom>(line, &pos);				parser.check <one_char <'?'> >(line, &pos);				theText = parser.get <text8_except <'?'> >(line, &pos);				parser.check <one_char <'?'> >(line, &pos);				parser.check <one_char <'='> >(line, &pos);			}			catch (std::exception& e)			{				delete (theCharset);				delete (theEncoding);				delete (theText);				throw;			}			m_charset = theCharset->value();			delete (theCharset);			// Decode text			utility::encoder::encoder* theEncoder = NULL;			if (theEncoding->value()[0] == 'q' || theEncoding->value()[0] == 'Q')			{				// Quoted-printable				theEncoder = new utility::encoder::qpEncoder();				theEncoder->getProperties()["rfc2047"] = true;			}			else if (theEncoding->value()[0] == 'b' || theEncoding->value()[0] == 'B')			{				// Base64

⌨️ 快捷键说明

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