The following code will enter an infinate loop when in ReadChars. I can only
make it happen when reading a Stream and with this particular XML. If I use
the ReadInnerXml call rather than my own ReadElementBodyAsXml the code works,
but is less efficent. ReadElementBodyAsXml is required by my application
with .Net Framework 1.1.
The code breaks on the second call to ReadElementBodyAsXml with the inner xml:
</EGDConfigExtension>
<EGDConfigExtension Company="http://pdweb.salem.ge.com"
ExtensionCode="MasterHmiResources"><HmiResources>
<HmiResource Name="hgyugyg" />
</HmiResources></EGDConfigExtension>
This is bad behavior, so I felt it should be posted. Maybe it is already
know to be fixed in SP1 (hopefully forthcoming).
Regards,
Rick
--- code that breaks ---
private void ReadXml()
{
FileStream fs = File.OpenRead(@"MasterSymbolTable.xml");
XmlTextReader reader = new XmlTextReader(fs, XmlNodeType.Element, null);
reader.MoveToContent();
reader.ReadToDescendant("EGDConfigExtension");
string xml = ReadElementBodyAsXml(reader);
reader.Read();
xml = ReadElementBodyAsXml(reader);
}
private string ReadElementBodyAsXml(XmlTextReader reader)
{
int startingLineNumber = reader.LineNumber;
int startingLinePosition = reader.LinePosition;
int startingDepth = reader.Depth;
bool startingElementIsEmpty = reader.IsEmptyElement;
string startingName = reader.Name;
System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element,
"Node type must be Element.",
"ReadElementBodyAsXml should be called when the reader is positioned on
an element. It will simply return null if it is not, but the intention is
for it to be used to read element content.");
char[] buffer = new char[512];
int totalRead = 0;
int i;
while ((i = reader.ReadChars(buffer, totalRead, buffer.Length -
totalRead)) 0)
{
totalRead += i;
if (reader.Depth <= startingDepth)
{
// Even though we read chars, the LineNumber and LinePosition do not
change
// unless we read a node. We don't want to read any more unless we are
// on a child node. But we also need to make sure that we are not still
// on the same node that we started with, since we could have some very
// big nodes. It is hard to tell if ReadChars returned because it did
// not have any more content buffered or if it got to the end of a node.
// If at the end of a node, which node?
// This code fixes SCR 2923.
if (reader.NodeType != XmlNodeType.Element)
break; // We must not be on the node we started on.
}
if (reader.NodeType == XmlNodeType.EndElement && reader.Depth ==
startingDepth)
break;
if (totalRead == buffer.Length)
{
char[] newBuf = new char[buffer.Length + 512];
Buffer.BlockCopy(buffer, 0, newBuf, 0, totalRead * 2); // Each char is
2 bytes.
buffer = newBuf;
}
}
string innerXml = null;
if (totalRead 0)
innerXml = new string(buffer, 0, totalRead);
else
innerXml = null;
return innerXml;
}
----- XML file MasterSymbolTable.Xml ---
<?xml version="1.0" encoding="utf-8"?>
<?GeCssClass type="GeIndsysNetworkCoe.EgdConfig.EgdMasterSymbol Table,
EgdCoeConfig"?>
<MasterEgdSymbolTable EGDSpecVersion="3.04" ConfigTimeSecs="1160762827"
ConfigTimeNSecs="704238500" xmlns="http://geindustrial.com/EGD" Name="Demo">
<EGDConfigExtension Company="http://pdweb.salem.ge.com"
ExtensionCode="MasterAlarms"><AlarmClasses>
<AlarmClass Name="Alarm" Description="Default Class for Process Alarms"
DescAlt="" NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Red" AlarmForegroundColor="White"
AckBackgroundColor="White" AckForegroundColor="Red" IsIntrinsic="true"
NormalSeverity="350" ActiveSeverity="500" />
<AlarmClass Name="Trip" Description="Default Class for Convertor Trips"
DescAlt="" NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Maroon" AlarmForegroundColor="White"
AckBackgroundColor="White" AckForegroundColor="Maroon" IsIntrinsic="true"
NormalSeverity="350" ActiveSeverity="500" />
<AlarmClass Name="System" Description="Default Class for WorkstationST
System alarms" DescAlt="" NormalBackgroundColor="White"
NormalForegroundColor="Black" AlarmBackgroundColor="Teal"
AlarmForegroundColor="White" AckBackgroundColor="White"
AckForegroundColor="Teal" IsIntrinsic="true" NormalSeverity="350"
ActiveSeverity="500" />
<AlarmClass Name="Diagnostic" Description="Default Class for Process
Diagnostics" DescAlt="" NormalBackgroundColor="White"
NormalForegroundColor="Black" AlarmBackgroundColor="Red"
AlarmForegroundColor="White" AckBackgroundColor="White"
AckForegroundColor="Red" IsIntrinsic="true" NormalSeverity="350"
ActiveSeverity="500" />
<AlarmClass Name="Hold" Description="Default Class for Holds" DescAlt=""
NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Yellow" AlarmForegroundColor="Black"
AckBackgroundColor="Black" AckForegroundColor="Yellow" IsIntrinsic="true"
NormalSeverity="350" ActiveSeverity="500" />
<AlarmClass Name="Diag" Description="Default Class for Process Diagnostics"
DescAlt="" NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Red" AlarmForegroundColor="White"
AckBackgroundColor="White" AckForegroundColor="Red" IsIntrinsic="true"
NormalSeverity="350" ActiveSeverity="500" />
<AlarmClass Name="Sys" Description="Default Class for WorkstationST System
alarms" DescAlt="" NormalBackgroundColor="White"
NormalForegroundColor="Black" AlarmBackgroundColor="Teal"
AlarmForegroundColor="White" AckBackgroundColor="White"
AckForegroundColor="Teal" IsIntrinsic="true" NormalSeverity="350"
ActiveSeverity="500" />
<AlarmClass Name="TEST" Description="Test Alarm Class" DescAlt=""
NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Maroon" AlarmForegroundColor="White"
AckBackgroundColor="White" AckForegroundColor="Maroon" NormalSeverity="350"
ActiveSeverity="500" />
<AlarmClass Name="OpSet" Description="Alarm Class for Operator Setpoint
Events" DescAlt="" NormalBackgroundColor="White"
NormalForegroundColor="Black" AlarmBackgroundColor="Yellow"
AlarmForegroundColor="Black" AckBackgroundColor="Black"
AckForegroundColor="Yellow" IsIntrinsic="true" NormalSeverity="350"
ActiveSeverity="500" />
<AlarmClass Name="SOE" Description="Default Class for Sequence of event"
DescAlt="" NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Yellow" AlarmForegroundColor="Black"
AckBackgroundColor="Black" AckForegroundColor="Yellow" IsIntrinsic="true"
NormalSeverity="350" ActiveSeverity="500" />
<AlarmClass Name="Event" Description="Default Class for Process Events"
DescAlt="" NormalBackgroundColor="White" NormalForegroundColor="Black"
AlarmBackgroundColor="Yellow" AlarmForegroundColor="Black"
AckBackgroundColor="Black" AckForegroundColor="Yellow" IsIntrinsic="true"
NormalSeverity="350" ActiveSeverity="500" />
</AlarmClasses></EGDConfigExtension>
<EGDConfigExtension Company="http://pdweb.salem.ge.com"
ExtensionCode="MasterHmiResources"><HmiResources>
<HmiResource Name="hgyugyg" />
</HmiResources></EGDConfigExtension>
<EGDConfigExtension Company="http://pdweb.salem.ge.com"
ExtensionCode="MasterPlantAreas"><PlantAreas>
<PlantAreaPath Path="Plant" />
<PlantAreaPath Path="Plant.PlantArea01" />
<PlantAreaPath Path="Plant.PlantArea01.PlantArea21" />
<PlantAreaPath Path="Plant.PlantArea02" />
<PlantAreaPath Path="Plant.PlantArea04" />
<PlantAreaPath Path="Plant.PlantArea14" />
<PlantAreaPath Path="Plant.PlantArea15" />
</PlantAreas></EGDConfigExtension>
</MasterEgdSymbolTable>