コード例 #1
0
ファイル: ByteArrayCodec.cs プロジェクト: JornWildt/Ramone
 public object ReadFrom(ReaderContext context)
 {
     using (MemoryStream input = new MemoryStream())
       {
     context.HttpStream.CopyTo(input);
     return input.ToArray();
       }
 }
コード例 #2
0
ファイル: CatAsHtmlCodec.cs プロジェクト: miqui/Ramone
 public object ReadFrom(ReaderContext context)
 {
   string text = null;
   using (StreamReader r = new StreamReader(context.HttpStream, Encoding.UTF8))
   {
     text = r.ReadToEnd();
   }
   return new Cat { Name = text };
 }
コード例 #3
0
        public object ReadFrom(ReaderContext context)
        {
            Encoding enc = MediaTypeParser.GetEncodingFromCharset(context.Response.ContentType, context.Session.DefaultEncoding);

              using (var textReader = new StreamReader(context.HttpStream, enc))
              using (var reader = XmlReader.Create(textReader))
              {
            return ReadFrom(reader, context);
              }
        }
コード例 #4
0
ファイル: AtomItemCodec.cs プロジェクト: miqui/Ramone
 protected override object ReadFrom(XmlReader reader, ReaderContext context)
 {
   return SyndicationItem.Load(reader);
 }
コード例 #5
0
ファイル: Parser.cs プロジェクト: themotte/utils
        /// <summary>
        /// Pass an XML document string in for processing.
        /// </summary>
        /// <param name="stringName">A human-readable identifier useful for debugging. Generally, the name of the file that the string was read from. Not required (but very useful.)</param>
        public void AddString(string input, string stringName = "(unnamed)")
        {
            // This is a really easy error to make; we might as well handle it.
            if (input.EndsWith(".xml"))
            {
                Dbg.Err($"It looks like you've passed the filename {input} to AddString instead of the actual XML file. Either use AddFile() or pass the file contents in.");
            }

            if (s_Status != Status.Accumulating)
            {
                Dbg.Err($"Adding data while while the world is in {s_Status} state; should be {Status.Accumulating} state");
            }

            XDocument doc;

            try
            {
                doc = XDocument.Parse(input, LoadOptions.SetLineInfo);
            }
            catch (System.Xml.XmlException e)
            {
                Dbg.Ex(e);
                return;
            }

            if (doc.Elements().Count() > 1)
            {
                // This isn't testable, unfortunately; XDocument doesn't even support multiple root elements.
                Dbg.Err($"{stringName}: Found {doc.Elements().Count()} root elements instead of the expected 1");
            }

            var readerContext = new ReaderContext(stringName, false);

            foreach (var rootElement in doc.Elements())
            {
                if (rootElement.Name.LocalName != "Defs")
                {
                    Dbg.Wrn($"{stringName}:{rootElement.LineNumber()}: Found root element with name \"{rootElement.Name.LocalName}\" when it should be \"Defs\"");
                }

                foreach (var defElement in rootElement.Elements())
                {
                    string typeName = defElement.Name.LocalName;

                    Type typeHandle = UtilType.ParseDefFormatted(typeName, stringName, defElement.LineNumber());
                    if (typeHandle == null || !typeof(Def).IsAssignableFrom(typeHandle))
                    {
                        Dbg.Err($"{stringName}:{defElement.LineNumber()}: {typeName} is not a valid root Def type");
                        continue;
                    }

                    if (defElement.Attribute("defName") == null)
                    {
                        Dbg.Err($"{stringName}:{defElement.LineNumber()}: No def name provided");
                        continue;
                    }

                    string defName = defElement.Attribute("defName").Value;
                    if (!DefNameValidator.IsMatch(defName))
                    {
                        Dbg.Err($"{stringName}:{defElement.LineNumber()}: Def name \"{defName}\" doesn't match regex pattern \"{DefNameValidator}\"");
                        continue;
                    }

                    // Consume defName so we know it's not hanging around
                    defElement.Attribute("defName").Remove();

                    // Check to see if we're abstract
                    bool abstrct = false;
                    {
                        var abstractAttribute = defElement.Attribute("abstract");
                        if (abstractAttribute != null)
                        {
                            if (!bool.TryParse(abstractAttribute.Value, out abstrct))
                            {
                                Dbg.Err($"{stringName}:{defElement.LineNumber()}: Error encountered when parsing abstract attribute");
                            }

                            abstractAttribute.Remove();
                        }
                    }

                    // Get our parent info
                    string parent = null;
                    {
                        var parentAttribute = defElement.Attribute("parent");
                        if (parentAttribute != null)
                        {
                            parent = parentAttribute.Value;

                            parentAttribute.Remove();
                        }
                    }

                    // Register ourselves as an available parenting object
                    {
                        var identifier = Tuple.Create(typeHandle.GetDefRootType(), defName);
                        if (potentialParents.ContainsKey(identifier))
                        {
                            Dbg.Err($"{stringName}:{defElement.LineNumber()}: Def {identifier.Item1}:{identifier:Item2} redefined");
                        }
                        else
                        {
                            potentialParents[identifier] = new Parent {
                                xml = defElement, context = readerContext, parent = parent
                            };
                        }
                    }

                    if (!abstrct)
                    {
                        // Not abstract, so create our instance
                        var defInstance = (Def)Activator.CreateInstance(typeHandle);
                        defInstance.DefName = defName;

                        Database.Register(defInstance);

                        if (parent == null)
                        {
                            // Non-parent objects are simple; we just handle them here in order to avoid unnecessary GC churn
                            finishWork.Add(() => Serialization.ParseElement(defElement, typeHandle, defInstance, readerContext, isRootDef: true));
                        }
                        else
                        {
                            // Add an inheritance resolution job; we'll take care of this soon
                            inheritanceJobs.Add(new InheritanceJob {
                                target = defInstance, xml = defElement, context = readerContext, parent = parent
                            });
                        }
                    }
                }
            }
        }
コード例 #6
0
 protected override JsonPatchDocument ReadFrom(TextReader reader, ReaderContext context)
 {
     return(JsonPatchDocument.Read(reader));
 }
コード例 #7
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				Type t = (Type) ReadObject (r, ctx);
				object value = ReadObject (r, ctx);
				
				return Enum.ToObject (t, value);
			}
コード例 #8
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				int len = Read7BitEncodedInt (r);
				ArrayList l = new ArrayList (len);
				
				for (int i = 0; i < len; i++)
					l.Add (ReadObject (r, ctx));
				
				return l;
			}
コード例 #9
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				return r.ReadChar ();
			}
コード例 #10
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				if (token == PrimaryId) {
					string s = r.ReadString ();
					ctx.CacheItem (s);
					return s;
				} else {
					return ctx.GetCache (r.ReadInt16 ());
				}
			}
コード例 #11
0
 public void Read(IntPtr data, ref int index, ref object result, ReaderContext context)
 {
     result = Activator.CreateInstance(typeof(I1Impl));
     factory(typeof(I1Impl)).Read(data, ref index, ref result, context);
 }
コード例 #12
0
        internal static object ParseElement(XElement element, Type type, object model, ReaderContext context, bool isRootDef = false, bool hasReferenceId = false)
        {
            // The first thing we do is parse all our attributes. This is because we want to verify that there are no attributes being ignored.
            // Don't return anything until we do our element.HasAtttributes check!

            // Figure out our intended type, if it's been overridden
            if (element.Attribute("class") != null)
            {
                var className    = element.Attribute("class").Value;
                var possibleType = (Type)ParseString(className, typeof(Type), null, context.sourceName, element.LineNumber());
                if (!type.IsAssignableFrom(possibleType))
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Explicit type {className} cannot be assigned to expected type {type}");
                }
                else if (model != null && model.GetType() != possibleType)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Explicit type {className} does not match already-provided instance {type}");
                }
                else
                {
                    type = possibleType;
                }

                element.Attribute("class").Remove();
            }

            bool   shouldBeNull = bool.Parse(element.ConsumeAttribute("null") ?? "false");
            string refId        = element.ConsumeAttribute("ref");

            if (shouldBeNull && refId != null)
            {
                Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Element cannot be both null and a reference at the same time");

                // There's no good answer here, but we're sticking with the null because it feels like an error-handling path that the user is more likely to properly support.
                refId = null;
            }

            // See if we just want to return null
            if (shouldBeNull)
            {
                // No remaining attributes are allowed in nulls
                if (element.HasAttributes)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Has unconsumed attributes");
                }

                // okay
                return(null);

                // Note: It may seem wrong that we can return null along with a non-null model.
                // The problem is that this is meant to be able to override defaults. If the default if an object, explicitly setting it to null *should* clear the object out.
                // If we actually need a specific object to be returned, for whatever reason, the caller has to do the comparison.
            }

            // See if we can get a ref out of it
            if (refId != null)
            {
                // No remaining attributes are allowed in refs
                if (element.HasAttributes)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Has unconsumed attributes");
                }

                if (context == null)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Found a reference object outside of record-reader mode");
                    return(model);
                }

                if (!context.refs.ContainsKey(refId))
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Found a reference object {refId} without a valid reference mapping");
                    return(model);
                }

                object refObject = context.refs[refId];
                if (!type.IsAssignableFrom(refObject.GetType()))
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Reference object {refId} is of type {refObject.GetType()}, which cannot be converted to expected type {type}");
                    return(model);
                }

                return(refObject);
            }

            // Converters may do their own processing, so we'll just defer off to them now; hell, you can even have both elements and text, if that's your jam
            if (Converters.ContainsKey(type))
            {
                // context might be null; that's OK at the moment
                object result;

                try
                {
                    result = Converters[type].Record(model, type, new RecorderReader(element, context));
                }
                catch (Exception e)
                {
                    Dbg.Ex(e);

                    if (model != null)
                    {
                        result = model;
                    }
                    else if (type.IsValueType)
                    {
                        result = Activator.CreateInstance(type);
                    }
                    else
                    {
                        result = null;
                    }
                }

                // This is an important check if we have a referenced type, because if we've changed the result, references won't link up to it properly.
                // Outside referenced types, it doesn't matter - we want to give people as much control over modification as possible.
                if (model != null && hasReferenceId && model != result)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Converter {Converters[type].GetType()} for {type} ignored the model {model} while reading a referenced object; this may cause lost data");
                    return(result);
                }

                if (result != null && !type.IsAssignableFrom(result.GetType()))
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Converter {Converters[type].GetType()} for {type} returned unexpected type {result.GetType()}");
                    return(null);
                }

                return(result);
            }

            // After this point we won't be using a converter in any way, we'll be requiring native Def types (as native as it gets, at least)

            bool hasElements = element.Elements().Any();
            bool hasText     = element.Nodes().OfType <XText>().Any();

            if (typeof(Def).IsAssignableFrom(type) && hasElements && !isRootDef)
            {
                Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Inline def definitions are not currently supported");
                return(null);
            }

            // Special case: IRecordables
            if (typeof(IRecordable).IsAssignableFrom(type))
            {
                var recordable = (IRecordable)(model ?? Activator.CreateInstance(type));

                recordable.Record(new RecorderReader(element, context));

                // TODO: support indices if this is within the Def system?

                return(recordable);
            }

            // No remaining attributes are allowed past this point!
            if (element.HasAttributes)
            {
                Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Has unconsumed attributes");
            }

            // All our standard text-using options
            if (hasText ||
                (typeof(Def).IsAssignableFrom(type) && !isRootDef) ||
                type == typeof(Type) ||
                type == typeof(string) ||
                type.IsPrimitive)
            {
                if (hasElements)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Elements are not valid when parsing {type}");
                }

                return(ParseString(element.GetText(), type, model, context.sourceName, element.LineNumber()));
            }

            // Nothing past this point even supports text, so let's just get angry and break stuff.
            if (hasText)
            {
                Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Text detected in a situation where it is invalid; will be ignored");
            }

            // Special case: Lists
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>))
            {
                // List<> handling
                Type referencedType = type.GetGenericArguments()[0];

                var list = (IList)(model ?? Activator.CreateInstance(type));

                // If you have a default list, but specify it in XML, we assume this is a full override. Clear the original list.
                list.Clear();

                foreach (var fieldElement in element.Elements())
                {
                    if (fieldElement.Name.LocalName != "li")
                    {
                        Dbg.Err($"{context.sourceName}:{fieldElement.LineNumber()}: Tag should be <li>, is <{fieldElement.Name.LocalName}>");
                    }

                    list.Add(ParseElement(fieldElement, referencedType, null, context));
                }

                return(list);
            }

            // Special case: Arrays
            if (type.IsArray)
            {
                Type referencedType = type.GetElementType();

                var elements = element.Elements().ToArray();

                // We don't bother falling back on model here; we probably need to recreate it anyway with the right length
                var array = (Array)Activator.CreateInstance(type, new object[] { elements.Length });

                for (int i = 0; i < elements.Length; ++i)
                {
                    var fieldElement = elements[i];
                    if (fieldElement.Name.LocalName != "li")
                    {
                        Dbg.Err($"{context.sourceName}:{fieldElement.LineNumber()}: Tag should be <li>, is <{fieldElement.Name.LocalName}>");
                    }

                    array.SetValue(ParseElement(fieldElement, referencedType, null, context), i);
                }

                return(array);
            }

            // Special case: Dictionaries
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary <,>))
            {
                // Dictionary<> handling
                Type keyType   = type.GetGenericArguments()[0];
                Type valueType = type.GetGenericArguments()[1];

                var dict = (IDictionary)(model ?? Activator.CreateInstance(type));

                // If you have a default dict, but specify it in XML, we assume this is a full override. Clear the original dict.
                dict.Clear();

                foreach (var fieldElement in element.Elements())
                {
                    if (fieldElement.Name.LocalName == "li")
                    {
                        // Treat this like a key/value pair
                        var keyNode   = fieldElement.ElementNamed("key");
                        var valueNode = fieldElement.ElementNamed("value");

                        if (keyNode == null)
                        {
                            Dbg.Err($"{context.sourceName}:{fieldElement.LineNumber()}: Dictionary includes li tag without a key");
                            continue;
                        }

                        if (valueNode == null)
                        {
                            Dbg.Err($"{context.sourceName}:{fieldElement.LineNumber()}: Dictionary includes li tag without a value");
                            continue;
                        }

                        var key = ParseElement(keyNode, keyType, null, context);

                        if (dict.Contains(key))
                        {
                            Dbg.Err($"{context.sourceName}:{fieldElement.LineNumber()}: Dictionary includes duplicate key {key.ToString()}");
                        }

                        dict[key] = ParseElement(valueNode, valueType, null, context);
                    }
                    else
                    {
                        var key = ParseString(fieldElement.Name.LocalName, keyType, null, context.sourceName, fieldElement.LineNumber());

                        if (dict.Contains(key))
                        {
                            Dbg.Err($"{context.sourceName}:{fieldElement.LineNumber()}: Dictionary includes duplicate key {fieldElement.Name.LocalName}");
                        }

                        dict[key] = ParseElement(fieldElement, valueType, null, context);
                    }
                }

                return(dict);
            }

            // At this point, we're either a class or a struct, and we need to do the reflection thing

            // If we have refs, something has gone wrong; we should never be doing reflection inside a Record system.
            // This is a really ad-hoc way of testing this and should be fixed.
            // One big problem here is that I'm OK with security vulnerabilities in def xmls. Those are either supplied by the developer or by mod authors who are intended to have full code support anyway.
            // I'm less OK with security vulnerabilities in save files. Nobody expects a savefile can compromise their system.
            // And the full reflection system is probably impossible to secure, whereas the Record system should be secureable.
            if (context.RecorderMode)
            {
                Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Falling back to reflection within a Record system; this is currently not allowed for security reasons");
                return(model);
            }

            // If we haven't been given a template class from our parent, go ahead and init to defaults
            if (model == null)
            {
                model = Activator.CreateInstance(type);
            }

            var setFields = new HashSet <string>();

            foreach (var fieldElement in element.Elements())
            {
                // Check for fields that have been set multiple times
                string fieldName = fieldElement.Name.LocalName;
                if (setFields.Contains(fieldName))
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Duplicate field {fieldName}");
                    // Just allow us to fall through; it's an error, but one with a reasonably obvious handling mechanism
                }
                setFields.Add(fieldName);

                var fieldInfo = type.GetFieldFromHierarchy(fieldName);
                if (fieldInfo == null)
                {
                    // Try to find a close match, if we can, just for a better error message
                    string match = null;
                    string canonicalFieldName = Util.LooseMatchCanonicalize(fieldName);

                    foreach (var testField in type.GetFieldsFromHierarchy())
                    {
                        if (Util.LooseMatchCanonicalize(testField.Name) == canonicalFieldName)
                        {
                            match = testField.Name;

                            // We could in theory do something overly clever where we try to find the best name, but I really don't care that much; this is meant as a quick suggestion, not an ironclad solution.
                            break;
                        }
                    }

                    if (match != null)
                    {
                        Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Field {fieldName} does not exist in type {type}; did you mean {match}?");
                    }
                    else
                    {
                        Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Field {fieldName} does not exist in type {type}");
                    }

                    continue;
                }

                if (fieldInfo.GetCustomAttribute <IndexAttribute>() != null)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Attempting to set index field {fieldName}; these are generated by the def system");
                    continue;
                }

                if (fieldInfo.GetCustomAttribute <NonSerializedAttribute>() != null)
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Attempting to set nonserialized field {fieldName}");
                    continue;
                }

                // Check for fields we're not allowed to set
                if (UtilReflection.ReflectionSetForbidden(fieldInfo))
                {
                    Dbg.Err($"{context.sourceName}:{element.LineNumber()}: Field {fieldName} is not allowed to be set through reflection");
                    continue;
                }

                fieldInfo.SetValue(model, ParseElement(fieldElement, fieldInfo.FieldType, fieldInfo.GetValue(model), context));
            }


            // Set up our index fields; this has to happen last in case we're a struct
            Index.Register(ref model);

            return(model);
        }
コード例 #13
0
 public void Read(ReaderContext context)
 {
 }
コード例 #14
0
        protected override object ReadFrom(XmlReader reader, ReaderContext context)
        {
            XmlSerializer serializer = GetSerializer(context.DataType);

            return(serializer.Deserialize(reader));
        }
コード例 #15
0
 public virtual void Read(ReaderContext context)
 {
     context.Scope.ActiveObject[FieldName] = Type.Read(context);
 }
コード例 #16
0
 protected abstract object ReadFrom(XmlReader reader, ReaderContext context);
コード例 #17
0
ファイル: InputBody.cs プロジェクト: likeshan168/graphite
 protected InputBody(ReaderContext context, T data)
     : this(context.Name, context.Filename, context.ContentType,
            context.ContentEncoding, context.ContentLength,
            context.Headers, data)
 {
 }
コード例 #18
0
ファイル: XmlBamlReader.cs プロジェクト: 95ulisse/ILEdit
			public ReaderContext(ReaderContext previous)
			{
				this.Previous = previous;
			}
コード例 #19
0
 public void Read(ReaderContext context)
 {
     context.Reader.Align(BlockSize);
 }
コード例 #20
0
ファイル: StreamCodec.cs プロジェクト: miqui/Ramone
 public object ReadFrom(ReaderContext context)
 {
   return context.HttpStream;
 }
コード例 #21
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				if (token == PrimaryId)
					return r.ReadInt32 ();
				else
					return (int) r.ReadByte ();
			}
コード例 #22
0
 public void Setup()
 {
     reader   = new PropertiesReader();
     context  = new ReaderContext();
     document = new CircuitDiagramDocument();
 }
コード例 #23
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				Pair p = new Pair ();
				p.First = ReadObject (r, ctx);
				p.Second = ReadObject (r, ctx);
				return p;
			}
コード例 #24
0
 public object ReadFrom(ReaderContext context)
 {
     return(context.HttpStream);
 }
コード例 #25
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				int len = Read7BitEncodedInt (r);
				object [] ret = new object [len];
				
				for (int i = 0; i < len; i++)
					ret [i] = ReadObject (r, ctx);
				
				return ret;
			}
コード例 #26
0
 protected abstract object ReadFrom(XmlReader reader, ReaderContext context);
コード例 #27
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				if (token == SecondaryId)
					return _binaryFormatter.Deserialize (r.BaseStream);
				Type t = (Type) ReadObject (r, ctx);
				int len = Read7BitEncodedInt (r);
				Array val = Array.CreateInstance (t, len);
				
				for (int i = 0; i < len; i++)
					val.SetValue (ReadObject (r, ctx), i);
				
				return val;
			}
コード例 #28
0
 protected override object Read(byte token, BinaryReader r, ReaderContext ctx)
 {
     return(Unit.Parse((string)base.Read(token, r, ctx)));
 }
コード例 #29
0
 protected override string ReadFrom(TextReader reader, ReaderContext context)
 {
     return(reader.ReadToEnd());
 }
コード例 #30
0
 protected abstract object Read(byte token, BinaryReader r, ReaderContext ctx);
コード例 #31
0
ファイル: Parser.cs プロジェクト: themotte/utils
        /// <summary>
        /// Finish all parsing.
        /// </summary>
        public void Finish()
        {
            if (s_Status != Status.Accumulating)
            {
                Dbg.Err($"Finishing while the world is in {s_Status} state; should be {Status.Accumulating} state");
            }
            s_Status = Status.Processing;

            // Resolve all our inheritance jobs
            foreach (var work in inheritanceJobs)
            {
                // These are the actions we need to perform; we actually have to resolve these backwards (it makes their construction a little easier)
                // The final parse is listed first, then all the children up to the final point
                var actions = new List <Action>();

                actions.Add(() => Serialization.ParseElement(work.xml, work.target.GetType(), work.target, work.context, isRootDef: true));

                string        currentDefName = work.target.DefName;
                XElement      currentXml     = work.xml;
                ReaderContext currentContext = work.context;

                string parentDefName = work.parent;
                while (parentDefName != null)
                {
                    var parentData = potentialParents.TryGetValue(Tuple.Create(work.target.GetType().GetDefRootType(), parentDefName));

                    // This is a struct for the sake of performance, so child itself won't be null
                    if (parentData.xml == null)
                    {
                        Dbg.Err($"{currentContext.sourceName}:{currentXml.LineNumber()}: Def {currentDefName} is attempting to use parent {parentDefName}, but no such def exists");

                        // Not much more we can do here.
                        break;
                    }

                    actions.Add(() => Serialization.ParseElement(parentData.xml, work.target.GetType(), work.target, parentData.context, isRootDef: true));

                    currentDefName = parentDefName;
                    currentXml     = parentData.xml;
                    currentContext = parentData.context;

                    parentDefName = parentData.parent;
                }

                finishWork.Add(() =>
                {
                    for (int i = actions.Count - 1; i >= 0; --i)
                    {
                        actions[i]();
                    }
                });
            }

            foreach (var work in finishWork)
            {
                work();
            }

            if (s_Status != Status.Processing)
            {
                Dbg.Err($"Distributing while the world is in {s_Status} state; should be {Status.Processing} state");
            }
            s_Status = Status.Distributing;

            staticReferencesRegistering.Clear();
            staticReferencesRegistering.UnionWith(staticReferences);
            foreach (var stat in staticReferences)
            {
                StaticReferencesAttribute.StaticReferencesFilled.Add(stat);

                foreach (var field in stat.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static))
                {
                    var def = Database.Get(field.FieldType, field.Name);
                    if (def == null)
                    {
                        Dbg.Err($"Failed to find {field.FieldType} named {field.Name}");
                    }
                    else if (!field.FieldType.IsAssignableFrom(def.GetType()))
                    {
                        Dbg.Err($"Static reference {field.FieldType} {stat}.{field.Name} is not compatible with {def.GetType()} {def}");
                        field.SetValue(null, null); // this is unnecessary, but it does kick the static constructor just in case we wouldn't do it otherwise
                    }
                    else
                    {
                        field.SetValue(null, def);
                    }
                }

                if (!staticReferencesRegistered.Contains(stat))
                {
                    Dbg.Err($"Failed to properly register {stat}; you may be missing a call to Def.StaticReferences.Initialized() in its static constructor");
                }
            }

            if (s_Status != Status.Distributing)
            {
                Dbg.Err($"Finalizing while the world is in {s_Status} state; should be {Status.Distributing} state");
            }
            s_Status = Status.Finalizing;

            foreach (var def in Database.List)
            {
                try
                {
                    def.ConfigErrors(err => Dbg.Err($"{def.GetType()} {def}: {err}"));
                }
                catch (Exception e)
                {
                    Dbg.Ex(e);
                }
            }

            foreach (var def in Database.List)
            {
                try
                {
                    def.PostLoad(err => Dbg.Err($"{def.GetType()} {def}: {err}"));
                }
                catch (Exception e)
                {
                    Dbg.Ex(e);
                }
            }

            if (s_Status != Status.Finalizing)
            {
                Dbg.Err($"Completing while the world is in {s_Status} state; should be {Status.Finalizing} state");
            }
            s_Status = Status.Finished;
        }
コード例 #32
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				Type t = (Type) ObjectFormatter.ReadObject (r, ctx);
				converter = TypeDescriptor.GetConverter (t);
				token = r.ReadByte ();
				string v = (string) base.Read (token, r, ctx);
				return converter.ConvertFrom (null, Helpers.InvariantCulture, v);
			}
コード例 #33
0
ファイル: XmlBamlReader.cs プロジェクト: 95ulisse/ILEdit
			public ReaderContext()
			{
				this.Previous = this;
			}
コード例 #34
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected abstract object Read (byte token, BinaryReader r, ReaderContext ctx);
コード例 #35
0
 protected override object Read(byte token, BinaryReader r, ReaderContext ctx)
 {
     return(token == PrimaryId);
 }
コード例 #36
0
 public ReadersController(ReaderContext context)
 {
     _context = context;
 }
コード例 #37
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				int len = Read7BitEncodedInt (r);
				byte [] buf = r.ReadBytes (len);
				if (buf.Length != len)
					throw new Exception ();
				
				return new BinaryFormatter ().Deserialize (new MemoryStream (buf));
			}
コード例 #38
0
 protected override object Read(byte token, BinaryReader r, ReaderContext ctx)
 {
     return(r.ReadChar());
 }
コード例 #39
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			public static object ReadObject (BinaryReader r, ReaderContext ctx)
			{
				byte sig = r.ReadByte ();
				
				if (sig == 0)
					return null;
				
				return readMap [sig].Read (sig, r, ctx);
			}
コード例 #40
0
 protected override object Read(byte token, BinaryReader r, ReaderContext ctx)
 {
     return(new DateTime(r.ReadInt64()));
 }
コード例 #41
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				string s = base.Read (token, r, ctx) as string;
				if (String.IsNullOrEmpty (s))
					throw new InvalidOperationException ("string must not be null or empty.");
				
				return new IndexedString (s);
			}
コード例 #42
0
 protected override object ReadFrom(XmlReader reader, ReaderContext context)
 {
     return(SyndicationItem.Load(reader));
 }
コード例 #43
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				return token == PrimaryId;
			}
コード例 #44
0
ファイル: TextCodecBase.cs プロジェクト: mathiaskok/Ramone
 protected abstract TEntity ReadFrom(TextReader reader, ReaderContext context);
コード例 #45
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				return new DateTime (r.ReadInt64 ());
			}
コード例 #46
0
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				if (token == PrimaryId)
					return Color.FromArgb (r.ReadInt32 ());
				else
					return Color.FromKnownColor ((KnownColor) r.ReadInt32 ());
			}
コード例 #47
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				Triplet t = new Triplet ();
				t.First = ReadObject (r, ctx);
				t.Second = ReadObject (r, ctx);
				t.Third = ReadObject (r, ctx);
				return t;
			}
コード例 #48
0
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				Type t = (Type) ReadObject (r, ctx);
				int len = Read7BitEncodedInt (r);
				Array val = Array.CreateInstance (t, len);
				
				for (int i = 0; i < len; i++)
					val.SetValue (ReadObject (r, ctx), i);
				
				return val;
			}
コード例 #49
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				int len = Read7BitEncodedInt (r);
				Hashtable ht = new Hashtable (len);
				
				for (int i = 0; i < len; i++) {
					object key = ReadObject (r, ctx);
					object val = ReadObject (r, ctx);
					
					ht.Add (key, val);
				}
				
				return ht;
			}
コード例 #50
0
        public override Resources.CreatePostDescriptor ReadFromHtml(HtmlDocument html, ReaderContext context)
        {
            HtmlNode doc = html.DocumentNode;

            Resources.CreatePostDescriptor descriptor = new CreatePostDescriptor
            {
                Form = doc.SelectNodes(@"//form").First().Form(context.Session,
                                                               new Uri(context.Response.ResponseUri.GetLeftPart(UriPartial.Path)),
                                                               context.Response.CharacterSet)
            };

            return(descriptor);
        }
コード例 #51
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				int value = r.ReadInt32 ();
				if (token == PrimaryId)
					return Color.FromArgb (value);
				else {
					if (value == -1) //isempty marker
						return Color.Empty;
					return Color.FromKnownColor ((KnownColor)value);
				}
			}
コード例 #52
0
        /// <summary>
        /// Parses the output of Write, generating an object and all its related serialized data.
        /// </summary>
        public static T Read <T>(string input, string stringName = "input")
        {
            XDocument doc;

            try
            {
                doc = XDocument.Parse(input, LoadOptions.SetLineInfo);
            }
            catch (System.Xml.XmlException e)
            {
                Dbg.Ex(e);
                return(default(T));
            }

            if (doc.Elements().Count() > 1)
            {
                // This isn't testable, unfortunately; XDocument doesn't even support multiple root elements.
                Dbg.Err($"{stringName}: Found {doc.Elements().Count()} root elements instead of the expected 1");
            }

            var record = doc.Elements().First();

            if (record.Name.LocalName != "Record")
            {
                Dbg.Wrn($"{stringName}:{record.LineNumber()}: Found root element with name \"{record.Name.LocalName}\" when it should be \"Record\"");
            }

            var recordFormatVersion = record.ElementNamed("recordFormatVersion");

            if (recordFormatVersion == null)
            {
                Dbg.Err($"{stringName}:{record.LineNumber()}: Missing record format version, assuming the data is up-to-date");
            }
            else if (recordFormatVersion.GetText() != "1")
            {
                Dbg.Err($"{stringName}:{recordFormatVersion.LineNumber()}: Unknown record format version {recordFormatVersion.GetText()}, expected 1 or earlier");

                // I would rather not guess about this
                return(default(T));
            }

            var refs = record.ElementNamed("refs");

            var readerContext = new ReaderContext(stringName, true);

            if (refs != null)
            {
                // First, we need to make the instances for all the references, so they can be crosslinked appropriately
                foreach (var reference in refs.Elements())
                {
                    if (reference.Name.LocalName != "Ref")
                    {
                        Dbg.Wrn($"{stringName}:{reference.LineNumber()}: Reference element should be named 'Ref'");
                    }

                    var id = reference.Attribute("id")?.Value;
                    if (id == null)
                    {
                        Dbg.Err($"{stringName}:{reference.LineNumber()}: Missing reference ID");
                        continue;
                    }

                    var className = reference.Attribute("class")?.Value;
                    if (className == null)
                    {
                        Dbg.Err($"{stringName}:{reference.LineNumber()}: Missing reference class name");
                        continue;
                    }

                    var possibleType = (Type)Serialization.ParseString(className, typeof(Type), null, stringName, reference.LineNumber());
                    if (possibleType.IsValueType)
                    {
                        Dbg.Err($"{stringName}:{reference.LineNumber()}: Reference assigned type {possibleType}, which is a value type");
                        continue;
                    }

                    // Create a stub so other things can reference it later
                    readerContext.refs[id] = possibleType.CreateInstanceSafe("object", () => $"{stringName}:{reference.LineNumber()}");
                    // Might be null; that's okay, CreateInstanceSafe has done the error reporting
                }

                // Now that all the refs exist, we can run through them again and actually parse them
                foreach (var reference in refs.Elements())
                {
                    var id = reference.Attribute("id")?.Value;
                    if (id == null)
                    {
                        // Just skip it, we don't have anything useful we can do here
                        continue;
                    }

                    // The serialization routines don't know how to deal with this, so we'll remove it now
                    reference.Attribute("id").Remove();

                    var refInstance = readerContext.refs.TryGetValue(id);
                    if (refInstance == null)
                    {
                        // We failed to parse this for some reason, so just skip it now
                        continue;
                    }

                    // Do our actual parsing
                    var refInstanceOutput = Serialization.ParseElement(reference, refInstance.GetType(), refInstance, readerContext, hasReferenceId: true);

                    if (refInstance != refInstanceOutput)
                    {
                        Dbg.Err($"{stringName}:{reference.LineNumber()}: Something really bizarre has happened and we got the wrong object back. Things are probably irrevocably broken. Please report this as a bug in Dec.");
                        continue;
                    }
                }
            }

            var data = record.ElementNamed("data");

            if (data == null)
            {
                Dbg.Err($"{stringName}:{record.LineNumber()}: No data element provided. This is not very recoverable.");

                return(default(T));
            }

            // And now, we can finally parse our actual root element!
            // (which accounts for a tiny percentage of things that need to be parsed)
            return((T)Serialization.ParseElement(data, typeof(T), null, readerContext));
        }
コード例 #53
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				if (token == PrimaryId) {
					string type = r.ReadString ();
					string assembly = r.ReadString ();
					Type t = Assembly.Load (assembly).GetType (type);
					ctx.CacheItem (t);
					return t;
				} else {
					return ctx.GetCache (r.ReadInt16 ());
				}
			}
コード例 #54
0
 public abstract T ReadFromHtml(HtmlDocument html, ReaderContext context);
コード例 #55
0
ファイル: ObjectStateFormatter.cs プロジェクト: nlhepler/mono
			protected override object Read (byte token, BinaryReader r, ReaderContext ctx)
			{
				return Unit.Parse ((string) base.Read (token, r, ctx));
			}
コード例 #56
0
        protected override object ReadFrom(TextReader reader, ReaderContext context)
        {
            FormUrlEncodingSerializer serializer = new FormUrlEncodingSerializer(context.DataType);

            return(serializer.Deserialize(reader, context.Session.SerializerSettings));
        }