about summary refs log tree commit diff stats
path: root/src/libtools/myalign32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libtools/myalign32.c')
-rwxr-xr-xsrc/libtools/myalign32.c935
1 files changed, 935 insertions, 0 deletions
diff --git a/src/libtools/myalign32.c b/src/libtools/myalign32.c
new file mode 100755
index 00000000..ee0b2790
--- /dev/null
+++ b/src/libtools/myalign32.c
@@ -0,0 +1,935 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <wchar.h>
+#include <sys/epoll.h>
+#include <fts.h>
+
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "myalign32.h"
+#include "debug.h"
+#include "box32.h"
+
+void myStackAlign32(const char* fmt, uint32_t* st, uint64_t* mystack)
+{
+    if(!fmt)
+        return;
+    // loop...
+    const char* p = fmt;
+    int state = 0;
+    double d;
+    while(*p)
+    {
+        switch(state) {
+            case 0:
+                switch(*p) {
+                    case '%': state = 1; ++p; break;
+                    default:
+                        ++p;
+                }
+                break;
+            case 1: // normal
+            case 2: // l
+            case 3: // ll
+            case 4: // L
+                switch(*p) {
+                    case '%': state = 0;  ++p; break; //%% = back to 0
+                    case 'l': ++state; if (state>3) state=3; ++p; break;
+                    case 'z': state = 2; ++p; break;
+                    case 'L': state = 4; ++p; break;
+                    case 'a':
+                    case 'A':
+                    case 'e':
+                    case 'E':
+                    case 'g':
+                    case 'G':
+                    case 'F':
+                    case 'f': state += 10; break;    //  float
+                    case 'd':
+                    case 'i':
+                    case 'o': state += 20; break;   // int
+                    case 'x':
+                    case 'X':
+                    case 'u': state += 40; break;   // uint
+                    case 'h': ++p; break;  // ignored...
+                    case '\'':
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                    case '.': 
+                    case '+': 
+                    case '-': ++p; break; // formating, ignored
+                    case 'm': state = 0; ++p; break; // no argument
+                    case 'n':
+                    case 'p':
+                    case 'S':
+                    case 's': state = 30; break; // pointers
+                    case '$': ++p; break; // should issue a warning, it's not handled...
+                    case '*': *(mystack++) = *(st++); ++p; break; // fetch an int in the stack....
+                    case ' ': state=0; ++p; break;
+                    default:
+                        state=20; // other stuff, put an int...
+                }
+                break;
+            case 11:    //double
+            case 12:    //%lg, still double
+            case 13:    //%llg, still double
+            case 23:    // 64bits int
+            case 43:    // 64bits uint
+                *(uint64_t*)mystack = *(uint64_t*)st;
+                st+=2; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 22:    // long int
+                *(int64_t*)mystack = from_long(*(long_t*)st);
+                st+=1; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 42:    // long uint
+                *(uint64_t*)mystack = from_ulong(*(ulong_t*)st);
+                st+=1; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 14:    //%LG long double
+                #ifdef HAVE_LD80BITS
+                memcpy(mystack, st, 10);
+                st+=3; mystack+=2;
+                #else
+                LD2D((void*)st, &d);
+                *(long double*)mystack = (long double)d;
+                st+=3; mystack+=2;
+                #endif
+                state = 0;
+                ++p;
+                break;
+            case 30:    //pointer
+                *(uintptr_t*)mystack = from_ptr(*st);
+                st++; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 20:    // fallback
+            case 21:
+            case 24:    // normal int / pointer
+            case 40:
+            case 41:
+                *mystack = *st;
+                ++mystack;
+                ++st;
+                state = 0;
+                ++p;
+                break;
+            default:
+                // whattt?
+                state = 0;
+        }
+    }
+}
+
+void myStackAlignGVariantNew32(const char* fmt, uint32_t* st, uint64_t* mystack)
+{
+    if (!fmt)
+        return;
+    
+    const char *p = fmt;
+    int state = 0;
+    int inblocks = 0;
+    int tmp;
+
+    do {
+        switch(state) {
+            case 0: // Nothing
+                switch(*p) {
+                    case 'b': // gboolean
+                    case 'y': // guchar
+                    case 'n': // gint16
+                    case 'q': // guint16
+                    case 'i': // gint32
+                    case 'u': // guint32
+                    case 'h': // gint32
+                    case 's': // const gchar*
+                    case 'o':
+                    case 'g':
+                    case 'v': // GVariant*
+                    case '*': // GVariant* of any type
+                    case '?': // GVariant* of basic type
+                    case 'r': // GVariant* of tuple type
+                        *mystack = *st;
+                        ++mystack;
+                        ++st;
+                        break;
+                    case 'x': // gint64
+                    case 't': // guint64
+                    case 'd': // gdouble
+                        *(uint64_t*)mystack = *(uint64_t*)st;
+                        st+=2; mystack+=1;
+                        break;
+                    case '{':
+                    case '(': ++inblocks; break;
+                    case '}':
+                    case ')': --inblocks; break;
+                    case 'a': state = 1; break; // GVariantBuilder* or GVariantIter**
+                    case 'm': state = 2; break; // maybe types
+                    case '@': state = 3; break; // GVariant* of type [type]
+                    case '^': state = 4; break; // pointer value
+                    case '&': break; // pointer: do nothing
+                }
+                break;
+            case 1: // Arrays
+                switch(*p) {
+                    case '{':
+                    case '(': ++tmp; break;
+                    case '}':
+                    case ')': --tmp; break;
+                }
+                if (*p == 'a') break;
+                if (tmp == 0) {
+                    *mystack = *st;
+                    ++mystack;
+                    ++st;
+                    state = 0;
+                }
+                break;
+            case 2: // Maybe-types
+                switch(*p) {
+                    case 'b': // gboolean
+                    case 'y': // guchar
+                    case 'n': // gint16
+                    case 'q': // guint16
+                    case 'i': // gint32
+                    case 'u': // guint32
+                    case 'h': // gint32
+                    case 'x': // gint64
+                    case 't': // guint64
+                    case 'd': // gdouble
+                    case '{':
+                    case '}':
+                    case '(':
+                    case ')':
+                        // Add a gboolean or gboolean*, no char increment
+                        *mystack = *st;
+                        ++mystack;
+                        ++st;
+                        --p;
+                        state = 0;
+                        break;
+                    case 'a': // GVariantBuilder* or GVariantIter**
+                    case 's': // const gchar*
+                    case 'o':
+                    case 'g':
+                    case 'v': // GVariant*
+                    case '@': // GVariant* of type [type]
+                    case '*': // GVariant* of any type
+                    case '?': // GVariant* of basic type
+                    case 'r': // GVariant* of tuple type
+                    case '&': // pointer
+                    case '^': // pointer value
+                        // Just maybe-NULL
+                        --p;
+                        state = 0;
+                        break;
+
+                    default: // Default to add a gboolean & reinit state?
+                        *mystack = *st;
+                        ++mystack;
+                        ++st;
+                        --p;
+                        state = 0;
+                }
+                break;
+            case 3: // GVariant*
+                switch(*p) {
+                    case '{':
+                    case '(': ++tmp; break;
+                    case '}':
+                    case ')': --tmp; break;
+                    case 'a': // GVariantBuilder* or GVariantIter**
+                        do { ++p; } while(*p == 'a'); // Use next character which is not an array (array definition)
+                        switch(*p) {
+                            case '{':
+                            case '(': ++tmp; break;
+                            case '}':
+                            case ')': --tmp; break;
+                        }
+                        break;
+                }
+                if (tmp == 0) {
+                    *mystack = *st;
+                    ++mystack;
+                    ++st;
+                    state = 0;
+                }
+                break;
+            case 4: // ^
+                if (*p == 'a') state = 5;
+                else if (*p == '&') state = 8;
+                else state = 0; //???
+                break;
+            case 5: // ^a
+                if ((*p == 's') || (*p == 'o') || (*p == 'y')) {
+                    *mystack = *st;
+                    ++mystack;
+                    ++st;
+                    state = 0;
+                } else if (*p == '&') state = 6;
+                else if (*p == 'a') state = 7;
+                else state = 0; //???
+                break;
+            case 6: // ^a&
+                if ((*p == 's') || (*p == 'o')) {
+                    *mystack = *st;
+                    ++mystack;
+                    ++st;
+                    state = 0;
+                } else if (*p == 'a') state = 7;
+                else state = 0; //???
+                break;
+            case 7: // ^aa / ^a&a
+                if (*p == 'y') {
+                    *mystack = *st;
+                    ++mystack;
+                    ++st;
+                    state = 0;
+                } else state = 0; //???
+            case 8: // ^&
+                if (*p == 'a') state = 9;
+                else state = 0; //???
+            case 9: // ^&a
+                if (*p == 'y') {
+                    *mystack = *st;
+                    ++mystack;
+                    ++st;
+                    state = 0;
+                } else state = 0; //???
+        }
+        ++p;
+    } while (*p && (inblocks || state));
+}
+
+void myStackAlignW32(const char* fmt, uint32_t* st, uint64_t* mystack)
+{
+    // loop...
+    const wchar_t* p = (const wchar_t*)fmt;
+    int state = 0;
+    double d;
+    while(*p)
+    {
+        switch(state) {
+            case 0:
+                switch(*p) {
+                    case '%': state = 1; ++p; break;
+                    default:
+                        ++p;
+                }
+                break;
+            case 1: // normal
+            case 2: // l
+            case 3: // ll
+            case 4: // L
+                switch(*p) {
+                    case '%': state = 0;  ++p; break; //%% = back to 0
+                    case 'l': ++state; if (state>3) state=3; ++p; break;
+                    case 'z': state = 2; ++p; break;
+                    case 'L': state = 4; ++p; break;
+                    case 'a':
+                    case 'A':
+                    case 'e':
+                    case 'E':
+                    case 'g':
+                    case 'G':
+                    case 'F':
+                    case 'f': state += 10; break;    //  float
+                    case 'd':
+                    case 'i':
+                    case 'o': state += 20; break;   // int
+                    case 'x':
+                    case 'X':
+                    case 'u': state += 40; break;   // unsigned
+                    case 'h': ++p; break;  // ignored...
+                    case '\'':
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                    case '.': 
+                    case '+': 
+                    case '-': ++p; break; // formating, ignored
+                    case 'm': state = 0; ++p; break; // no argument
+                    case 'n':
+                    case 'p':
+                    case 'S':
+                    case 's': state = 30; break; // pointers
+                    case '$': ++p; break; // should issue a warning, it's not handled...
+                    case '*': *(mystack++) = *(st++); ++p; break; //fetch an int in the stack
+                    case ' ': state=0; ++p; break;
+                    default:
+                        state=20; // other stuff, put an int...
+                }
+                break;
+            case 11:    //double
+            case 12:    //%lg, still double
+            case 13:    //%llg, still double
+            case 23:    // 64bits int
+            case 43:    // 64bits uint
+                *(uint64_t*)mystack = *(uint64_t*)st;
+                st+=2; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 22:    // long int
+                *(int64_t*)mystack = from_long(*(long_t*)st);
+                st+=1; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 42:    // long uint
+                *(uint64_t*)mystack = from_ulong(*(ulong_t*)st);
+                st+=1; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 14:    //%LG long double
+                #ifdef HAVE_LD80BITS
+                memcpy(mystack, st, 10);
+                st+=3; mystack+=2;
+                #else
+                LD2D((void*)st, &d);
+                *(long double*)mystack = (long double)d;
+                st+=3; mystack+=2;
+                #endif
+                state = 0;
+                ++p;
+                break;
+            case 30:    //pointer
+                *(uintptr_t*)mystack = from_ptr(*st);
+                st++; mystack+=1;
+                state = 0;
+                ++p;
+                break;
+            case 20:    // fallback
+            case 40:
+            case 21:
+            case 24:    // normal int / pointer
+                *mystack = *st;
+                ++mystack;
+                ++st;
+                state = 0;
+                ++p;
+                break;
+            default:
+                // whattt?
+                state = 0;
+        }
+    }
+}
+
+
+#if 0
+
+typedef struct __attribute__((packed)) {
+  unsigned char   *body_data;
+  long    body_storage;
+  long    body_fill;
+  long    body_returned;
+
+
+  int     *lacing_vals;
+  int64_t *granule_vals;
+  long    lacing_storage;
+  long    lacing_fill;
+  long    lacing_packet;
+  long    lacing_returned;
+
+  unsigned char    header[282];
+  int              header_fill __attribute__ ((aligned (4)));
+
+  int     e_o_s;
+  int     b_o_s;
+  long    serialno;
+  long    pageno;
+  int64_t  packetno;
+  int64_t   granulepos;
+
+} ogg_stream_state_x64;
+
+typedef struct __attribute__((packed)) vorbis_dsp_state_x64 {
+  int analysisp;
+  void *vi; //vorbis_info
+
+  float **pcm;
+  float **pcmret;
+  int      pcm_storage;
+  int      pcm_current;
+  int      pcm_returned;
+
+  int  preextrapolate;
+  int  eofflag;
+
+  long lW;
+  long W;
+  long nW;
+  long centerW;
+
+  int64_t granulepos;
+  int64_t sequence;
+
+  int64_t glue_bits;
+  int64_t time_bits;
+  int64_t floor_bits;
+  int64_t res_bits;
+
+  void       *backend_state;
+} vorbis_dsp_state_x64;
+
+typedef struct __attribute__((packed)) {
+  long endbyte;
+  int  endbit;
+
+  unsigned char *buffer;
+  unsigned char *ptr;
+  long storage;
+} oggpack_buffer_x64;
+
+typedef struct __attribute__((packed)) vorbis_block_x64 {
+
+  float  **pcm;
+  oggpack_buffer_x64 opb;
+
+  long  lW;
+  long  W;
+  long  nW;
+  int   pcmend;
+  int   mode;
+
+  int         eofflag;
+  int64_t granulepos;
+  int64_t sequence;
+  void *vd;
+  
+  void               *localstore;
+  long                localtop;
+  long                localalloc;
+  long                totaluse;
+  void *reap;
+
+  long glue_bits;
+  long time_bits;
+  long floor_bits;
+  long res_bits;
+
+  void *internal;
+
+} vorbis_block_x64;
+
+typedef struct __attribute__((packed)) OggVorbis_x64  {
+  void            *datasource; /* Pointer to a FILE *, etc. */
+  int              seekable;
+  int64_t      offset;
+  int64_t      end;
+  ogg_sync_state   oy;
+
+  /* If the FILE handle isn't seekable (eg, a pipe), only the current
+     stream appears */
+  int              links;
+  int64_t     *offsets;
+  int64_t     *dataoffsets;
+  long            *serialnos;
+  int64_t     *pcmlengths; /* overloaded to maintain binary
+                                  compatibility; x2 size, stores both
+                                  beginning and end values */
+  void     *vi; //vorbis_info
+  void  *vc;    //vorbis_comment
+
+  /* Decoding working state local storage */
+  int64_t      pcm_offset;
+  int              ready_state;
+  long             current_serialno;
+  int              current_link;
+
+  double           bittrack;
+  double           samptrack;
+
+  ogg_stream_state_x64 os; /* take physical pages, weld into a logical
+                          stream of packets */
+  vorbis_dsp_state_x64 vd; /* central working state for the packet->PCM decoder */
+  vorbis_block_x64     vb; /* local working space for packet->PCM decode */
+
+  ov_callbacks callbacks;
+
+} OggVorbis_x64;
+
+#define TRANSFERT \
+GO(datasource) \
+GO(seekable) \
+GO(offset) \
+GO(end) \
+GOM(oy, sizeof(ogg_sync_state)) \
+GO(links) \
+GO(offsets) \
+GO(dataoffsets) \
+GO(serialnos) \
+GO(pcmlengths) \
+GO(vi) \
+GO(vc) \
+GO(pcm_offset) \
+GO(ready_state) \
+GO(current_serialno) \
+GO(current_link) \
+GOM(bittrack, 16) \
+GO(os.body_data) \
+GO(os.body_storage) \
+GO(os.body_fill) \
+GO(os.body_returned) \
+GO(os.lacing_vals) \
+GO(os.granule_vals) \
+GO(os.lacing_storage) \
+GO(os.lacing_fill) \
+GO(os.lacing_packet) \
+GO(os.lacing_returned) \
+GOM(os.header, 282) \
+GO(os.header_fill) \
+GO(os.e_o_s) \
+GO(os.b_o_s) \
+GO(os.serialno) \
+GO(os.pageno) \
+GO(os.packetno) \
+GO(os.granulepos) \
+GO(vd.analysisp) \
+GO(vd.vi) \
+GO(vd.pcm) \
+GO(vd.pcmret) \
+GO(vd.pcm_storage) \
+GO(vd.pcm_current) \
+GO(vd.pcm_returned) \
+GO(vd.preextrapolate) \
+GO(vd.eofflag) \
+GO(vd.lW) \
+GO(vd.W) \
+GO(vd.nW) \
+GO(vd.centerW) \
+GO(vd.granulepos) \
+GO(vd.sequence) \
+GO(vd.glue_bits) \
+GO(vd.time_bits) \
+GO(vd.floor_bits) \
+GO(vd.res_bits) \
+GO(vd.backend_state) \
+GO(vb.pcm) \
+GO(vb.opb.endbyte) \
+GO(vb.opb.endbit) \
+GO(vb.opb.buffer) \
+GO(vb.opb.ptr) \
+GO(vb.opb.storage) \
+GO(vb.lW) \
+GO(vb.W) \
+GO(vb.nW) \
+GO(vb.pcmend) \
+GO(vb.mode) \
+GO(vb.eofflag) \
+GO(vb.granulepos) \
+GO(vb.sequence) \
+GO(vb.localstore) \
+GO(vb.localtop) \
+GO(vb.localalloc) \
+GO(vb.totaluse) \
+GO(vb.reap) \
+GO(vb.glue_bits) \
+GO(vb.time_bits) \
+GO(vb.floor_bits) \
+GO(vb.res_bits) \
+GO(vb.internal) \
+GOM(callbacks, sizeof(ov_callbacks))
+
+void AlignOggVorbis(void* dest, void* source)
+{
+     // Arm -> x64
+     OggVorbis_x64* src = (OggVorbis_x64*)source;
+     OggVorbis*     dst = (OggVorbis*)dest;
+
+     #define GO(A) dst->A = src->A;
+     #define GOM(A, S) memcpy(&dst->A, &src->A, S);
+     TRANSFERT
+     #undef GO
+     #undef GOM
+     dst->vb.vd = (src->vb.vd == &src->vd)?&dst->vd:(vorbis_dsp_state*)src->vb.vd;
+}
+void UnalignOggVorbis(void* dest, void* source)
+{
+    // x64 -> Arm
+     OggVorbis_x64* dst = (OggVorbis_x64*)dest;
+     OggVorbis*     src = (OggVorbis*)source;
+
+     #define GO(A) dst->A = src->A;
+     #define GOM(A, S) memcpy(&dst->A, &src->A, S);
+     TRANSFERT
+     #undef GO
+     #undef GOM
+     dst->vb.vd = (src->vb.vd == &src->vd)?&dst->vd:(vorbis_dsp_state_x64*)src->vb.vd;
+}
+#undef TRANSFERT
+
+#define TRANSFERT \
+GO(analysisp) \
+GO(vi) \
+GO(pcm) \
+GO(pcmret) \
+GO(pcm_storage) \
+GO(pcm_current) \
+GO(pcm_returned) \
+GO(preextrapolate) \
+GO(eofflag) \
+GO(lW) \
+GO(W) \
+GO(nW) \
+GO(centerW) \
+GO(granulepos) \
+GO(sequence) \
+GO(glue_bits) \
+GO(time_bits) \
+GO(floor_bits) \
+GO(res_bits) \
+GO(backend_state)
+
+void UnalignVorbisDspState(void* dest, void* source)
+{
+    // Arm -> x64
+     #define GO(A) ((vorbis_dsp_state_x64*)dest)->A = ((vorbis_dsp_state*)source)->A;
+     #define GOM(A, S) memcpy(&((vorbis_dsp_state_x64*)dest)->A, &((vorbis_dsp_state*)source)->A, S);
+     TRANSFERT
+     #undef GO
+     #undef GOM
+}
+void AlignVorbisDspState(void* dest, void* source)
+{
+    // x64 -> Arm
+     #define GO(A) ((vorbis_dsp_state*)dest)->A = ((vorbis_dsp_state_x64*)source)->A;
+     #define GOM(A, S) memcpy(&((vorbis_dsp_state*)dest)->A, &((vorbis_dsp_state_x64*)source)->A, S);
+     TRANSFERT
+     #undef GO
+     #undef GOM
+}
+#undef TRANSFERT
+
+#define TRANSFERT \
+GO(pcm) \
+GO(opb.endbyte) \
+GO(opb.endbit) \
+GO(opb.buffer) \
+GO(opb.ptr) \
+GO(opb.storage) \
+GO(lW) \
+GO(W) \
+GO(nW) \
+GO(pcmend) \
+GO(mode) \
+GO(eofflag) \
+GO(granulepos) \
+GO(sequence) \
+GO(vd) \
+GO(localstore) \
+GO(localtop) \
+GO(localalloc) \
+GO(totaluse) \
+GO(reap) \
+GO(glue_bits) \
+GO(time_bits) \
+GO(floor_bits) \
+GO(res_bits) \
+GO(internal)
+
+void UnalignVorbisBlock(void* dest, void* source)
+{
+    // Arm -> x64
+     #define GO(A) ((vorbis_block_x64*)dest)->A = ((vorbis_block*)source)->A;
+     #define GOM(A, S) memcpy(&((vorbis_block_x64*)dest)->A, &((vorbis_block*)source)->A, S);
+     TRANSFERT
+     #undef GO
+     #undef GOM
+}
+void AlignVorbisBlock(void* dest, void* source)
+{
+    // x64 -> Arm
+     #define GO(A) ((vorbis_block*)dest)->A = ((vorbis_block_x64*)source)->A;
+     #define GOM(A, S) memcpy(&((vorbis_block*)dest)->A, &((vorbis_block_x64*)source)->A, S);
+     TRANSFERT
+     #undef GO
+     #undef GOM
+}
+
+#undef TRANSFERT
+
+typedef union __attribute__((packed)) x64_epoll_data {
+    void    *ptr;
+    int      fd;
+    uint32_t u32;
+    uint64_t u64;
+} x64_epoll_data_t;
+
+struct __attribute__((packed)) x64_epoll_event {
+    uint32_t            events;
+    x64_epoll_data_t    data;
+};
+// Arm -> x64
+void UnalignEpollEvent(void* dest, void* source, int nbr)
+{
+    struct x64_epoll_event *x64_struct = (struct x64_epoll_event*)dest;
+    struct epoll_event *arm_struct = (struct epoll_event*)source;
+    while(nbr) {
+        x64_struct->events = arm_struct->events;
+        x64_struct->data.u64 = arm_struct->data.u64;
+        ++x64_struct;
+        ++arm_struct;
+        --nbr;
+    }
+}
+
+// x64 -> Arm
+void AlignEpollEvent(void* dest, void* source, int nbr)
+{
+    struct x64_epoll_event *x64_struct = (struct x64_epoll_event*)source;
+    struct epoll_event *arm_struct = (struct epoll_event*)dest;
+    while(nbr) {
+        arm_struct->events = x64_struct->events;
+        arm_struct->data.u64 = x64_struct->data.u64;
+        ++x64_struct;
+        ++arm_struct;
+        --nbr;
+    }
+}
+
+typedef struct __attribute__((packed)) x64_SMPEG_Info_s {
+    int has_audio;
+    int has_video;
+    int width;
+    int height;
+    int current_frame;
+    double current_fps;
+    char audio_string[80];
+    int  audio_current_frame;
+    uint32_t current_offset;
+    uint32_t total_size;
+    double current_time;
+    double total_time;
+} x64_SMPEG_Info_t;
+
+#define TRANSFERT \
+GO(has_audio) \
+GO(has_video) \
+GO(width) \
+GO(height) \
+GO(current_frame) \
+GO(current_fps) \
+GOM(audio_string, 80) \
+GO(audio_current_frame) \
+GO(current_offset) \
+GO(total_size) \
+GO(current_time) \
+GO(total_time)
+
+
+// Arm -> x64
+void UnalignSmpegInfo(void* dest, void* source)
+{
+    #define GO(A) ((x64_SMPEG_Info_t*)dest)->A = ((my_SMPEG_Info_t*)source)->A;
+    #define GOM(A, S) memcpy(&((x64_SMPEG_Info_t*)dest)->A, &((my_SMPEG_Info_t*)source)->A, S);
+    TRANSFERT
+    #undef GO
+    #undef GOM
+}
+// x64 -> Arm
+void AlignSmpegInfo(void* dest, void* source)
+{
+    #define GO(A) ((my_SMPEG_Info_t*)dest)->A = ((x64_SMPEG_Info_t*)source)->A;
+    #define GOM(A, S) memcpy(&((my_SMPEG_Info_t*)dest)->A, &((x64_SMPEG_Info_t*)source)->A, S);
+    TRANSFERT
+    #undef GO
+    #undef GOM
+}
+#undef TRANSFERT
+
+#define TRANSFERT   \
+GOV(fts_cycle)      \
+GOV(fts_parent)     \
+GOV(fts_link)       \
+GO(fts_number)      \
+GO(fts_pointer)     \
+GO(fts_accpath)     \
+GO(fts_path)        \
+GO(fts_errno)       \
+GO(fts_symfd)       \
+GO(fts_pathlen)     \
+GO(fts_namelen)     \
+GO(fts_ino)         \
+GO(fts_dev)         \
+GO(fts_nlink)       \
+GO(fts_level)       \
+GO(fts_info)        \
+GO(fts_flags)       \
+GO(fts_instr)       \
+GO(fts_statp)       \
+GOM(fts_name, sizeof(void*))
+
+// Arm -> x64
+void UnalignFTSENT(void* dest, void* source)
+{
+    #define GO(A) ((x64_ftsent_t*)dest)->A = ((FTSENT*)source)->A;
+    #define GOV(A) ((x64_ftsent_t*)dest)->A = (void*)((FTSENT*)source)->A;
+    #define GOM(A, S) memcpy(&((x64_ftsent_t*)dest)->A, &((FTSENT*)source)->A, S);
+    TRANSFERT
+    #undef GO
+    #undef GOV
+    #undef GOM
+}
+// x64 -> Arm
+void AlignFTSENT(void* dest, void* source)
+{
+    #define GO(A) ((FTSENT*)dest)->A = ((x64_ftsent_t*)source)->A;
+    #define GOV(A) ((FTSENT*)dest)->A = (void*)((x64_ftsent_t*)source)->A;
+    #define GOM(A, S) memcpy(&((FTSENT*)dest)->A, &((x64_ftsent_t*)source)->A, S);
+    TRANSFERT
+    #undef GO
+    #undef GOV
+    #undef GOM
+}
+#undef TRANSFERT
+
+void alignNGValue(my_GValue_t* v, void* value, int n)
+{
+    while(n) {
+        v->g_type = *(int*)value;
+        memcpy(v->data, value+4, 2*sizeof(double));
+        ++v;
+        value+=4+2*sizeof(double);
+        --n;
+    }
+}
+void unalignNGValue(void* value, my_GValue_t* v, int n)
+{
+    while(n) {
+        *(int*)value = v->g_type;
+        memcpy(value+4, v->data, 2*sizeof(double));
+        ++v;
+        value+=4+2*sizeof(double);
+        --n;
+    }
+}
+
+#endif
\ No newline at end of file