예제 #1
0
        /// <summary>
        /// Create an instance by specified byte array and start position.
        /// </summary>
        /// <returns>An System.Array that contains all array members.</returns>
        public override object Parse(ElementInstance parent, Stream stream, long stopAt)
        {
            Debug.Assert(DataElement != null);

            int len = EvalLength(parent, stream, stopAt);

            ArrayList list = new ArrayList();
            for (int i = 0; i < len; i++)
            {
                list.Add(DataElement.Parse(parent, stream, stopAt));
            }

            ArrayInstance inst = new ArrayInstance(parent, DataElement, list.ToArray());
            return inst;
        }
예제 #2
0
 public StructInstance(ElementInstance parent, Element[] elements)
     : base(parent)
 {
     _elements = elements;
 }
예제 #3
0
 public ElementInstance(ElementInstance parent)
 {
     _parent = parent;
 }
예제 #4
0
 public ArrayInstance(ElementInstance parent, Element type, Object[] elements)
     : base(parent)
 {
     this.Type = type;
     this.Elements = elements;
 }
예제 #5
0
        private int EvalLength(ElementInstance parent, Stream stream, long stopAt)
        {
            int len = 0;

            if (Length == null)
            {
                Debug.Assert(stopAt >= stream.Position);
                len = (int)((stopAt - stream.Position) / DataElement.Size);
            }
            else
            {
                try
                {
                    len = Convert.ToInt32(Length);
                }
                catch (FormatException)
                {
                    IConvertible evalLen = parent.Eval(Length) as IConvertible;
                    if (evalLen != null)
                    {
                        len = evalLen.ToInt32(null);
                    }
                }
            }

            return len;
        }
예제 #6
0
        /// <summary>
        /// Create an instance by specified byte array and start position.
        /// </summary>
        public override object Parse(ElementInstance parent, Stream stream, long stopAt)
        {
            StructInstance inst = new StructInstance(parent, Elements);
            if (Elements != null)
            {
                foreach (Element elem in Elements)
                {
                    if (elem.EvalCondition(inst))
                    {
                        if (stream.Position >= stopAt)
                        {
                            break;	// don't read beyond boundary.
                        }

                        object elemInst = elem.Parse(inst, stream, stopAt);
                        // Elements that don't have a name will not be added directly
                        if (elem.Name != null && elem.Name != string.Empty)
                        {
                            inst[elem.Name] = elemInst;
                        }
                    }
                }
            }
            return inst;
        }
예제 #7
0
 private void AddBitFields(ElementInstance parent, int data)
 {
     if (BitsFields != null && parent is StructInstance)
     {
         foreach (BitsField f in BitsFields)
         {
             Debug.Assert(f.length >= 1);
             int mask = (1 << f.length) - 1;
             int bits = (data >> f.offset) & mask;
             ((StructInstance) parent)[f.name] = bits;
         }
     }
 }
예제 #8
0
        public override object Parse(ElementInstance parent, Stream stream, long stopAt)
        {
            char type = DataType[0];
            char prefix = Char.ToLower(type);
            int size = Size;

            string dataType = DataType.ToLower();

            if (prefix == 'b')  // byte
            {
                if (size <= 1)
                {
                    int b = stream.ReadByte();
                    AddBitFields(parent, b);
                    return b;
                }
                else
                {
                    byte[] data = new byte[size];
                    stream.Read( data, 0, size);
                    return data;
                }
            }
            else if (prefix == 's') // fixed-length string
            {
                byte[] data = new byte[size];
                stream.Read( data, 0, size);
                string s = Encoding.UTF8.GetString(data, 0, size);

                // a workaround for '\0'-stuffed stream
                if (s.IndexOf('\0') >= 0)
                {
                    s = s.Substring( 0, s.IndexOf("\0"));
                }
                return s;
            }
            else if (prefix == 'z') // zero-ended string
            {
                size = (int) (stopAt - stream.Position);

                byte[] data = new byte[size];
                stream.Read( data, 0, size);

                int z = Array.IndexOf(data, 0, 0, size);
                if (z < 0)
                    z = data.Length;

                string s = Encoding.UTF8.GetString(data, 0, z);
                return s;
            }
            // vluimsbf8: Variable length code unsigned integer, most significant bit first.
            // The size of vluimsbf8 is a multiple of one byte. The first bit (Ext) of each
            // byte specifies if set to 1 that another byte is present for this vluimsbf8 code
            // word. The unsigned integer is encoded by the concatenation of the seven least
            // significant bits of each byte belonging to this vluimsbf8 code word.
            else if (prefix == 'v')
            {
                int i = 0;
                int b = 0x80;
                int bytes = 0;
                for (; (b & 0x80) != 0; bytes++)
                {
                    b = stream.ReadByte();
                    i = i << 7 | (b & 0x7f);
                }

                if (type == 'v' && bytes > 1)
                {
                    return Util.EndianFlip(i, bytes);
                }
                return i;
            }
            else if ("iuf".IndexOf(prefix) >= 0) // signed/unsigned integer
            {
                byte[] data = new byte[size];
                stream.Read( data, 0, size);

                if (size == 8)
                {
                    long i = data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24 |
                             data[4] << 32 | data[5] << 40 | data[6] << 48 | data[7] << 56;
                    return i;
                }
                else if (size == 4 || size == 3)
                {
                    int i;

                    if (size == 4)
                    {
                        i = data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24;
                    }
                    else
                    {
                        i = data[0] | data[1] << 8 | data[2] << 16;
                    }

                    // Big-indian integer is identified by upper case 'I'
                    if (type == 'I')
                    {
                        return Util.EndianFlip(i, size);
                    }
                    // Big-indian unsigned integer is identified by upper case 'U'
                    else if (type == 'U')
                    {
                        return Util.EndianFlip((uint) i, size);
                    }
                    else if (type == 'u')
                    {
                        return (uint) i;
                    }
                    return i;
                }
                else if (size == 2)
                {
                    short i = (short) (data[0] | data[1] << 8);
                    if (type == 'I')
                    {
                        return (short) Util.EndianFlip((int) i, size);
                    }
                    else if (type == 'U')
                    {
                        return (ushort) Util.EndianFlip(((uint) i), size);
                    }
                    else if (type == 'u')
                    {
                        return (ushort) i;
                    }

                    return i;
                }
                else
                {
                    Debug.Assert( false, "Invalid field size!");
                }
            }

            return null;
        }
예제 #9
0
 /// <summary>
 /// To construct instance from specified stream.
 /// </summary>
 /// <param name="parent"></param>
 /// <param name="stream"></param>
 /// <param name="stopAt"></param>
 /// <returns></returns>
 public abstract object Parse(ElementInstance parent, Stream stream, long stopAt);
예제 #10
0
        /// <summary>
        /// Evaluate bool expression
        /// </summary>
        /// <param name="inst"></param>
        /// <returns></returns>
        public bool EvalCondition(ElementInstance inst)
        {
            if (Condition != null)
            {
                try
                {
                    BoolExprLexer lexer = new BoolExprLexer(new StringReader(Condition));
                    BoolExprParser parser = new BoolExprParser(lexer);
                    ConditionEvaluator treeParser = new ConditionEvaluator();

                    parser.expression();
                    antlr.collections.AST ast = parser.getAST();

                    treeParser.Instance = inst;
                    return treeParser.expression(ast);
                }
                catch (Exception ex)
                {
                    Debug.Write(ex);
                    return false;
                }
            }

            return true;
        }