1 /*
2  * Copyright (C) 2016 The Android Open Source Project
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 
17 package com.android.bugreport.util;
18 
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.FileReader;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.regex.Pattern;
25 import java.util.regex.Matcher;
26 
27 /**
28  * A stream of parsed lines.  Can be rewound, and sub-regions cloned for
29  * recursive descent parsing.
30  */
31 public class Lines<T extends Line> {
32     private final ArrayList<? extends Line> mList;
33     private final int mMin;
34     private final int mMax;
35 
36     /**
37      * The read position inside the list.
38      */
39     public int pos;
40 
41     /**
42      * Read the whole file into a Lines object.
43      */
readLines(File file)44     public static Lines<Line> readLines(File file) throws IOException {
45         BufferedReader reader = null;
46         try {
47             reader = new BufferedReader(new FileReader(file));
48             return Lines.readLines(reader);
49         } finally {
50             if (reader != null) {
51                 reader.close();
52             }
53         }
54     }
55 
56     /**
57      * Read the whole file into a Lines object.
58      */
readLines(BufferedReader in)59     public static Lines<Line> readLines(BufferedReader in) throws IOException {
60         final ArrayList<Line> list = new ArrayList<Line>();
61 
62         int lineno = 0;
63         String text;
64         while ((text = in.readLine()) != null) {
65             lineno++;
66             list.add(new Line(lineno, text));
67         }
68 
69         return new Lines<Line>(list);
70     }
71 
72     /**
73      * Construct with a list of lines.
74      */
Lines(ArrayList<? extends Line> list)75     public Lines(ArrayList<? extends Line> list) {
76         this.mList = list;
77         mMin = 0;
78         mMax = mList.size();
79     }
80 
81     /**
82      * Construct with a list of lines, and a range inside that list.  The
83      * read position will be set to min, so the new Lines can be read from
84      * the beginning.
85      */
Lines(ArrayList<? extends Line> list, int min, int max)86     private Lines(ArrayList<? extends Line> list, int min, int max) {
87         mList = list;
88         mMin = min;
89         mMax = max;
90         this.pos = min;
91     }
92 
93     /**
94      * If there are more lines to read within the current range.
95      */
hasNext()96     public boolean hasNext() {
97         return pos < mMax;
98     }
99 
100     /**
101      * Return the next line, or null if there are no more lines to read. Also
102      * returns null in the error condition where pos is before the beginning.
103      */
next()104     public Line next() {
105         if (pos >= mMin && pos < mMax) {
106             return this.mList.get(pos++);
107         } else {
108             return null;
109         }
110     }
111 
112     /**
113      * Move the read position back by one line.
114      */
rewind()115     public void rewind() {
116         pos--;
117     }
118 
119     /**
120      * Move th read position to the given pos.
121      */
rewind(int pos)122     public void rewind(int pos) {
123         this.pos = pos;
124     }
125 
126     /**
127      * Return the number of lines.
128      */
size()129     public int size() {
130         return mMax - mMin;
131     }
132 
133     /**
134      * Return a new Lines object restricted to the [from,to) range.
135      * The array list and Lines objects are shared, so be careful
136      * if you modify the lines themselves.
137      */
copy(int from, int to)138     public Lines<T> copy(int from, int to) {
139         return new Lines<T>(mList, Math.max(mMin, from), Math.min(mMax, to));
140     }
141 }
142 
143