You've already forked revanced-patcher
mirror of
https://github.com/revanced/revanced-patcher
synced 2025-09-13 18:30:49 +02:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
98ce0abfa9 | ||
![]() |
db4348c4fa | ||
![]() |
4839f87519 | ||
![]() |
809862c997 | ||
![]() |
fd5c878cee | ||
![]() |
124332f0e9 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,3 +1,17 @@
|
|||||||
|
# [5.1.0](https://github.com/revanced/revanced-patcher/compare/v5.0.1...v5.1.0) (2022-09-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* RwLock for opening files in `DomFileEditor` ([db4348c](https://github.com/revanced/revanced-patcher/commit/db4348c4faf51bfe29678baacfbe76ba645ec0b9))
|
||||||
|
|
||||||
|
## [5.0.1](https://github.com/revanced/revanced-patcher/compare/v5.0.0...v5.0.1) (2022-09-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* revert breaking changes ([#106](https://github.com/revanced/revanced-patcher/issues/106)) ([124332f](https://github.com/revanced/revanced-patcher/commit/124332f0e9bbdaf4f1aeeb6a31333093eeba1642))
|
||||||
|
|
||||||
# [5.0.0](https://github.com/revanced/revanced-patcher/compare/v4.5.0...v5.0.0) (2022-09-21)
|
# [5.0.0](https://github.com/revanced/revanced-patcher/compare/v4.5.0...v5.0.0) (2022-09-21)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ dependencies {
|
|||||||
implementation("xpp3:xpp3:1.1.4c")
|
implementation("xpp3:xpp3:1.1.4c")
|
||||||
implementation("org.smali:smali:2.5.2")
|
implementation("org.smali:smali:2.5.2")
|
||||||
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
||||||
implementation("org.apktool:apktool-lib:2.7.0-SNAPSHOT")
|
implementation("org.apktool:apktool-lib:2.8.1-SNAPSHOT")
|
||||||
|
|
||||||
implementation(kotlin("reflect"))
|
implementation(kotlin("reflect"))
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 5.0.0
|
version = 5.1.0
|
||||||
|
@@ -30,10 +30,12 @@ class ResourceData(private val resourceCacheDirectory: File) : Data, Iterable<Fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DomFileEditor is a wrapper for a file that can be edited as a dom document.
|
* Wrapper for a file that can be edited as a dom document.
|
||||||
|
* Note: This constructor does not check for locks to the file when writing. Use the secondary constructor.
|
||||||
*
|
*
|
||||||
* @param inputStream the input stream to read the xml file from.
|
* @param inputStream the input stream to read the xml file from.
|
||||||
* @param outputStream the output stream to write the xml file to. If null, the file will not be written.
|
* @param outputStream the output stream to write the xml file to. If null, the file will be read only.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class DomFileEditor internal constructor(
|
class DomFileEditor internal constructor(
|
||||||
private val inputStream: InputStream,
|
private val inputStream: InputStream,
|
||||||
@@ -41,6 +43,7 @@ class DomFileEditor internal constructor(
|
|||||||
) : Closeable {
|
) : Closeable {
|
||||||
// path to the xml file to unlock the resource when closing the editor
|
// path to the xml file to unlock the resource when closing the editor
|
||||||
private var filePath: String? = null
|
private var filePath: String? = null
|
||||||
|
private var closed: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The document of the xml file
|
* The document of the xml file
|
||||||
@@ -48,37 +51,53 @@ class DomFileEditor internal constructor(
|
|||||||
val file: Document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream)
|
val file: Document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream)
|
||||||
.also(Document::normalize)
|
.also(Document::normalize)
|
||||||
|
|
||||||
|
|
||||||
// lazily open an output stream
|
// lazily open an output stream
|
||||||
// this is required because when constructing a DomFileEditor the output stream is created along with the input stream, which is not allowed
|
// this is required because when constructing a DomFileEditor the output stream is created along with the input stream, which is not allowed
|
||||||
// the workaround is to lazily create the output stream. This way it would be used after the input stream is closed, which happens in the constructor
|
// the workaround is to lazily create the output stream. This way it would be used after the input stream is closed, which happens in the constructor
|
||||||
constructor(file: File) : this(file.inputStream(), lazy { file.outputStream() }) {
|
constructor(file: File) : this(file.inputStream(), lazy { file.outputStream() }) {
|
||||||
|
// increase the lock
|
||||||
|
locks.merge(file.path, 1, Integer::sum)
|
||||||
filePath = file.path
|
filePath = file.path
|
||||||
|
|
||||||
// prevent sharing mutability of the same file between multiple instances of DomFileEditor
|
|
||||||
if (locks.contains(filePath))
|
|
||||||
throw IllegalStateException("Can not create a DomFileEditor for that file because it is already locked by another instance of DomFileEditor.")
|
|
||||||
locks.add(filePath!!)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the editor. Write backs and decreases the lock count.
|
||||||
|
* Note: Will not write back to the file if the file is still locked.
|
||||||
|
*/
|
||||||
override fun close() {
|
override fun close() {
|
||||||
|
if (closed) return
|
||||||
|
|
||||||
inputStream.close()
|
inputStream.close()
|
||||||
|
|
||||||
// if the output stream is not null, do not close it
|
// if the output stream is not null, do not close it
|
||||||
outputStream?.let {
|
outputStream?.let {
|
||||||
val result = StreamResult(it.value)
|
// prevent writing to same file, if it is being locked
|
||||||
TransformerFactory.newInstance().newTransformer().transform(DOMSource(file), result)
|
// isLocked will be false if the editor was created through a stream
|
||||||
|
val isLocked = filePath?.let { path ->
|
||||||
|
val isLocked = locks[path]!! > 1
|
||||||
|
// decrease the lock count if the editor was opened for a file
|
||||||
|
locks.merge(path, -1, Integer::sum)
|
||||||
|
isLocked
|
||||||
|
} ?: false
|
||||||
|
|
||||||
it.value.close()
|
// if unlocked, write back to the file
|
||||||
|
if (!isLocked) {
|
||||||
|
it.value.use { stream ->
|
||||||
|
val result = StreamResult(stream)
|
||||||
|
TransformerFactory.newInstance().newTransformer().transform(DOMSource(file), result)
|
||||||
|
}
|
||||||
|
|
||||||
|
it.value.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the lock, if it exists
|
closed = true
|
||||||
filePath?.let {
|
|
||||||
locks.remove(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
// list of locked file paths
|
// map of concurrent open files
|
||||||
val locks = mutableListOf<String>()
|
val locks = mutableMapOf<String, Int>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user