Add cleaning for reverse, underline, and italic formatting.
[xudocci.git] / src / main / java / net / pterodactylus / irc / util / MessageCleaner.java
1 /*
2  * XdccDownloader - MessageCleaner.java - Copyright © 2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.irc.util;
19
20 import static net.pterodactylus.irc.util.MessageCleaner.Attributes.italics;
21 import static net.pterodactylus.irc.util.MessageCleaner.Attributes.reverse;
22 import static net.pterodactylus.irc.util.MessageCleaner.Attributes.underline;
23
24 import java.io.IOException;
25 import java.io.StringReader;
26 import java.util.EnumSet;
27 import java.util.Set;
28
29 /**
30  * Removes formatting codes from IRC messages.
31  *
32  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
33  */
34 public class MessageCleaner {
35
36         /** The kind of attributes to clear. */
37         public enum Attributes {
38
39                 bold,
40                 color,
41                 clear,
42                 reverse,
43                 underline,
44                 italics
45
46         }
47
48         /** A default instance. */
49         private static final MessageCleaner DEFAULT_INSTANCE = new MessageCleaner();
50
51         /**
52          * Cleans all formatting from the given line.
53          *
54          * @param line
55          *              The line to remove all formatting from
56          * @return The given line with all formatting removed
57          */
58         public String clean(String line) {
59                 return clean(line, EnumSet.allOf(Attributes.class));
60         }
61
62         /**
63          * Cleans the given formattings from the given line.
64          *
65          * @param line
66          *              The line to remove all formatting from
67          * @param attributes
68          *              The attributes to remove
69          * @return The given line with all given formatting removed
70          */
71         public String clean(String line, Set<Attributes> attributes) {
72                 StringBuilder clean = new StringBuilder(line.length());
73
74                 StringReader reader = new StringReader(line);
75
76                 try {
77                         int inColorCode = 0;
78                         while (true) {
79                                 int r = reader.read();
80                                 if (r == -1) {
81                                         break;
82                                 }
83                                 char c = (char) r;
84                                 if ((c == 2) && (attributes.contains(Attributes.bold))) {
85                                         continue;
86                                 }
87                                 if ((c == 3) && (attributes.contains(Attributes.color))) {
88                                         inColorCode = 1;
89                                         continue;
90                                 }
91                                 if ((c == 15) && (attributes.contains(Attributes.clear))) {
92                                         continue;
93                                 }
94                                 if ((c == 22) && attributes.contains(reverse)) {
95                                         continue;
96                                 }
97                                 if ((c == 29) && attributes.contains(italics)) {
98                                         continue;
99                                 }
100                                 if ((c == 31) && attributes.contains(underline)) {
101                                         continue;
102                                 }
103                                 if (inColorCode > 0) {
104                                         if (inColorCode == 1) {
105                                                 if ((c < '0') || (c > '9')) {
106                                                         inColorCode = 0;
107                                                 } else {
108                                                         if (c == '9') {
109                                                                 inColorCode = 8;
110                                                         } else {
111                                                                 ++inColorCode;
112                                                         }
113                                                         continue;
114                                                 }
115                                         } else if (inColorCode == 2) {
116                                                 if (c == ',') {
117                                                         inColorCode = 4;
118                                                         continue;
119                                                 }
120                                                 if ((c < '0') || (c > '5')) {
121                                                         inColorCode = 0;
122                                                 } else {
123                                                         ++inColorCode;
124                                                         continue;
125                                                 }
126                                         } else if (inColorCode == 3) {
127                                                 if (c == ',') {
128                                                         ++inColorCode;
129                                                         continue;
130                                                 } else {
131                                                         inColorCode = 0;
132                                                 }
133                                         } else if (inColorCode == 4) {
134                                                 if (c == '9') {
135                                                         inColorCode = 9;
136                                                         continue;
137                                                 } else if ((c < '0') || (c > '9')) {
138                                                         inColorCode = 0;
139                                                 } else {
140                                                         ++inColorCode;
141                                                         continue;
142                                                 }
143                                         } else if (inColorCode == 5) {
144                                                 inColorCode = 0;
145                                                 if ((c >= '0') && (c <= '5')) {
146                                                         continue;
147                                                 }
148                                         } else if (inColorCode == 8) {
149                                                 if (c == '9') {
150                                                         inColorCode = 3;
151                                                         continue;
152                                                 } else if (c == ',') {
153                                                         inColorCode = 4;
154                                                         continue;
155                                                 } else {
156                                                         inColorCode = 0;
157                                                 }
158                                         } else if (inColorCode == 9) {
159                                                 inColorCode = 0;
160                                                 if (c == '9') {
161                                                         continue;
162                                                 }
163                                         }
164                                 }
165                                 clean.append(c);
166                         }
167                 } catch (IOException ioe1) {
168                         /* StringReader will never throw. */
169                 }
170
171                 return clean.toString();
172         }
173
174         //
175         // STATIC METHODS
176         //
177
178         /**
179          * Returns the default instance.
180          *
181          * @return The default instance
182          */
183         public static MessageCleaner getDefaultInstance() {
184                 return DEFAULT_INSTANCE;
185         }
186
187 }