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