1 /* 2 * Copyright (C) 2011 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 package com.android.loganalysis.parser; 17 18 import com.android.loganalysis.item.ProcrankItem; 19 import com.android.loganalysis.util.ArrayUtil; 20 21 import java.util.List; 22 import java.util.regex.Matcher; 23 import java.util.regex.Pattern; 24 25 /** 26 * A {@link IParser} to handle the output of {@code procrank}. Memory values returned are in units 27 * of kilobytes. 28 */ 29 public class ProcrankParser implements IParser { 30 31 /** Match a valid line, such as: 32 * " 1313 78128K 77996K 48603K 45812K com.google.android.apps.maps" */ 33 private static final Pattern SHORT_LINE_PAT = Pattern.compile( 34 "\\s*(\\d+)\\s+" + /* PID [1] */ 35 "(\\d+)K\\s+(\\d+)K\\s+(\\d+)K\\s+(\\d+)K\\s+" + /* Vss Rss Pss Uss [2-5] */ 36 "(\\S+)" /* process name [6] */); 37 private static final Pattern LONG_LINE_PAT = Pattern.compile( 38 "\\s*(\\d+)\\s+" + /* PID [1] */ 39 "(\\d+)K\\s+(\\d+)K\\s+(\\d+)K\\s+(\\d+)K\\s+" + /* Vss Rss Pss Uss [2-5] */ 40 "(\\d+)K\\s+(\\d+)K\\s+(\\d+)K\\s+(\\d+)K\\s+" + /* Swap PSwap USwap ZSwap [6-9] */ 41 "(\\S+)" /* process name [10] */); 42 43 /** Match the end of the Procrank table, determined by three or more sets of "------". */ 44 private static final Pattern END_PAT = Pattern.compile("^(\\s+-{6}){3,}$"); 45 46 /** 47 * {@inheritDoc} 48 */ 49 @Override parse(List<String> lines)50 public ProcrankItem parse(List<String> lines) { 51 final String text = ArrayUtil.join("\n", lines).replaceAll("\\s+$", ""); 52 if ("".equals(text.trim())) { 53 return null; 54 } 55 56 ProcrankItem item = new ProcrankItem(); 57 item.setText(text); 58 59 for (String line : lines) { 60 // If we have reached the end. 61 Matcher endMatcher = END_PAT.matcher(line); 62 if (endMatcher.matches()) { 63 return item; 64 } 65 66 Matcher m = SHORT_LINE_PAT.matcher(line); 67 if (m.matches()) { 68 item.addProcrankLine(Integer.parseInt(m.group(1)), m.group(6), 69 Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)), 70 Integer.parseInt(m.group(4)), Integer.parseInt(m.group(5))); 71 continue; 72 } 73 74 m = LONG_LINE_PAT.matcher(line); 75 if (m.matches()) { 76 item.addProcrankLine(Integer.parseInt(m.group(1)), m.group(10), 77 Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)), 78 Integer.parseInt(m.group(4)), Integer.parseInt(m.group(5))); 79 } 80 } 81 82 return item; 83 } 84 } 85 86