Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (2)
......@@ -74,9 +74,10 @@ static void parse_recordings( vlc_object_t *p_obj, const json_value *node, acous
}
}
static bool ParseJson( vlc_object_t *p_obj, const void *p_buffer, acoustid_results_t *p_results )
static bool ParseJson( vlc_object_t *p_obj, const void *p_buffer, size_t i_buffer,
acoustid_results_t *p_results )
{
json_value *root = json_parse_document( p_obj, p_buffer );
json_value *root = json_parse_document( p_obj, p_buffer, i_buffer );
if( !root )
return false;
......@@ -153,12 +154,13 @@ int acoustid_lookup_fingerprint( const acoustid_config_t *p_cfg, acoustid_finger
}
msg_Dbg( p_cfg->p_obj, "Querying AcoustID from %s", psz_url );
void *p_buffer = json_retrieve_document( p_cfg->p_obj, psz_url );
size_t i_buffer;
void *p_buffer = json_retrieve_document( p_cfg->p_obj, psz_url, &i_buffer );
free( psz_url );
if( !p_buffer )
return VLC_EGENERIC;
if ( ParseJson( p_cfg->p_obj, p_buffer, & p_data->results ) )
if ( ParseJson( p_cfg->p_obj, p_buffer, i_buffer, & p_data->results ) )
msg_Dbg( p_cfg->p_obj, "results count == %d", p_data->results.count );
else
msg_Dbg( p_cfg->p_obj, "No results" );
......
/* vim: set et ts=3 sw=3 ft=c:
/* vim: set et ts=3 sw=3 sts=3 ft=c:
*
* Copyright (C) 2012 James McLaughlin et al. All rights reserved.
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
* https://github.com/udp/json-parser
*
* Redistribution and use in source and binary forms, with or without
......@@ -35,50 +35,58 @@
#endif
#endif
#ifdef __cplusplus
const struct _json_value json_value_none; /* zero-d by ctor */
#else
const struct _json_value json_value_none = { 0, 0, { 0 }, { 0 } };
#endif
const struct _json_value json_value_none;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
typedef unsigned short json_uchar;
typedef unsigned int json_uchar;
static unsigned char hex_value (json_char c)
{
if (c >= 'A' && c <= 'F')
return (c - 'A') + 10;
if (c >= 'a' && c <= 'f')
return (c - 'a') + 10;
if (c >= '0' && c <= '9')
if (isdigit(c))
return c - '0';
return 0xFF;
switch (c) {
case 'a': case 'A': return 0x0A;
case 'b': case 'B': return 0x0B;
case 'c': case 'C': return 0x0C;
case 'd': case 'D': return 0x0D;
case 'e': case 'E': return 0x0E;
case 'f': case 'F': return 0x0F;
default: return 0xFF;
}
}
typedef struct
{
json_settings settings;
int first_pass;
unsigned long used_memory;
unsigned int uint_max;
unsigned long ulong_max;
json_settings settings;
int first_pass;
const json_char * ptr;
unsigned int cur_line, cur_col;
} json_state;
static void * json_alloc (json_state * state, unsigned long size, int zero)
static void * default_alloc (size_t size, int zero, void * user_data)
{
void * mem;
return zero ? calloc (1, size) : malloc (size);
}
static void default_free (void * ptr, void * user_data)
{
free (ptr);
}
static void * json_alloc (json_state * state, unsigned long size, int zero)
{
if ((state->ulong_max - state->used_memory) < size)
return 0;
......@@ -88,14 +96,12 @@ static void * json_alloc (json_state * state, unsigned long size, int zero)
return 0;
}
if (! (mem = zero ? calloc (size, 1) : malloc (size)))
return 0;
return mem;
return state->settings.mem_alloc (size, zero, state->settings.user_data);
}
static int new_value
(json_state * state, json_value ** top, json_value ** root, json_value ** alloc, json_type type)
static int new_value (json_state * state,
json_value ** top, json_value ** root, json_value ** alloc,
json_type type)
{
json_value * value;
int values_size;
......@@ -154,10 +160,11 @@ static int new_value
return 1;
}
value = (json_value *) json_alloc (state, sizeof (json_value), 1);
if (!value)
if (! (value = (json_value *) json_alloc
(state, sizeof (json_value) + state->settings.value_extra, 1)))
{
return 0;
}
if (!*root)
*root = value;
......@@ -165,6 +172,11 @@ static int new_value
value->type = type;
value->parent = *top;
#ifdef JSON_TRACK_SOURCE
value->line = state->cur_line;
value->col = state->cur_col;
#endif
if (*alloc)
(*alloc)->_reserved.next_alloc = value;
......@@ -173,38 +185,67 @@ static int new_value
return 1;
}
#define e_off \
((int) (i - cur_line_begin))
#define whitespace \
case '\n': ++ cur_line; cur_line_begin = i; \
/* fall through */ \
case '\n': ++ state.cur_line; state.cur_col = 0; \
case ' ': case '\t': case '\r'
#define string_add(b) \
do { if (!state.first_pass) string [string_length] = b; ++ string_length; } while (0);
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;
#define line_and_col \
state.cur_line, state.cur_col
json_value * json_parse_ex (json_settings * settings, const json_char * json, char * error_buf)
static const long
flag_next = 1 << 0,
flag_reproc = 1 << 1,
flag_need_comma = 1 << 2,
flag_seek_value = 1 << 3,
flag_escaped = 1 << 4,
flag_string = 1 << 5,
flag_need_colon = 1 << 6,
flag_done = 1 << 7,
flag_num_negative = 1 << 8,
flag_num_zero = 1 << 9,
flag_num_e = 1 << 10,
flag_num_e_got_sign = 1 << 11,
flag_num_e_negative = 1 << 12,
flag_line_comment = 1 << 13,
flag_block_comment = 1 << 14;
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error_buf)
{
json_char error [128];
unsigned int cur_line;
const json_char * cur_line_begin, * i;
json_char error [json_error_max];
const json_char * end;
json_value * top, * root, * alloc = 0;
json_state state;
json_state state = { 0 };
long flags;
long num_digits = 0, num_fraction = 0, num_e = 0;
long num_digits = 0, num_e = 0;
json_int_t num_fraction = 0;
/* Skip UTF-8 BOM
*/
if (length >= 3 && ((unsigned char) json [0]) == 0xEF
&& ((unsigned char) json [1]) == 0xBB
&& ((unsigned char) json [2]) == 0xBF)
{
json += 3;
length -= 3;
}
error[0] = '\0';
end = (json + length);
memset (&state, 0, sizeof (json_state));
memcpy (&state.settings, settings, sizeof (json_settings));
if (!state.settings.mem_alloc)
state.settings.mem_alloc = default_alloc;
if (!state.settings.mem_free)
state.settings.mem_free = default_free;
memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
......@@ -215,39 +256,22 @@ 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 = NULL;
json_char * string = 0;
unsigned int string_length = 0;
top = root = 0;
flags = flag_seek_value;
cur_line = 1;
cur_line_begin = json;
state.cur_line = 1;
for (i = json ;; ++ i)
for (state.ptr = json ;; ++ state.ptr)
{
json_char b = *i;
if (flags & flag_done)
{
if (!b)
break;
switch (b)
{
whitespace:
continue;
default:
sprintf (error, "%d:%d: Trailing garbage: `%c`", cur_line, e_off, b);
goto e_failed;
};
}
json_char b = (state.ptr == end ? 0 : *state.ptr);
if (flags & flag_string)
{
if (!b)
{ sprintf (error, "Unexpected EOF in string (at %d:%d)", cur_line, e_off);
{ sprintf (error, "Unexpected EOF in string (at %d:%d)", line_and_col);
goto e_failed;
}
......@@ -267,19 +291,41 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 't': string_add ('\t'); break;
case 'u':
if ((uc_b1 = hex_value (*++ i)) == 0xFF || (uc_b2 = hex_value (*++ i)) == 0xFF
|| (uc_b3 = hex_value (*++ i)) == 0xFF || (uc_b4 = hex_value (*++ i)) == 0xFF)
if (end - state.ptr < 4 ||
(uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
{
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, cur_line, e_off);
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
goto e_failed;
}
uc_b1 = uc_b1 * 16 + uc_b2;
uc_b2 = uc_b3 * 16 + uc_b4;
uc_b1 = (uc_b1 << 4) | uc_b2;
uc_b2 = (uc_b3 << 4) | uc_b4;
uchar = (uc_b1 << 8) | uc_b2;
uchar = ((json_char) uc_b1) * 256 + uc_b2;
if ((uchar & 0xF800) == 0xD800) {
json_uchar uchar2;
if (sizeof (json_char) >= sizeof (json_uchar) || (uc_b1 == 0 && uc_b2 <= 0x7F))
if (end - state.ptr < 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' ||
(uc_b1 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b2 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b3 = hex_value (*++ state.ptr)) == 0xFF ||
(uc_b4 = hex_value (*++ state.ptr)) == 0xFF)
{
sprintf (error, "Invalid character value `%c` (at %d:%d)", b, line_and_col);
goto e_failed;
}
uc_b1 = (uc_b1 << 4) | uc_b2;
uc_b2 = (uc_b3 << 4) | uc_b4;
uchar2 = (uc_b1 << 8) | uc_b2;
uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF);
}
if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F))
{
string_add ((json_char) uchar);
break;
......@@ -290,19 +336,32 @@ 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 & 0x7) << 2);
string [string_length ++] = 0x80 | (uc_b2 & 0x3F);
{ string [string_length ++] = 0xC0 | (uchar >> 6);
string [string_length ++] = 0x80 | (uchar & 0x3F);
}
break;
}
if (uchar <= 0xFFFF) {
if (state.first_pass)
string_length += 3;
else
{ string [string_length ++] = 0xE0 | (uchar >> 12);
string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
string [string_length ++] = 0x80 | (uchar & 0x3F);
}
break;
}
if (state.first_pass)
string_length += 3;
string_length += 4;
else
{ string [string_length ++] = 0xE0 | ((uc_b1 & 0xF0) >> 4);
string [string_length ++] = 0x80 | ((uc_b1 & 0xF) << 2) | ((uc_b2 & 0xC0) >> 6);
string [string_length ++] = 0x80 | (uc_b2 & 0x3F);
{ string [string_length ++] = 0xF0 | (uchar >> 18);
string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F);
string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F);
string [string_length ++] = 0x80 | (uchar & 0x3F);
}
break;
......@@ -346,6 +405,9 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
top->u.object.values [top->u.object.length].name
= (json_char *) top->_reserved.object_mem;
top->u.object.values [top->u.object.length].name_length
= string_length;
(*(json_char **) &top->_reserved.object_mem) += string_length + 1;
}
......@@ -363,6 +425,85 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
}
}
if (state.settings.settings & json_enable_comments)
{
if (flags & (flag_line_comment | flag_block_comment))
{
if (flags & flag_line_comment)
{
if (b == '\r' || b == '\n' || !b)
{
flags &= ~ flag_line_comment;
-- state.ptr; /* so null can be reproc'd */
}
continue;
}
if (flags & flag_block_comment)
{
if (!b)
{ sprintf (error, "%d:%d: Unexpected EOF in block comment", line_and_col);
goto e_failed;
}
if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/')
{
flags &= ~ flag_block_comment;
++ state.ptr; /* skip closing sequence */
}
continue;
}
}
else if (b == '/')
{
if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object)
{ sprintf (error, "%d:%d: Comment not allowed here", line_and_col);
goto e_failed;
}
if (++ state.ptr == end)
{ sprintf (error, "%d:%d: EOF unexpected", line_and_col);
goto e_failed;
}
switch (b = *state.ptr)
{
case '/':
flags |= flag_line_comment;
continue;
case '*':
flags |= flag_block_comment;
continue;
default:
sprintf (error, "%d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b);
goto e_failed;
};
}
}
if (flags & flag_done)
{
if (!b)
break;
switch (b)
{
whitespace:
continue;
default:
sprintf (error, "%d:%d: Trailing garbage: `%c`",
state.cur_line, state.cur_col, b);
goto e_failed;
};
}
if (flags & flag_seek_value)
{
switch (b)
......@@ -374,8 +515,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
if (top && top->type == json_array)
flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next;
else if (!(state.settings.settings & json_relaxed_commas))
{ sprintf (error, "%d:%d: Unexpected ]", cur_line, e_off);
else
{ sprintf (error, "%d:%d: Unexpected ]", line_and_col);
goto e_failed;
}
......@@ -390,7 +531,10 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
continue;
}
else
{ sprintf (error, "%d:%d: Expected , before %c", cur_line, e_off, b);
{
sprintf (error, "%d:%d: Expected , before %c",
state.cur_line, state.cur_col, b);
goto e_failed;
}
}
......@@ -402,7 +546,10 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
continue;
}
else
{ sprintf (error, "%d:%d: Expected : before %c", cur_line, e_off, b);
{
sprintf (error, "%d:%d: Expected : before %c",
state.cur_line, state.cur_col, b);
goto e_failed;
}
}
......@@ -440,8 +587,11 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 't':
if (*(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' ||
*(++ state.ptr) != 'u' || *(++ state.ptr) != 'e')
{
goto e_unknown_value;
}
if (!new_value (&state, &top, &root, &alloc, json_boolean))
goto e_alloc_failure;
......@@ -453,8 +603,12 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 'f':
if (*(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' ||
*(++ state.ptr) != 'l' || *(++ state.ptr) != 's' ||
*(++ state.ptr) != 'e')
{
goto e_unknown_value;
}
if (!new_value (&state, &top, &root, &alloc, json_boolean))
goto e_alloc_failure;
......@@ -464,8 +618,11 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 'n':
if (*(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' ||
*(++ state.ptr) != 'l' || *(++ state.ptr) != 'l')
{
goto e_unknown_value;
}
if (!new_value (&state, &top, &root, &alloc, json_null))
goto e_alloc_failure;
......@@ -485,7 +642,13 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
while (isdigit (b) || b == '+' || b == '-'
|| b == 'e' || b == 'E' || b == '.')
{
b = *++ i;
if ( (++ state.ptr) == end)
{
b = 0;
break;
}
b = *state.ptr;
}
flags |= flag_next | flag_reproc;
......@@ -510,7 +673,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
continue;
}
else
{ sprintf (error, "%d:%d: Unexpected %c when seeking value", cur_line, e_off, b);
{ sprintf (error, "%d:%d: Unexpected %c when seeking value", line_and_col, b);
goto e_failed;
}
};
......@@ -529,9 +692,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case '"':
if (flags & flag_need_comma && !(state.settings.settings & json_relaxed_commas))
{
sprintf (error, "%d:%d: Expected , before \"", cur_line, e_off);
if (flags & flag_need_comma)
{ sprintf (error, "%d:%d: Expected , before \"", line_and_col);
goto e_failed;
}
......@@ -555,10 +717,8 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
break;
}
/* fall through */
default:
sprintf (error, "%d:%d: Unexpected `%c` in object", cur_line, e_off, b);
sprintf (error, "%d:%d: Unexpected `%c` in object", line_and_col, b);
goto e_failed;
};
......@@ -576,7 +736,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
if (! (flags & flag_num_e))
{
if (flags & flag_num_zero)
{ sprintf (error, "%d:%d: Unexpected `0` before `%c`", cur_line, e_off, b);
{ sprintf (error, "%d:%d: Unexpected `0` before `%c`", line_and_col, b);
goto e_failed;
}
......@@ -613,7 +773,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
else if (b == '.' && top->type == json_integer)
{
if (!num_digits)
{ sprintf (error, "%d:%d: Expected digit before `.`", cur_line, e_off);
{ sprintf (error, "%d:%d: Expected digit before `.`", line_and_col);
goto e_failed;
}
......@@ -629,11 +789,11 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
if (top->type == json_double)
{
if (!num_digits)
{ sprintf (error, "%d:%d: Expected digit after `.`", cur_line, e_off);
{ sprintf (error, "%d:%d: Expected digit after `.`", line_and_col);
goto e_failed;
}
top->u.dbl += ((double) num_fraction) / (pow ( (double) 10.0, (double) num_digits));
top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits));
}
if (b == 'e' || b == 'E')
......@@ -655,11 +815,12 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
else
{
if (!num_digits)
{ sprintf (error, "%d:%d: Expected digit after `e`", cur_line, e_off);
{ sprintf (error, "%d:%d: Expected digit after `e`", line_and_col);
goto e_failed;
}
top->u.dbl *= pow (10, (double) (flags & flag_num_e_negative ? - num_e : num_e));
top->u.dbl *= pow (10.0, (double)
(flags & flag_num_e_negative ? - num_e : num_e));
}
if (flags & flag_num_negative)
......@@ -681,7 +842,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
if (flags & flag_reproc)
{
flags &= ~ flag_reproc;
-- i;
-- state.ptr;
}
if (flags & flag_next)
......@@ -740,7 +901,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
e_unknown_value:
sprintf (error, "%d:%d: Unknown value", cur_line, e_off);
sprintf (error, "%d:%d: Unknown value", line_and_col);
goto e_failed;
e_alloc_failure:
......@@ -750,7 +911,7 @@ e_alloc_failure:
e_overflow:
sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
sprintf (error, "%d:%d: Too long (caught overflow)", line_and_col);
goto e_failed;
e_failed:
......@@ -769,25 +930,23 @@ e_failed:
while (alloc)
{
top = alloc->_reserved.next_alloc;
free (alloc);
state.settings.mem_free (alloc, state.settings.user_data);
alloc = top;
}
if (!state.first_pass)
json_value_free (root);
json_value_free_ex (&state.settings, root);
return 0;
}
json_value * json_parse (const json_char * json)
json_value * json_parse (const json_char * json, size_t length)
{
json_settings settings;
memset (&settings, 0, sizeof (json_settings));
return json_parse_ex (&settings, json, 0);
json_settings settings = { 0 };
return json_parse_ex (&settings, json, length, 0);
}
void json_value_free (json_value * value)
void json_value_free_ex (json_settings * settings, json_value * value)
{
json_value * cur_value;
......@@ -804,7 +963,7 @@ void json_value_free (json_value * value)
if (!value->u.array.length)
{
free (value->u.array.values);
settings->mem_free (value->u.array.values, settings->user_data);
break;
}
......@@ -815,7 +974,7 @@ void json_value_free (json_value * value)
if (!value->u.object.length)
{
free (value->u.object.values);
settings->mem_free (value->u.object.values, settings->user_data);
break;
}
......@@ -824,7 +983,7 @@ void json_value_free (json_value * value)
case json_string:
free (value->u.string.ptr);
settings->mem_free (value->u.string.ptr, settings->user_data);
break;
default:
......@@ -833,6 +992,14 @@ void json_value_free (json_value * value)
cur_value = value;
value = value->parent;
free (cur_value);
settings->mem_free (cur_value, settings->user_data);
}
}
void json_value_free (json_value * value)
{
json_settings settings = { 0 };
settings.mem_free = default_free;
json_value_free_ex (&settings, value);
}
/* vim: set et ts=3 sw=3 ft=c:
/* vim: set et ts=3 sw=3 sts=3 ft=c:
*
* Copyright (C) 2012 James McLaughlin et al. All rights reserved.
* Copyright (C) 2012, 2013, 2014 James McLaughlin et al. All rights reserved.
* https://github.com/udp/json-parser
*
* Redistribution and use in source and binary forms, with or without
......@@ -36,10 +35,16 @@
#endif
#ifndef json_int_t
#include <inttypes.h>
#define json_int_t int64_t
#ifndef _MSC_VER
#include <inttypes.h>
#define json_int_t int64_t
#else
#define json_int_t __int64
#endif
#endif
#include <stdlib.h>
#ifdef __cplusplus
#include <string.h>
......@@ -54,9 +59,19 @@ typedef struct
unsigned long max_memory;
int settings;
/* Custom allocator support (leave null to use malloc/free)
*/
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
void * user_data; /* will be passed to mem_alloc and mem_free */
size_t value_extra; /* how much extra space to allocate for values? */
} json_settings;
#define json_relaxed_commas 1
#define json_enable_comments 0x01
typedef enum
{
......@@ -99,10 +114,21 @@ typedef struct _json_value
struct
{
json_char * name;
unsigned int name_length;
struct _json_value * value;
} * values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} object;
struct
......@@ -110,6 +136,15 @@ typedef struct _json_value
unsigned int length;
struct _json_value ** values;
#if defined(__cplusplus) && __cplusplus >= 201103L
decltype(values) begin () const
{ return values;
}
decltype(values) end () const
{ return values + length;
}
#endif
} array;
} u;
......@@ -121,6 +156,14 @@ typedef struct _json_value
} _reserved;
#ifdef JSON_TRACK_SOURCE
/* Location of the value in the source JSON
*/
unsigned int line, col;
#endif
/* Some C++ operator sugar */
......@@ -209,15 +252,25 @@ typedef struct _json_value
} json_value;
json_value * json_parse
(const json_char * json);
json_value * json_parse (const json_char * json,
size_t length);
json_value * json_parse_ex
(json_settings * settings, const json_char * json, char * error);
#define json_error_max 128
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
void json_value_free (json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
void json_value_free_ex (json_settings * settings,
json_value *);
#ifdef __cplusplus
} /* extern "C" */
#endif
......
......@@ -54,12 +54,12 @@ char * json_dupstring(const json_value *node, const char *key)
}
static inline
json_value * json_parse_document(vlc_object_t *p_obj, const char *psz_buffer)
json_value * json_parse_document(vlc_object_t *p_obj, const char *psz_buffer, size_t i_buffer)
{
json_settings settings;
char psz_error[128];
memset (&settings, 0, sizeof (json_settings));
json_value *root = json_parse_ex(&settings, psz_buffer, psz_error);
json_value *root = json_parse_ex(&settings, psz_buffer, i_buffer, psz_error);
if (root == NULL)
{
msg_Warn(p_obj, "Can't parse json data: %s", psz_error);
......@@ -79,7 +79,7 @@ error:
}
static inline
void * json_retrieve_document(vlc_object_t *p_obj, const char *psz_url)
void * json_retrieve_document(vlc_object_t *p_obj, const char *psz_url, size_t *buf_size)
{
bool saved_no_interact = p_obj->no_interact;
p_obj->no_interact = true;
......@@ -95,29 +95,29 @@ void * json_retrieve_document(vlc_object_t *p_obj, const char *psz_url)
/* read answer */
char *p_buffer = NULL;
int i_ret = 0;
*buf_size = 0;
for(;;)
{
int i_read = 65536;
if(i_ret >= INT_MAX - i_read)
if(*buf_size >= (SIZE_MAX - i_read - 1))
break;
p_buffer = realloc_or_free(p_buffer, 1 + i_ret + i_read);
p_buffer = realloc_or_free(p_buffer, 1 + *buf_size + i_read);
if(unlikely(p_buffer == NULL))
{
vlc_stream_Delete(p_stream);
return NULL;
}
i_read = vlc_stream_Read(p_stream, &p_buffer[i_ret], i_read);
i_read = vlc_stream_Read(p_stream, &p_buffer[*buf_size], i_read);
if(i_read <= 0)
break;
i_ret += i_read;
*buf_size += i_read;
}
vlc_stream_Delete(p_stream);
p_buffer[i_ret] = 0;
p_buffer[*buf_size++] = '\0';
return p_buffer;
}
......
......@@ -47,14 +47,15 @@ static musicbrainz_lookup_t * musicbrainz_lookup_new(void)
static musicbrainz_lookup_t * musicbrainz_lookup(vlc_object_t *p_obj, const char *psz_url)
{
msg_Dbg(p_obj, "Querying MB for %s", psz_url);
void *p_buffer = json_retrieve_document(p_obj, psz_url);
size_t i_buffer;
void *p_buffer = json_retrieve_document(p_obj, psz_url, &i_buffer);
if(!p_buffer)
return NULL;
musicbrainz_lookup_t *p_lookup = musicbrainz_lookup_new();
if(p_lookup)
{
p_lookup->root = json_parse_document(p_obj, p_buffer);
p_lookup->root = json_parse_document(p_obj, p_buffer, i_buffer);
if (!p_lookup->root)
msg_Dbg(p_obj, "No results");
}
......
......@@ -673,7 +673,7 @@ void intf_sys_t::processAuthMessage( const castchannel::CastMessage& msg )
void intf_sys_t::processHeartBeatMessage( const castchannel::CastMessage& msg )
{
json_value *p_data = json_parse(msg.payload_utf8().c_str());
json_value *p_data = json_parse(msg.payload_utf8().c_str(), msg.payload_utf8().length());
std::string type((*p_data)["type"]);
if (type == "PING")
......@@ -696,7 +696,7 @@ void intf_sys_t::processHeartBeatMessage( const castchannel::CastMessage& msg )
bool intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg )
{
json_value *p_data = json_parse(msg.payload_utf8().c_str());
json_value *p_data = json_parse(msg.payload_utf8().c_str(), msg.payload_utf8().length());
std::string type((*p_data)["type"]);
bool ret = true;
......@@ -800,7 +800,7 @@ bool intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg )
void intf_sys_t::processMediaMessage( const castchannel::CastMessage& msg )
{
json_value *p_data = json_parse(msg.payload_utf8().c_str());
json_value *p_data = json_parse(msg.payload_utf8().c_str(), msg.payload_utf8().length());
std::string type((*p_data)["type"]);
int64_t requestId = (json_int_t) (*p_data)["requestId"];
......@@ -947,7 +947,7 @@ void intf_sys_t::processMediaMessage( const castchannel::CastMessage& msg )
void intf_sys_t::processConnectionMessage( const castchannel::CastMessage& msg )
{
json_value *p_data = json_parse(msg.payload_utf8().c_str());
json_value *p_data = json_parse(msg.payload_utf8().c_str(), msg.payload_utf8().length());
std::string type((*p_data)["type"]);
json_value_free(p_data);
......