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