• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2018 Google Inc.
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  *     https://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 trebuchet.importers.ftrace.events
18 
19 import trebuchet.importers.ftrace.FtraceImporterState
20 import trebuchet.importers.ftrace.FtraceLine
21 import trebuchet.io.DataSlice
22 import trebuchet.model.InvalidId
23 import trebuchet.util.BufferReader
24 import trebuchet.util.MatchResult
25 import trebuchet.util.StringCache
26 import java.util.regex.Matcher
27 import java.util.regex.Pattern
28 
29 const val FtraceLineRE = """^ *(.{1,16})-(\d+) +(?:\( *(\d+)?-*\) )?\[(\d+)] (?:[dX.][^\s]+)? *([\d.]*): *([^:]*): *(.*) *$"""
30 
31 interface FtraceEventDetails {
32     fun import(event: FtraceEvent, state: FtraceImporterState)
33 }
34 
35 val NoDetails = object : FtraceEventDetails {
importnull36     override fun import(event: FtraceEvent, state: FtraceImporterState) {}
37 }
38 
39 typealias EventDetailsParser = (state: EventParserState, slice: DataSlice) -> FtraceEventDetails?
40 
41 class SharedEventParserState {
42     private val patterns = mutableListOf<Pattern>()
43     private val detailHandlers = hashMapOf<String, EventDetailsParser>()
44     private var frozen = false
45 
46     init {
<lambda>null47         EventRegistry.forEach { it(this) }
48     }
49 
addPatternnull50     fun addPattern(newPattern: String) = addPattern(Pattern.compile(newPattern))
51 
52     fun addPattern(newPattern: Pattern): Int {
53         if (frozen) throw IllegalStateException("State is frozen")
54         val index = patterns.size
55         patterns.add(newPattern)
56         return index
57     }
58 
createParsernull59     fun createParser(): EventParserState {
60         frozen = true
61         return EventParserState(patterns, detailHandlers)
62     }
63 
onParseDetailsnull64     fun onParseDetails(funcName: String, parser: EventDetailsParser) {
65         if (frozen) throw IllegalStateException("State is frozen")
66         detailHandlers[funcName] = parser
67     }
68 
onParseDetailsWithMatchnull69     inline fun onParseDetailsWithMatch(funcName: String, regex: String,
70                                        crossinline result: MatchResult.() -> FtraceEventDetails?) {
71         val patternMatcher = addPattern(regex)
72         onParseDetails(funcName) { state, details ->
73             state.ifMatches(patternMatcher, details) {
74                 return@onParseDetails this.result()
75             }
76             null
77         }
78     }
79 
onParseDetailsWithMatchnull80     inline fun onParseDetailsWithMatch(funcNames: Array<String>, regex: String,
81                                        crossinline result: MatchResult.() -> FtraceEventDetails?) {
82         val patternMatcher = addPattern(regex)
83         funcNames.forEach { funcName ->
84             onParseDetails(funcName) { state, details ->
85                 state.ifMatches(patternMatcher, details) {
86                     return@onParseDetails this.result()
87                 }
88                 null
89             }
90         }
91     }
92 }
93 
94 val GlobalSharedParserState = SharedEventParserState()
95 
createEventParsernull96 fun createEventParser() = GlobalSharedParserState.createParser()
97 
98 class EventParserState constructor(patterns: List<Pattern>,
99                                    private val detailHandlers: Map<String, EventDetailsParser>) {
100     val matchers = Array<Matcher>(patterns.size) { patterns[it].matcher("") }
101     val stringCache = StringCache()
102     val reader = BufferReader()
103 
104     inline fun ifMatches(matcher: Int, slice: DataSlice, result: MatchResult.() -> Unit): Boolean {
105         reader.reset(slice, stringCache)
106         return reader.tryMatch(matchers[matcher], result)
107     }
108 
109     fun detailsForText(funcName: CharSequence, detailsSlice: DataSlice): FtraceEventDetails {
110         return detailHandlers[funcName]?.invoke(this, detailsSlice) ?: NoDetails
111     }
112 
113     inline fun <T> readDetails(detailsSlice: DataSlice, init: BufferReader.() -> T): T {
114         return reader.read(detailsSlice, stringCache, init)
115     }
116 }