5
// Michael Hutchinson <mhutchinson@novell.com>
7
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
9
// Permission is hereby granted, free of charge, to any person obtaining
10
// a copy of this software and associated documentation files (the
11
// "Software"), to deal in the Software without restriction, including
12
// without limitation the rights to use, copy, modify, merge, publish,
13
// distribute, sublicense, and/or sell copies of the Software, and to
14
// permit persons to whom the Software is furnished to do so, subject to
15
// the following conditions:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
using System.Collections.Generic;
33
namespace MonoDevelop.Xml.StateEngine
35
public class XmlFreeState : RootState
37
protected const int FREE = 0;
38
protected const int BRACKET = FREE + 1;
39
protected const int BRACKET_EXCLAM = BRACKET + 1;
40
protected const int COMMENT = BRACKET_EXCLAM + 1;
41
protected const int CDATA = COMMENT + 1;
42
protected const int DOCTYPE = CDATA + 1;
43
protected const int MAXCONST = DOCTYPE;
46
XmlClosingTagState closingTagState;
47
XmlCommentState commentState;
48
XmlCDataState cDataState;
49
XmlDocTypeState docTypeState;
50
XmlProcessingInstructionState processingInstructionState;
52
public XmlFreeState () : this (new XmlTagState (), new XmlClosingTagState ()) {}
54
public XmlFreeState (XmlTagState tagState, XmlClosingTagState closingTagState)
55
: this (tagState, closingTagState, new XmlCommentState (), new XmlCDataState (),
56
new XmlDocTypeState (), new XmlProcessingInstructionState ()) {}
60
XmlClosingTagState closingTagState,
61
XmlCommentState commentState,
62
XmlCDataState cDataState,
63
XmlDocTypeState docTypeState,
64
XmlProcessingInstructionState processingInstructionState)
66
this.tagState = tagState;
67
this.closingTagState = closingTagState;
68
this.commentState = commentState;
69
this.cDataState = cDataState;
70
this.docTypeState = docTypeState;
71
this.processingInstructionState = processingInstructionState;
73
Adopt (this.TagState);
74
Adopt (this.ClosingTagState);
75
Adopt (this.CommentState);
76
Adopt (this.CDataState);
77
Adopt (this.DocTypeState);
78
Adopt (this.ProcessingInstructionState);
81
protected XmlTagState TagState {
82
get { return tagState; }
85
protected XmlClosingTagState ClosingTagState {
86
get { return closingTagState; }
89
protected XmlCommentState CommentState {
90
get { return commentState; }
93
protected XmlCDataState CDataState {
94
get { return cDataState; }
97
protected XmlDocTypeState DocTypeState {
98
get { return docTypeState; }
101
protected XmlProcessingInstructionState ProcessingInstructionState {
102
get { return processingInstructionState; }
105
public override State PushChar (char c, IParseContext context, ref string rollback)
108
if (context.StateTag != FREE)
109
context.LogError ("Incomplete tag opening; encountered unexpected '<'.",
110
new MonoDevelop.Projects.Dom.DomRegion (
111
context.LocationMinus (LengthFromOpenBracket (context) + 1),
112
context.LocationMinus (1)));
113
context.StateTag = BRACKET;
117
switch (context.StateTag) {
119
//FIXME: handle entities?
124
rollback = string.Empty;
125
return this.ProcessingInstructionState;
126
} else if (c == '!') {
127
context.StateTag = BRACKET_EXCLAM;
129
} else if (c == '/') {
130
return this.ClosingTagState;
131
} else if (char.IsLetter (c) || c == '_') {
132
rollback = string.Empty;
139
context.StateTag = CDATA;
141
} else if (c == '-') {
142
context.StateTag = COMMENT;
144
} else if (c == 'D') {
145
context.StateTag = DOCTYPE;
156
string cdataStr = "CDATA[";
157
if (c == cdataStr [context.KeywordBuilder.Length]) {
158
context.KeywordBuilder.Append (c);
159
if (context.KeywordBuilder.Length < cdataStr.Length)
164
context.KeywordBuilder.Length = 0;
169
string docTypeStr = "OCTYPE";
170
if (c == docTypeStr [context.KeywordBuilder.Length]) {
171
context.KeywordBuilder.Append (c);
172
if (context.KeywordBuilder.Length < docTypeStr.Length)
177
context.KeywordBuilder.Length = 0;
182
context.LogError ("Incomplete tag opening; encountered unexpected character '" + c + "'.",
183
new MonoDevelop.Projects.Dom.DomRegion (
184
context.LocationMinus (LengthFromOpenBracket (context)),
187
context.StateTag = FREE;
191
static int LengthFromOpenBracket (IParseContext context)
193
switch (context.StateTag) {
202
return 3 + context.KeywordBuilder.Length;
208
public override XDocument CreateDocument ()
210
return new XDocument ();