ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VP_SDK / ATcodec / ATcodec.c
diff --git a/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VP_SDK/ATcodec/ATcodec.c b/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VP_SDK/ATcodec/ATcodec.c
new file mode 100644 (file)
index 0000000..c3531df
--- /dev/null
@@ -0,0 +1,611 @@
+/**
+ * @file ATcodec_Buffer.c
+ * @author aurelien.morelle@parrot.fr
+ * @date 2006/12/06
+ */
+#include <VP_Os/vp_os_assert.h>
+#include <VP_Os/vp_os_malloc.h>
+#include <VP_Os/vp_os_print.h>
+
+#include <ATcodec/ATcodec.h>
+#include <ATcodec/ATcodec_Buffer.h>
+
+/************************************************************************
+ * For private use in 'vp_atcodec_sscanf' and 'vp_atcodec_sprintf' functions
+ ************************************************************************/
+
+#ifdef AT_CODEC_DEBUG
+
+#define PRINTF_DEBUG printf
+#define CURCHARS_DEBUG(str_val, fmt_val) ATCODEC_PRINT("Current characters : str_val='%c' ; fmt_val='%c'\n", str_val, fmt_val)
+#define PRINT_DEBUG ATCODEC_PRINT("Sortie ligne %i\n", __LINE__)
+
+#else
+
+static inline void tmp_printf(char *str, ...){}
+
+#define PRINTF_DEBUG tmp_printf
+#define CURCHARS_DEBUG(str_val, fmt_val)
+#define PRINT_DEBUG
+
+#endif
+
+#define EXIT_LOOP_IF(cond) \
+  if(cond) \
+    { \
+      bContinue = ATCODEC_FALSE; \
+      PRINT_DEBUG; \
+      break; \
+    }
+
+typedef struct _ListParams
+{
+  char *listLengthPtr;
+  int list_length;
+  char *list_ptr_b;
+  char *list_ptr_e;
+  char list_char;
+}
+ListParams;
+
+
+ATCODEC_RET
+vp_atcodec_sscanf(ATcodec_Memory_t *str, ATcodec_Memory_t *fmt, ATcodec_Memory_t *mem, int *len_dec)
+{
+  int fmt_val,
+    str_val,
+    tmp_val,
+    tmp2_val = 0,
+    nbOpen;
+  char *stringLengthPtr;
+
+  ATcodec_Buffer_t listsParams;
+  ListParams listParams,
+    *listParamsPtr;
+
+  char *tmp_ptr,
+    *tmp2_ptr = NULL;
+
+  ATCODEC_RET bContinue = ATCODEC_TRUE;
+
+  int inList = -1,
+    escaped = -1,
+    inFacultative = -1;
+
+  ATcodec_Buffer_init(&listsParams, sizeof(ListParams), 1);
+
+  fmt_val = ATcodec_Memory_Get_Char(fmt);
+  str_val = ATcodec_Memory_Get_Char(str);
+
+  while (bContinue == ATCODEC_TRUE && fmt_val != '\0')
+    {
+      if (fmt_val == '%' && escaped)
+       {
+         switch (( fmt_val = ATcodec_Memory_Get_Char(fmt)))
+           {
+           case 'l' :
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+
+             EXIT_LOOP_IF(fmt_val != '{');
+
+             inList = 0;
+             listParams.list_ptr_b = fmt->current;
+             listParams.list_length = 0;
+
+             listParams.listLengthPtr = mem->current;
+             ATcodec_Memory_Raw_Put_Int(mem, 0xFFFFFFFF);
+
+             nbOpen = 0;
+             while(fmt_val != '\0' && ((fmt_val = ATcodec_Memory_Get_Char(fmt)) != '}' || !escaped || nbOpen--))
+               {
+                 if (fmt_val == '\\')
+                   {
+                     escaped = 0;
+                   }
+                 else if (fmt_val == '{' && escaped)
+                   {
+                     nbOpen++;
+                   }
+                 else
+                   {
+                     escaped = -1;
+                   }
+               }
+
+             EXIT_LOOP_IF(fmt_val == '\0'); // does a '}' lack ?
+
+             listParams.list_ptr_e = fmt->current;
+
+             listParams.list_char = ATcodec_Memory_Get_Char(fmt);
+
+             fmt->current = listParams.list_ptr_b;
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+
+             ATcodec_Buffer_pushElement(&listsParams, &listParams);
+             break;
+
+           case 'd' :
+             EXIT_LOOP_IF((str_val < '0' || str_val > '9') && str_val != '-'); // not supported
+
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+             EXIT_LOOP_IF(fmt_val >= '0' && fmt_val <= '9'); // not supported
+
+             ATcodec_Memory_Unget_Char(str);
+             tmp_val = ATcodec_Memory_Str_Get_Int(str);
+
+             str_val = ATcodec_Memory_Get_Char(str); // processes next characters
+             ATcodec_Memory_Raw_Put_Int(mem, tmp_val);
+             break;
+
+           case 's' :
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+
+             if (fmt_val == '\\')
+               {
+                 escaped = 0;
+                 fmt_val = ATcodec_Memory_Get_Char(fmt);
+               }
+
+             if (fmt_val == ']' && escaped) // supported
+               {
+                 fmt_val = ATcodec_Memory_Get_Char(fmt); // just skips this character
+                 inFacultative = -1;
+               }
+             else
+               {
+                 EXIT_LOOP_IF
+                   (
+                    (fmt_val == '[' && escaped) ||  // not supported yet
+                    (fmt_val == '%' && escaped) ||  // not supported
+                    str_val == fmt_val              // empty string case, prohibited
+                    );
+               }
+
+             escaped = -1;
+             stringLengthPtr = mem->current;
+             ATcodec_Memory_Raw_Put_Int(mem, 0xFFFFFFFF);
+
+             tmp_val = 0;
+             do
+               {
+                 ATcodec_Memory_Put_Char(mem, str_val);
+                 tmp_val++;
+                 str_val = ATcodec_Memory_Get_Char(str);
+               }
+             while (str_val != fmt_val);
+             ATcodec_Memory_Put_Char(mem, '\0');
+             tmp_ptr = mem->current;
+             mem->current = stringLengthPtr;
+             ATcodec_Memory_Raw_Put_Int(mem, tmp_val);
+             mem->current = tmp_ptr;
+             break;
+
+           case 'c' :
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+             /**
+              * To match "%c", <str_val> can be any character excepted <str_lastchar>,
+              * but as we are already in the loop, it is different from <str_lastchar>.
+              * So, we just "eat" one character.
+              **/
+             str_val = ATcodec_Memory_Get_Char(str);
+             ATcodec_Memory_Put_Char(mem, str_val);
+             break;
+
+           default : // prohibited pattern
+             bContinue = ATCODEC_FALSE; // exits with failure
+             PRINT_DEBUG;
+             break;
+           }
+       }
+      else if (!inList && fmt_val == '}' && escaped)
+       {
+         listParamsPtr = (ListParams *)ATcodec_Buffer_topElement(&listsParams);
+         VP_OS_ASSERT(listParamsPtr);
+
+         if (str_val == ',') // one list element parsed
+           {
+             str_val = ATcodec_Memory_Get_Char(str);
+             fmt->current = listParamsPtr->list_ptr_b;
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+             listParamsPtr->list_length++;
+           }
+         else
+           {
+             EXIT_LOOP_IF
+               (
+                (listParamsPtr->list_char != '\0') ||
+                (str_val != listParamsPtr->list_char)
+                );
+
+             // entire list parsed
+             fmt->current = listParamsPtr->list_ptr_e;
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+             *listParamsPtr->listLengthPtr = ++listParamsPtr->list_length;
+             ATcodec_Buffer_justPopElement(&listsParams);
+             inList = ( ATcodec_Buffer_topElement(&listsParams) ? -1 : 0 );
+           }
+       }
+      else if (fmt_val == '\\' && escaped)
+       {
+         fmt_val = ATcodec_Memory_Get_Char(fmt);
+         escaped = 0;
+       }
+      else if (fmt_val == '[' && escaped)
+       {
+         if ((fmt_val = ATcodec_Memory_Get_Char(fmt)) == '\\')
+           {
+             escaped = 0;
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+           }
+
+         if (fmt_val != '%' || !escaped)
+           {
+             escaped = -1;
+
+             if (str_val == fmt_val)
+               {
+                 // it musts match the facultative pattern
+                 ATcodec_Memory_Raw_Put_Int(mem, (int)0);
+                 str_val = ATcodec_Memory_Get_Char(str); // processes next characters
+                 fmt_val = ATcodec_Memory_Get_Char(fmt);
+                 // nothing else to do, global loop does the job
+                 inFacultative = 0;
+               }
+             else
+               {
+                 // we skip the facultative pattern
+                 ATcodec_Memory_Raw_Put_Int(mem, (int)-1);
+
+                 while(fmt_val != '\0' && ((fmt_val = ATcodec_Memory_Get_Char(fmt)) != ']' || !escaped))
+                   {
+                     escaped = ( fmt_val == '\\' ? 0 : -1 );
+                   }
+
+                 EXIT_LOOP_IF(fmt_val == '\0'); // does a ']' lack ?
+
+                 fmt_val = ATcodec_Memory_Get_Char(fmt);
+               }
+           }
+         else
+           {
+             escaped = -1;
+
+             // we have to manage a '%' as beginning of the facultative pattern which is too complicated
+             // so, we skip the facultative pattern to test the character that follows it
+             tmp_ptr = fmt->current; // points to the '%' character
+             tmp_val = fmt_val; // is equal to '%'
+
+             while(fmt_val != '\0' && ((fmt_val = ATcodec_Memory_Get_Char(fmt)) != ']' || !escaped))
+               {
+                 escaped = ( fmt_val == '\\' ? 0 : -1 );
+               }
+
+             EXIT_LOOP_IF(fmt_val == '\0'); // does a ']' lack ?
+
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+             if (fmt_val == '\\')
+               {
+                 escaped = 0;
+                 tmp2_val = fmt_val;
+                 tmp2_ptr = fmt->current;
+                 fmt_val = ATcodec_Memory_Get_Char(fmt);
+               }
+
+             if (str_val != fmt_val && !(!inList && fmt_val == '}' && str_val == ','))
+               {
+                 escaped = -1;
+                 // we do not really support this case but we try to be lucky ;-)
+                 fmt->current = tmp_ptr;
+                 fmt_val = tmp_val;
+                 // we try to match the facultative pattern
+                 ATcodec_Memory_Raw_Put_Int(mem, (int)0);
+                 // nothing else to do, global loop does the job
+                 inFacultative = 0;
+               }
+             else
+               {
+                 if (!escaped)
+                   {
+                     fmt_val = tmp2_val;
+                     fmt->current = tmp2_ptr;
+                     escaped = -1;
+                   }
+                 // we skip the facultative pattern
+                 ATcodec_Memory_Raw_Put_Int(mem, (int)-1);
+               }
+           }
+       }
+      else if (fmt_val == ']' && escaped)
+       {
+         fmt_val = ATcodec_Memory_Get_Char(fmt);
+         inFacultative = -1;
+         // nothing to do : global loop does the job
+       }
+      else if (str_val == fmt_val) // matches
+       {
+         // TODO : Verify as much as possible if rules are respected
+
+         EXIT_LOOP_IF
+           (
+            ((str_val == ',' || str_val == '}') && !inList && escaped) ||
+            ((str_val == '[' || str_val == ']') && !inFacultative && escaped)
+            );
+
+         str_val = ATcodec_Memory_Get_Char(str); // processes next characters
+         fmt_val = ATcodec_Memory_Get_Char(fmt);
+         escaped = -1;
+       }
+      else if (fmt_val != '\0') // it does not match
+       {
+         bContinue = ATCODEC_FALSE; // exits with failure
+         PRINT_DEBUG;
+         CURCHARS_DEBUG(str_val, fmt_val);
+         break;
+       }
+    }
+
+  while (bContinue == ATCODEC_TRUE && (fmt_val != '\0'))
+    {
+      if (fmt_val == ']')
+       {
+         fmt_val = ATcodec_Memory_Get_Char(fmt);
+       }
+      else if (fmt_val == '[')
+       {
+         ATcodec_Memory_Raw_Put_Int(mem, (int)-1); // we skip the facultative pattern
+
+         while(fmt_val != '\0' && ((fmt_val = ATcodec_Memory_Get_Char(fmt)) != ']' || !escaped))
+           {
+             escaped = ( fmt_val == '\\' ? 0 : -1 );
+           }
+
+         EXIT_LOOP_IF(fmt_val == '\0'); // does a ']' lack ?
+
+         fmt_val = ATcodec_Memory_Get_Char(fmt);
+       }
+      else if (!inList && fmt_val == '}')
+       {
+         listParamsPtr = (ListParams *)ATcodec_Buffer_topElement(&listsParams);
+         VP_OS_ASSERT(listParamsPtr);
+
+         fmt_val = ATcodec_Memory_Get_Char(fmt);
+         *listParamsPtr->listLengthPtr = ++listParamsPtr->list_length;
+         ATcodec_Buffer_justPopElement(&listsParams);
+
+         inList = ( ATcodec_Buffer_topElement(&listsParams) ? -1 : 0 );
+       }
+      else
+       {
+         bContinue = ATCODEC_FALSE;
+         PRINT_DEBUG;
+         CURCHARS_DEBUG(str_val, fmt_val);
+       }
+    }
+
+  ATcodec_Buffer_destroy(&listsParams);
+  *len_dec = (unsigned)str->current-(unsigned)str->start;
+  return bContinue;
+}
+
+/**
+ * Used to differentiate case where va_list is used from case where a memory area is used.
+ */
+static char ATCODEC_sprintf_memory_GetChar(ATcodec_Memory_t *mem, va_list *va)
+{
+  return ATcodec_Memory_Get_Char(mem);
+}
+
+static void ATCODEC_sprintf_memory_GetString(ATcodec_Memory_t *mem, va_list *va, char *dst)
+{
+  ATcodec_Memory_Get_String(mem, dst);
+}
+
+static int ATCODEC_sprintf_memory_Raw_GetInt(ATcodec_Memory_t *mem, va_list *va)
+{
+  return ATcodec_Memory_Raw_Get_Int(mem);
+}
+
+static char ATCODEC_sprintf_valist_GetChar(ATcodec_Memory_t *mem, va_list *va)
+{
+  return (char)va_arg(*va, int);
+}
+
+static void ATCODEC_sprintf_valist_GetString(ATcodec_Memory_t *mem, va_list *va, char *dst)
+{
+  strcpy(dst, va_arg(*va, char *));
+}
+
+static int ATCODEC_sprintf_valist_Raw_GetInt(ATcodec_Memory_t *mem, va_list *va)
+{
+  return va_arg(*va, int);
+}
+
+typedef struct _sprintf_funcs
+{
+  char (* ATCODEC_sprintf_GetChar      )(ATcodec_Memory_t *mem, va_list *va);
+  void (* ATCODEC_sprintf_GetString    )(ATcodec_Memory_t *mem, va_list *va, char *dst);
+  int  (* ATCODEC_sprintf_Raw_GetInt   )(ATcodec_Memory_t *mem, va_list *va);
+}
+sprintf_funcs;
+
+static sprintf_funcs sprintf_funcs_memory =
+{
+  ATCODEC_sprintf_memory_GetChar,
+  ATCODEC_sprintf_memory_GetString,
+  ATCODEC_sprintf_memory_Raw_GetInt
+};
+
+static sprintf_funcs sprintf_funcs_valist =
+{
+  ATCODEC_sprintf_valist_GetChar,
+  ATCODEC_sprintf_valist_GetString,
+  ATCODEC_sprintf_valist_Raw_GetInt
+};
+
+
+ATCODEC_RET
+ATCodec_common_sprintf(ATcodec_Memory_t *dest, int32_t *len, ATcodec_Memory_t *fmt, int params_from_memory, ATcodec_Memory_t *mem, va_list *va)
+{
+  int fmt_val,
+    nbOpen,
+    value;
+
+  char str[1024];
+  char *str_ptr;
+
+  ATcodec_Buffer_t listsParams;
+  ListParams listParams,
+    *listParamsPtr;
+
+  ATCODEC_RET bContinue = ATCODEC_TRUE;
+
+  int escaped = -1,
+    inList = -1;
+
+  sprintf_funcs *funcs;
+
+  if(params_from_memory)
+    {
+      funcs = &sprintf_funcs_memory;
+    }
+  else
+    {
+      funcs = &sprintf_funcs_valist;
+    }
+
+  ATcodec_Buffer_init(&listsParams, sizeof(ListParams), 1);
+
+  fmt_val = ATcodec_Memory_Get_Char(fmt);
+
+  while (bContinue == ATCODEC_TRUE && fmt_val != '\0')
+    {
+      if (fmt_val == '%' && escaped)
+       {
+         switch ((fmt_val = ATcodec_Memory_Get_Char(fmt)))
+           {
+           case 'l' :
+             listParams.list_length = funcs->ATCODEC_sprintf_Raw_GetInt(mem, va);
+
+             fmt_val = ATcodec_Memory_Get_Char(fmt);
+
+             EXIT_LOOP_IF(fmt_val != '{');
+
+             inList = 0;
+             listParams.list_ptr_b = fmt->current;
+
+             nbOpen = 0;
+             while(fmt_val != '\0' && ((fmt_val = ATcodec_Memory_Get_Char(fmt)) != '}' || !escaped || nbOpen--))
+               {
+                 if (fmt_val == '\\')
+                   {
+                     escaped = 0;
+                   }
+                 else if (fmt_val == '{' && escaped)
+                   {
+                     nbOpen++;
+                   }
+                 else
+                   {
+                     escaped = -1;
+                   }
+               }
+
+             EXIT_LOOP_IF(fmt_val == '\0'); // does a '}' lack ?
+
+             fmt->current = listParams.list_ptr_b;
+
+             ATcodec_Buffer_pushElement(&listsParams, &listParams);
+             break;
+
+           case 'd' :
+             value = funcs->ATCODEC_sprintf_Raw_GetInt(mem, va);
+             ATcodec_Memory_Str_Put_Int (dest, value);
+             break;
+
+           case 's' :
+             str_ptr = &str[0];
+             funcs->ATCODEC_sprintf_GetString(mem, va, str_ptr);
+             while (*str_ptr)
+               {
+                 ATcodec_Memory_Put_Char(dest, *str_ptr++);
+               }
+             break;
+
+           case 'c' :
+             ATcodec_Memory_Put_Char(dest, funcs->ATCODEC_sprintf_GetChar(mem, va));
+             break;
+
+           default : // prohibited pattern
+             bContinue = ATCODEC_FALSE; // exits with failure
+             PRINT_DEBUG;
+             break;
+           }
+       }
+      else if (!inList && fmt_val == '}' && escaped)
+       {
+         listParamsPtr = (ListParams *)ATcodec_Buffer_topElement(&listsParams);
+         VP_OS_ASSERT(listParamsPtr);
+
+         if (--listParamsPtr->list_length)
+           {
+             fmt->current = listParamsPtr->list_ptr_b;
+             ATcodec_Memory_Put_Char(dest, ',');
+           }
+         else
+           {
+             ATcodec_Buffer_justPopElement(&listsParams);
+
+             inList = ( ATcodec_Buffer_topElement(&listsParams) ? -1 : 0 );
+           }
+       }
+      else if (fmt_val == '\\' && escaped)
+       {
+         escaped = 0;
+       }
+      else if (fmt_val == '[' && escaped)
+       {
+         if(!(int)funcs->ATCODEC_sprintf_Raw_GetInt(mem, va)) // dump facultative pattern
+           {
+             // nothing to do
+           }
+         else // do not dump facultative pattern
+           {
+             // skip facultative pattern
+             while(fmt_val != '\0' && ((fmt_val = ATcodec_Memory_Get_Char(fmt)) != ']' || !escaped))
+               {
+                 escaped = ( fmt_val == '\\' ? 0 : -1 );
+               }
+
+             EXIT_LOOP_IF(fmt_val == '\0'); // does a ']' lack ?
+           }
+       }
+      else if (fmt_val != ']' || !escaped)
+       {
+         escaped = -1;
+         ATcodec_Memory_Put_Char(dest, fmt_val);
+       }
+
+      fmt_val = ATcodec_Memory_Get_Char(fmt);
+    }
+
+  ATcodec_Buffer_destroy(&listsParams);
+  ATcodec_Memory_Put_Char(dest, '\0');
+
+  *len = (unsigned)dest->current-(unsigned)dest->start-1; //+1; Do not count the termination zero character
+  return bContinue;
+}
+
+
+ATCODEC_RET
+vp_atcodec_sprintf_valist(ATcodec_Memory_t *dest, int32_t *len, ATcodec_Memory_t *fmt, va_list *va)
+{
+  return ATCodec_common_sprintf(dest, len, fmt, 0, NULL, va);
+}
+
+
+ATCODEC_RET
+vp_atcodec_sprintf_params(ATcodec_Memory_t *dest, int32_t *len, ATcodec_Memory_t *fmt, ATcodec_Memory_t *params)
+{
+  return ATCodec_common_sprintf(dest, len, fmt, 1, params, NULL);
+}
+