Wednesday, June 09, 2010

Hackweek Day II - Attack of the code

Today has been reasonably productive. I found some bugs in the libgpod bindings which were fairly major and implemented some more features in banshee.

First the fun bug. The libgpod bindings did the normal thing of defining a managed struct which mirrored the native struct that libgpod uses. This means we can do a trivial byte copy of the unmanaged memory into one of our managed structs and trivially access the information in a safe way. This is all well and good right up until you realise that when you update a property on that struct, you are not actually changing the value of the unmanaged memory. Essentially you have two copies of the same data which are disconnected - one in managed memory and one in native memory. Updating one copy is not reflected in the other and there's no easy way to keep them synced without the risk of losing data.

After a bit of brainstorming with Jeremie, we came up with a rather neat and nifty solution. Take this struct as an example:

struct NativeDate {
public int Day;
public int Month;
public int Year;
}


If native code allocates one of those and passes it to .NET as an IntPtr, there is a trivial way to map this to managed code without requiring a copy of the data.

unsafe class Date {
IntPtr Native {
get; set;
}

public int Day {
get { return ((NativeDate *)Native)->Day; }
set { ((NativeDate *) Native)->Day = value; }
}
public int Month {
get { return ((NativeDate *) Native)->Month; }
set { ((NativeDate *) Native)->Month = value; }
}

public int Year {
get { return ((NativeDate *) Native)->Year; }
set { ((NativeDate *) Native)->Year = value; }
}

public Date (IntPtr native)
{
Native = native;
}
}


All we do is use a bit of unsafe code to take the pointer that we got from native code and cast it to a NativeStruct* and read or write the data as appropriate. Now both managed land and unmanaged land are working off the same hunk of memory so they can never get out of sync.

Now for the features! Banshee can now sync music to my iPhone and remove it aswell! This means all the basic stuff that's required for basic syncing is supported now. It took a lot longer than it should've to get this working because my iPhone wasn't actually set up right. There was a command (i can't remember the name of it now) which should've been run automatically to populate iTunes_Control/Device with some required information. This was never run for some bizarre reason (yay for bleeding edge) which meant nothing I did could ever actually update the database.

However once I got that setup, things progressed pretty rapidly. There's one major feature left which is automatic detection when the device is mounted. If i can get this done tomorrow i'll try to upstream everything and get people testing this by the weekend (or friday!).

4 comments:

generic viagra for men said...

Very nice Blog post thanks a lot for this great article post I love to read such a nice blog.


Smith Alan

Generic viagra without prescription said...

Good post...Thanks for posting..
Regards,

yatesspain.blogspot.com said...

I read really much helpful information here!

aliya seen said...

The blog content writing provides different techniques off writing online with great variations.

Hit Counter