Files
mkv-prop-test/MKVTest/SerializeMkvInfo.cs
T

211 lines
6.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace MKVTest
{
internal class SerializeMkvInfo
{
public List<string> SerializeFile(string filePath)
{
var file = File.ReadAllLines(filePath);
if (file.Length == 0) return new List<string>();
var lastDepthLevel = 0;
//var paddingOffSet = GetDepth(file[0]);
//var xml = new StringBuilder();
var stack = new Stack<XmlTag>();
var xml = new List<string> {"<File>"};
//Create a root node for the file.
var rootNode = new XmlTag()
{
Name = "File"
};
stack.Push(rootNode);
for (var i = 0; i < file.Length; i++)
{
var depth = GetDepth(file[i]);
var tag = CreateTagFromString(file[i]);
var padding = new StringBuilder();
//for (var j = depth - paddingOffSet; j > 0; j--)
//{
// padding.Append(" ");
//}
if (i == file.Length - 1)
{
var t = stack.Pop();
xml.Insert(xml.Count - 1, padding + "<" + t.Name + " Value=\"" + t.Value + "\" />");
xml[xml.Count - 1] = padding + "<" + tag.Name + " Value=\"" + tag.Value + "\" />";
//Unwind the stack.
xml.AddRange(stack.Select(s => "</" + s.Name + ">"));
continue;
}
if (depth == lastDepthLevel)
{
if (stack.Count != 0)
{
var t = stack.Pop();
xml[xml.Count - 1] = padding + "<" + t.Name + " Value=\"" + t.Value + "\" />";
}
}
else if (depth < lastDepthLevel)
{
//Moving up
if (stack.Count != 0)
{
var t = stack.Pop();
xml[xml.Count - 1] = padding + "<" + t.Name + " Value=\"" + t.Value + "\" />";
var diff = lastDepthLevel - depth;
var subPadding = new StringBuilder();
for (var j = 0; j < diff; j++)
{
subPadding.Clear();
//for (var k = padding.Length - j; k != 0; k--)
//{
// subPadding.Append(" ");
//}
if (stack.Count != 0)
{
xml.Add(subPadding + "</" + stack.Pop().Name + ">");
}
else
{
break;
}
}
}
}
if(tag.Name != string.Empty) xml.Add(padding + "<" + tag.Name + ">");
stack.Push(tag);
lastDepthLevel = depth;
}
return xml;
}
public List<XmlTag> CreateTagListFromFile(string filePath)
{
var file = File.ReadAllLines(filePath);
if (file.Length == 0) return new List<XmlTag>();
var tags = new List<XmlTag>();
foreach (var line in file)
{
var tag = CreateTagFromString(line);
if(tag.Name != string.Empty) tags.Add(tag);
}
return tags;
}
private static XmlTag CreateTagFromString(string text, XmlTag parent = null)
{
var tag = new XmlTag();
var clearingPadding = true;
var foundDelimiter = false;
var insideBraces = false;
var name = new StringBuilder();
var value = new StringBuilder();
var attributes = new List<MkvAttribute>();
for (var i = 0; i < text.Length; i++)
{
if ((char.IsSymbol(text[i]) || char.IsPunctuation(text[i]) || char.IsWhiteSpace(text[i])) && clearingPadding)
{
continue;
}
if ((text[i].ToString() == ":" || text[i] == ',') && !foundDelimiter)
{
foundDelimiter = true;
continue;
}
clearingPadding = false;
if (foundDelimiter)
{
if (text[i] == '(')
{
insideBraces = true;
continue;
}
if (insideBraces && text[i] == ')')
{
insideBraces = false;
continue;
}
if(!insideBraces) value.Append(text[i]);
}
else
{
if (text[i] == '(')
{
insideBraces = true;
continue;
}
if(text[i] == ')')
{
insideBraces = false;
continue;
}
if(!insideBraces) name.Append(text[i]);
}
}
//if (text.Contains("Segment, "))
//{
// name.Clear();
//}
tag.Name = FormatTagName(name.ToString());
tag.Value = value.ToString().Trim();
tag.Parent = parent;
return tag;
}
private static string FormatTagName(string text)
{
if (text.Length == 0) return string.Empty;
var name = new StringBuilder();
var previousCharWasWhiteSpace = false;
foreach (var c in text)
{
if (!char.IsWhiteSpace(c))
{
name.Append(previousCharWasWhiteSpace ? char.ToUpper(c) : c);
previousCharWasWhiteSpace = false;
}
if (char.IsWhiteSpace(c))
{
previousCharWasWhiteSpace = true;
}
}
return name.ToString();
}
private static int GetDepth(string line)
{
if (line.Length == 0) return -1;
var depth = 0;
for (var i = 0; i < line.Length; i++)
{
if (char.IsPunctuation(line[i]) || char.IsWhiteSpace(line[i]) || char.IsSymbol(line[i]))
{
depth++;
}
else
{
break;
}
}
return depth;
}
}
}