public SimisJinxReader(SimisStreamReader reader, SimisProvider provider, SimisJinxFormat jinxStreamFormat) : base(reader) { JinxStreamFormat = jinxStreamFormat; SimisProvider = provider; StreamLength = reader.UncompressedLength; BlockEndOffsets = new Stack <uint>(); PendingTokens = new Queue <SimisToken>(); ReadStream(out JinxStreamIsBinary, ref JinxStreamFormat); }
SimisFile(string fileName, bool streamIsBinary, bool streamIsCompressed, bool jinxStreamIsBinary, SimisJinxFormat jinxStreamFormat, SimisTreeNode tree, SimisAce ace, SimisProvider simisProvider) { FileName = fileName; StreamIsBinary = streamIsBinary; StreamIsCompressed = streamIsCompressed; JinxStreamIsBinary = jinxStreamIsBinary; JinxStreamFormat = jinxStreamFormat; Tree = tree; Ace = ace; SimisProvider = simisProvider; }
void ReadStream(out bool JinxStreamIsBinary, ref SimisJinxFormat JinxStreamFormat) { { PinReader(); var signature = new String(Reader.ReadChars(4)); if ((signature[3] != 'b') && (signature[3] != 't')) { throw new ReaderException(Reader, Reader.StreamIsBinary, PinReaderChanged(), "Signature '" + signature + "' is invalid. Final character must be 'b' or 't'."); } JinxStreamIsBinary = (signature[3] == 'b'); var simisFormat = signature.Substring(1, 2); if (JinxStreamFormat != null) { if (JinxStreamFormat.Format != simisFormat) { throw new ReaderException(Reader, JinxStreamIsBinary, PinReaderChanged(), "Simis format '" + simisFormat + "' does not match format provided by caller '" + JinxStreamFormat.Format + "'."); } } else { JinxStreamFormat = SimisProvider.GetForFormat(simisFormat); if (JinxStreamFormat == null) { throw new ReaderException(Reader, JinxStreamIsBinary, PinReaderChanged(), "Simis format '" + simisFormat + "' is not known to " + SimisProvider + "."); } } } { PinReader(); var signature = new String(Reader.ReadChars(8)); if (signature != "______\r\n") { throw new ReaderException(Reader, JinxStreamIsBinary, PinReaderChanged(), "Signature '" + signature + "' is invalid."); } } if (!JinxStreamIsBinary) { // Consume all whitespace up to the first token. while ((Reader.BaseStream.Position < Reader.BaseStream.Length) && WhitespaceChars.Any(c => c == Reader.PeekChar())) { Reader.ReadChar(); } } }
public SimisProvider(string directory) { var tokenNames = new Dictionary <uint, string>(); var tokenIds = new Dictionary <string, uint>(); var formats = new List <SimisJinxFormat>(); foreach (var filename in Directory.GetFiles(directory, "*.bnf")) { var BNF = new BnfFile(filename); try { BNF.ReadFile(); } catch (FileException ex) { if (ex.InnerException is InvalidDataException) { // BNF didn't specify all required stuff, skip it. continue; } throw ex; } var simisFormat = new SimisJinxFormat(BNF); formats.Add(simisFormat); } formats.Sort((a, b) => StringComparer.InvariantCultureIgnoreCase.Compare(a.Name, b.Name)); using (var tokens = new StreamReader(File.OpenRead(directory + @"\tokens.csv"), Encoding.ASCII)) { while (!tokens.EndOfStream) { var csv = tokens.ReadLine().Split(','); if ((csv.Length != 3) || !csv[0].StartsWith("0x") || !csv[1].StartsWith("0x")) { continue; } var tokenId = (uint)(ushort.Parse(csv[0].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture) << 16) + ushort.Parse(csv[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); tokenNames.Add(tokenId, csv[2]); tokenIds.Add(csv[2], tokenId); } } TokenNames = tokenNames; TokenIds = tokenIds; Formats = formats; }
public SimisJinxWriter(SimisStreamWriter writer, SimisProvider simisProvider, bool jinxStreamIsBinary, SimisJinxFormat jinxStreamFormat) : base(writer) { SimisProvider = simisProvider; JinxStreamIsBinary = jinxStreamIsBinary; JinxStreamFormat = jinxStreamFormat; TextBlocked = true; BlockStarts = new Stack <long>(); if (JinxStreamIsBinary) { Writer.Write(("JINX0" + JinxStreamFormat.Format + "b______\r\n").ToCharArray()); } else { Writer.Write(("JINX0" + JinxStreamFormat.Format + "t______\r\n\r\n").ToCharArray()); } }
public static SimisReader FromStream(Stream stream, SimisProvider simisProvider, SimisJinxFormat jinxStreamFormat) { if (!stream.CanRead) { throw new ArgumentException("Stream must support reading.", "stream"); } if (!stream.CanSeek) { throw new ArgumentException("Stream must support seeking.", "stream"); } var reader = SimisStreamReader.FromStream(stream); var position = reader.BaseStream.Position; var signature = new String(reader.ReadChars(4)); switch (signature) { case "JINX": return(new SimisJinxReader(reader, simisProvider, jinxStreamFormat)); case "\x01\x00\x00\x00": return(new SimisAceReader(reader)); default: throw new ReaderException(reader, reader.StreamIsBinary, (int)(reader.BaseStream.Position - position), "Signature '" + signature + "' is invalid."); } }
public static SimisJinxWriter ToJinxStream(Stream stream, bool streamIsBinary, bool streamIsCompressed, SimisProvider simisProvider, bool jinxStreamIsBinary, SimisJinxFormat jinxStreamFormat) { if (!stream.CanWrite) { throw new ArgumentException("Stream must support writing.", "stream"); } if (!stream.CanSeek) { throw new ArgumentException("Stream must support seeking.", "stream"); } return(new SimisJinxWriter(SimisStreamWriter.ToStream(stream, streamIsBinary, streamIsCompressed), simisProvider, jinxStreamIsBinary, jinxStreamFormat)); }
void ReadStream(Stream stream, out bool streamIsBinary, out bool streamIsCompressed, out bool jinxStreamIsBinary, out SimisJinxFormat jinxStreamFormat, out SimisTreeNode tree, out SimisAce ace) { using (var reader = SimisReader.FromStream(stream, SimisProvider, JinxStreamFormat)) { streamIsBinary = reader.StreamIsBinary; streamIsCompressed = reader.StreamIsCompressed; switch (reader.GetType().Name) { case "SimisJinxReader": var readerJinx = (SimisJinxReader)reader; var blockStack = new Stack <KeyValuePair <SimisToken, List <SimisTreeNode> > >(); blockStack.Push(new KeyValuePair <SimisToken, List <SimisTreeNode> >(null, new List <SimisTreeNode>())); while (!readerJinx.EndOfStream) { var token = readerJinx.ReadToken(); switch (token.Kind) { case SimisTokenKind.Block: blockStack.Push(new KeyValuePair <SimisToken, List <SimisTreeNode> >(token, new List <SimisTreeNode>())); break; case SimisTokenKind.BlockBegin: break; case SimisTokenKind.BlockEnd: if (blockStack.Peek().Key != null) { var block = blockStack.Pop(); var node = new SimisTreeNode(block.Key.Type, block.Key.Name, block.Value); blockStack.Peek().Value.Add(node); } break; case SimisTokenKind.IntegerUnsigned: blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerUnsigned(token.Type, token.Name, token.IntegerUnsigned)); break; case SimisTokenKind.IntegerSigned: blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerSigned(token.Type, token.Name, token.IntegerSigned)); break; case SimisTokenKind.IntegerDWord: blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerDWord(token.Type, token.Name, token.IntegerDWord)); break; case SimisTokenKind.IntegerWord: blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerWord(token.Type, token.Name, (ushort)token.IntegerDWord)); break; case SimisTokenKind.IntegerByte: blockStack.Peek().Value.Add(new SimisTreeNodeValueIntegerByte(token.Type, token.Name, (byte)token.IntegerDWord)); break; case SimisTokenKind.Float: blockStack.Peek().Value.Add(new SimisTreeNodeValueFloat(token.Type, token.Name, token.Float)); break; case SimisTokenKind.String: blockStack.Peek().Value.Add(new SimisTreeNodeValueString(token.Type, token.Name, token.String)); break; } } var rootBlock = blockStack.Pop(); jinxStreamIsBinary = readerJinx.JinxStreamIsBinary; jinxStreamFormat = readerJinx.JinxStreamFormat; tree = new SimisTreeNode("<root>", "", rootBlock.Value); ace = null; break; case "SimisAceReader": var readerAce = (SimisAceReader)reader; jinxStreamIsBinary = false; jinxStreamFormat = null; tree = null; ace = readerAce.Read(); break; default: throw new NotImplementedException(); } } }
/// <summary> /// Creates a <see cref="SimisFile"/> from the component parts (JINX type). /// </summary> /// <param name="fileName">The file to write to.</param> /// <param name="streamIsBinary">The <see cref="bool"/> indicating whether the stream should use binary/ASCII or Unicode text (UTF-16) when written from this <see cref="SimisFile"/>.</param> /// <param name="streamIsCompressed">The <see cref="bool"/> indicating whether the stream should be compressed when written from this <see cref="SimisFile"/>.</param> /// <param name="jinxStreamIsBinary">The <see cref="bool"/> indicating whether the Jinx stream should use binary or text when written from this <see cref="SimisFile"/>.</param> /// <param name="jinxStreamFormat">The <see cref="SimisJinxFormat"/> for this <see cref="SimisFile"/>.</param> /// <param name="tree">The <see cref="SimisTreeNode"/> tree for this <see cref="SimisFile"/>.</param> /// <param name="simisProvider">A <see cref="SimisProvider"/> within which the appropriate <see cref="Bnf"/> for writing can be found.</param> public SimisFile(string fileName, bool streamIsBinary, bool streamIsCompressed, bool jinxStreamIsBinary, SimisJinxFormat jinxStreamFormat, SimisTreeNode tree, SimisProvider simisProvider) : this(fileName, streamIsBinary, streamIsCompressed, jinxStreamIsBinary, jinxStreamFormat, tree, null, simisProvider) { }