private static void ReadTextResources(String fileName) {
// Check for byte order marks in the beginning of the input file, but
// default to UTF-8.
using(LineNumberStreamReader sr = new LineNumberStreamReader(fileName, new UTF8Encoding(true), true))
{
StringBuilder name = new StringBuilder(255);
StringBuilder value = new StringBuilder(2048);
int ch = sr.Read();
while (ch != -1) {
if (ch == '\n' || ch == '\r') {
ch = sr.Read();
continue;
}
// Skip over commented lines or ones starting with whitespace.
// Support LocStudio INF format's comment char, ';'
if (ch == '#' || ch == '\t' || ch == ' ' || ch == ';') {
// comment char (or blank line) - skip line.
sr.ReadLine();
ch = sr.Read();
continue;
}
// Note that in Beta we recommended users should put a [strings]
// section in their file. Now it's completely unnecessary and can
// only cause bugs. We will not parse anything using '[' stuff now
// and we should give a warning about seeing [strings] stuff.
// In V1.1 or V2, we can rip this out completely, I hope.
if (ch == '[') {
String skip = sr.ReadLine();
if (skip.Equals("strings]"))
Warning(SR.GetString(SR.StringsTagObsolete), fileName, sr.LineNumber - 1, 1);
else
throw new TextFileException(SR.GetString(SR.INFFileBracket, skip), fileName, sr.LineNumber - 1, 1);
ch = sr.Read();
continue;
}
// Read in name
name.Length = 0;
while (ch != '=') {
if (ch == '\r' || ch == '\n')
throw new TextFileException(SR.GetString(SR.NoEqualsWithNewLine, name.Length, name), fileName, sr.LineNumber, sr.LinePosition);
name.Append((char)ch);
ch = sr.Read();
if (ch == -1)
break;
}
if (name.Length == 0)
throw new TextFileException(SR.GetString(SR.NoEquals), fileName, sr.LineNumber, sr.LinePosition);
// For the INF file, we must allow a space on both sides of the equals
// sign. Deal with it.
if (name[name.Length-1] == ' ') {
name.Length = name.Length - 1;
}
ch = sr.Read(); // move past =
// If it exists, move past the first space after the equals sign.
if (ch == ' ')
ch = sr.Read();
// Read in value
value.Length = 0;
while(ch != -1) {
// Did we read @"\r" or @"\n"?
bool quotedNewLine = false;
if (ch == '\\') {
ch = sr.Read();
switch (ch) {
case '\\':
// nothing needed
break;
case 'n':
ch = '\n';
quotedNewLine = true;
break;
case 'r':
ch = '\r';
quotedNewLine = true;
break;
case 't':
ch = '\t';
break;
case '"':
ch = '\"';
break;
case 'u':
char[] hex = new char[4];
int numChars = 4;
int index = 0;
while(numChars > 0) {
int n = sr.Read(hex, index, numChars);
if (n == 0)
throw new TextFileException(SR.GetString(SR.BadEscape, (char) ch, name.ToString()), fileName, sr.LineNumber, sr.LinePosition);
index += n;
numChars -= n;
}
ch = (char) UInt16.Parse(new String(hex), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
quotedNewLine = (ch == '\n' || ch == '\r');
break;
default:
throw new TextFileException(SR.GetString(SR.BadEscape, (char) ch, name.ToString()), fileName, sr.LineNumber, sr.LinePosition);
}
}
// Consume endline...
// Endline can be \r\n or \n. But do not treat a
// quoted newline (ie, @"\r" or @"\n" in text) as a
// real new line. They aren't the end of a line.
if (!quotedNewLine) {
if (ch == '\r') {
ch = sr.Read();
if (ch == -1) {
break;
}
else if (ch == '\n') {
ch = sr.Read();
break;
}
}
else if (ch == '\n') {
ch = sr.Read();
break;
}
}
value.Append((char)ch);
ch = sr.Read();
}
// Note that value can be an empty string
AddResource(name.ToString(), value.ToString(), fileName, sr.LineNumber, sr.LinePosition);
}
}
}