]> git.sesse.net Git - vlc/commitdiff
misc: acoustid: update json parser.
authorFrancois Cartegnie <fcvlcdev@free.fr>
Wed, 10 Apr 2013 11:49:34 +0000 (13:49 +0200)
committerFrancois Cartegnie <fcvlcdev@free.fr>
Wed, 10 Apr 2013 13:47:22 +0000 (15:47 +0200)
Removes locale fix and conditionally builds fingerprinter.

configure.ac
modules/misc/Modules.am
modules/misc/webservices/acoustid.c
modules/misc/webservices/json.c
modules/misc/webservices/json.h
modules/misc/webservices/use_json.h [deleted file]

index 42144339541a27d5a4915ba93b2cdd274cd13820..30634ad84ac912ff0587c3caea24393236bdb8ec 100644 (file)
@@ -3604,6 +3604,22 @@ AS_IF([test "$enable_kai" != "no"], [
 AC_SUBST(KAI_LIBS)
 AM_CONDITIONAL([HAVE_KAI], [test "${have_kai}" = "yes"])
 
+dnl
+dnl  chromaprint audio track fingerprinter
+dnl
+m4_pushdef([libchromaprint_version], 0.6.0)
+PKG_WITH_MODULES([CHROMAPRINT],[libchromaprint >= libchromaprint_version],
+    VLC_ADD_PLUGIN([stream_out_chromaprint fingerprinter])
+    VLC_ADD_CFLAGS([stream_out_chromaprint],[${CHROMAPRINT_CFLAGS}] [-I./webservices -I../stream_out])
+    VLC_ADD_LIBS([stream_out_chromaprint],[${CHROMAPRINT_LIBS}])
+    VLC_ADD_LIBS([fingerprinter],[-lm]),
+    AS_IF([test "${enable_chromaprint}" = "yes"],
+        [AC_MSG_ERROR(Library [libchromaprint >= libchromaprint_version] needed for [chromaprint] was not found)],
+        [AC_MSG_WARN(Library [libchromaprint >= libchromaprint_version] needed for [chromaprint] was not found)]
+         ),
+    [(Chromaprint based audio fingerprinter)],[auto])
+m4_popdef([libchromaprint_version])
+
 dnl
 dnl  Interface plugins
 dnl
@@ -3834,11 +3850,6 @@ dnl  goom visualization plugin
 dnl
 PKG_ENABLE_MODULES_VLC([GOOM], [], [libgoom2], [goom visualization plugin], [auto])
 
-dnl
-dnl  chromaprint audio track fingerprinter
-dnl
-PKG_ENABLE_MODULES_VLC([CHROMAPRINT], [stream_out_chromaprint], [libchromaprint >= 0.6.0], (Chromaprint based audio fingerprinter), [auto], [-I./webservices -I../stream_out])
-
 dnl
 dnl libprojectM visualization plugin
 dnl
index df8e1a5a919265ad3e1d2e287e8ddf3d076ff2bf..d2d6a22e2c1249dc8d0484be7825ee026cf1dabc 100644 (file)
@@ -3,7 +3,6 @@ SOURCES_audioscrobbler = audioscrobbler.c
 SOURCES_fingerprinter = fingerprinter.c \
        webservices/acoustid.c \
        webservices/acoustid.h \
-       webservices/use_json.h \
        webservices/json.c \
        webservices/json.h
 
@@ -55,7 +54,6 @@ libstats_plugin_la_LIBADD = $(AM_LIBADD)
 
 libvlc_LTLIBRARIES += \
        libaudioscrobbler_plugin.la \
-       libfingerprinter_plugin.la \
        liblogger_plugin.la \
        libstats_plugin.la
 
index 4729a9509e1393acd7ef66f367fccba67ad0cb97..3c16110721cef177eebf0f0b10c4ef25fdcce2ce 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <vlc/vlc.h>
 #include "acoustid.h"
-#include "use_json.h"
+#include "json.h"
 
 /*****************************************************************************
  * Requests lifecycle
index 00cf43f693e253914f9c5b29b020db9e670ecbe8..26e63e80d9aed91b27af29d2b1f0c296b27e5904 100644 (file)
 #ifdef __cplusplus
    const struct _json_value json_value_none; /* zero-d by ctor */
 #else
-   const struct _json_value json_value_none = { 0 };
+   const struct _json_value json_value_none = { 0, 0, { 0 }, { 0 } };
 #endif
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
+#include <math.h>
 
 typedef unsigned short json_uchar;
 
@@ -117,6 +118,7 @@ static int new_value
                return 0;
             }
 
+            value->u.array.length = 0;
             break;
 
          case json_object:
@@ -131,6 +133,7 @@ static int new_value
 
             value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
 
+            value->u.object.length = 0;
             break;
 
          case json_string:
@@ -141,14 +144,13 @@ static int new_value
                return 0;
             }
 
+            value->u.string.length = 0;
             break;
 
          default:
             break;
       };
 
-      value->u.array.length = 0;
-
       return 1;
    }
 
@@ -181,10 +183,11 @@ static int new_value
 #define string_add(b)  \
    do { if (!state.first_pass) string [string_length] = b;  ++ string_length; } while (0);
 
-const static int
-   flag_next = 1, flag_reproc = 2, flag_need_comma = 4, flag_seek_value = 8, flag_exponent = 16,
-   flag_got_exponent_sign = 32, flag_escaped = 64, flag_string = 128, flag_need_colon = 256,
-   flag_done = 512;
+static const long
+   flag_next = 1,  flag_reproc = 2,  flag_need_comma = 4,  flag_seek_value = 8,
+   flag_escaped = 16,  flag_string = 32,  flag_need_colon = 64,  flag_done = 128,
+   flag_num_negative = 256,  flag_num_zero = 512,  flag_num_e = 1024,
+   flag_num_e_got_sign = 2048,  flag_num_e_negative = 4096;
 
 json_value * json_parse_ex (json_settings * settings, const json_char * json, char * error_buf)
 {
@@ -193,7 +196,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
    const json_char * cur_line_begin, * i;
    json_value * top, * root, * alloc = 0;
    json_state state;
-   int flags;
+   long flags;
+   long num_digits = 0, num_fraction = 0, num_e = 0;
 
    error[0] = '\0';
 
@@ -210,8 +214,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
    {
       json_uchar uchar;
       unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
-      json_char * string;
-      unsigned int string_length;
+      json_char * string = NULL;
+      unsigned int string_length = 0;
 
       top = root = 0;
       flags = flag_seek_value;
@@ -285,7 +289,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
                         if (state.first_pass)
                            string_length += 2;
                         else
-                        {  string [string_length ++] = 0xC0 | ((uc_b2 & 0xC0) >> 6) | ((uc_b1 & 0x3) << 3);
+                        {  string [string_length ++] = 0xC0 | ((uc_b2 & 0xC0) >> 6) | ((uc_b1 & 0x7) << 2);
                            string [string_length ++] = 0x80 | (uc_b2 & 0x3F);
                         }
 
@@ -475,17 +479,34 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
                            if (!new_value (&state, &top, &root, &alloc, json_integer))
                               goto e_alloc_failure;
 
-                           flags &= ~ (flag_exponent | flag_got_exponent_sign);
-
-                           if (state.first_pass)
-                              continue;
-
-                           if (top->type == json_double)
-                              top->u.dbl = strtod (i, (json_char **) &i);
-                           else
-                              top->u.integer = strtol (i, (json_char **) &i, 10);
-
-                           flags |= flag_next | flag_reproc;
+                           if (!state.first_pass)
+                           {
+                              while (isdigit (b) || b == '+' || b == '-'
+                                        || b == 'e' || b == 'E' || b == '.')
+                              {
+                                 b = *++ i;
+                              }
+
+                              flags |= flag_next | flag_reproc;
+                              break;
+                           }
+
+                           flags &= ~ (flag_num_negative | flag_num_e |
+                                        flag_num_e_got_sign | flag_num_e_negative |
+                                           flag_num_zero);
+
+                           num_digits = 0;
+                           num_fraction = 0;
+                           num_e = 0;
+
+                           if (b != '-')
+                           {
+                              flags |= flag_reproc;
+                              break;
+                           }
+
+                           flags |= flag_num_negative;
+                           continue;
                         }
                         else
                         {  sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b);
@@ -545,32 +566,108 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
             case json_double:
 
                if (isdigit (b))
-                  continue;
-
-               if (b == 'e' || b == 'E')
                {
-                  if (!(flags & flag_exponent))
+                  ++ num_digits;
+
+                  if (top->type == json_integer || flags & flag_num_e)
                   {
-                     flags |= flag_exponent;
-                     top->type = json_double;
+                     if (! (flags & flag_num_e))
+                     {
+                        if (flags & flag_num_zero)
+                        {  sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b);
+                           goto e_failed;
+                        }
 
+                        if (num_digits == 1 && b == '0')
+                           flags |= flag_num_zero;
+                     }
+                     else
+                     {
+                        flags |= flag_num_e_got_sign;
+                        num_e = (num_e * 10) + (b - '0');
+                        continue;
+                     }
+
+                     top->u.integer = (top->u.integer * 10) + (b - '0');
                      continue;
                   }
+
+                  num_fraction = (num_fraction * 10) + (b - '0');
+                  continue;
                }
-               else if (b == '+' || b == '-')
+
+               if (b == '+' || b == '-')
                {
-                  if (flags & flag_exponent && !(flags & flag_got_exponent_sign))
+                  if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign))
                   {
-                     flags |= flag_got_exponent_sign;
+                     flags |= flag_num_e_got_sign;
+
+                     if (b == '-')
+                        flags |= flag_num_e_negative;
+
                      continue;
                   }
                }
                else if (b == '.' && top->type == json_integer)
                {
+                  if (!num_digits)
+                  {  sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);
+                     goto e_failed;
+                  }
+
                   top->type = json_double;
+                  top->u.dbl = (double) top->u.integer;
+
+                  num_digits = 0;
                   continue;
                }
 
+               if (! (flags & flag_num_e))
+               {
+                  if (top->type == json_double)
+                  {
+                     if (!num_digits)
+                     {  sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);
+                        goto e_failed;
+                     }
+
+                     top->u.dbl += ((double) num_fraction) / (pow ( (double) 10.0, (double) num_digits));
+                  }
+
+                  if (b == 'e' || b == 'E')
+                  {
+                     flags |= flag_num_e;
+
+                     if (top->type == json_integer)
+                     {
+                        top->type = json_double;
+                        top->u.dbl = (double) top->u.integer;
+                     }
+
+                     num_digits = 0;
+                     flags &= ~ flag_num_zero;
+
+                     continue;
+                  }
+               }
+               else
+               {
+                  if (!num_digits)
+                  {  sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);
+                     goto e_failed;
+                  }
+
+                  top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));
+               }
+
+               if (flags & flag_num_negative)
+               {
+                  if (top->type == json_integer)
+                     top->u.integer = - top->u.integer;
+                  else
+                     top->u.dbl = - top->u.dbl;
+               }
+
                flags |= flag_next | flag_reproc;
                break;
 
index d69bbda1e3abe62fb8c9410db08ef48b5eaefd77..693310298e91e9cb49ab8c78a8d202558e1cf8cb 100644 (file)
-/*****************************************************************************
- * json.h: json-parser fixups
- *****************************************************************************
- * Copyright (C) 2012 VLC authors and VideoLAN
+
+/* vim: set et ts=3 sw=3 ft=c:
+ *
+ * Copyright (C) 2012 James McLaughlin et al.  All rights reserved.
+ * https://github.com/udp/json-parser
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
+ * 1. Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
 #ifndef _JSON_H
-#ifndef _JSONFIXUPS_H
-#define _JSONFIXUPS_H
+#define _JSON_H
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
+#ifndef json_char
+   #define json_char char
 #endif
-#include <vlc_common.h>
-#include <vlc_charset.h>
-/* json.c depends on the locale */
-#define strtod(foo,bar) us_strtod(foo,bar)
-#include "use_json.h"
 
+#ifndef json_int_t
+   #ifndef _WIN32
+      #include <inttypes.h>
+      #define json_int_t int64_t
+   #else
+      #define json_int_t __int64
+   #endif
+#endif
+
+#ifdef __cplusplus
+
+   #include <string.h>
+
+   extern "C"
+   {
+
+#endif
+
+typedef struct
+{
+   unsigned long max_memory;
+   int settings;
+
+} json_settings;
+
+#define json_relaxed_commas 1
+
+typedef enum
+{
+   json_none,
+   json_object,
+   json_array,
+   json_integer,
+   json_double,
+   json_string,
+   json_boolean,
+   json_null
+
+} json_type;
+
+extern const struct _json_value json_value_none;
+
+typedef struct _json_value
+{
+   struct _json_value * parent;
+
+   json_type type;
+
+   union
+   {
+      int boolean;
+      json_int_t integer;
+      double dbl;
+
+      struct
+      {
+         unsigned int length;
+         json_char * ptr; /* null terminated */
+
+      } string;
+
+      struct
+      {
+         unsigned int length;
+
+         struct
+         {
+            json_char * name;
+            struct _json_value * value;
+
+         } * values;
+
+      } object;
+
+      struct
+      {
+         unsigned int length;
+         struct _json_value ** values;
+
+      } array;
+
+   } u;
+
+   union
+   {
+      struct _json_value * next_alloc;
+      void * object_mem;
+
+   } _reserved;
+
+
+   /* Some C++ operator sugar */
+
+   #ifdef __cplusplus
+
+      public:
+
+         inline _json_value ()
+         {  memset (this, 0, sizeof (_json_value));
+         }
+
+         inline const struct _json_value &operator [] (int index) const
+         {
+            if (type != json_array || index < 0
+                     || ((unsigned int) index) >= u.array.length)
+            {
+               return json_value_none;
+            }
+
+            return *u.array.values [index];
+         }
+
+         inline const struct _json_value &operator [] (const char * index) const
+         {
+            if (type != json_object)
+               return json_value_none;
+
+            for (unsigned int i = 0; i < u.object.length; ++ i)
+               if (!strcmp (u.object.values [i].name, index))
+                  return *u.object.values [i].value;
+
+            return json_value_none;
+         }
+
+         inline operator const char * () const
+         {
+            switch (type)
+            {
+               case json_string:
+                  return u.string.ptr;
+
+               default:
+                  return "";
+            };
+         }
+
+         inline operator json_int_t () const
+         {
+            switch (type)
+            {
+               case json_integer:
+                  return u.integer;
+
+               case json_double:
+                  return (json_int_t) u.dbl;
+
+               default:
+                  return 0;
+            };
+         }
+
+         inline operator bool () const
+         {
+            if (type != json_boolean)
+               return false;
+
+            return u.boolean != 0;
+         }
+
+         inline operator double () const
+         {
+            switch (type)
+            {
+               case json_integer:
+                  return (double) u.integer;
+
+               case json_double:
+                  return u.dbl;
+
+               default:
+                  return 0;
+            };
+         }
+
+   #endif
+
+} json_value;
+
+json_value * json_parse
+   (const json_char * json);
+
+json_value * json_parse_ex
+   (json_settings * settings, const json_char * json, char * error);
+
+void json_value_free (json_value *);
+
+
+#ifdef __cplusplus
+   } /* extern "C" */
 #endif
+
 #endif
diff --git a/modules/misc/webservices/use_json.h b/modules/misc/webservices/use_json.h
deleted file mode 100644 (file)
index 2fb8c01..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* vim: set et ts=3 sw=3 ft=c:
- *
- * Copyright (C) 2012 James McLaughlin et al.  All rights reserved.
- * https://github.com/udp/json-parser
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _JSON_H
-#define _JSON_H
-
-#ifndef json_char
-   #define json_char char
-#endif
-
-#ifdef __cplusplus
-
-   #include <string.h>
-
-   extern "C"
-   {
-
-#endif
-
-typedef struct
-{
-   unsigned long max_memory;
-   int settings;
-
-} json_settings;
-
-#define json_relaxed_commas 1
-
-typedef enum
-{
-   json_none,
-   json_object,
-   json_array,
-   json_integer,
-   json_double,
-   json_string,
-   json_boolean,
-   json_null
-
-} json_type;
-
-extern const struct _json_value json_value_none;
-
-typedef struct _json_value
-{
-   struct _json_value * parent;
-
-   json_type type;
-
-   union
-   {
-      int boolean;
-      long integer;
-      double dbl;
-
-      struct
-      {
-         unsigned int length;
-         json_char * ptr; /* null terminated */
-
-      } string;
-
-      struct
-      {
-         unsigned int length;
-
-         struct
-         {
-            json_char * name;
-            struct _json_value * value;
-
-         } * values;
-
-      } object;
-
-      struct
-      {
-         unsigned int length;
-         struct _json_value ** values;
-
-      } array;
-
-   } u;
-
-   union
-   {
-      struct _json_value * next_alloc;
-      void * object_mem;
-
-   } _reserved;
-
-
-   /* Some C++ operator sugar */
-
-   #ifdef __cplusplus
-
-      public:
-
-         inline _json_value ()
-         {  memset (this, 0, sizeof (_json_value));
-         }
-
-         inline const struct _json_value &operator [] (int index) const
-         {
-            if (type != json_array || index < 0
-                     || ((unsigned int) index) >= u.array.length)
-            {
-               return json_value_none;
-            }
-
-            return *u.array.values [index];
-         }
-
-         inline const struct _json_value &operator [] (const char * index) const
-         {
-            if (type != json_object)
-               return json_value_none;
-
-            for (unsigned int i = 0; i < u.object.length; ++ i)
-               if (!strcmp (u.object.values [i].name, index))
-                  return *u.object.values [i].value;
-
-            return json_value_none;
-         }
-
-         inline operator const char * () const
-         {
-            switch (type)
-            {
-               case json_string:
-                  return u.string.ptr;
-
-               default:
-                  return "";
-            };
-         }
-
-         inline operator long () const
-         {  return u.integer;
-         }
-
-         inline operator bool () const
-         {  return u.boolean != 0;
-         }
-
-   #endif
-
-} json_value;
-
-json_value * json_parse
-   (const json_char * json);
-
-json_value * json_parse_ex
-   (json_settings * settings, const json_char * json, char * error);
-
-void json_value_free (json_value *);
-
-
-#ifdef __cplusplus
-   } /* extern "C" */
-#endif
-
-#endif