Welcome, Guest. Please login or register.

Author Topic: GeneralSaver (was: Access to compiler's variable types possible ?)  (Read 6979 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline sigler

  • Newbie
  • *
  • Join Date: Jul 2004
  • Posts: 6
    • Show all replies
Re: Access to compiler's variable types possible ?
« on: December 21, 2006, 02:40:23 AM »
Damn, I just wrote a lengthy post which I lost, here's the short version:

struct mystruct
{
char* typeinfo;
short x;
float y;
char* name;
mystruct* linkto;
};

s = short
f = float
p = pointer to another struct
P = pointer to nullterminated string

char* mystruct_typeinfo = "sfPp";


void main()
{
struct mystruct* instance = (struct mystruct*)malloc(sizeof(struct mystruct);
instance->typeinfo = mystruct_typeinfo;
}

--
Sigurd Lerstad
 

Offline sigler

  • Newbie
  • *
  • Join Date: Jul 2004
  • Posts: 6
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #1 on: December 21, 2006, 08:40:21 PM »
You have a choice, either have each struct contain a pointer to a serialize function like others have suggested, or have each struct contain a pointer to a type info descriptor. Both choices are okay, the 'pointer to serialize function' is probably the easiest to implement, though requires that you write the serialize function for each struct. The pointer to type info is a fancier approach, that could take some more time implementing, ideally, the type info string should have been made automatically when you compile your program, but it doesn't, so you must do some extra work for each struct here as well.
If you DO go for the pointer to typeinfo.. there are ways to solve most of the problems others have raised with it. endianness.. not a problem, just be consistant, choose either little endian or big endian in the file format. Alignment issues, when writing: you know the alignment of the architecture your currently running on, just have a #define __alignment__ 2 or 4 in your program or something like that. parse the typeinfo string character by character, and fetch the fields from the struct (which is just an array of bytes at this point, obeying the __alignment__ define. But write it to file with no padding between the fields. When reading, just do the reverse, read the fields from the file with no padding, and write them into the struct memory obeying the __alignment__ define.

The typeinfo string (it doesn't need to be string, and it doesn't need to have one character per field either, you could go for a more complex typeinfo struct or string)
can also contain info on which fields you want or don't want to be serialized.. like maybe a '|' before a character could mean, don't serialize this field (you still need it, in order to skip it when fetching the fields from memory). As for unions, they're more complex, you could say that there's always an int before the union saying which field of the union is currently active.. like this

struct mystruct
{
char* typeinfo;
int type;
union
{
  char* string;
  int integer;
  float floatnumber;
} u;
}

You'd need to expand the typeinfo string syntax also: so the above struct is:

i=int
f=float
P = null terminated string
u(...) = union, this implies an int first, and the elements in the union within the parantheses

char* typeinfo_mystruct = "u(Pif)";

--
Sigurd Lerstad
 

Offline sigler

  • Newbie
  • *
  • Join Date: Jul 2004
  • Posts: 6
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #2 on: December 21, 2006, 09:15:50 PM »
Also, and this is valid for both the pointer to Serialize, and pointer to typeinfo string. A good way to serialize pointers and also necessary if the pointers go in cycles, is to store each pointer as an int

struct Object
{
  char* typeinfo;
};

You need some map helper stuff, in c++, this is easy with std::map<..>

std::map mapStore;
std::map mapLoad;

StorePointer(struct* pObject)
{
  if (pObject == NULL)
  {
    objectid = 0;
    write objectid;
    return;
  }

  int objectid = mapStore.find(pObject)

  if (objectid > 0)
  {
    write objectid;
  }
else
  {
    objectid = mapStore.size()+1;

    mapStore.insert(pObject, objectid);

     write objectid;

   // the following is when using the pointer to typeinfo method

   write pObject->typeinfo string or something here

    for each field in pObject->typeinfo
       if field is pointer
         StorePointer(pFieldPointer) // recurse
  }
}

struct Object* LoadObject()
{
  int objectid;
  read objectid;
  if (objectid == 0) return NULL;

  pObject = mapLoad.find(objectid);

  if (pObject)
  {
   return pObject;
  }
  else
  {
    objectid = mapLoad.size()+1;

   // the following is when using the pointer to typeinfo method

    read typeinfo string or something
    calculate size of struct based on typeinfo string
    pObject = allocate memory
   
    mapLoad.insert(objectid, pObject)

    for each field in typeinfo
      if field is pointer
        fieldvalue = LoadObject() // Recurse
  }
}

--
Sigurd Lerstad
 

Offline sigler

  • Newbie
  • *
  • Join Date: Jul 2004
  • Posts: 6
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #3 on: December 27, 2006, 10:25:03 PM »
Quote

Jose wrote:
@sigler
Thanks for taking the time but I never bothered with C++ :-) Maybe one of these days...



The one thing that was c++ specific was the use of the map class, the rest can be used in c as well. The map class simple associates a key with some value, and if you search for the key, it returns the value. the map class implements this as a binary tree, so searching for a key is very quick, but you can implement it using a simple list as well, doing a linear search for the key in the list, and once found, return the value.

Anyway, the pseudocode I wrote was how to deal with cyclic pointers, e.g

struct myclass1
{
  struct myclass2* pointer;
};

struct myclass2
{
  struct myclass1* pointer;
};

Also, maybe you should follow your original idea, extract the debug info in the exe file, parsing the hunks, and the stabs debug info in the debug hunk. I once did this, but it wasn't usable for me, since I needed c++ debug info, and stabs doesn't support namespaces (a feature of c++), but if you only do c, then that's okay.

You still need to embed a pointer in each struct to some typeinfo in order to know of what type a struct is dynamically. But this typeinfo is now automatically created from the stabs info, instead of you needing to manually create it.

--
Sigurd Lerstad
 

Offline sigler

  • Newbie
  • *
  • Join Date: Jul 2004
  • Posts: 6
    • Show all replies
Re: Access to compiler's variable types possible ?
« Reply #4 on: January 26, 2007, 12:52:13 AM »
Hi, yes, struct like

struct x
{
  int arr[5];
};

will have the arr data embedded inside the struct at the point of declaration. If not, it would be a pointer like

struct x
{
  int *arr;
};

about making it a library: why not.

Quote

Jose wrote:
Hi there:-D. I've made the saver part of the code and it's compiling well for about a week now. I'm now correcting the remaining bugs that make the file save incorrectly. Most types are saving well though, but I've stumbled into something that I hope doesn't make the whole thing useless: Arrays (inside structs or not). It seems that sasc (will try with VBCC at the end cause I need the sasc debugger for now) saves fixed size arrays inside the struct itself. Can I assume this to be the standard or are there some compiler/compiler settings that just add the array's pointer and keep the elements in other place ? If the answer is yes then we're screwed, it won't be "general saver" anymore.

Finally, if this turns out to work, do you guys think it's worth it to make a library of it ?

:pint: