예제 #1
0
            public bool Match(StructureField fa, StructureField fb)
            {
                this.fa            = fa;
                this.fb            = fb;
                this.fNestedStruct = null;
                this.fOther        = null;
                this.NextFieldA    = null;
                this.NextFieldB    = null;
                var strFa = fa.DataType.TypeReferenceAs <StructureType>();
                var strFb = fb.DataType.TypeReferenceAs <StructureType>();

                // only one field should be nested structure
                if (
                    (strFa == null && strFb == null) ||
                    (strFa != null && strFb != null))
                {
                    return(false);
                }

                // check which of two fields is nested structure and store it
                // and other field in corresponding variables.
                int strSize;

                if (strFa != null)
                {
                    fNestedStruct = fa;
                    fOther        = fb;
                    strSize       = strFa.GetInferredSize();
                }
                else
                {
                    fNestedStruct = fb;
                    fOther        = fa;
                    strSize       = strFb.GetInferredSize();
                }

                // check if other field is inside nested structure
                return(
                    fOther.Offset >= fNestedStruct.Offset &&
                    fOther.Offset < fNestedStruct.Offset + strSize);
            }
예제 #2
0
        public int Compare(StructureType x, StructureType y, int count)
        {
            int d;

            if (x.Size > 0 && y.Size > 0)
            {
                d = x.Size - y.Size;
                if (d != 0)
                {
                    return(d);
                }
            }
            d = x.Fields.Count - y.Fields.Count;
            if (d != 0)
            {
                return(d);
            }

            ++count;
            IEnumerator <StructureField> ex = x.Fields.GetEnumerator();
            IEnumerator <StructureField> ey = y.Fields.GetEnumerator();

            while (ex.MoveNext())
            {
                ey.MoveNext();
                StructureField fx = ex.Current;
                StructureField fy = ey.Current;
                d = fx.Offset - fy.Offset;
                if (d != 0)
                {
                    return(d);
                }
                d = Compare(fx.DataType, fy.DataType, count);
                if (d != 0)
                {
                    return(d);
                }
            }
            return(0);
        }
예제 #3
0
        /// <summary>
        /// Unifies two structures by merging the fields in offset order.
        /// </summary>
        /// <remarks>
        /// Fields are taken from
        /// </remarks>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public DataType UnifyStructures(StructureType a, StructureType b)
        {
            int newSize = 0;

            if (a.Size != 0 && b.Size != 0)
            {
                if (a.Size != b.Size)
                {
                    return(MakeUnion(a, b));
                }
                else
                {
                    newSize = a.Size;
                }
            }
            else if (a.Size != 0)
            {
                newSize = a.Size;
            }
            else if (b.Size != 0)
            {
                newSize = b.Size;
            }

            string name = null;

            if (a.Name != null)
            {
                if (b.Name != null && a.Name != b.Name)
                {
                    throw new NotSupportedException("Both structures have names! Woo! Return null and make union of it?");
                }
                else
                {
                    name = a.Name;
                }
            }
            else
            {
                name = b.Name;
            }

            StructureType mem = factory.CreateStructureType(name, newSize);

            mem.IsSegment = (a.IsSegment || b.IsSegment);

            IEnumerator <StructureField> ea = a.Fields.GetEnumerator();
            IEnumerator <StructureField> eb = b.Fields.GetEnumerator();
            StructureField fa = null;
            StructureField fb = null;

            for (;;)
            {
                if (fa == null && ea.MoveNext())
                {
                    fa = ea.Current;
                }
                if (fb == null && eb.MoveNext())
                {
                    fb = eb.Current;
                }

                if (fa == null || fb == null)
                {
                    break;
                }

                if (fa.Offset < fb.Offset)
                {
                    mem.Fields.Add(fa.Clone());
                    fa = null;
                }
                else if (fa.Offset > fb.Offset)
                {
                    mem.Fields.Add(fb.Clone());
                    fb = null;
                }
                else
                {
                    var    fieldType = Unify(fa.DataType, fb.DataType);
                    string fieldName;
                    if (!TryMakeFieldName(fa, fb, out fieldName))
                    {
                        throw new NotSupportedException(
                                  string.Format(
                                      "Failed to unify field '{0}' in structure '{1}' with field '{2}' in structure '{3}'.",
                                      fa.Name, a, fb.Name, b));
                    }
                    mem.Fields.Add(fa.Offset, fieldType, fieldName);
                    fa = null;
                    fb = null;
                }
            }
            if (fa != null)
            {
                mem.Fields.Add(fa);
                while (ea.MoveNext())
                {
                    StructureField f = ea.Current;
                    mem.Fields.Add(f.Clone());
                }
            }
            if (fb != null)
            {
                mem.Fields.Add(fb);
                while (eb.MoveNext())
                {
                    StructureField f = eb.Current;
                    mem.Fields.Add(f.Clone());
                }
            }
            mem.ForceStructure = a.ForceStructure | b.ForceStructure;
            return(mem);
        }
예제 #4
0
 public TypeVariable EnsureFieldTypeVariable(TypeFactory factory, StructureField field)
 {
     throw new NotImplementedException();
 }