• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.server.permission.access.util
18 
19 import com.android.modules.utils.BinaryXmlPullParser
20 import java.io.IOException
21 import java.io.InputStream
22 import org.xmlpull.v1.XmlPullParser
23 import org.xmlpull.v1.XmlPullParserException
24 
25 /**
26  * Parse content from [InputStream] with [BinaryXmlPullParser].
27  */
28 @Throws(IOException::class, XmlPullParserException::class)
parseBinaryXmlnull29 inline fun InputStream.parseBinaryXml(block: BinaryXmlPullParser.() -> Unit) {
30     BinaryXmlPullParser().apply {
31         setInput(this@parseBinaryXml, null)
32         block()
33     }
34 }
35 
36 /**
37  * Iterate through child tags of the current tag.
38  * <p>
39  * Attributes for the current tag needs to be accessed before this method is called because this
40  * method will advance the parser past the start tag of the current tag. The code inspecting each
41  * child tag may access the attributes of the child tag, and/or call [forEachTag] recursively to
42  * inspect grandchild tags, which will naturally leave the parser at either the start tag or the end
43  * tag of the child tag it inspected.
44  *
45  * @see BinaryXmlPullParser.next
46  * @see BinaryXmlPullParser.getEventType
47  * @see BinaryXmlPullParser.getDepth
48  */
49 @Throws(IOException::class, XmlPullParserException::class)
forEachTagnull50 inline fun BinaryXmlPullParser.forEachTag(block: BinaryXmlPullParser.() -> Unit) {
51     when (val eventType = eventType) {
52         // Document start or start tag of the parent tag.
53         XmlPullParser.START_DOCUMENT, XmlPullParser.START_TAG -> nextTagOrEnd()
54         else -> throw XmlPullParserException("Unexpected event type $eventType")
55     }
56     while (true) {
57         when (val eventType = eventType) {
58             // Start tag of a child tag.
59             XmlPullParser.START_TAG -> {
60                 val childDepth = depth
61                 block()
62                 // block() should leave the parser at either the start tag (no grandchild tags
63                 // expected) or the end tag (grandchild tags parsed with forEachTag()) of this child
64                 // tag.
65                 val postBlockDepth = depth
66                 if (postBlockDepth != childDepth) {
67                     throw XmlPullParserException(
68                         "Unexpected post-block depth $postBlockDepth, expected $childDepth"
69                     )
70                 }
71                 // Skip the parser to the end tag of this child tag.
72                 while (true) {
73                     when (val childEventType = this.eventType) {
74                         // Start tag of either this child tag or a grandchild tag.
75                         XmlPullParser.START_TAG -> nextTagOrEnd()
76                         XmlPullParser.END_TAG -> {
77                             if (depth > childDepth) {
78                                 // End tag of a grandchild tag.
79                                 nextTagOrEnd()
80                             } else {
81                                 // End tag of this child tag.
82                                 break
83                             }
84                         }
85                         else ->
86                             throw XmlPullParserException("Unexpected event type $childEventType")
87                     }
88                 }
89                 // Skip the end tag of this child tag.
90                 nextTagOrEnd()
91             }
92             // End tag of the parent tag, or document end.
93             XmlPullParser.END_TAG, XmlPullParser.END_DOCUMENT -> break
94             else -> throw XmlPullParserException("Unexpected event type $eventType")
95         }
96     }
97 }
98 
99 /**
100  * Advance the parser until the current event is one of [XmlPullParser.START_TAG],
101  * [XmlPullParser.START_TAG] and [XmlPullParser.START_TAG]
102  *
103  * @see BinaryXmlPullParser.next
104  */
105 @Throws(IOException::class, XmlPullParserException::class)
106 @Suppress("NOTHING_TO_INLINE")
nextTagOrEndnull107 inline fun BinaryXmlPullParser.nextTagOrEnd(): Int {
108     while (true) {
109         when (val eventType = next()) {
110             XmlPullParser.START_TAG, XmlPullParser.END_TAG, XmlPullParser.END_DOCUMENT ->
111                 return eventType
112             else -> continue
113         }
114     }
115 }
116 
117 /**
118  * @see BinaryXmlPullParser.getName
119  */
120 inline val BinaryXmlPullParser.tagName: String
121     get() = name
122 
123 /**
124  * Check whether an attribute exists for the current tag.
125  */
126 @Suppress("NOTHING_TO_INLINE")
hasAttributenull127 inline fun BinaryXmlPullParser.hasAttribute(name: String): Boolean = getAttributeIndex(name) != -1
128 
129 /**
130  * @see BinaryXmlPullParser.getAttributeIndex
131  */
132 @Suppress("NOTHING_TO_INLINE")
133 inline fun BinaryXmlPullParser.getAttributeIndex(name: String): Int = getAttributeIndex(null, name)
134 
135 /**
136  * @see BinaryXmlPullParser.getAttributeIndexOrThrow
137  */
138 @Suppress("NOTHING_TO_INLINE")
139 @Throws(XmlPullParserException::class)
140 inline fun BinaryXmlPullParser.getAttributeIndexOrThrow(name: String): Int =
141     getAttributeIndexOrThrow(null, name)
142 
143 /**
144  * @see BinaryXmlPullParser.getAttributeValue
145  */
146 @Suppress("NOTHING_TO_INLINE")
147 @Throws(XmlPullParserException::class)
148 inline fun BinaryXmlPullParser.getAttributeValue(name: String): String? =
149     getAttributeValue(null, name)
150 
151 /**
152  * @see BinaryXmlPullParser.getAttributeValue
153  */
154 @Suppress("NOTHING_TO_INLINE")
155 @Throws(XmlPullParserException::class)
156 inline fun BinaryXmlPullParser.getAttributeValueOrThrow(name: String): String =
157     getAttributeValue(getAttributeIndexOrThrow(name))
158 
159 /**
160  * @see BinaryXmlPullParser.getAttributeBytesHex
161  */
162 @Suppress("NOTHING_TO_INLINE")
163 inline fun BinaryXmlPullParser.getAttributeBytesHex(name: String): ByteArray? =
164     getAttributeBytesHex(null, name, null)
165 
166 /**
167  * @see BinaryXmlPullParser.getAttributeBytesHex
168  */
169 @Suppress("NOTHING_TO_INLINE")
170 @Throws(XmlPullParserException::class)
171 inline fun BinaryXmlPullParser.getAttributeBytesHexOrThrow(name: String): ByteArray =
172     getAttributeBytesHex(null, name)
173 
174 /**
175  * @see BinaryXmlPullParser.getAttributeBytesBase64
176  */
177 @Suppress("NOTHING_TO_INLINE")
178 inline fun BinaryXmlPullParser.getAttributeBytesBase64(name: String): ByteArray? =
179     getAttributeBytesBase64(null, name, null)
180 
181 /**
182  * @see BinaryXmlPullParser.getAttributeBytesBase64
183  */
184 @Suppress("NOTHING_TO_INLINE")
185 @Throws(XmlPullParserException::class)
186 inline fun BinaryXmlPullParser.getAttributeBytesBase64OrThrow(name: String): ByteArray =
187     getAttributeBytesBase64(null, name)
188 
189 /**
190  * @see BinaryXmlPullParser.getAttributeInt
191  */
192 @Suppress("NOTHING_TO_INLINE")
193 inline fun BinaryXmlPullParser.getAttributeIntOrDefault(name: String, defaultValue: Int): Int =
194     getAttributeInt(null, name, defaultValue)
195 
196 /**
197  * @see BinaryXmlPullParser.getAttributeInt
198  */
199 @Suppress("NOTHING_TO_INLINE")
200 @Throws(XmlPullParserException::class)
201 inline fun BinaryXmlPullParser.getAttributeIntOrThrow(name: String): Int =
202     getAttributeInt(null, name)
203 
204 /**
205  * @see BinaryXmlPullParser.getAttributeIntHex
206  */
207 @Suppress("NOTHING_TO_INLINE")
208 inline fun BinaryXmlPullParser.getAttributeIntHexOrDefault(name: String, defaultValue: Int): Int =
209     getAttributeIntHex(null, name, defaultValue)
210 
211 /**
212  * @see BinaryXmlPullParser.getAttributeIntHex
213  */
214 @Suppress("NOTHING_TO_INLINE")
215 @Throws(XmlPullParserException::class)
216 inline fun BinaryXmlPullParser.getAttributeIntHexOrThrow(name: String): Int =
217     getAttributeIntHex(null, name)
218 
219 /**
220  * @see BinaryXmlPullParser.getAttributeLong
221  */
222 @Suppress("NOTHING_TO_INLINE")
223 inline fun BinaryXmlPullParser.getAttributeLongOrDefault(name: String, defaultValue: Long): Long =
224     getAttributeLong(null, name, defaultValue)
225 
226 /**
227  * @see BinaryXmlPullParser.getAttributeLong
228  */
229 @Suppress("NOTHING_TO_INLINE")
230 @Throws(XmlPullParserException::class)
231 inline fun BinaryXmlPullParser.getAttributeLongOrThrow(name: String): Long =
232     getAttributeLong(null, name)
233 
234 /**
235  * @see BinaryXmlPullParser.getAttributeLongHex
236  */
237 @Suppress("NOTHING_TO_INLINE")
238 inline fun BinaryXmlPullParser.getAttributeLongHexOrDefault(
239     name: String,
240     defaultValue: Long
241 ): Long = getAttributeLongHex(null, name, defaultValue)
242 
243 /**
244  * @see BinaryXmlPullParser.getAttributeLongHex
245  */
246 @Suppress("NOTHING_TO_INLINE")
247 @Throws(XmlPullParserException::class)
248 inline fun BinaryXmlPullParser.getAttributeLongHexOrThrow(name: String): Long =
249     getAttributeLongHex(null, name)
250 
251 /**
252  * @see BinaryXmlPullParser.getAttributeFloat
253  */
254 @Suppress("NOTHING_TO_INLINE")
255 inline fun BinaryXmlPullParser.getAttributeFloatOrDefault(
256     name: String,
257     defaultValue: Float
258 ): Float = getAttributeFloat(null, name, defaultValue)
259 
260 /**
261  * @see BinaryXmlPullParser.getAttributeFloat
262  */
263 @Suppress("NOTHING_TO_INLINE")
264 @Throws(XmlPullParserException::class)
265 inline fun BinaryXmlPullParser.getAttributeFloatOrThrow(name: String): Float =
266     getAttributeFloat(null, name)
267 
268 /**
269  * @see BinaryXmlPullParser.getAttributeDouble
270  */
271 @Suppress("NOTHING_TO_INLINE")
272 inline fun BinaryXmlPullParser.getAttributeDoubleOrDefault(
273     name: String,
274     defaultValue: Double
275 ): Double = getAttributeDouble(null, name, defaultValue)
276 
277 /**
278  * @see BinaryXmlPullParser.getAttributeDouble
279  */
280 @Suppress("NOTHING_TO_INLINE")
281 @Throws(XmlPullParserException::class)
282 inline fun BinaryXmlPullParser.getAttributeDoubleOrThrow(name: String): Double =
283     getAttributeDouble(null, name)
284 
285 /**
286  * @see BinaryXmlPullParser.getAttributeBoolean
287  */
288 @Suppress("NOTHING_TO_INLINE")
289 inline fun BinaryXmlPullParser.getAttributeBooleanOrDefault(
290     name: String,
291     defaultValue: Boolean
292 ): Boolean = getAttributeBoolean(null, name, defaultValue)
293 
294 /**
295  * @see BinaryXmlPullParser.getAttributeBoolean
296  */
297 @Suppress("NOTHING_TO_INLINE")
298 @Throws(XmlPullParserException::class)
299 inline fun BinaryXmlPullParser.getAttributeBooleanOrThrow(name: String): Boolean =
300     getAttributeBoolean(null, name)
301