Commit 29667876 authored by Francois Cartegnie's avatar Francois Cartegnie

misc: acoustid: update json parser.

Removes locale fix and conditionally builds fingerprinter.
parent 027bd907
...@@ -3604,6 +3604,22 @@ AS_IF([test "$enable_kai" != "no"], [ ...@@ -3604,6 +3604,22 @@ AS_IF([test "$enable_kai" != "no"], [
AC_SUBST(KAI_LIBS) AC_SUBST(KAI_LIBS)
AM_CONDITIONAL([HAVE_KAI], [test "${have_kai}" = "yes"]) 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
dnl Interface plugins dnl Interface plugins
dnl dnl
...@@ -3834,11 +3850,6 @@ dnl goom visualization plugin ...@@ -3834,11 +3850,6 @@ dnl goom visualization plugin
dnl dnl
PKG_ENABLE_MODULES_VLC([GOOM], [], [libgoom2], [goom visualization plugin], [auto]) 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
dnl libprojectM visualization plugin dnl libprojectM visualization plugin
dnl dnl
......
...@@ -3,7 +3,6 @@ SOURCES_audioscrobbler = audioscrobbler.c ...@@ -3,7 +3,6 @@ SOURCES_audioscrobbler = audioscrobbler.c
SOURCES_fingerprinter = fingerprinter.c \ SOURCES_fingerprinter = fingerprinter.c \
webservices/acoustid.c \ webservices/acoustid.c \
webservices/acoustid.h \ webservices/acoustid.h \
webservices/use_json.h \
webservices/json.c \ webservices/json.c \
webservices/json.h webservices/json.h
...@@ -55,7 +54,6 @@ libstats_plugin_la_LIBADD = $(AM_LIBADD) ...@@ -55,7 +54,6 @@ libstats_plugin_la_LIBADD = $(AM_LIBADD)
libvlc_LTLIBRARIES += \ libvlc_LTLIBRARIES += \
libaudioscrobbler_plugin.la \ libaudioscrobbler_plugin.la \
libfingerprinter_plugin.la \
liblogger_plugin.la \ liblogger_plugin.la \
libstats_plugin.la libstats_plugin.la
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include "acoustid.h" #include "acoustid.h"
#include "use_json.h" #include "json.h"
/***************************************************************************** /*****************************************************************************
* Requests lifecycle * Requests lifecycle
......
...@@ -38,13 +38,14 @@ ...@@ -38,13 +38,14 @@
#ifdef __cplusplus #ifdef __cplusplus
const struct _json_value json_value_none; /* zero-d by ctor */ const struct _json_value json_value_none; /* zero-d by ctor */
#else #else
const struct _json_value json_value_none = { 0 }; const struct _json_value json_value_none = { 0, 0, { 0 }, { 0 } };
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <math.h>
typedef unsigned short json_uchar; typedef unsigned short json_uchar;
...@@ -117,6 +118,7 @@ static int new_value ...@@ -117,6 +118,7 @@ static int new_value
return 0; return 0;
} }
value->u.array.length = 0;
break; break;
case json_object: case json_object:
...@@ -131,6 +133,7 @@ static int new_value ...@@ -131,6 +133,7 @@ static int new_value
value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size;
value->u.object.length = 0;
break; break;
case json_string: case json_string:
...@@ -141,14 +144,13 @@ static int new_value ...@@ -141,14 +144,13 @@ static int new_value
return 0; return 0;
} }
value->u.string.length = 0;
break; break;
default: default:
break; break;
}; };
value->u.array.length = 0;
return 1; return 1;
} }
...@@ -181,10 +183,11 @@ static int new_value ...@@ -181,10 +183,11 @@ static int new_value
#define string_add(b) \ #define string_add(b) \
do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0); do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
const static int static const long
flag_next = 1, flag_reproc = 2, flag_need_comma = 4, flag_seek_value = 8, flag_exponent = 16, flag_next = 1, flag_reproc = 2, flag_need_comma = 4, flag_seek_value = 8,
flag_got_exponent_sign = 32, flag_escaped = 64, flag_string = 128, flag_need_colon = 256, flag_escaped = 16, flag_string = 32, flag_need_colon = 64, flag_done = 128,
flag_done = 512; 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) 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 ...@@ -193,7 +196,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
const json_char * cur_line_begin, * i; const json_char * cur_line_begin, * i;
json_value * top, * root, * alloc = 0; json_value * top, * root, * alloc = 0;
json_state state; json_state state;
int flags; long flags;
long num_digits = 0, num_fraction = 0, num_e = 0;
error[0] = '\0'; error[0] = '\0';
...@@ -210,8 +214,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch ...@@ -210,8 +214,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
{ {
json_uchar uchar; json_uchar uchar;
unsigned char uc_b1, uc_b2, uc_b3, uc_b4; unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
json_char * string; json_char * string = NULL;
unsigned int string_length; unsigned int string_length = 0;
top = root = 0; top = root = 0;
flags = flag_seek_value; flags = flag_seek_value;
...@@ -285,7 +289,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch ...@@ -285,7 +289,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
if (state.first_pass) if (state.first_pass)
string_length += 2; string_length += 2;
else 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); string [string_length ++] = 0x80 | (uc_b2 & 0x3F);
} }
...@@ -475,17 +479,34 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch ...@@ -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)) if (!new_value (&state, &top, &root, &alloc, json_integer))
goto e_alloc_failure; goto e_alloc_failure;
flags &= ~ (flag_exponent | flag_got_exponent_sign); if (!state.first_pass)
{
while (isdigit (b) || b == '+' || b == '-'
|| b == 'e' || b == 'E' || b == '.')
{
b = *++ i;
}
if (state.first_pass) flags |= flag_next | flag_reproc;
continue; break;
}
if (top->type == json_double) flags &= ~ (flag_num_negative | flag_num_e |
top->u.dbl = strtod (i, (json_char **) &i); flag_num_e_got_sign | flag_num_e_negative |
else flag_num_zero);
top->u.integer = strtol (i, (json_char **) &i, 10);
flags |= flag_next | flag_reproc; num_digits = 0;
num_fraction = 0;
num_e = 0;
if (b != '-')
{
flags |= flag_reproc;
break;
}
flags |= flag_num_negative;
continue;
} }
else else
{ sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b); { sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b);
...@@ -545,31 +566,107 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch ...@@ -545,31 +566,107 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case json_double: case json_double:
if (isdigit (b)) if (isdigit (b))
continue; {
++ num_digits;
if (b == 'e' || b == 'E') if (top->type == json_integer || flags & flag_num_e)
{ {
if (!(flags & flag_exponent)) if (! (flags & flag_num_e))
{ {
flags |= flag_exponent; if (flags & flag_num_zero)
top->type = json_double; { 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; continue;
} }
top->u.integer = (top->u.integer * 10) + (b - '0');
continue;
} }
else if (b == '+' || b == '-')
num_fraction = (num_fraction * 10) + (b - '0');
continue;
}
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; continue;
} }
} }
else if (b == '.' && top->type == json_integer) 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->type = json_double;
top->u.dbl = (double) top->u.integer;
}
num_digits = 0;
flags &= ~ flag_num_zero;
continue; 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; flags |= flag_next | flag_reproc;
break; break;
......
/*****************************************************************************
* json.h: json-parser fixups /* vim: set et ts=3 sw=3 ft=c:
***************************************************************************** *
* Copyright (C) 2012 VLC authors and VideoLAN * 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 * Redistribution and use in source and binary forms, with or without
* under the terms of the GNU Lesser General Public License as published by * modification, are permitted provided that the following conditions
* the Free Software Foundation; either version 2.1 of the License, or * are met:
* (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * 1. Redistributions of source code must retain the above copyright
* but WITHOUT ANY WARRANTY; without even the implied warranty of * notice, this list of conditions and the following disclaimer.
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * 2. Redistributions in binary form must reproduce the above copyright
* along with this program; if not, write to the Free Software Foundation, * notice, this list of conditions and the following disclaimer in the
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * 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 _JSON_H
#ifndef _JSONFIXUPS_H #define _JSON_H
#define _JSONFIXUPS_H
#ifdef HAVE_CONFIG_H #ifndef json_char
# include "config.h" #define json_char char
#endif #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
#endif #endif
/* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment