public override void ReadAttributesAndContent(XmlInput xmlinput)
{
string kindText = xmlinput.GetAttributeString("kind");
switch (kindText) {
case "normal": kind = ControlPointKind.Normal; break;
case "start": kind = ControlPointKind.Start; break;
case "finish": kind = ControlPointKind.Finish; break;
case "crossing-point": kind = ControlPointKind.CrossingPoint; break;
case "map-exchange": kind = ControlPointKind.MapExchange; break;
default: xmlinput.BadXml("Invalid control point kind '{0}'", kindText); break;
}
if (kind == ControlPointKind.Normal || kind == ControlPointKind.Start || kind == ControlPointKind.MapExchange)
symbolIds = new string[6];
else if (kind == ControlPointKind.Finish || kind == ControlPointKind.CrossingPoint)
symbolIds = new string[1];
code = null;
descriptionText = null;
columnFText = null;
// Old file format had a single gaps attribute for all scales. Put this in the dictionary with scale of 0, then update after load is finished.
string gapText = xmlinput.GetAttributeString("gaps", "");
if (gapText != "") {
uint gapValue = Convert.ToUInt32(gapText, 2);
if (gaps == null)
gaps = new Dictionary<int, CircleGap[]>();
gaps[0] = CircleGap.ComputeCircleGaps(gapValue);
}
string codeAngle = xmlinput.GetAttributeString("all-controls-code-angle", "");
if (codeAngle != "") {
customCodeLocation = true;
codeLocationAngle = XmlConvert.ToSingle(codeAngle);
}
if (kind == ControlPointKind.CrossingPoint)
orientation = xmlinput.GetAttributeFloat("orientation");
bool first = true;
while (xmlinput.FindSubElement(first, "code", "location", "description", "description-text", "gaps", "circle-gaps", "punch-pattern", "description-text-line")) {
switch (xmlinput.Name) {
case "code":
if (kind != ControlPointKind.Normal)
xmlinput.BadXml("Only normal control points can have a code");
code = xmlinput.GetContentString();
break;
case "location":
float x = xmlinput.GetAttributeFloat("x");
float y = xmlinput.GetAttributeFloat("y");
location = new PointF(x, y);
xmlinput.Skip();
break;
case "punch-pattern":
punches = new PunchPattern();
punches.size = xmlinput.GetAttributeInt("size");
punches.dots = new bool[punches.size, punches.size];
string punchPattern = xmlinput.GetContentString();
int index = 0;
for (int i = 0; i < punches.size; ++i)
for (int j = 0; j < punches.size; ++j) {
char c;
do {
if (index >= punchPattern.Length) {
xmlinput.BadXml("invalid punch pattern");
goto QUITPUNCHPATTERN;
}
c = punchPattern[index++];
} while (c != '0' && c != '1');
punches.dots[i, j] = (c == '1');
}
QUITPUNCHPATTERN:
break;
case "gaps": {
int scale = xmlinput.GetAttributeInt("scale", 0);
gapText = xmlinput.GetContentString().Trim();
if (gapText != "") {
if (gaps == null)
gaps = new Dictionary<int, CircleGap[]>();
if (gapText.Contains(":")) {
// For 2.0 beta 1 compatibility only.
gaps[scale] = CircleGap.DecodeGaps(gapText);
}
else if (!gaps.ContainsKey(scale)) {
// Only use the old-style if the new-style wasn't found.
uint gapValue = Convert.ToUInt32(gapText, 2);
gaps[scale] = CircleGap.ComputeCircleGaps(gapValue);
}
}
break;
}
case "circle-gaps": {
int scale = xmlinput.GetAttributeInt("scale", 0);
gapText = xmlinput.GetContentString().Trim();
if (gapText != "") {
if (gaps == null)
gaps = new Dictionary<int, CircleGap[]>();
if (gapText.Contains(":")) {
// This is the new-style; overrides old style if both present.
gaps[scale] = CircleGap.DecodeGaps(gapText);
}
}
break;
}
case "description-text":
descriptionText = xmlinput.GetContentString();
break;
case "description-text-line":
xmlinput.CheckElement("description-text-line");
string locationText = xmlinput.GetAttributeString("location");
if (locationText == "before")
descTextBefore = xmlinput.GetContentString();
else if (locationText == "after")
descTextAfter = xmlinput.GetContentString();
else {
xmlinput.BadXml("location attribute on description-text-line must be \"before\" or \"after\"");
xmlinput.Skip();
}
break;
case "description":
string box = xmlinput.GetAttributeString("box");
string symbolId = xmlinput.GetAttributeString("iof-2004-ref", null);
string text = xmlinput.GetContentString();
switch (box) {
case "all": symbolIds[0] = symbolId; break;
case "C": symbolIds[0] = symbolId; break;
case "D": symbolIds[1] = symbolId; break;
case "E": symbolIds[2] = symbolId; break;
case "F": symbolIds[3] = symbolId; break;
case "G": symbolIds[4] = symbolId; break;
case "H": symbolIds[5] = symbolId; break;
default: xmlinput.BadXml("Invalid box type '{0}'", box); break;
}
if (box == "F" && !string.IsNullOrEmpty(text))
columnFText = text;
break;
}
first = false;
}
}