Gridarta Editor
FixedDtdInputStream.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.utils.xml;
21 
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.charset.StandardCharsets;
26 import org.jetbrains.annotations.NotNull;
27 import org.jetbrains.annotations.Nullable;
28 
34 public class FixedDtdInputStream extends InputStream {
35 
39  @NotNull
40  private final InputStream inputStream;
41 
45  @NotNull
46  private final String rootElement;
47 
51  @NotNull
52  private final String systemId;
53 
57  private int state;
58 
63  @Nullable
64  private InputStream inject;
65 
73  public FixedDtdInputStream(@NotNull final InputStream inputStream, @NotNull final String rootElement, @NotNull final String systemId) {
74  this.inputStream = inputStream;
75  this.rootElement = rootElement;
76  this.systemId = systemId;
77  }
78 
79  @Override
80  public int read() throws IOException {
81  if (inject != null) {
82  final int ch = inject.read();
83  if (ch != -1) {
84  return ch;
85  }
86  inject = null;
87  }
88 
89  final int ch = inputStream.read();
90  if (ch == -1) {
91  return -1;
92  }
93 
94  switch (state) {
95  case 0:
96  if (ch == '<') {
97  state = 1;
98  }
99  break;
100 
101  case 1:
102  //noinspection IfCanBeSwitch
103  if (ch == '?') {
104  state = 2;
105  } else if (ch == '!') {
106  state = 4;
107  } else {
108  final String doctypeDeclaration = "DOCTYPE " + rootElement + " SYSTEM \"" + systemId + "\"><" + (char) ch;
109  inject = new ByteArrayInputStream(doctypeDeclaration.getBytes(StandardCharsets.US_ASCII));
110  state = 12;
111  return '!';
112  }
113  break;
114 
115  case 2:
116  if (ch == '?') {
117  state = 3;
118  }
119  break;
120 
121  case 3:
122  if (ch == '>') {
123  state = 0;
124  } else if (ch != '?') {
125  state = 2;
126  }
127  break;
128 
129  case 4:
130  if (ch == 'D') {
131  state = 5;
132  } else {
133  state = 11;
134  }
135  break;
136 
137  case 5:
138  if (ch == 'O') {
139  state = 6;
140  } else {
141  state = 11;
142  }
143  break;
144 
145  case 6:
146  if (ch == 'C') {
147  state = 7;
148  } else {
149  state = 11;
150  }
151  break;
152 
153  case 7:
154  if (ch == 'T') {
155  state = 8;
156  } else {
157  state = 11;
158  }
159  break;
160 
161  case 8:
162  if (ch == 'Y') {
163  state = 9;
164  } else {
165  state = 11;
166  }
167  break;
168 
169  case 9:
170  if (ch == 'P') {
171  state = 10;
172  } else {
173  state = 11;
174  }
175  break;
176 
177  case 10:
178  if (ch == 'E') {
179  state = 12;
180  } else {
181  state = 11;
182  }
183  break;
184 
185  case 11:
186  if (ch == '>') {
187  state = 0;
188  }
189  break;
190 
191  case 12:
192  break;
193  }
194 
195  return ch;
196  }
197 
198 }
InputStream inject
The InputStream that injects the <!DOCTYPE...> declaration.
Injects a <!DOCTYPE...> declaration into an.
final InputStream inputStream
The InputStream that is modified.
FixedDtdInputStream(@NotNull final InputStream inputStream, @NotNull final String rootElement, @NotNull final String systemId)
Creates a new instance.
final String systemId
The system ID for the DOCTYPE declaration.
final String rootElement
The tag name of the root element in the DOCTYPE declaration.