Пример #1
0
        private void button1_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            Sh4Blocks.GetBlocks(BlockListType.MostTimeConsuming, 30);
            disasmview1.Text = x86Disasm.DisasmBytesBlock(
                Sh4Blocks.blocks[0].x86Code
                , Sh4Blocks.blocks[0].CompiledBlock
                );
            for (u32 i = 0; i < Sh4Blocks.blocks.Length; i++)
            {
                ListViewItem temp = new ListViewItem
                                    (
                    new string[]
                {
                    h32b(Sh4Blocks.blocks[i].address),
                    Sh4Blocks.blocks[i].size.ToString(),
                    Sh4Blocks.blocks[i].Cycles.ToString(),

                    Sh4Blocks.blocks[i].Calls.ToString(),
                    Sh4Blocks.blocks[i].CallTime.ToString(),

                    Sh4Blocks.blocks[i].x86CyclesPerCall.ToString(),
                    Sh4Blocks.blocks[i].x86CyclesPerSh4Cycle.ToString(),
                    Sh4Blocks.blocks[i].x86CyclesPerSh4Op.ToString()
                }
                                    );
                temp.Tag = Sh4Blocks.blocks[i];
                listView1.Items.Add(temp);
            }
        }
Пример #2
0
            public bool Read(BinaryReader br)
            {
                u32 bytes = br.ReadUInt32();

                // bit format:
                // aaaa aaaa iiic cccc cccc cccc cccc cccc

                // 8-bits : number of attributes
                Attributes = Convert.ToByte(bytes & 0xFF);

                // 3-bits : info flags
                RawInfo = Convert.ToByte((bytes >> 8) & 0x7);

                // 21-bits : number of child nodes
                u32 raw_children = (bytes >> 11) & 0x1FFFFF;

                // note: we store raw_children as u16 for alignment purposes
                // aaaa aaaa iiic cccc cccc cccc ccc- ---- (- = ignored)

#if DEBUG
                if (raw_children > 0xFFFF)
                {
                    //Console.WriteLine("Warning: huge number of child nodes");
                }
#endif

                Children = Convert.ToUInt16(raw_children & 0xFFFF);

                return(true);
            }
Пример #3
0
        Node[] GetNodeArray()
        {
            List <Node> nodes = new List <Node>();

            // level 0
            nodes.Add(root);
            // level 1+
            u32 depth = 1;

            while (true)
            {
                Node[] ns = GetNodesAtDepth(root.Nodes, depth);

                if (ns.Length == 0)
                {
                    break;
                }
                else
                {
                    nodes.AddRange(ns);
                    ++depth;
                }
            }

            return(nodes.ToArray());
        }
Пример #4
0
        private bool ReadWrapper(BinaryReader br, ref Node owner, u32 depth)
        {
            bool success = true;

            Node n = new Node();

            success &= n.Read(br, depth);

            // try to parse other blocks
            if (success)
            {
                if (n.Offset != 0)
                {
                    long pos = br.BaseStream.Position;

                    // seek to child pos
                    br.BaseStream.Position = n.Offset;

                    for (u32 i = 0; i < n.Flags.Children; i++)
                    {
                        success &= ReadWrapper(br, ref n, depth + 1);
                    }

                    // seek back
                    br.BaseStream.Position = pos;
                }

                owner.Nodes.Add(n);
            }

            return(success);
        }
Пример #5
0
        public static string DecodeString(BinaryReader br, u32 size)
        {
            byte[] b = br.ReadBytes((int)size);

            string str = chEnc.GetString(b);

            return(str.Replace("\n", SourceNewLineMarker));
        }
Пример #6
0
            public Ref(string raw_string, bool coreString)
            {
                offset    = 0;
                value     = raw_string;
                main_pool = coreString;

                AddToCache();
            }
Пример #7
0
            public Ref(BinaryReader br, bool coreString)
            {
                offset    = 0;
                value     = ReadNullTerminatedString(br, br.ReadUInt32());
                main_pool = coreString;

                AddToCache();
            }
Пример #8
0
 public u64 ReadU64()
 {
     fixed(byte *bptr = &data[read_index])
     {
         read_index += 8;
         return(*(u64 *)bptr);
     }
 }
Пример #9
0
 public u32 ReadU32()
 {
     fixed(byte *bptr = &data[read_index])
     {
         read_index += 4;
         return(*(u32 *)bptr);
     }
 }
Пример #10
0
            public bool Write(BinaryWriter bw, u32 of1, u32 of2)
            {
                // text offset
                Text.Fixup(of1, of2);
                bw.Write(Text.offset);
                // flags
                Flags.Write(bw);
                foreach (Attribute a in Attributes)
                {
                    a.Name.Fixup(of1, of2);
                    a.Value.Fixup(of1, of2);
                    a.Write(bw);
                }

                switch (Flags.RawInfo)
                {
                case 0:
                    bw.Write(Offset);
                    break;

                case 1:
                    End.Fixup(of1, of2);
                    bw.Write(End.offset);
                    bw.Write(Offset);
                    break;

                case 2:
                case 6:
                    End.Fixup(of1, of2);
                    bw.Write(End.offset);
                    if (Flags.Children > 0)
                    {
                        bw.Write(Offset);
                    }
                    break;

                case 3:
                case 7:
                    Inner.Fixup(of1, of2);
                    End2.Fixup(of1, of2);
                    bw.Write(Inner.offset);
                    bw.Write(End2.offset);
                    if (Flags.Children > 0)
                    {
                        bw.Write(Offset);
                    }
                    break;

                default:
                    //Console.WriteLine("Unsupported info");
                    break;
                }

                return(true);
            }
Пример #11
0
        static u32 GetShaderNum(u32 UseAlpha, u32 Texture, u32 IgnoreTexA, u32 ShadInstr, u32 Offset)
        {
            u32 rv = 0;

            rv |= UseAlpha; rv <<= 1;
            rv |= Texture; rv <<= 1;
            rv |= IgnoreTexA; rv <<= 2;
            rv |= ShadInstr; rv <<= 1;
            rv |= Offset;

            return(rv);
        }
Пример #12
0
            public void Write(BinaryWriter bw)
            {
                u32 val = Value;

                while (val >= 0x80)
                {
                    u8 b = (u8)(val | 0x80);

                    bw.Write(b);
                    val >>= 7;
                }

                bw.Write((u8)(val & 0xFF));
            }
Пример #13
0
            public u32 Length()
            {
                u32 val = Value;
                u32 len = 1;

                while (val >= 0x80)
                {
                    u8 b = (u8)(val | 0x80);
                    val >>= 7;
                    len++;
                }

                return(len);
            }
Пример #14
0
        public static void GetBlocks(BlockListType type, u32 count)
        {
            nullDCInstance.dpa packet = new nullDCInstance.dpa();
            ndc.SendString("blocks " + ((u32)type).ToString() + " " + count.ToString() + " 0");//the last 0 is for binary transfer :)
            ndc.GetPacket(ref packet);
            u32 blk_num = (u32)(packet.sz / (9 * 4));

            blocks = new Sh4Block[blk_num];
            for (u32 i = 0; i < blk_num; i++)
            {
                blocks[i] = new Sh4Block();
                blocks[i].ReadFromPacket(ref packet);
            }
        }
Пример #15
0
        static public string ReadNullTerminatedString(BinaryReader br, u32 targetpos)
        {
#if DEBUG
            if (targetpos >= br.BaseStream.Length)
            {
                return("");
            }
#endif

            long   pos = br.BaseStream.Position;
            string str = ReadNullTerminatedStringAt(br, targetpos);
            br.BaseStream.Position = pos;

            return(str);
        }
Пример #16
0
        public static bool GetNumber(string val, ref u32 result)
        {
            bool valid = true;

            try
            {
                result = 0;
                result = Convert.ToUInt32(val);
            }
            catch
            {
                valid = false;
            }

            return(valid);
        }
Пример #17
0
            public void PrepareForExport()
            {
                // xxxxx refactor asap

                Inst[] items = Strings.OrderBy(x => x.Value).ToArray();

                u32 InternalOffset = 0;

                for (int i = 0; i < items.Count(); i++)
                {
                    items[i].Offset = InternalOffset;
                    InternalOffset += Convert.ToUInt32(items[i].Value.Length + 1);
                }

                Strings = items.ToList();
            }
Пример #18
0
            public u32 Size()
            {
                u32 my_size = 0;

                // text offset
                my_size += 4;
                // flags
                my_size += NodeFlags.Size();
                // attribute entries (read from flags)
                my_size += Attribute.Size() * Flags.Attributes;
                // check against info
                switch (Flags.RawInfo)
                {
                case 0:
                    my_size += 4;
                    break;

                case 1:
                    my_size += 4 + 4;
                    break;

                case 2:
                case 6:
                    my_size += 4;
                    if (Flags.Children > 0)
                    {
                        my_size += 4;
                    }
                    break;

                case 3:
                case 7:
                    my_size += 4 + 4;
                    if (Flags.Children > 0)
                    {
                        my_size += 4;
                    }
                    break;

                default:
                    //Console.WriteLine("Unsupported info");
                    break;
                }

                return(my_size);
            }
Пример #19
0
            public bool Read(BinaryReader br)
            {
                bool valid = true;

                string magic = Encoding.Default.GetString(br.ReadBytes(XML_FLAG.Length));

                valid &= (magic == XML_FLAG);

                blockData        = br.ReadUInt32();
                blockStrings     = br.ReadUInt32();
                blockLineEndings = br.ReadUInt32();

                valid &= (blockLineEndings < br.BaseStream.Length);
                valid &= (blockStrings < blockLineEndings);
                valid &= (blockData < blockStrings);

                return(valid);
            }
Пример #20
0
            public bool Write(BinaryWriter bw)
            {
                u32 bytes = 0;

                u32 tmp = Children;

                bytes |= tmp << 11;

                tmp    = RawInfo;
                bytes |= (tmp & 0x7) << 8;

                tmp    = Attributes;
                bytes |= (tmp & 0xFF);

                bw.Write(bytes);

                return(true);
            }
Пример #21
0
 public void ReadFromPacket(ref nullprof.nullDCInstance.dpa packet)
 {
     // u32 addr;
     address = packet.ReadU32();
     // void* sh4_code;
     sh4Code = packet.ReadU32();
     // void* x86_code;
     x86Code = packet.ReadU32();
     // u32 sh4_bytes;
     size = packet.ReadU32();
     // u32 x86_bytes;
     x86CodeSize = packet.ReadU32();
     // u32 sh4_cycles;
     Cycles = packet.ReadU32();
     //u64 time;
     CallTime = packet.ReadU64();
     // u32 calls;
     Calls = packet.ReadU32();
 }
Пример #22
0
            public void Read(BinaryReader br)
            {
                int val   = 0;
                int shift = 0;

                while (shift < (5 * 7))
                {
                    u8 b = br.ReadByte();

                    val   |= ((b & 0x7F) << shift);
                    shift += 7;

                    if ((b & 0x80) == 0)
                    {
                        break;
                    }
                }

                Value = (u32)val;
            }
Пример #23
0
        static void Main(string[] args)
        {
            string Shader = File.ReadAllText("pixel.cg");

            for (u32 UseAlpha = 0; UseAlpha < 2; UseAlpha++)
            {
                for (u32 Texture = 0; Texture < 2; Texture++)
                {
                    bool fst = true;
                    for (u32 IgnoreTexA = 0; IgnoreTexA < 2; IgnoreTexA++)
                    {
                        for (u32 ShadInstr = 0; ShadInstr < 4; ShadInstr++)
                        {
                            for (u32 Offset = 0; Offset < 2; Offset++)
                            {
                                if (Texture == 0 && !fst)
                                {
                                    fst = fst;
                                }
                                else
                                {
                                    u32    sid  = GetShaderNum(UseAlpha, Texture, IgnoreTexA, ShadInstr, Offset);
                                    string file = "pixel_" + sid + ".cg";
                                    string data =
                                        "#define pp_UseAlpha " + UseAlpha + "\n" +
                                        "#define pp_Texture " + Texture + "\n" +
                                        "#define pp_IgnoreTexA " + IgnoreTexA + "\n" +
                                        "#define pp_ShadInstr " + ShadInstr + "\n" +
                                        "#define pp_Offset " + Offset + "\n";

                                    File.WriteAllText(file, data + Shader.Replace("ps_main_%d", "ps_main_" + sid));
                                    Console.Write("shaders/" + file + " ");
                                }
                                fst = false;
                            }
                        }
                    }
                }
            }
        }
Пример #24
0
        // horrible. but we need all child nodes ordered by depth in a 1d array
        Node[] GetNodesAtDepth(List <Node> nodes, u32 depth)
        {
            List <Node> local_nodes = new List <Node>();

            foreach (Node n in nodes)
            {
                if (n.Depth == depth)
                {
                    local_nodes.Add(n);
                }
                else if (n.Depth < depth)
                {
                    Node[] ns = GetNodesAtDepth(n.Nodes, depth);
                    if (ns.Length > 0)
                    {
                        local_nodes.AddRange(ns);
                    }
                }
            }

            return(local_nodes.ToArray());
        }
Пример #25
0
            // Text file with edits into database
            public bool ReadSource(string file_name)
            {
                bool valid = true;

                localeDb.Clear();

                valid &= File.Exists(file_name);

                if (valid)
                {
                    StreamReader src = new StreamReader(file_name);

                    u32    item_id = 0;
                    string name;
                    while ((name = src.ReadLine()) != null)
                    {
                        // horrible check that name is actually the item_id
                        if (GetNumber(name, ref item_id))
                        {
                            name = src.ReadLine();
                        }

                        string value = src.ReadLine();

                        if (value == null)
                        {
                            valid = false;
                            break;
                        }

                        localeDb.Add(new Entry(name, value, item_id));
                    }

                    src.Close();
                }

                return(valid);
            }
Пример #26
0
 public void Fixup(u32 of1, u32 of2, u32 of3)
 {
     blockData        = of1;
     blockStrings     = of2;
     blockLineEndings = of3;
 }
Пример #27
0
            public bool Read(BinaryReader br, u32 depth)
            {
                bool valid = true;

                Depth = depth;
                Text  = new AlienString.Ref(br, true);

                valid &= Flags.Read(br);

                // get attributes

                if (Flags.Attributes > 0)
                {
#if DEBUG
                    if (Flags.Attributes > 100)
                    {
                        //Console.WriteLine("Possible large number of attributes -> {0} (node={1})", Flags.Attributes, Text);
                    }
#endif
                    for (u32 attribs = 0; attribs < (u32)Flags.Attributes; attribs++)
                    {
                        Attribute a = new Attribute();
                        valid &= a.Read(br);

                        if (!valid)
                        {
                            return(false);
                        }

                        Attributes.Add(a);
                    }
                }

                switch (Flags.RawInfo)
                {
                case 0:     // 000

                    Offset = br.ReadUInt32();

#if DEBUG
                    if (Offset != 28)
                    {
                        // Console.WriteLine("Interesting offset {0}", Offset);
                    }
#endif

                    break;

                case 1:     // 001
                    End    = new AlienString.Ref(br, false);
                    Offset = br.ReadUInt32();

                    break;

                case 2:     // 010 -> last in sequence
                case 6:     // 110 -> continued sequence
                    End = new AlienString.Ref(br, false);

                    if (Flags.Children > 0)
                    {
                        Offset = br.ReadUInt32();
                    }

                    break;

                case 3:     // 011 -> last in sequence
                case 7:     // 111 -> continued sequence

                    // note: inner text is stored in the second pool

                    Inner = new AlienString.Ref(br, false);    // inner text or line diff
                    End2  = new AlienString.Ref(br, false);    // line ending

                    if (Flags.Children > 0)
                    {
                        Offset = br.ReadUInt32();
                    }

                    break;

                default:
                    // flags may need sorting out
                    break;
                }

                return(valid);
            }
Пример #28
0
            public int op; /* The opcode */

            #endregion Fields

            #region Constructors

            public _aFlagOp(int op, u32 mask)
            {
                this.op = op;
                this.mask = mask;
            }
Пример #29
0
        /*
         *************************************************************************
         **
         ** This file contains low-level memory & pool allocation drivers
         **
         ** This file contains implementations of the low-level memory allocation
         ** routines specified in the sqlite3_mem_methods object.
         **
         *************************************************************************
         */

        /*
        ** Like malloc(), but remember the size of the allocation
        ** so that we can find it later using sqlite3MemSize().
        **
        ** For this low-level routine, we are guaranteed that nByte>0 because
        ** cases of nByte<=0 will be intercepted and dealt with by higher level
        ** routines.
        */
#if SQLITE_POOL_MEM
#if TRUE
        static byte[] sqlite3MemMalloc(u32 nByte)
        {
            return(new byte[nByte]);
        }
Пример #30
0
/*
** Change the value of the P3 operand for a specific instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
  assert( p!=0 );
  if( ((u32)p->nOp)>addr ){
    p->aOp[addr].p3 = val;
  }
}
Пример #31
0
        static int sqlite3VdbeSerialGet(
            byte[] buf,     /* Buffer to deserialize from */
            u32 serial_type,              /* Serial type to deserialize */
            Mem pMem                     /* Memory cell to write value into */
            )
        {
            switch ( serial_type )
              {
            case 10:   /* Reserved for future use */
            case 11:   /* Reserved for future use */
            case 0:
              {  /* NULL */
            pMem.flags = MEM_Null;
            break;
              }
            case 1:
              { /* 1-byte signed integer */
            pMem.u.i = (sbyte)buf[0];
            pMem.flags = MEM_Int;
            return 1;
              }
            case 2:
              { /* 2-byte signed integer */
            pMem.u.i = (int)( ( ( buf[0] ) << 8 ) | buf[1] );
            pMem.flags = MEM_Int;
            return 2;
              }
            case 3:
              { /* 3-byte signed integer */
            pMem.u.i = (int)( ( ( buf[0] ) << 16 ) | ( buf[1] << 8 ) | buf[2] );
            pMem.flags = MEM_Int;
            return 3;
              }
            case 4:
              { /* 4-byte signed integer */
            pMem.u.i = (int)( ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] );
            pMem.flags = MEM_Int;
            return 4;
              }
            case 5:
              { /* 6-byte signed integer */
            u64 x = (ulong)( ( ( buf[0] ) << 8 ) | buf[1] );
            u32 y = (u32)( ( buf[2] << 24 ) | ( buf[3] << 16 ) | ( buf[4] << 8 ) | buf[5] );
            x = ( x << 32 ) | y;
            pMem.u.i = (i64)x;
            pMem.flags = MEM_Int;
            return 6;
              }
            case 6:   /* 8-byte signed integer */
            case 7:
              { /* IEEE floating point */
            u64 x;
            u32 y;
            #if !NDEBUG && !SQLITE_OMIT_FLOATING_POINT
            /* Verify that integers and floating point values use the same
            ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
            ** defined that 64-bit floating point values really are mixed
            ** endian.
            */
            const u64 t1 = ( (u64)0x3ff00000 ) << 32;
            const double r1 = 1.0;
            u64 t2 = t1;
            #if  SQLITE_MIXED_ENDIAN_64BIT_FLOAT
            swapMixedEndianFloat(t2);
            #endif
            Debug.Assert( sizeof( double ) == sizeof( u64 ) && memcmp( BitConverter.GetBytes( r1 ), BitConverter.GetBytes( t2 ), sizeof( double ) ) == 0 );//Debug.Assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, t2, sizeof(r1))==0 );
            #endif

            x = (u64)( ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] );
            y = (u32)( ( buf[4] << 24 ) | ( buf[5] << 16 ) | ( buf[6] << 8 ) | buf[7] );
            x = ( x << 32 ) | y;
            if ( serial_type == 6 )
            {
              pMem.u.i = (i64)x;
              pMem.flags = MEM_Int;
            }
            else
            {
              Debug.Assert( sizeof( i64 ) == 8 && sizeof( double ) == 8 );
            #if  SQLITE_MIXED_ENDIAN_64BIT_FLOAT
            swapMixedEndianFloat(x);
            #endif
            #if WINDOWS_PHONE
            pMem.r = BitConverter.ToDouble(BitConverter.GetBytes((long)x), 0);
            #else
              pMem.r = BitConverter.Int64BitsToDouble( (long)x );// memcpy(pMem.r, x, sizeof(x))
            #endif
              pMem.flags = MEM_Real;
            }
            return 8;
              }
            case 8:    /* Integer 0 */
            case 9:
              {  /* Integer 1 */
            pMem.u.i = serial_type - 8;
            pMem.flags = MEM_Int;
            return 0;
              }
            default:
              {
            int len = (int)( ( serial_type - 12 ) / 2 );
            pMem.xDel = null;
            if ( ( serial_type & 0x01 ) != 0 )
            {
              pMem.flags = MEM_Str | MEM_Ephem;
              pMem.z = Encoding.UTF8.GetString( buf, 0, len );//memcpy( buf, pMem.z, len );
              pMem.n = pMem.z.Length;// len;
              pMem.zBLOB = null;
            }
            else
            {
              pMem.flags = MEM_Blob | MEM_Ephem;
              pMem.zBLOB = sqlite3Malloc( len );
              buf.CopyTo( pMem.zBLOB, 0 );
              pMem.n = len;// len;
              pMem.z = null;
            }
            return len;
              }
              }
              return 0;
        }
Пример #32
0
 static u32 sqlite3VdbeSerialTypeLen( u32 serial_type )
 {
     if ( serial_type >= 12 )
       {
     return (u32)( ( serial_type - 12 ) / 2 );
       }
       else
       {
     return aSize[serial_type];
       }
 }
Пример #33
0
        public bool ExportBML(BinaryWriter bw)
        {
            // the nodes are exported as a single-dimensional blob (instead of a tree using recursion)

            // pass 1; recursively fixup all nodes (mainly the flags)
            FixupAllNodes(root, true);

            // pass 2; strip the node relationships and fetch our node blob
            Node[] nodearray = GetNodeArray();

            // pass 3; calculate offsets from known data
            u32 node_size = 0;

            foreach (Node n in nodearray)
            {
                node_size += n.Size();
            }

            MemoryStream p1 = AlienString.StringPool1.Export();
            MemoryStream p2 = AlienString.StringPool2.Export();

            u32 block1 = Header.Size()
                         + node_size
                         + 1; // extra null byte

            u32 block2 = block1
                         + 1 // extra null byte
                         + (u32)p1.Length;

            u32 block3 = block2
                         + (u32)p2.Length;

            u32 file_size = block3
                            + 1; // extra null byte

            // pass 4; fixup and export this horrible mess
            hdr.Fixup(block1, block2, block3);

            // we know the size so lets preallocate the buffer
            bw.BaseStream.SetLength(file_size);

            u32 of1 = block1 + 1;
            u32 of2 = block2;

            // -- header
            hdr.Write(bw);

            // -- node blob
            u32 cur_depth        = 0;
            u32 cur_depth_offset = 0;

            foreach (Node n in nodearray)
            {
                // here we fixup the child offsets

                // to do this, we need to calculate the starting position of the next depth. sigh.
                if (n.Flags.Children > 0)
                {
                    if (cur_depth != n.Depth + 1)
                    {
                        // we need to loop through the ENTIRE array just to set cur_depth_offset
                        // only do this when the depth changes
                        // xxxxx even better, do this outside of the loop

                        // -- start from the start of the node pool
                        cur_depth_offset = Header.Size();

                        foreach (Node nn in nodearray)
                        {
                            if (nn.Depth == n.Depth + 1)
                            {
                                break;
                            }

                            // -- count all nodes up to this point
                            cur_depth_offset += nn.Size();
                        }

                        cur_depth = n.Depth + 1;
                    }

                    // now we have an offset

                    n.Offset = cur_depth_offset;

                    // next, we need to update the cur_depth_offset anyway

                    foreach (Node child in n.Nodes)
                    {
                        cur_depth_offset += child.Size();
                    }
                }

                // now we can write it out
                n.Write(bw, of1, of2);
            }

            // -- string pools
            bw.BaseStream.Seek(block1 + 1, SeekOrigin.Begin);
            p1.WriteTo(bw.BaseStream);
            p2.WriteTo(bw.BaseStream);

            return(true);
        }
Пример #34
0
            public bool ReadXML(XmlElement ele, u32 depth)
            {
                bool valid = true;

                Depth = depth;
                Text  = new AlienString.Ref(ele.Name, true);

                if (ele.HasAttributes)
                {
                    if (ele.Attributes.Count > 0xFF)
                    {
                        //Console.WriteLine("Too many attributes for {0}", Text.value);
                        valid = false;
                        return(valid);
                    }

                    foreach (XmlAttribute attr in ele.Attributes)
                    {
                        Attribute a = new Attribute();
                        a.ReadXML(attr.Name, attr.Value);
                        Attributes.Add(a);
                    }
                }

                if (ele.HasChildNodes)
                {
                    // inner text is treated as a special text node, so it has children.. (YIKES)

                    foreach (XmlNode xnode in ele.ChildNodes)
                    {
                        // special parser requirements

                        switch (xnode.NodeType)
                        {
                        case XmlNodeType.Element:

                            XmlElement child = (xnode as XmlElement);

                            Node nchild = new Node();

                            valid &= nchild.ReadXML(child, depth + 1);

                            if (valid)
                            {
                                Nodes.Add(nchild);
                            }

                            break;

                        case XmlNodeType.Text:

                            Inner = new AlienString.Ref(AlienString.DecodeXml(xnode.Value), false);
                            End2  = new AlienString.Ref("\r\n", false);

                            break;

                        case XmlNodeType.Comment:

                            // Could be added as Inner/End2, but not required
                            //Console.WriteLine("Found XML comment - skipping it");

                            break;

                        default:
                            // Console.WriteLine("XmlNodeType not handled - skipping it");
                            break;
                        }
                    }
                }

                bool last_child = !HasElementSibling(ele);

                Fixup(last_child);

                return(valid);
            }