All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.casperix.file_data.FileDataLoader.kt Maven / Gradle / Ivy

There is a newer version: 0.9.0
Show newest version
package ru.casperix.file_data

import ru.casperix.misc.Left
import ru.casperix.misc.Right
import ru.casperix.multiplatform.loader.ResourceLoadError
import ru.casperix.multiplatform.loader.resourceLoader
import ru.casperix.signals.concrete.EitherFuture
import ru.casperix.signals.concrete.map

object FileDataLoader {
    class InvalidFileData(val path: String, val message: String) : ResourceLoadError

    fun load(path: String): EitherFuture {
        return resourceLoader.loadText(path).map({
            try {
                Right(parse(it))
            } catch (e: Throwable) {
                Left(InvalidFileData(path, e.message ?: ""))
            }
        }, {
            it
        })
    }

    private fun parse(raw: String): FileData {
        val lines = raw.replace("\r\n", "\n").replace("\r", "\n").split("\n")
        val stream = lines.toMutableList()

        val fileData = FileData()
        var currentPage = PageData()
        var currentBlock: BlockData? = null

        fileData.pageList += currentPage

        while (true) {
            val next = stream.removeFirstOrNull() ?: return fileData

            val firstChar = next.firstOrNull()

            if (firstChar == null) {
                //  next page
                currentPage = PageData()
                fileData.pageList += currentPage
            } else if (!firstChar.isWhitespace()) {
                //  next block
                currentBlock = BlockData(next)
                currentPage.blockList += currentBlock
            } else {
                if (currentBlock == null) {
                    println("Invalid name-value place: \"$next\"")
                    continue
                }
                //  next name-value
                val parts = Regex("\\s*(\\w+)\\s*:\\s*(.+)").findAll(next).toList().flatMap {
                    it.groupValues
                }

                val name = parts.getOrNull(1)
                val value = parts.getOrNull(2)
                if (name != null && value != null) {
                    currentBlock.values[name] = value
                } else {
                    println("Cant parse line: \"$next\"")
                    continue
                }
            }

        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy