1 /*
2 ** Copyright 2002, Double Precision Inc.
3 **
4 ** See COPYING for distribution information.
5 */
6 #include "libmail_config.h"
7 #include "imap.H"
8 #include "imapparsefmt.H"
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 
13 using namespace std;
14 
15 /////////////////////////////////////////////////////////////////////////
16 //
17 // Parse a structured IMAP reply
18 
imapparsefmt()19 mail::imapparsefmt::imapparsefmt()
20 	: current(NULL), nil(false), value(""), parent(NULL)
21 {
22 }
23 
imapparsefmt(mail::imapparsefmt * parentArg)24 mail::imapparsefmt::imapparsefmt(mail::imapparsefmt *parentArg)
25 	: current(NULL), nil(false), value(""), parent(parentArg)
26 {
27 	parent->children.push_back(this);
28 }
29 
imapparsefmt(const mail::imapparsefmt & cpy)30 mail::imapparsefmt::imapparsefmt(const mail::imapparsefmt &cpy)
31 	: current(NULL), nil(false), value(""), parent(NULL)
32 {
33 	try {
34 		(*this)=cpy;
35 	} catch (...)
36 	{
37 		destroy();
38 		children.clear();
39 		LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
40 	}
41 }
42 
~imapparsefmt()43 mail::imapparsefmt::~imapparsefmt()
44 {
45 	destroy();
46 }
47 
48 mail::imapparsefmt &mail::imapparsefmt
49 ::operator=(const mail::imapparsefmt &cpy)
50 {
51 	destroy();
52 	children.clear();
53 
54 	current=cpy.current;
55 	nil=cpy.nil;
56 	value=cpy.value;
57 	parent=cpy.parent;
58 
59 	vector<mail::imapparsefmt *>::const_iterator b=cpy.children.begin(),
60 		e=cpy.children.end();
61 
62 	while (b != e)
63 	{
64 		mail::imapparsefmt *ptr=new mail::imapparsefmt(**b);
65 
66 		if (!ptr)
67 			LIBMAIL_THROW("Out of memory.");
68 
69 		try {
70 			ptr->parent=this;
71 			children.push_back(ptr);
catch(...)72 		} catch (...)
73 		{
74 			delete ptr;
75 			LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
76 		}
77 		b++;
78 	}
79 	return *this;
80 }
81 
destroy()82 void mail::imapparsefmt::destroy()
83 {
84 	vector<mail::imapparsefmt *>::iterator b=children.begin(),
85 		e=children.end();
86 
87 	while (b != e)
88 	{
89 		delete *b;
90 		b++;
91 	}
92 }
93 
process(mail::imap & imapAccount,mail::imapHandlerStructured::Token & t,bool & parse_error)94 bool mail::imapparsefmt::process(mail::imap &imapAccount,
95 				 mail::imapHandlerStructured::Token &t,
96 				 bool &parse_error)
97 {
98 	parse_error=false;
99 	if (current == NULL)	// Start of tree.
100 	{
101 		if (t == mail::imapHandlerStructured::NIL)
102 		{
103 			nil=1;
104 			return true;
105 		}
106 
107 		if (t == mail::imapHandlerStructured::ATOM ||
108 		    t == mail::imapHandlerStructured::STRING)
109 		{
110 			value=t.text;
111 			return true;
112 		}
113 		if (t != '(')
114 		{
115 			parse_error=true;
116 			return true;
117 		}
118 
119 		current=this;
120 		return false;
121 	}
122 
123 	if (t == ')')
124 	{
125 		current=current->parent;
126 		return (current == NULL);
127 	}
128 
129 	mail::imapparsefmt *child=new mail::imapparsefmt(current);
130 
131 	if (t == mail::imapHandlerStructured::NIL)
132 	{
133 		child->nil=1;
134 		return false;
135 	}
136 
137 	if (t == mail::imapHandlerStructured::ATOM ||
138 	    t == mail::imapHandlerStructured::STRING)
139 	{
140 		child->value=t.text;
141 		return false;
142 	}
143 
144 	if (t != '(')
145 	{
146 		parse_error=1;
147 		return true;
148 	}
149 
150 	current=child;
151 	return false;
152 }
153