crlf
[idea/community.git] / platform / util / src / com / intellij / openapi / util / text / LineTokenizer.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.util.text;
17
18 import com.intellij.util.ArrayUtil;
19 import com.intellij.util.text.CharArrayCharSequence;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 /**
25  *
26  */
27 public class LineTokenizer {
28   private int myOffset = 0;
29   private int myLength = 0;
30   private int myLineSeparatorLength = 0;
31   private boolean atEnd = false;
32   private CharSequence myText;
33
34   public static String[] tokenize(CharSequence chars, boolean includeSeparators) {
35     return tokenize(chars, includeSeparators, true);
36   }
37
38   private static String[] tokenize(final CharSequence chars, final boolean includeSeparators, final boolean skipLastEmptyLine) {
39     if (chars == null || chars.length() == 0){
40       return ArrayUtil.EMPTY_STRING_ARRAY;
41     }
42
43     LineTokenizer tokenizer = new LineTokenizer(chars);
44     List<String> lines = new ArrayList<String>();
45     while(!tokenizer.atEnd()){
46       int offset = tokenizer.getOffset();
47       String line;
48       if (includeSeparators){
49         line = chars.subSequence(offset, offset + tokenizer.getLength() + tokenizer.getLineSeparatorLength()).toString();
50       }
51       else{
52         line = chars.subSequence(offset, offset + tokenizer.getLength()).toString();
53       }
54       lines.add(line);
55       tokenizer.advance();
56     }
57
58     if (!skipLastEmptyLine && stringEdnsWithSeparator(tokenizer)) lines.add("");
59
60     return lines.toArray(new String[lines.size()]);
61   }
62
63   public static int calcLineCount(final CharSequence chars, final boolean skipLastEmptyLine) {
64     int lineCount = 0;
65     if (chars != null && chars.length() != 0) {
66       final LineTokenizer tokenizer = new LineTokenizer(chars);
67       while (!tokenizer.atEnd()) {
68         lineCount += 1;
69         tokenizer.advance();
70       }
71       if (!skipLastEmptyLine && stringEdnsWithSeparator(tokenizer)) {
72         lineCount += 1;
73       }
74     }
75     return lineCount;
76   }
77
78   public static String[] tokenize(char[] chars, boolean includeSeparators) {
79     return tokenize(chars, includeSeparators, true);
80   }
81
82   public static String[] tokenize(char[] chars, boolean includeSeparators, boolean skipLastEmptyLine) {
83     return tokenize(chars, 0, chars.length, includeSeparators, skipLastEmptyLine);
84   }
85
86   public static String[] tokenize(char[] chars, int startOffset, int endOffset, boolean includeSeparators,
87                                   boolean skipLastEmptyLine) {
88     return tokenize(new CharArrayCharSequence(chars, startOffset, endOffset), includeSeparators, skipLastEmptyLine);
89   }
90
91   private static boolean stringEdnsWithSeparator(LineTokenizer tokenizer) {
92     return tokenizer.getLineSeparatorLength() > 0;
93   }
94
95   public static String[] tokenize(char[] chars, int startOffset, int endOffset, boolean includeSeparators) {
96     return tokenize(chars, startOffset, endOffset, includeSeparators, true);
97   }
98
99   public LineTokenizer(CharSequence text) {
100     myText = text;
101     myOffset = 0;
102     advance();
103   }
104
105   public LineTokenizer(char[] text, int startOffset, int endOffset) {
106     this(new CharArrayCharSequence(text, startOffset, endOffset));
107   }
108
109   public final boolean atEnd() {
110     return atEnd;
111   }
112
113   public final int getOffset() {
114     return myOffset;
115   }
116
117   public final int getLength() {
118     return myLength;
119   }
120
121   public final int getLineSeparatorLength() {
122     return myLineSeparatorLength;
123   }
124
125   public void advance() {
126     int i = myOffset + myLength + myLineSeparatorLength;
127     final int textLength = myText.length();
128     if (i >= textLength){
129       atEnd = true;
130       return;
131     }
132     while(i < textLength){
133       char c = myText.charAt(i);
134       if (c == '\r' || c == '\n') break;
135       i++;
136     }
137
138     myOffset = myOffset + myLength + myLineSeparatorLength;
139     myLength = i - myOffset;
140
141     myLineSeparatorLength = 0;
142     if (i == textLength) return;
143
144     char first = myText.charAt(i);
145     if (first == '\r' || first == '\n') {
146       myLineSeparatorLength = 1;
147     }
148
149     i++;
150     if (i == textLength) return;
151
152     char second = myText.charAt(i);
153     if (first == '\r' && second == '\n') {
154       myLineSeparatorLength = 2;
155     }
156   }
157 }