Herbert Poul
5 years ago
9 changed files with 145 additions and 31 deletions
@ -0,0 +1,35 @@
|
||||
import 'package:kdbx/src/kdbx_xml.dart'; |
||||
import 'package:xml/xml.dart' as xml; |
||||
|
||||
extension XmlElementExt on xml.XmlElement { |
||||
xml.XmlElement singleElement(String nodeName, |
||||
{xml.XmlElement Function() orElse}) { |
||||
final elements = findElements(nodeName); |
||||
if (elements.isEmpty) { |
||||
if (orElse != null) { |
||||
final ret = orElse(); |
||||
children.add(ret); |
||||
return ret; |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
return elements.single; |
||||
} |
||||
|
||||
String singleTextNode(String nodeName) { |
||||
return findElements(nodeName).single.text; |
||||
} |
||||
|
||||
/// If an element child with the given name already exists, |
||||
/// it will be removed and the given element will be added. |
||||
/// otherwise it will be only added. |
||||
void replaceSingle(xml.XmlElement element) { |
||||
XmlUtils.removeChildrenByName(this, element.name.local); |
||||
children.add(element); |
||||
} |
||||
} |
||||
|
||||
extension ObjectExt<T> on T { |
||||
R let<R>(R Function(T that) op) => op(this); |
||||
} |
@ -0,0 +1,37 @@
|
||||
import 'package:kdbx/src/kdbx_object.dart'; |
||||
import 'package:kdbx/src/kdbx_xml.dart'; |
||||
import 'package:xml/xml.dart' as xml; |
||||
import 'package:kdbx/src/internal/extension_utils.dart'; |
||||
|
||||
class KdbxCustomData extends KdbxNode { |
||||
KdbxCustomData.create() |
||||
: data = {}, |
||||
super.create(TAG_NAME); |
||||
|
||||
KdbxCustomData.read(xml.XmlElement node) |
||||
: data = Map.fromEntries( |
||||
node.findElements(KdbxXml.NODE_CUSTOM_DATA_ITEM).map((el) { |
||||
final key = el.singleTextNode(KdbxXml.NODE_KEY); |
||||
final value = el.singleTextNode(KdbxXml.NODE_VALUE); |
||||
return MapEntry(key, value); |
||||
})), |
||||
super.read(node); |
||||
|
||||
static const String TAG_NAME = 'CustomData'; |
||||
|
||||
final Map<String, String> data; |
||||
|
||||
@override |
||||
xml.XmlElement toXml() { |
||||
final el = super.toXml(); |
||||
el.children.clear(); |
||||
el.children.addAll( |
||||
data.entries |
||||
.map((e) => XmlUtils.createNode(KdbxXml.NODE_CUSTOM_DATA_ITEM, [ |
||||
XmlUtils.createTextNode(KdbxXml.NODE_KEY, e.key), |
||||
XmlUtils.createTextNode(KdbxXml.NODE_VALUE, e.value), |
||||
])), |
||||
); |
||||
return el; |
||||
} |
||||
} |
@ -0,0 +1,42 @@
|
||||
import 'package:kdbx/src/internal/extension_utils.dart'; |
||||
import 'package:kdbx/src/kdbx_custom_data.dart'; |
||||
import 'package:kdbx/src/kdbx_object.dart'; |
||||
import 'package:kdbx/src/kdbx_xml.dart'; |
||||
import 'package:meta/meta.dart'; |
||||
import 'package:xml/xml.dart' as xml; |
||||
|
||||
class KdbxMeta extends KdbxNode { |
||||
KdbxMeta.create({ |
||||
@required String databaseName, |
||||
String generator = 'kdbx.dart', |
||||
}) : customData = KdbxCustomData.create(), |
||||
super.create('Meta') { |
||||
this.databaseName.set(databaseName); |
||||
this.generator.set(generator); |
||||
} |
||||
|
||||
KdbxMeta.read(xml.XmlElement node) |
||||
: customData = node |
||||
.singleElement('CustomData') |
||||
?.let((e) => KdbxCustomData.read(e)) ?? |
||||
KdbxCustomData.create(), |
||||
super.read(node); |
||||
|
||||
final KdbxCustomData customData; |
||||
|
||||
StringNode get generator => StringNode(this, 'Generator'); |
||||
|
||||
StringNode get databaseName => StringNode(this, 'DatabaseName'); |
||||
|
||||
Base64Node get headerHash => Base64Node(this, 'HeaderHash'); |
||||
|
||||
BooleanNode get recycleBinEnabled => BooleanNode(this, 'RecycleBinEnabled'); |
||||
|
||||
UuidNode get recycleBinUUID => UuidNode(this, 'RecycleBinUUID'); |
||||
|
||||
DateTimeUtcNode get recycleBinChanged => |
||||
DateTimeUtcNode(this, 'RecycleBinChanged'); |
||||
|
||||
@override |
||||
xml.XmlElement toXml() => super.toXml()..replaceSingle(customData.toXml()); |
||||
} |
Loading…
Reference in new issue