Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit b87d772e authored by Ricki Hirner's avatar Ricki Hirner Committed by GitHub
Browse files

XmlUtils.newPullParser: enable FEATURE_RELAXED if available (#44)

* XmlUtils.newPullParser: enable FEATURE_RELAXED if available

* Added KDoc
parent 6a0b597c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ interface Property {
                        log.log(Level.WARNING, "Ignoring invalid property", e)
                    }
                }

                eventType = parser.next()
            }

+37 −9
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

package at.bitfire.dav4jvm

import at.bitfire.dav4jvm.exception.DavException
import at.bitfire.dav4jvm.exception.InvalidPropertyException
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
@@ -15,18 +16,45 @@ import java.io.IOException

object XmlUtils {

    private val factory: XmlPullParserFactory
    init {
        try {
            factory = XmlPullParserFactory.newInstance()
            factory.isNamespaceAware = true
        } catch (e: XmlPullParserException) {
            throw RuntimeException("Couldn't create XmlPullParserFactory", e)
    /**
     * Requests the parser to be as lenient as possible when parsing invalid XML.
     *
     * See [https://www.xmlpull.org/](xmlpull.org) and specific implementations, for instance
     * [Android XML](https://developer.android.com/reference/android/util/Xml#FEATURE_RELAXED)
     */
    private const val FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed"

    /** [XmlPullParserFactory] that is namespace-aware and does relaxed parsing */
    private val relaxedFactory =
        XmlPullParserFactory.newInstance().apply {
            isNamespaceAware = true
            setFeature(FEATURE_RELAXED, true)
        }

    /** [XmlPullParserFactory] that is namespace-aware */
    private val standardFactory: XmlPullParserFactory =
        XmlPullParserFactory.newInstance().apply {
            isNamespaceAware = true
        }

    /**
     * Creates a new [XmlPullParser].
     *
     * First tries to create a namespace-aware parser that supports [FEATURE_RELAXED]. If that
     * fails, it falls back to a namespace-aware parser without relaxed parsing.
     */
    fun newPullParser(): XmlPullParser =
        try {
            relaxedFactory.newPullParser()
        } catch (_: XmlPullParserException) {
            // FEATURE_RELAXED may not be supported, try without it
            null
        }
        ?: standardFactory.newPullParser()
        ?: throw DavException("Couldn't create XML parser")

    fun newPullParser() = factory.newPullParser()!!
    fun newSerializer() = factory.newSerializer()!!
    fun newSerializer(): XmlSerializer = standardFactory.newSerializer()
        ?: throw DavException("Couldn't create XML serializer")


    @Throws(IOException::class, XmlPullParserException::class)