/*
* vector sigma (https://github.com/vectorsigma72)
* Copyright 2020 vector sigma All Rights Reserved.
*
* The source code contained or described herein and all documents related
* to the source code ("Material") are owned by vector sigma.
* Title to the Material remains with vector sigma or its suppliers and licensors.
* The Material is proprietary of vector sigma and is protected by worldwide copyright.
* No part of the Material may be used, copied, reproduced, modified, published,
* uploaded, posted, transmitted, distributed, or disclosed in any way without
* vector sigma's prior express written permission.
*
* No license under any patent, copyright, trade secret or other intellectual
* property right is granted to or conferred upon you by disclosure or delivery
* of the Materials, either expressly, by implication, inducement, estoppel or
* otherwise. Any license under such intellectual property rights must be
* express and approved by vector sigma in writing.
*
* Unless otherwise agreed by vector sigma in writing, you may not remove or alter
* this notice or any other notice embedded in Materials by vector sigma in any way.
*
* The license is granted for the CloverBootloader project (i.e. https://github.com/CloverHackyColor/CloverBootloader)
* and all the users as long as the Material is used only within the
* source code and for the exclusive use of CloverBootloader, which must
* be free from any type of payment or commercial service for the license to be valid.
*/
import Foundation
//MARK: PENode to Plist
///Conver the given PENode to a XML Property List v1
func gConvertPENodeToPlist(node: PENode?) -> String {
var plist : String = ""
if (node == nil) {
return plist
}
let ro = node!.tagdata!
let type = node!.tagdata!.type
if type == .Dictionary {
if node!.count == 0 {
plist = xml1Header + "\n" + "" + "\n" + xml1Footer
} else {
plist = xml1Header + "\n" + gSerializeNodeToPlist(node: node!, file: "", indentation: 0) + xml1Footer
}
} else if type == .Array {
if node!.count == 0 {
plist = xml1Header + "\n" + "" + "\n" + xml1Footer
} else {
plist = xml1Header + "\n" + gSerializeNodeToPlist(node: node!, file: "", indentation: 0) + xml1Footer
}
} else if type == .String {
plist = xml1Header + "\n" + "" + (ro.value as! String).encodingXMLCharacters + "" + "\n" + xml1Footer
} else if type == .Data {
let data = ro.value as! NSData
let strBase64 : String = (data as Data).base64EncodedString(options: .endLineWithLineFeed)
plist = xml1Header + "\n" + "" + strBase64 + "" + "\n" + xml1Footer
} else if type == .Date {
plist = xml1Header + "\n" + "" + utcDateToString(ro.value as! Date) + "" + "\n" + xml1Footer
} else if type == .Number {
let strNum = "\(node!.tagdata!.value!)"
if (strNum as NSString).range(of: ".").location != NSNotFound {
plist = xml1Header + "\n" + "" + strNum + "" + "\n" + xml1Footer
} else {
plist = xml1Header + "\n" + "" + strNum + "" + "\n" + xml1Footer
}
} else if type == .Bool {
let n = node!.tagdata!.value as! NSNumber
plist = xml1Header + "\n" + (n.boolValue ? "" : "") + "\n" + xml1Footer
}
return plist
}
///This func is meant to be called only by the gConvertPENodeToPlist(node: ) function
func gSerializeNodeToPlist(node: PENode, file: String, indentation: Int) -> String {
var str : String = ""
var indent : String = ""
// isRoot means that is still empty and we need to add the open/close tag for the Dictionary (or array)
let isRoot : Bool = (node.isRootNode == nil) ? false : node.isRootNode!
var i : Int = indentation <= 0 ? 1 : indentation
let indentChild : Int = isRoot ? i : i + 1
while i != 0 {
indent = indent + "\t"
i -= 1
}
let type = node.tagdata!.type
if type == .Dictionary {
if !isRoot {
if node.peparent != nil && node.peparent!.tagdata!.type != .Array {
str += indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
}
} else {
str = "\n"
}
if node.mutableChildren.count > 0 {
/*
New item
test
hi
*/
if !isRoot {
str = str + indent + "" + "\n"
}
for child in node.mutableChildren {
str = str + gSerializeNodeToPlist(node: child as! PENode, file: str, indentation: indentChild)
}
if !isRoot {
str = str + indent + "" + "\n"
}
} else {
/*
New item
*/
str = str + indent + "" + "\n"
}
} else if type == .Array {
if !isRoot {
str += indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
} else {
str = "\n"
}
if node.mutableChildren.count > 0 {
/*
New item
hi
*/
if !isRoot {
str = str + indent + "" + "\n"
}
for child in node.mutableChildren {
str = str + gSerializeNodeToPlist(node: child as! PENode, file: str, indentation: indentChild)
}
if !isRoot {
str = str + indent + "" + "\n"
}
} else {
/*
New item
*/
str = str + indent + "" + "\n"
}
} else if type == .String {
/*
test
hi
*/
if node.peparent!.tagdata!.type != .Array {
str = str + indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
} else if isRoot {
str = str + indent + "" + localizedNewItem + "" + "\n"
}
str = str + indent + "" + (node.tagdata!.value as! String).encodingXMLCharacters + "" + "\n"
} else if type == .Data {
if node.peparent!.tagdata!.type != .Array {
str = str + indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
} else if isRoot {
str = str + indent + "" + localizedNewItem + "" + "\n"
}
let data = node.tagdata!.value as! NSData
let strBase64 : String = (data as Data).base64EncodedString(options: .endLineWithLineFeed)
str = str + indent + "" + strBase64 + "" + "\n"
} else if type == .Date {
if node.peparent!.tagdata!.type != .Array {
str = str + indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
} else if isRoot {
str = str + indent + "" + localizedNewItem + "" + "\n"
}
str = str + indent + "" + utcDateToString(node.tagdata!.value as! Date) + "" + "\n"
} else if type == .Number {
if node.peparent!.tagdata!.type != .Array {
str = str + indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
} else if isRoot {
str = str + indent + "" + localizedNewItem + "" + "\n"
}
let strNum = "\(node.tagdata!.value!)"
if (strNum as NSString).range(of: ".").location != NSNotFound {
// 1.2
str = str + indent + "" + strNum + "" + "\n"
} else {
// 1
str = str + indent + "" + strNum + "" + "\n"
}
} else if type == .Bool {
if node.peparent!.tagdata!.type != .Array {
str = str + indent + "" + node.tagdata!.key.encodingXMLCharacters + "" + "\n"
} else if isRoot {
str = str + indent + "" + localizedNewItem + "" + "\n"
}
let n = node.tagdata!.value as! NSNumber
str += indent + (n.boolValue ? "" : "") + "\n"
}
if isRoot {
if node.tagdata!.type == .Array {
str = str + "\n"
} else {
str = str + "\n"
}
}
return str
}