?
Solved

Casting Hashtable as ArrayList

Posted on 2006-04-11
12
Medium Priority
?
616 Views
Last Modified: 2006-11-18
Hi,

Having a little problem with this code below. It errors when I try to use the positions array I've casted and when I use (htFields[field] as ArrayList).Add(i);.

Thanks for reading and for your help.

---

       private void loadDescriptors(string descriptor)
        {
            Hashtable htFields = new Hashtable();
            ArrayList alFields = new ArrayList();

            int i = 0;
            int basePtr = pointers.getPointer(descriptor);
            while (true)
            {
                int ptr = memory.ReadInteger(basePtr);

                if ((ptr & 0x40000000) == 0x40000000)
                    break;

                string field = memory.ReadString(ptr, 64);

                if (field == "OBJECT_FIELD_GUID" && i > 2)
                    break;

                if (!htFields.ContainsKey(field))
                    htFields.Add(field, i * 4);

                // Exception: Object not set to a reference of an instance
                (htFields[field] as ArrayList).Add(i);
                alFields.Add(field);

                basePtr += 0x14;
                i++;
            }

            Console.WriteLine("public class " + descriptor);
            Console.WriteLine("{");
            foreach (string field in alFields)
            {
                if (htFields.ContainsKey(field))
                {
                    ArrayList positions = (ArrayList)htFields[field];

                    Console.Write("\tpublic static int[] " + field + " = {");

                    // Exception when using 'positions'
                    for (i = 0; i < positions.Count; i++)
                    {
                        if (i > 0)
                            Console.Write(",");

                        if (i % 5 == 0 && positions.Count > 2)
                        {
                            Console.WriteLine("");
                            Console.Write("\t\t\t");
                        }

                        Console.Write("0x" + ((int)positions[i] * 4).ToString("X"));
                    }
                    Console.WriteLine("};");

                    htFields.Remove(field);
                }
            }
            Console.WriteLine("};");
        }
0
Comment
Question by:valvet
  • 7
  • 5
12 Comments
 
LVL 12

Expert Comment

by:AGBrown
ID: 16431891
When you add to your arraylist, it looks like you are using
htFields.Add(field, i * 4);
This is adding an integer multiplied by 4. Then you do
((ArrayList)htFields[field]) - except this cast is invalid, as you have an integer instead of an arraylist.

Would:
htFields.Add(field, new ArrayList(i * 4));
be more appropriate?

Andy
0
 

Author Comment

by:valvet
ID: 16432086
Oh, yeah. I was wondering why I got an int error if I moved it around hehe.

I do get a duplicate entry somewhere.. perhaps you can help me find that too? :-)

        private Hashtable loadDescriptors(string descriptor)
        {
            Hashtable htFields = new Hashtable();
            ArrayList alFields = new ArrayList();

            int i = 0;
            int basePtr = owner.pointers.getPointer(descriptor);
            while (true)
            {
                int ptr = owner.Memory.ReadInteger(basePtr);

                if ((ptr & 0x40000000) == 0x40000000)
                    break;

                string field = owner.Memory.ReadString(ptr, 64);

                if (field == "OBJECT_FIELD_GUID" && i > 2)
                    break;

                if (!htFields.ContainsKey(field))
                    htFields.Add(field, i * 4);

                //(htFields[field] as ArrayList).Add(i);
                htFields.Add(field, new ArrayList(i * 4));
                alFields.Add(field);

                basePtr += 0x14;
                i++;
            }


            Console.WriteLine("public class " + descriptor);
            Console.WriteLine("{");
            foreach (string field in alFields)
            {
                if (htFields.ContainsKey(field))
                {
                    ArrayList positions = (ArrayList)htFields[field];

                    Console.Write("\tpublic static int[] " + field + " = {");
                    for (i = 0; i < positions.Count; i++)
                    {
                        if (i > 0)
                            Console.Write(",");

                        if (i % 5 == 0 && positions.Count > 2)
                        {
                            Console.WriteLine("");
                            Console.Write("\t\t\t");
                        }

                        Console.Write("0x" + ((int)positions[i] * 4).ToString("X"));
                    }
                    Console.WriteLine("};");

                    htFields.Remove(field);
                }
            }

            Console.WriteLine("};");

            return htFields;
        }


"Item has already been added. Key in dictionary: '&#9644;'  Key being added: '&#9644;'"

I wish the errors could be a little more specific hehe. Throw new Exception(HoldUsersHandAndPointToLine)

Cheers :-)
0
 
LVL 12

Accepted Solution

by:
AGBrown earned 400 total points
ID: 16432118
So now you have this:

      if (!htFields.ContainsKey(field))
      htFields.Add(field, i * 4);

      //(htFields[field] as ArrayList).Add(i);
      htFields.Add(field, new ArrayList(i * 4));
      alFields.Add(field);

And I think you need:

      if (!htFields.ContainsKey(field))
      {
            //htFields.Add(field, i * 4); // <-------- got rid of this line

            // <---------------- put these lines inside the block that tests for existence in the hashtable
            // <---------------- otherwise will get duplicate entry in hashtable
            //(htFields[field] as ArrayList).Add(i);
            htFields.Add(field, new ArrayList(i * 4));
            alFields.Add(field);
      }
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:valvet
ID: 16432138
Thanks alot! That appears to have worked.. to some extent. Think I can manage from here ;-).

Cheers.
0
 

Author Comment

by:valvet
ID: 16432265
Sorry to bother you again :-)...

I'm a bit puzzled as to why:

ArrayList positions = (ArrayList)htFields[field];

.Count keeps returning 0 and there for the for loop never get's executed..
0
 

Author Comment

by:valvet
ID: 16432275
Other than that, the rest is outputting fine

ArrayList positions = (ArrayList)htFields[field];
Console.WriteLine("Count: {0}", positions.Count);

--

public static int[] DYNAMICOBJECT_BYTES = {};
Count: 0
0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16432304
Count will be zero if you haven't added any items to the arraylist, which I think you haven't as when you add the arraylist to the hashtable you only set it's capacity, you don't add any items.

Try .Capacity instead for your loop and see if that helps.
0
 

Author Comment

by:valvet
ID: 16432321
Ok now it outputtet 8 as Capacity..

Index was out of range. Must be non-negative and less than the size of the colle
ction.

Strange, but there's something in the position's array. I shall try a foreach loop
0
 

Author Comment

by:valvet
ID: 16432327
Hmm, nope. No output.. that's odd.
0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16432357
Well, if you are going with the code you posted starting "Oh, yeah. I was wondering why I ..." then you haven't actually put any entries into the arraylist, so it won't give you anything, and you will get that error.

Capacity is not always set to what you set it to - it is set to optimal values that .NET decides on.

You need to, in your first loop, put something into each position in the arraylist after you have instantiated it and put it in the hashtable, otherwise it will be empty. So after your

     if (!htFields.ContainsKey(field))
     {
          //htFields.Add(field, i * 4); // <-------- got rid of this line

          // <---------------- put these lines inside the block that tests for existence in the hashtable
          // <---------------- otherwise will get duplicate entry in hashtable
          //(htFields[field] as ArrayList).Add(i);
          htFields.Add(field, new ArrayList(i * 4));
          alFields.Add(field);
     }
you need to fill the arraylist with some values.
0
 

Author Comment

by:valvet
ID: 16432369
Ah, alright. I'll play around with that, thanks again :-).
0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16432379
Good luck. I'm off for the night now, so if you have any more questions I would put them in a fresh question.

A.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question