From: Clark C . E. <cc...@cl...> - 2001-06-05 22:44:48
|
Jason, I don't want to step on toes... so let me know if I am... but, anyway, I spent some time thinking this trough a bit more.... ... First, what a simple "printer" would look like from the application programmer's perspective. Simply connect the dots, i.e., get the reader and writer interfaces and then connect them together. Large processing-pipelines can be built using something like this... IYamlIterator reader = new YamlReader(inputstream); IYamlVisitor writer = new YamlWriter(outputstream); YamlConnect(reader,writer); Second, here is the new improved YAML interface proposal... this seperates out the items common to the Iterator and Visitor and puts them into a single "Event" class... namespace YAML { pubic interface IYamlEvent { string Key { get; } /* if parent is a map */ int Index { get; } /* if parent is a list */ string Anchor { get; } IYamlNodeType Type { get; } IYamlNode Node { get; } /* in-memory repr, if any */ } public interface IYamlIterator : extends IYamlEvent { bool Next(); IYamlIterator First(); IYamlIterator Parent { get; } string Read { get; } } public interface IYamlVisitor { IYamlVisitor Begin( IYamlEvent event ); void Write( string ChunkOfValue ); void End( IYamlEvent event ); } public enum YamlNodeType { Scalar, List, Map, Reference } // // in-memory directed graph nodes... // public interface IYamlNode { YamlNodeType Type { get; } string Value { get; } IYamlNode Child(string key); /* maps only */ IYamlNode Child(int index); /* lists only */ int Size() { get; } /* lists only */ IYamlIterator Children(); IYamlIterator Parents(); void VisitChildren(IYamlVisitor); void VisitParents(IYamlVisitor); } } Third, here is what the push to pull connect function would look like. This is a generic Iterator to Visitor converter which would be part of the standard YAML library. void YamlConect( IYamlVisitor writer, IYamlIterator reader ) { do { IYamlVisitor childWriter = writer->Begin(reader); if(childWriter) { switch(reader.Type) { case Map: case List: IYamlIterator childReader = reader->First(); if(childReader) YamlConnect(childWriter,childReader); case Scalar: childWriter->Write(reader->Read()); } } writer->End(reader); while(reader.Next()); } This may look complicated, beacuse the "first" and "begin" function return subordinate processors. However, this gives greater flexibility since at each level of the processing hierarchy a subordinate Iterator or Visitor can hold state information. Best, Clark |