google-protobuf 3.0.0.alpha.3 → 3.0.0.alpha.3.1.pre
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/ext/google/protobuf_c/defs.c +5 -3
- data/ext/google/protobuf_c/encode_decode.c +85 -75
- data/ext/google/protobuf_c/extconf.rb +1 -3
- data/ext/google/protobuf_c/message.c +9 -44
- data/ext/google/protobuf_c/protobuf.c +7 -10
- data/ext/google/protobuf_c/protobuf.h +9 -9
- data/ext/google/protobuf_c/repeated_field.c +55 -95
- data/ext/google/protobuf_c/storage.c +2 -5
- data/ext/google/protobuf_c/upb.c +248 -822
- data/ext/google/protobuf_c/upb.h +467 -511
- data/lib/google/protobuf.rb +0 -27
- data/tests/basic.rb +9 -119
- metadata +17 -27
- data/lib/google/protobuf/message_exts.rb +0 -53
- data/lib/google/protobuf/repeated_field.rb +0 -188
data/ext/google/protobuf_c/upb.c
CHANGED
@@ -1779,275 +1779,6 @@ upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
|
|
1779
1779
|
void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
|
1780
1780
|
upb_inttable_iter_setdone(iter);
|
1781
1781
|
}
|
1782
|
-
/*
|
1783
|
-
* upb - a minimalist implementation of protocol buffers.
|
1784
|
-
*
|
1785
|
-
* Copyright (c) 2014 Google Inc. See LICENSE for details.
|
1786
|
-
* Author: Josh Haberman <jhaberman@gmail.com>
|
1787
|
-
*/
|
1788
|
-
|
1789
|
-
|
1790
|
-
#include <stdlib.h>
|
1791
|
-
#include <stdio.h>
|
1792
|
-
#include <string.h>
|
1793
|
-
|
1794
|
-
typedef struct cleanup_ent {
|
1795
|
-
upb_cleanup_func *cleanup;
|
1796
|
-
void *ud;
|
1797
|
-
struct cleanup_ent *next;
|
1798
|
-
} cleanup_ent;
|
1799
|
-
|
1800
|
-
static void *seeded_alloc(void *ud, void *ptr, size_t oldsize, size_t size);
|
1801
|
-
|
1802
|
-
/* Default allocator **********************************************************/
|
1803
|
-
|
1804
|
-
// Just use realloc, keeping all allocated blocks in a linked list to destroy at
|
1805
|
-
// the end.
|
1806
|
-
|
1807
|
-
typedef struct mem_block {
|
1808
|
-
// List is doubly-linked, because in cases where realloc() moves an existing
|
1809
|
-
// block, we need to be able to remove the old pointer from the list
|
1810
|
-
// efficiently.
|
1811
|
-
struct mem_block *prev, *next;
|
1812
|
-
#ifndef NDEBUG
|
1813
|
-
size_t size; // Doesn't include mem_block structure.
|
1814
|
-
#endif
|
1815
|
-
char data[];
|
1816
|
-
} mem_block;
|
1817
|
-
|
1818
|
-
typedef struct {
|
1819
|
-
mem_block *head;
|
1820
|
-
} default_alloc_ud;
|
1821
|
-
|
1822
|
-
static void *default_alloc(void *_ud, void *ptr, size_t oldsize, size_t size) {
|
1823
|
-
UPB_UNUSED(oldsize);
|
1824
|
-
default_alloc_ud *ud = _ud;
|
1825
|
-
|
1826
|
-
mem_block *from = ptr ? (void*)((char*)ptr - sizeof(mem_block)) : NULL;
|
1827
|
-
|
1828
|
-
#ifndef NDEBUG
|
1829
|
-
if (from) {
|
1830
|
-
assert(oldsize <= from->size);
|
1831
|
-
}
|
1832
|
-
#endif
|
1833
|
-
|
1834
|
-
mem_block *block = realloc(from, size + sizeof(mem_block));
|
1835
|
-
if (!block) return NULL;
|
1836
|
-
|
1837
|
-
#ifndef NDEBUG
|
1838
|
-
block->size = size;
|
1839
|
-
#endif
|
1840
|
-
|
1841
|
-
if (from) {
|
1842
|
-
if (block != from) {
|
1843
|
-
// The block was moved, so pointers in next and prev blocks must be
|
1844
|
-
// updated to its new location.
|
1845
|
-
if (block->next) block->next->prev = block;
|
1846
|
-
if (block->prev) block->prev->next = block;
|
1847
|
-
}
|
1848
|
-
} else {
|
1849
|
-
// Insert at head of linked list.
|
1850
|
-
block->prev = NULL;
|
1851
|
-
block->next = ud->head;
|
1852
|
-
if (block->next) block->next->prev = block;
|
1853
|
-
ud->head = block;
|
1854
|
-
}
|
1855
|
-
|
1856
|
-
return &block->data;
|
1857
|
-
}
|
1858
|
-
|
1859
|
-
static void default_alloc_cleanup(void *_ud) {
|
1860
|
-
default_alloc_ud *ud = _ud;
|
1861
|
-
mem_block *block = ud->head;
|
1862
|
-
|
1863
|
-
while (block) {
|
1864
|
-
void *to_free = block;
|
1865
|
-
block = block->next;
|
1866
|
-
free(to_free);
|
1867
|
-
}
|
1868
|
-
}
|
1869
|
-
|
1870
|
-
|
1871
|
-
/* Standard error functions ***************************************************/
|
1872
|
-
|
1873
|
-
static bool default_err(void *ud, const upb_status *status) {
|
1874
|
-
UPB_UNUSED(ud);
|
1875
|
-
fprintf(stderr, "upb error: %s\n", upb_status_errmsg(status));
|
1876
|
-
return false;
|
1877
|
-
}
|
1878
|
-
|
1879
|
-
static bool write_err_to(void *ud, const upb_status *status) {
|
1880
|
-
upb_status *copy_to = ud;
|
1881
|
-
upb_status_copy(copy_to, status);
|
1882
|
-
return false;
|
1883
|
-
}
|
1884
|
-
|
1885
|
-
|
1886
|
-
/* upb_env ********************************************************************/
|
1887
|
-
|
1888
|
-
void upb_env_init(upb_env *e) {
|
1889
|
-
e->ok_ = true;
|
1890
|
-
e->bytes_allocated = 0;
|
1891
|
-
e->cleanup_head = NULL;
|
1892
|
-
|
1893
|
-
default_alloc_ud *ud = (default_alloc_ud*)&e->default_alloc_ud;
|
1894
|
-
ud->head = NULL;
|
1895
|
-
|
1896
|
-
// Set default functions.
|
1897
|
-
upb_env_setallocfunc(e, default_alloc, ud);
|
1898
|
-
upb_env_seterrorfunc(e, default_err, NULL);
|
1899
|
-
}
|
1900
|
-
|
1901
|
-
void upb_env_uninit(upb_env *e) {
|
1902
|
-
cleanup_ent *ent = e->cleanup_head;
|
1903
|
-
|
1904
|
-
while (ent) {
|
1905
|
-
ent->cleanup(ent->ud);
|
1906
|
-
ent = ent->next;
|
1907
|
-
}
|
1908
|
-
|
1909
|
-
// Must do this after running cleanup functions, because this will delete
|
1910
|
-
// the memory we store our cleanup entries in!
|
1911
|
-
if (e->alloc == default_alloc) {
|
1912
|
-
default_alloc_cleanup(e->alloc_ud);
|
1913
|
-
}
|
1914
|
-
}
|
1915
|
-
|
1916
|
-
UPB_FORCEINLINE void upb_env_setallocfunc(upb_env *e, upb_alloc_func *alloc,
|
1917
|
-
void *ud) {
|
1918
|
-
e->alloc = alloc;
|
1919
|
-
e->alloc_ud = ud;
|
1920
|
-
}
|
1921
|
-
|
1922
|
-
UPB_FORCEINLINE void upb_env_seterrorfunc(upb_env *e, upb_error_func *func,
|
1923
|
-
void *ud) {
|
1924
|
-
e->err = func;
|
1925
|
-
e->err_ud = ud;
|
1926
|
-
}
|
1927
|
-
|
1928
|
-
void upb_env_reporterrorsto(upb_env *e, upb_status *status) {
|
1929
|
-
e->err = write_err_to;
|
1930
|
-
e->err_ud = status;
|
1931
|
-
}
|
1932
|
-
|
1933
|
-
bool upb_env_ok(const upb_env *e) {
|
1934
|
-
return e->ok_;
|
1935
|
-
}
|
1936
|
-
|
1937
|
-
bool upb_env_reporterror(upb_env *e, const upb_status *status) {
|
1938
|
-
e->ok_ = false;
|
1939
|
-
return e->err(e->err_ud, status);
|
1940
|
-
}
|
1941
|
-
|
1942
|
-
bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
|
1943
|
-
cleanup_ent *ent = upb_env_malloc(e, sizeof(cleanup_ent));
|
1944
|
-
if (!ent) return false;
|
1945
|
-
|
1946
|
-
ent->cleanup = func;
|
1947
|
-
ent->ud = ud;
|
1948
|
-
ent->next = e->cleanup_head;
|
1949
|
-
e->cleanup_head = ent;
|
1950
|
-
|
1951
|
-
return true;
|
1952
|
-
}
|
1953
|
-
|
1954
|
-
void *upb_env_malloc(upb_env *e, size_t size) {
|
1955
|
-
e->bytes_allocated += size;
|
1956
|
-
if (e->alloc == seeded_alloc) {
|
1957
|
-
// This is equivalent to the next branch, but allows inlining for a
|
1958
|
-
// measurable perf benefit.
|
1959
|
-
return seeded_alloc(e->alloc_ud, NULL, 0, size);
|
1960
|
-
} else {
|
1961
|
-
return e->alloc(e->alloc_ud, NULL, 0, size);
|
1962
|
-
}
|
1963
|
-
}
|
1964
|
-
|
1965
|
-
void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
|
1966
|
-
assert(oldsize <= size);
|
1967
|
-
char *ret = e->alloc(e->alloc_ud, ptr, oldsize, size);
|
1968
|
-
|
1969
|
-
#ifndef NDEBUG
|
1970
|
-
// Overwrite non-preserved memory to ensure callers are passing the oldsize
|
1971
|
-
// that they truly require.
|
1972
|
-
memset(ret + oldsize, 0xff, size - oldsize);
|
1973
|
-
#endif
|
1974
|
-
|
1975
|
-
return ret;
|
1976
|
-
}
|
1977
|
-
|
1978
|
-
size_t upb_env_bytesallocated(const upb_env *e) {
|
1979
|
-
return e->bytes_allocated;
|
1980
|
-
}
|
1981
|
-
|
1982
|
-
|
1983
|
-
/* upb_seededalloc ************************************************************/
|
1984
|
-
|
1985
|
-
// Be conservative and choose 16 in case anyone is using SSE.
|
1986
|
-
static const size_t maxalign = 16;
|
1987
|
-
|
1988
|
-
static size_t align_up(size_t size) {
|
1989
|
-
return ((size + maxalign - 1) / maxalign) * maxalign;
|
1990
|
-
}
|
1991
|
-
|
1992
|
-
UPB_FORCEINLINE static void *seeded_alloc(void *ud, void *ptr, size_t oldsize,
|
1993
|
-
size_t size) {
|
1994
|
-
UPB_UNUSED(ptr);
|
1995
|
-
|
1996
|
-
upb_seededalloc *a = ud;
|
1997
|
-
size = align_up(size);
|
1998
|
-
|
1999
|
-
assert(a->mem_limit >= a->mem_ptr);
|
2000
|
-
|
2001
|
-
if (oldsize == 0 && size <= (size_t)(a->mem_limit - a->mem_ptr)) {
|
2002
|
-
// Fast path: we can satisfy from the initial allocation.
|
2003
|
-
void *ret = a->mem_ptr;
|
2004
|
-
a->mem_ptr += size;
|
2005
|
-
return ret;
|
2006
|
-
} else {
|
2007
|
-
// Slow path: fallback to other allocator.
|
2008
|
-
a->need_cleanup = true;
|
2009
|
-
// Is `ptr` part of the user-provided initial block? Don't pass it to the
|
2010
|
-
// default allocator if so; otherwise, it may try to realloc() the block.
|
2011
|
-
char *chptr = ptr;
|
2012
|
-
if (chptr >= a->mem_base && chptr < a->mem_limit) {
|
2013
|
-
return a->alloc(a->alloc_ud, NULL, 0, size);
|
2014
|
-
} else {
|
2015
|
-
return a->alloc(a->alloc_ud, ptr, oldsize, size);
|
2016
|
-
}
|
2017
|
-
}
|
2018
|
-
}
|
2019
|
-
|
2020
|
-
void upb_seededalloc_init(upb_seededalloc *a, void *mem, size_t len) {
|
2021
|
-
a->mem_base = mem;
|
2022
|
-
a->mem_ptr = mem;
|
2023
|
-
a->mem_limit = (char*)mem + len;
|
2024
|
-
a->need_cleanup = false;
|
2025
|
-
a->returned_allocfunc = false;
|
2026
|
-
|
2027
|
-
default_alloc_ud *ud = (default_alloc_ud*)&a->default_alloc_ud;
|
2028
|
-
ud->head = NULL;
|
2029
|
-
|
2030
|
-
upb_seededalloc_setfallbackalloc(a, default_alloc, ud);
|
2031
|
-
}
|
2032
|
-
|
2033
|
-
void upb_seededalloc_uninit(upb_seededalloc *a) {
|
2034
|
-
if (a->alloc == default_alloc && a->need_cleanup) {
|
2035
|
-
default_alloc_cleanup(a->alloc_ud);
|
2036
|
-
}
|
2037
|
-
}
|
2038
|
-
|
2039
|
-
UPB_FORCEINLINE void upb_seededalloc_setfallbackalloc(upb_seededalloc *a,
|
2040
|
-
upb_alloc_func *alloc,
|
2041
|
-
void *ud) {
|
2042
|
-
assert(!a->returned_allocfunc);
|
2043
|
-
a->alloc = alloc;
|
2044
|
-
a->alloc_ud = ud;
|
2045
|
-
}
|
2046
|
-
|
2047
|
-
upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) {
|
2048
|
-
a->returned_allocfunc = true;
|
2049
|
-
return seeded_alloc;
|
2050
|
-
}
|
2051
1782
|
/*
|
2052
1783
|
* upb - a minimalist implementation of protocol buffers.
|
2053
1784
|
*
|
@@ -2224,14 +1955,7 @@ static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
|
|
2224
1955
|
if (closure_type && *context_closure_type &&
|
2225
1956
|
closure_type != *context_closure_type) {
|
2226
1957
|
// TODO(haberman): better message for debugging.
|
2227
|
-
|
2228
|
-
upb_status_seterrf(&h->status_,
|
2229
|
-
"closure type does not match for field %s",
|
2230
|
-
upb_fielddef_name(f));
|
2231
|
-
} else {
|
2232
|
-
upb_status_seterrmsg(
|
2233
|
-
&h->status_, "closure type does not match for message-level handler");
|
2234
|
-
}
|
1958
|
+
upb_status_seterrmsg(&h->status_, "closure type does not match");
|
2235
1959
|
return false;
|
2236
1960
|
}
|
2237
1961
|
|
@@ -2629,7 +2353,7 @@ bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
|
|
2629
2353
|
*s = f->selector_base;
|
2630
2354
|
break;
|
2631
2355
|
}
|
2632
|
-
assert(
|
2356
|
+
assert(*s < upb_fielddef_containingtype(f)->selector_count);
|
2633
2357
|
return true;
|
2634
2358
|
}
|
2635
2359
|
|
@@ -4571,7 +4295,7 @@ void upb_inttable_compact(upb_inttable *t) {
|
|
4571
4295
|
counts[log2ceil(key)]++;
|
4572
4296
|
}
|
4573
4297
|
|
4574
|
-
|
4298
|
+
int arr_size;
|
4575
4299
|
int arr_count = upb_inttable_count(t);
|
4576
4300
|
|
4577
4301
|
if (upb_inttable_count(t) >= max_key * MIN_DENSITY) {
|
@@ -5798,54 +5522,6 @@ static upb_inttable reftables[212] = {
|
|
5798
5522
|
#include <stdlib.h>
|
5799
5523
|
#include <string.h>
|
5800
5524
|
|
5801
|
-
// upb_deflist is an internal-only dynamic array for storing a growing list of
|
5802
|
-
// upb_defs.
|
5803
|
-
typedef struct {
|
5804
|
-
upb_def **defs;
|
5805
|
-
size_t len;
|
5806
|
-
size_t size;
|
5807
|
-
bool owned;
|
5808
|
-
} upb_deflist;
|
5809
|
-
|
5810
|
-
// We keep a stack of all the messages scopes we are currently in, as well as
|
5811
|
-
// the top-level file scope. This is necessary to correctly qualify the
|
5812
|
-
// definitions that are contained inside. "name" tracks the name of the
|
5813
|
-
// message or package (a bare name -- not qualified by any enclosing scopes).
|
5814
|
-
typedef struct {
|
5815
|
-
char *name;
|
5816
|
-
// Index of the first def that is under this scope. For msgdefs, the
|
5817
|
-
// msgdef itself is at start-1.
|
5818
|
-
int start;
|
5819
|
-
} upb_descreader_frame;
|
5820
|
-
|
5821
|
-
// The maximum number of nested declarations that are allowed, ie.
|
5822
|
-
// message Foo {
|
5823
|
-
// message Bar {
|
5824
|
-
// message Baz {
|
5825
|
-
// }
|
5826
|
-
// }
|
5827
|
-
// }
|
5828
|
-
//
|
5829
|
-
// This is a resource limit that affects how big our runtime stack can grow.
|
5830
|
-
// TODO: make this a runtime-settable property of the Reader instance.
|
5831
|
-
#define UPB_MAX_MESSAGE_NESTING 64
|
5832
|
-
|
5833
|
-
struct upb_descreader {
|
5834
|
-
upb_sink sink;
|
5835
|
-
upb_deflist defs;
|
5836
|
-
upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
|
5837
|
-
int stack_len;
|
5838
|
-
|
5839
|
-
uint32_t number;
|
5840
|
-
char *name;
|
5841
|
-
bool saw_number;
|
5842
|
-
bool saw_name;
|
5843
|
-
|
5844
|
-
char *default_string;
|
5845
|
-
|
5846
|
-
upb_fielddef *f;
|
5847
|
-
};
|
5848
|
-
|
5849
5525
|
static char *upb_strndup(const char *buf, size_t n) {
|
5850
5526
|
char *ret = malloc(n + 1);
|
5851
5527
|
if (!ret) return NULL;
|
@@ -5925,6 +5601,36 @@ static void upb_deflist_qualify(upb_deflist *l, char *str, int32_t start) {
|
|
5925
5601
|
|
5926
5602
|
/* upb_descreader ************************************************************/
|
5927
5603
|
|
5604
|
+
void upb_descreader_init(upb_descreader *r, const upb_handlers *handlers,
|
5605
|
+
upb_status *status) {
|
5606
|
+
UPB_UNUSED(status);
|
5607
|
+
upb_deflist_init(&r->defs);
|
5608
|
+
upb_sink_reset(upb_descreader_input(r), handlers, r);
|
5609
|
+
r->stack_len = 0;
|
5610
|
+
r->name = NULL;
|
5611
|
+
r->default_string = NULL;
|
5612
|
+
}
|
5613
|
+
|
5614
|
+
void upb_descreader_uninit(upb_descreader *r) {
|
5615
|
+
free(r->name);
|
5616
|
+
upb_deflist_uninit(&r->defs);
|
5617
|
+
free(r->default_string);
|
5618
|
+
while (r->stack_len > 0) {
|
5619
|
+
upb_descreader_frame *f = &r->stack[--r->stack_len];
|
5620
|
+
free(f->name);
|
5621
|
+
}
|
5622
|
+
}
|
5623
|
+
|
5624
|
+
upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n) {
|
5625
|
+
*n = r->defs.len;
|
5626
|
+
upb_deflist_donaterefs(&r->defs, owner);
|
5627
|
+
return r->defs.defs;
|
5628
|
+
}
|
5629
|
+
|
5630
|
+
upb_sink *upb_descreader_input(upb_descreader *r) {
|
5631
|
+
return &r->sink;
|
5632
|
+
}
|
5633
|
+
|
5928
5634
|
static upb_msgdef *upb_descreader_top(upb_descreader *r) {
|
5929
5635
|
assert(r->stack_len > 1);
|
5930
5636
|
int index = r->stack[r->stack_len-1].start - 1;
|
@@ -6097,7 +5803,7 @@ static bool parse_default(char *str, upb_fielddef *f) {
|
|
6097
5803
|
break;
|
6098
5804
|
}
|
6099
5805
|
case UPB_TYPE_UINT32: {
|
6100
|
-
|
5806
|
+
long val = strtoul(str, &end, 0);
|
6101
5807
|
if (val > UINT32_MAX || errno == ERANGE || *end)
|
6102
5808
|
success = false;
|
6103
5809
|
else
|
@@ -6364,45 +6070,6 @@ static void reghandlers(const void *closure, upb_handlers *h) {
|
|
6364
6070
|
|
6365
6071
|
#undef D
|
6366
6072
|
|
6367
|
-
void descreader_cleanup(void *_r) {
|
6368
|
-
upb_descreader *r = _r;
|
6369
|
-
free(r->name);
|
6370
|
-
upb_deflist_uninit(&r->defs);
|
6371
|
-
free(r->default_string);
|
6372
|
-
while (r->stack_len > 0) {
|
6373
|
-
upb_descreader_frame *f = &r->stack[--r->stack_len];
|
6374
|
-
free(f->name);
|
6375
|
-
}
|
6376
|
-
}
|
6377
|
-
|
6378
|
-
|
6379
|
-
/* Public API ****************************************************************/
|
6380
|
-
|
6381
|
-
upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
|
6382
|
-
upb_descreader *r = upb_env_malloc(e, sizeof(upb_descreader));
|
6383
|
-
if (!r || !upb_env_addcleanup(e, descreader_cleanup, r)) {
|
6384
|
-
return NULL;
|
6385
|
-
}
|
6386
|
-
|
6387
|
-
upb_deflist_init(&r->defs);
|
6388
|
-
upb_sink_reset(upb_descreader_input(r), h, r);
|
6389
|
-
r->stack_len = 0;
|
6390
|
-
r->name = NULL;
|
6391
|
-
r->default_string = NULL;
|
6392
|
-
|
6393
|
-
return r;
|
6394
|
-
}
|
6395
|
-
|
6396
|
-
upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n) {
|
6397
|
-
*n = r->defs.len;
|
6398
|
-
upb_deflist_donaterefs(&r->defs, owner);
|
6399
|
-
return r->defs.defs;
|
6400
|
-
}
|
6401
|
-
|
6402
|
-
upb_sink *upb_descreader_input(upb_descreader *r) {
|
6403
|
-
return &r->sink;
|
6404
|
-
}
|
6405
|
-
|
6406
6073
|
const upb_handlers *upb_descreader_newhandlers(const void *owner) {
|
6407
6074
|
const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s);
|
6408
6075
|
const upb_handlers *h = upb_handlers_newfrozen(
|
@@ -6474,6 +6141,7 @@ mgroup *newgroup(const void *owner) {
|
|
6474
6141
|
|
6475
6142
|
static void freemethod(upb_refcounted *r) {
|
6476
6143
|
upb_pbdecodermethod *method = (upb_pbdecodermethod*)r;
|
6144
|
+
upb_byteshandler_uninit(&method->input_handler_);
|
6477
6145
|
|
6478
6146
|
if (method->dest_handlers_) {
|
6479
6147
|
upb_handlers_unref(method->dest_handlers_, method);
|
@@ -7405,7 +7073,10 @@ void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) {
|
|
7405
7073
|
*/
|
7406
7074
|
|
7407
7075
|
#include <inttypes.h>
|
7076
|
+
#include <setjmp.h>
|
7077
|
+
#include <stdarg.h>
|
7408
7078
|
#include <stddef.h>
|
7079
|
+
#include <stdlib.h>
|
7409
7080
|
|
7410
7081
|
#ifdef UPB_DUMP_BYTECODE
|
7411
7082
|
#include <stdio.h>
|
@@ -7451,17 +7122,18 @@ static bool consumes_input(opcode op) {
|
|
7451
7122
|
|
7452
7123
|
static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
|
7453
7124
|
|
7454
|
-
// It's unfortunate that we have to micro-manage the compiler
|
7455
|
-
//
|
7456
|
-
//
|
7457
|
-
//
|
7458
|
-
//
|
7459
|
-
|
7125
|
+
// It's unfortunate that we have to micro-manage the compiler this way,
|
7126
|
+
// especially since this tuning is necessarily specific to one hardware
|
7127
|
+
// configuration. But emperically on a Core i7, performance increases 30-50%
|
7128
|
+
// with these annotations. Every instance where these appear, gcc 4.2.1 made
|
7129
|
+
// the wrong decision and degraded performance in benchmarks.
|
7130
|
+
#define FORCEINLINE static inline __attribute__((always_inline))
|
7131
|
+
#define NOINLINE __attribute__((noinline))
|
7460
7132
|
|
7461
7133
|
static void seterr(upb_pbdecoder *d, const char *msg) {
|
7462
|
-
|
7463
|
-
|
7464
|
-
|
7134
|
+
// TODO(haberman): encapsulate this access to pipeline->status, but not sure
|
7135
|
+
// exactly what that interface should look like.
|
7136
|
+
upb_status_seterrmsg(d->status, msg);
|
7465
7137
|
}
|
7466
7138
|
|
7467
7139
|
void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
|
@@ -7504,7 +7176,7 @@ static bool in_residual_buf(const upb_pbdecoder *d, const char *p) {
|
|
7504
7176
|
// and the parsing stack, so must be called whenever either is updated.
|
7505
7177
|
static void set_delim_end(upb_pbdecoder *d) {
|
7506
7178
|
size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs;
|
7507
|
-
if (delim_ofs <= (
|
7179
|
+
if (delim_ofs <= (d->end - d->buf)) {
|
7508
7180
|
d->delim_end = d->buf + delim_ofs;
|
7509
7181
|
d->data_end = d->delim_end;
|
7510
7182
|
} else {
|
@@ -7629,8 +7301,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) {
|
|
7629
7301
|
|
7630
7302
|
// Copies the next "bytes" bytes into "buf" and advances the stream.
|
7631
7303
|
// Requires that this many bytes are available in the current buffer.
|
7632
|
-
|
7633
|
-
size_t bytes) {
|
7304
|
+
FORCEINLINE void consumebytes(upb_pbdecoder *d, void *buf, size_t bytes) {
|
7634
7305
|
assert(bytes <= curbufleft(d));
|
7635
7306
|
memcpy(buf, d->ptr, bytes);
|
7636
7307
|
advance(d, bytes);
|
@@ -7639,8 +7310,8 @@ UPB_FORCEINLINE static void consumebytes(upb_pbdecoder *d, void *buf,
|
|
7639
7310
|
// Slow path for getting the next "bytes" bytes, regardless of whether they are
|
7640
7311
|
// available in the current buffer or not. Returns a status code as described
|
7641
7312
|
// in decoder.int.h.
|
7642
|
-
|
7643
|
-
|
7313
|
+
static NOINLINE int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
|
7314
|
+
size_t bytes) {
|
7644
7315
|
const size_t avail = curbufleft(d);
|
7645
7316
|
consumebytes(d, buf, avail);
|
7646
7317
|
bytes -= avail;
|
@@ -7649,7 +7320,7 @@ UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
|
|
7649
7320
|
advancetobuf(d, d->buf_param, d->size_param);
|
7650
7321
|
}
|
7651
7322
|
if (curbufleft(d) >= bytes) {
|
7652
|
-
consumebytes(d,
|
7323
|
+
consumebytes(d, buf + avail, bytes);
|
7653
7324
|
return DECODE_OK;
|
7654
7325
|
} else if (d->data_end == d->delim_end) {
|
7655
7326
|
seterr(d, "Submessage ended in the middle of a value or group");
|
@@ -7661,8 +7332,7 @@ UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
|
|
7661
7332
|
|
7662
7333
|
// Gets the next "bytes" bytes, regardless of whether they are available in the
|
7663
7334
|
// current buffer or not. Returns a status code as described in decoder.int.h.
|
7664
|
-
|
7665
|
-
size_t bytes) {
|
7335
|
+
FORCEINLINE int32_t getbytes(upb_pbdecoder *d, void *buf, size_t bytes) {
|
7666
7336
|
if (curbufleft(d) >= bytes) {
|
7667
7337
|
// Buffer has enough data to satisfy.
|
7668
7338
|
consumebytes(d, buf, bytes);
|
@@ -7672,20 +7342,19 @@ UPB_FORCEINLINE static int32_t getbytes(upb_pbdecoder *d, void *buf,
|
|
7672
7342
|
}
|
7673
7343
|
}
|
7674
7344
|
|
7675
|
-
|
7676
|
-
|
7345
|
+
static NOINLINE size_t peekbytes_slow(upb_pbdecoder *d, void *buf,
|
7346
|
+
size_t bytes) {
|
7677
7347
|
size_t ret = curbufleft(d);
|
7678
7348
|
memcpy(buf, d->ptr, ret);
|
7679
7349
|
if (in_residual_buf(d, d->ptr)) {
|
7680
7350
|
size_t copy = UPB_MIN(bytes - ret, d->size_param);
|
7681
|
-
memcpy(
|
7351
|
+
memcpy(buf + ret, d->buf_param, copy);
|
7682
7352
|
ret += copy;
|
7683
7353
|
}
|
7684
7354
|
return ret;
|
7685
7355
|
}
|
7686
7356
|
|
7687
|
-
|
7688
|
-
size_t bytes) {
|
7357
|
+
FORCEINLINE size_t peekbytes(upb_pbdecoder *d, void *buf, size_t bytes) {
|
7689
7358
|
if (curbufleft(d) >= bytes) {
|
7690
7359
|
memcpy(buf, d->ptr, bytes);
|
7691
7360
|
return bytes;
|
@@ -7699,8 +7368,8 @@ UPB_FORCEINLINE static size_t peekbytes(upb_pbdecoder *d, void *buf,
|
|
7699
7368
|
|
7700
7369
|
// Slow path for decoding a varint from the current buffer position.
|
7701
7370
|
// Returns a status code as described in decoder.int.h.
|
7702
|
-
|
7703
|
-
|
7371
|
+
NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
|
7372
|
+
uint64_t *u64) {
|
7704
7373
|
*u64 = 0;
|
7705
7374
|
uint8_t byte = 0x80;
|
7706
7375
|
int bitpos;
|
@@ -7718,7 +7387,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
|
|
7718
7387
|
|
7719
7388
|
// Decodes a varint from the current buffer position.
|
7720
7389
|
// Returns a status code as described in decoder.int.h.
|
7721
|
-
|
7390
|
+
FORCEINLINE int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
|
7722
7391
|
if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) {
|
7723
7392
|
*u64 = *d->ptr;
|
7724
7393
|
advance(d, 1);
|
@@ -7741,7 +7410,7 @@ UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
|
|
7741
7410
|
|
7742
7411
|
// Decodes a 32-bit varint from the current buffer position.
|
7743
7412
|
// Returns a status code as described in decoder.int.h.
|
7744
|
-
|
7413
|
+
FORCEINLINE int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
|
7745
7414
|
uint64_t u64;
|
7746
7415
|
int32_t ret = decode_varint(d, &u64);
|
7747
7416
|
if (ret >= 0) return ret;
|
@@ -7760,14 +7429,14 @@ UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
|
|
7760
7429
|
// Decodes a fixed32 from the current buffer position.
|
7761
7430
|
// Returns a status code as described in decoder.int.h.
|
7762
7431
|
// TODO: proper byte swapping for big-endian machines.
|
7763
|
-
|
7432
|
+
FORCEINLINE int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) {
|
7764
7433
|
return getbytes(d, u32, 4);
|
7765
7434
|
}
|
7766
7435
|
|
7767
7436
|
// Decodes a fixed64 from the current buffer position.
|
7768
7437
|
// Returns a status code as described in decoder.int.h.
|
7769
7438
|
// TODO: proper byte swapping for big-endian machines.
|
7770
|
-
|
7439
|
+
FORCEINLINE int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) {
|
7771
7440
|
return getbytes(d, u64, 8);
|
7772
7441
|
}
|
7773
7442
|
|
@@ -7791,7 +7460,7 @@ static bool decoder_push(upb_pbdecoder *d, uint64_t end) {
|
|
7791
7460
|
if (end > fr->end_ofs) {
|
7792
7461
|
seterr(d, "Submessage end extends past enclosing submessage.");
|
7793
7462
|
return false;
|
7794
|
-
} else if (fr == d->limit) {
|
7463
|
+
} else if ((fr + 1) == d->limit) {
|
7795
7464
|
seterr(d, kPbDecoderStackOverflow);
|
7796
7465
|
return false;
|
7797
7466
|
}
|
@@ -7818,8 +7487,8 @@ static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) {
|
|
7818
7487
|
// Pops a frame from the decoder stack.
|
7819
7488
|
static void decoder_pop(upb_pbdecoder *d) { d->top--; }
|
7820
7489
|
|
7821
|
-
|
7822
|
-
|
7490
|
+
NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
|
7491
|
+
uint64_t expected) {
|
7823
7492
|
uint64_t data = 0;
|
7824
7493
|
size_t bytes = upb_value_size(expected);
|
7825
7494
|
size_t read = peekbytes(d, &data, bytes);
|
@@ -7971,17 +7640,10 @@ static int32_t dispatch(upb_pbdecoder *d) {
|
|
7971
7640
|
if (ret == DECODE_ENDGROUP) {
|
7972
7641
|
goto_endmsg(d);
|
7973
7642
|
return DECODE_OK;
|
7974
|
-
} else
|
7975
|
-
|
7976
|
-
|
7977
|
-
// directly preceded by OP_CHECKDELIM, rewind to it now to re-check the
|
7978
|
-
// delimited end.
|
7979
|
-
d->pc = d->last - 1;
|
7980
|
-
assert(getop(*d->pc) == OP_CHECKDELIM);
|
7981
|
-
return DECODE_OK;
|
7643
|
+
} else {
|
7644
|
+
d->pc = d->last - 1; // Rewind to CHECKDELIM.
|
7645
|
+
return ret;
|
7982
7646
|
}
|
7983
|
-
|
7984
|
-
return ret;
|
7985
7647
|
}
|
7986
7648
|
|
7987
7649
|
// Callers know that the stack is more than one deep because the opcodes that
|
@@ -8204,10 +7866,7 @@ size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
|
|
8204
7866
|
void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint) {
|
8205
7867
|
upb_pbdecoder *d = closure;
|
8206
7868
|
UPB_UNUSED(size_hint);
|
8207
|
-
d->top->end_ofs = UINT64_MAX;
|
8208
|
-
d->bufstart_ofs = 0;
|
8209
7869
|
d->call_len = 1;
|
8210
|
-
d->callstack[0] = &halt;
|
8211
7870
|
d->pc = pc;
|
8212
7871
|
return d;
|
8213
7872
|
}
|
@@ -8216,8 +7875,6 @@ void *upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint) {
|
|
8216
7875
|
UPB_UNUSED(hd);
|
8217
7876
|
UPB_UNUSED(size_hint);
|
8218
7877
|
upb_pbdecoder *d = closure;
|
8219
|
-
d->top->end_ofs = UINT64_MAX;
|
8220
|
-
d->bufstart_ofs = 0;
|
8221
7878
|
d->call_len = 0;
|
8222
7879
|
return d;
|
8223
7880
|
}
|
@@ -8274,120 +7931,58 @@ bool upb_pbdecoder_end(void *closure, const void *handler_data) {
|
|
8274
7931
|
return true;
|
8275
7932
|
}
|
8276
7933
|
|
7934
|
+
void upb_pbdecoder_init(upb_pbdecoder *d, const upb_pbdecodermethod *m,
|
7935
|
+
upb_status *s) {
|
7936
|
+
d->limit = &d->stack[UPB_DECODER_MAX_NESTING];
|
7937
|
+
upb_bytessink_reset(&d->input_, &m->input_handler_, d);
|
7938
|
+
d->method_ = m;
|
7939
|
+
d->callstack[0] = &halt;
|
7940
|
+
d->status = s;
|
7941
|
+
upb_pbdecoder_reset(d);
|
7942
|
+
}
|
7943
|
+
|
8277
7944
|
void upb_pbdecoder_reset(upb_pbdecoder *d) {
|
8278
7945
|
d->top = d->stack;
|
7946
|
+
d->top->end_ofs = UINT64_MAX;
|
8279
7947
|
d->top->groupnum = 0;
|
7948
|
+
d->bufstart_ofs = 0;
|
8280
7949
|
d->ptr = d->residual;
|
8281
7950
|
d->buf = d->residual;
|
8282
7951
|
d->end = d->residual;
|
8283
7952
|
d->residual_end = d->residual;
|
7953
|
+
d->call_len = 1;
|
8284
7954
|
}
|
8285
7955
|
|
8286
|
-
|
8287
|
-
|
8288
|
-
return entries * sizeof(upb_pbdecoder_frame);
|
7956
|
+
uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) {
|
7957
|
+
return offset(d);
|
8289
7958
|
}
|
8290
7959
|
|
8291
|
-
|
7960
|
+
// Not currently required, but to support outgrowing the static stack we need
|
7961
|
+
// this.
|
7962
|
+
void upb_pbdecoder_uninit(upb_pbdecoder *d) {
|
8292
7963
|
UPB_UNUSED(d);
|
8293
|
-
|
8294
|
-
#ifdef UPB_USE_JIT_X64
|
8295
|
-
if (d->method_->is_native_) {
|
8296
|
-
// Each native stack frame needs two pointers, plus we need a few frames for
|
8297
|
-
// the enter/exit trampolines.
|
8298
|
-
size_t ret = entries * sizeof(void*) * 2;
|
8299
|
-
ret += sizeof(void*) * 10;
|
8300
|
-
return ret;
|
8301
|
-
}
|
8302
|
-
#endif
|
8303
|
-
|
8304
|
-
return entries * sizeof(uint32_t*);
|
8305
7964
|
}
|
8306
7965
|
|
8307
|
-
|
8308
|
-
|
8309
|
-
|
8310
|
-
#ifndef NDEBUG
|
8311
|
-
size_t size_before = upb_env_bytesallocated(e);
|
8312
|
-
#endif
|
8313
|
-
|
8314
|
-
upb_pbdecoder *d = upb_env_malloc(e, sizeof(upb_pbdecoder));
|
8315
|
-
if (!d) return NULL;
|
8316
|
-
|
8317
|
-
d->method_ = m;
|
8318
|
-
d->callstack = upb_env_malloc(e, callstacksize(d, default_max_nesting));
|
8319
|
-
d->stack = upb_env_malloc(e, stacksize(d, default_max_nesting));
|
8320
|
-
if (!d->stack || !d->callstack) {
|
8321
|
-
return NULL;
|
8322
|
-
}
|
8323
|
-
|
8324
|
-
d->env = e;
|
8325
|
-
d->limit = d->stack + default_max_nesting - 1;
|
8326
|
-
d->stack_size = default_max_nesting;
|
8327
|
-
|
8328
|
-
upb_pbdecoder_reset(d);
|
8329
|
-
upb_bytessink_reset(&d->input_, &m->input_handler_, d);
|
7966
|
+
const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) {
|
7967
|
+
return d->method_;
|
7968
|
+
}
|
8330
7969
|
|
7970
|
+
bool upb_pbdecoder_resetoutput(upb_pbdecoder *d, upb_sink* sink) {
|
7971
|
+
// TODO(haberman): do we need to test whether the decoder is already on the
|
7972
|
+
// stack (like calling this from within a callback)? Should we support
|
7973
|
+
// rebinding the output at all?
|
8331
7974
|
assert(sink);
|
8332
7975
|
if (d->method_->dest_handlers_) {
|
8333
7976
|
if (sink->handlers != d->method_->dest_handlers_)
|
8334
|
-
return
|
7977
|
+
return false;
|
8335
7978
|
}
|
8336
7979
|
upb_sink_reset(&d->top->sink, sink->handlers, sink->closure);
|
8337
|
-
|
8338
|
-
// If this fails, increase the value in decoder.h.
|
8339
|
-
assert(upb_env_bytesallocated(e) - size_before <= UPB_PB_DECODER_SIZE);
|
8340
|
-
return d;
|
8341
|
-
}
|
8342
|
-
|
8343
|
-
uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) {
|
8344
|
-
return offset(d);
|
8345
|
-
}
|
8346
|
-
|
8347
|
-
const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) {
|
8348
|
-
return d->method_;
|
7980
|
+
return true;
|
8349
7981
|
}
|
8350
7982
|
|
8351
7983
|
upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d) {
|
8352
7984
|
return &d->input_;
|
8353
7985
|
}
|
8354
|
-
|
8355
|
-
size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d) {
|
8356
|
-
return d->stack_size;
|
8357
|
-
}
|
8358
|
-
|
8359
|
-
bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
|
8360
|
-
assert(d->top >= d->stack);
|
8361
|
-
|
8362
|
-
if (max < (size_t)(d->top - d->stack)) {
|
8363
|
-
// Can't set a limit smaller than what we are currently at.
|
8364
|
-
return false;
|
8365
|
-
}
|
8366
|
-
|
8367
|
-
if (max > d->stack_size) {
|
8368
|
-
// Need to reallocate stack and callstack to accommodate.
|
8369
|
-
size_t old_size = stacksize(d, d->stack_size);
|
8370
|
-
size_t new_size = stacksize(d, max);
|
8371
|
-
void *p = upb_env_realloc(d->env, d->stack, old_size, new_size);
|
8372
|
-
if (!p) {
|
8373
|
-
return false;
|
8374
|
-
}
|
8375
|
-
d->stack = p;
|
8376
|
-
|
8377
|
-
old_size = callstacksize(d, d->stack_size);
|
8378
|
-
new_size = callstacksize(d, max);
|
8379
|
-
p = upb_env_realloc(d->env, d->callstack, old_size, new_size);
|
8380
|
-
if (!p) {
|
8381
|
-
return false;
|
8382
|
-
}
|
8383
|
-
d->callstack = p;
|
8384
|
-
|
8385
|
-
d->stack_size = max;
|
8386
|
-
}
|
8387
|
-
|
8388
|
-
d->limit = d->stack + max - 1;
|
8389
|
-
return true;
|
8390
|
-
}
|
8391
7986
|
/*
|
8392
7987
|
* upb - a minimalist implementation of protocol buffers.
|
8393
7988
|
*
|
@@ -8450,68 +8045,6 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
|
|
8450
8045
|
|
8451
8046
|
#include <stdlib.h>
|
8452
8047
|
|
8453
|
-
// The output buffer is divided into segments; a segment is a string of data
|
8454
|
-
// that is "ready to go" -- it does not need any varint lengths inserted into
|
8455
|
-
// the middle. The seams between segments are where varints will be inserted
|
8456
|
-
// once they are known.
|
8457
|
-
//
|
8458
|
-
// We also use the concept of a "run", which is a range of encoded bytes that
|
8459
|
-
// occur at a single submessage level. Every segment contains one or more runs.
|
8460
|
-
//
|
8461
|
-
// A segment can span messages. Consider:
|
8462
|
-
//
|
8463
|
-
// .--Submessage lengths---------.
|
8464
|
-
// | | |
|
8465
|
-
// | V V
|
8466
|
-
// V | |--------------- | |-----------------
|
8467
|
-
// Submessages: | |-----------------------------------------------
|
8468
|
-
// Top-level msg: ------------------------------------------------------------
|
8469
|
-
//
|
8470
|
-
// Segments: ----- ------------------- -----------------
|
8471
|
-
// Runs: *---- *--------------*--- *----------------
|
8472
|
-
// (* marks the start)
|
8473
|
-
//
|
8474
|
-
// Note that the top-level menssage is not in any segment because it does not
|
8475
|
-
// have any length preceding it.
|
8476
|
-
//
|
8477
|
-
// A segment is only interrupted when another length needs to be inserted. So
|
8478
|
-
// observe how the second segment spans both the inner submessage and part of
|
8479
|
-
// the next enclosing message.
|
8480
|
-
typedef struct {
|
8481
|
-
uint32_t msglen; // The length to varint-encode before this segment.
|
8482
|
-
uint32_t seglen; // Length of the segment.
|
8483
|
-
} upb_pb_encoder_segment;
|
8484
|
-
|
8485
|
-
struct upb_pb_encoder {
|
8486
|
-
upb_env *env;
|
8487
|
-
|
8488
|
-
// Our input and output.
|
8489
|
-
upb_sink input_;
|
8490
|
-
upb_bytessink *output_;
|
8491
|
-
|
8492
|
-
// The "subclosure" -- used as the inner closure as part of the bytessink
|
8493
|
-
// protocol.
|
8494
|
-
void *subc;
|
8495
|
-
|
8496
|
-
// The output buffer and limit, and our current write position. "buf"
|
8497
|
-
// initially points to "initbuf", but is dynamically allocated if we need to
|
8498
|
-
// grow beyond the initial size.
|
8499
|
-
char *buf, *ptr, *limit;
|
8500
|
-
|
8501
|
-
// The beginning of the current run, or undefined if we are at the top level.
|
8502
|
-
char *runbegin;
|
8503
|
-
|
8504
|
-
// The list of segments we are accumulating.
|
8505
|
-
upb_pb_encoder_segment *segbuf, *segptr, *seglimit;
|
8506
|
-
|
8507
|
-
// The stack of enclosing submessages. Each entry in the stack points to the
|
8508
|
-
// segment where this submessage's length is being accumulated.
|
8509
|
-
int *stack, *top, *stacklimit;
|
8510
|
-
|
8511
|
-
// Depth of startmsg/endmsg calls.
|
8512
|
-
int depth;
|
8513
|
-
};
|
8514
|
-
|
8515
8048
|
/* low-level buffering ********************************************************/
|
8516
8049
|
|
8517
8050
|
// Low-level functions for interacting with the output buffer.
|
@@ -8529,23 +8062,25 @@ static upb_pb_encoder_segment *top(upb_pb_encoder *e) {
|
|
8529
8062
|
// Call to ensure that at least "bytes" bytes are available for writing at
|
8530
8063
|
// e->ptr. Returns false if the bytes could not be allocated.
|
8531
8064
|
static bool reserve(upb_pb_encoder *e, size_t bytes) {
|
8532
|
-
if ((
|
8533
|
-
// Grow buffer.
|
8065
|
+
if ((e->limit - e->ptr) < bytes) {
|
8534
8066
|
size_t needed = bytes + (e->ptr - e->buf);
|
8535
8067
|
size_t old_size = e->limit - e->buf;
|
8536
|
-
|
8537
8068
|
size_t new_size = old_size;
|
8538
|
-
|
8539
8069
|
while (new_size < needed) {
|
8540
8070
|
new_size *= 2;
|
8541
8071
|
}
|
8542
8072
|
|
8543
|
-
char *
|
8073
|
+
char *realloc_from = (e->buf == e->initbuf) ? NULL : e->buf;
|
8074
|
+
char *new_buf = realloc(realloc_from, new_size);
|
8544
8075
|
|
8545
8076
|
if (new_buf == NULL) {
|
8546
8077
|
return false;
|
8547
8078
|
}
|
8548
8079
|
|
8080
|
+
if (realloc_from == NULL) {
|
8081
|
+
memcpy(new_buf, e->initbuf, old_size);
|
8082
|
+
}
|
8083
|
+
|
8549
8084
|
e->ptr = new_buf + (e->ptr - e->buf);
|
8550
8085
|
e->runbegin = new_buf + (e->runbegin - e->buf);
|
8551
8086
|
e->limit = new_buf + new_size;
|
@@ -8558,7 +8093,7 @@ static bool reserve(upb_pb_encoder *e, size_t bytes) {
|
|
8558
8093
|
// Call when "bytes" bytes have been writte at e->ptr. The caller *must* have
|
8559
8094
|
// previously called reserve() with at least this many bytes.
|
8560
8095
|
static void encoder_advance(upb_pb_encoder *e, size_t bytes) {
|
8561
|
-
assert((
|
8096
|
+
assert((e->limit - e->ptr) >= bytes);
|
8562
8097
|
e->ptr += bytes;
|
8563
8098
|
}
|
8564
8099
|
|
@@ -8614,17 +8149,21 @@ static bool start_delim(upb_pb_encoder *e) {
|
|
8614
8149
|
}
|
8615
8150
|
|
8616
8151
|
if (++e->segptr == e->seglimit) {
|
8617
|
-
|
8152
|
+
upb_pb_encoder_segment *realloc_from =
|
8153
|
+
(e->segbuf == e->seginitbuf) ? NULL : e->segbuf;
|
8618
8154
|
size_t old_size =
|
8619
8155
|
(e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment);
|
8620
8156
|
size_t new_size = old_size * 2;
|
8621
|
-
upb_pb_encoder_segment *new_buf =
|
8622
|
-
upb_env_realloc(e->env, e->segbuf, old_size, new_size);
|
8157
|
+
upb_pb_encoder_segment *new_buf = realloc(realloc_from, new_size);
|
8623
8158
|
|
8624
8159
|
if (new_buf == NULL) {
|
8625
8160
|
return false;
|
8626
8161
|
}
|
8627
8162
|
|
8163
|
+
if (realloc_from == NULL) {
|
8164
|
+
memcpy(new_buf, e->seginitbuf, old_size);
|
8165
|
+
}
|
8166
|
+
|
8628
8167
|
e->segptr = new_buf + (e->segptr - e->segbuf);
|
8629
8168
|
e->seglimit = new_buf + (new_size / sizeof(upb_pb_encoder_segment));
|
8630
8169
|
e->segbuf = new_buf;
|
@@ -8895,12 +8434,6 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
|
|
8895
8434
|
}
|
8896
8435
|
}
|
8897
8436
|
|
8898
|
-
void upb_pb_encoder_reset(upb_pb_encoder *e) {
|
8899
|
-
e->segptr = NULL;
|
8900
|
-
e->top = NULL;
|
8901
|
-
e->depth = 0;
|
8902
|
-
}
|
8903
|
-
|
8904
8437
|
|
8905
8438
|
/* public API *****************************************************************/
|
8906
8439
|
|
@@ -8909,42 +8442,40 @@ const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
|
|
8909
8442
|
return upb_handlers_newfrozen(m, owner, newhandlers_callback, NULL);
|
8910
8443
|
}
|
8911
8444
|
|
8912
|
-
|
8913
|
-
upb_bytessink *output) {
|
8914
|
-
const size_t initial_bufsize = 256;
|
8915
|
-
const size_t initial_segbufsize = 16;
|
8916
|
-
// TODO(haberman): make this configurable.
|
8917
|
-
const size_t stack_size = 64;
|
8918
|
-
#ifndef NDEBUG
|
8919
|
-
const size_t size_before = upb_env_bytesallocated(env);
|
8920
|
-
#endif
|
8921
|
-
|
8922
|
-
upb_pb_encoder *e = upb_env_malloc(env, sizeof(upb_pb_encoder));
|
8923
|
-
if (!e) return NULL;
|
8445
|
+
#define ARRAYSIZE(x) (sizeof(x) / sizeof(x[0]))
|
8924
8446
|
|
8925
|
-
|
8926
|
-
e->
|
8927
|
-
e->
|
8447
|
+
void upb_pb_encoder_init(upb_pb_encoder *e, const upb_handlers *h) {
|
8448
|
+
e->output_ = NULL;
|
8449
|
+
e->subc = NULL;
|
8450
|
+
e->buf = e->initbuf;
|
8451
|
+
e->ptr = e->buf;
|
8452
|
+
e->limit = e->buf + ARRAYSIZE(e->initbuf);
|
8453
|
+
e->segbuf = e->seginitbuf;
|
8454
|
+
e->seglimit = e->segbuf + ARRAYSIZE(e->seginitbuf);
|
8455
|
+
e->stacklimit = e->stack + ARRAYSIZE(e->stack);
|
8456
|
+
upb_sink_reset(&e->input_, h, e);
|
8457
|
+
}
|
8928
8458
|
|
8929
|
-
|
8930
|
-
|
8459
|
+
void upb_pb_encoder_uninit(upb_pb_encoder *e) {
|
8460
|
+
if (e->buf != e->initbuf) {
|
8461
|
+
free(e->buf);
|
8931
8462
|
}
|
8932
8463
|
|
8933
|
-
e->
|
8934
|
-
|
8935
|
-
|
8464
|
+
if (e->segbuf != e->seginitbuf) {
|
8465
|
+
free(e->segbuf);
|
8466
|
+
}
|
8467
|
+
}
|
8936
8468
|
|
8469
|
+
void upb_pb_encoder_resetoutput(upb_pb_encoder *e, upb_bytessink *output) {
|
8937
8470
|
upb_pb_encoder_reset(e);
|
8938
|
-
upb_sink_reset(&e->input_, h, e);
|
8939
|
-
|
8940
|
-
e->env = env;
|
8941
8471
|
e->output_ = output;
|
8942
8472
|
e->subc = output->closure;
|
8943
|
-
|
8473
|
+
}
|
8944
8474
|
|
8945
|
-
|
8946
|
-
|
8947
|
-
|
8475
|
+
void upb_pb_encoder_reset(upb_pb_encoder *e) {
|
8476
|
+
e->segptr = NULL;
|
8477
|
+
e->top = NULL;
|
8478
|
+
e->depth = 0;
|
8948
8479
|
}
|
8949
8480
|
|
8950
8481
|
upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
|
@@ -8969,26 +8500,26 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
|
|
8969
8500
|
const upb_pbdecodermethod *decoder_m =
|
8970
8501
|
upb_pbdecodermethod_new(&opts, &decoder_m);
|
8971
8502
|
|
8972
|
-
|
8973
|
-
|
8974
|
-
upb_env_reporterrorsto(&env, status);
|
8503
|
+
upb_pbdecoder decoder;
|
8504
|
+
upb_descreader reader;
|
8975
8505
|
|
8976
|
-
|
8977
|
-
|
8978
|
-
|
8506
|
+
upb_pbdecoder_init(&decoder, decoder_m, status);
|
8507
|
+
upb_descreader_init(&reader, reader_h, status);
|
8508
|
+
upb_pbdecoder_resetoutput(&decoder, upb_descreader_input(&reader));
|
8979
8509
|
|
8980
8510
|
// Push input data.
|
8981
|
-
bool ok = upb_bufsrc_putbuf(str, len, upb_pbdecoder_input(decoder));
|
8511
|
+
bool ok = upb_bufsrc_putbuf(str, len, upb_pbdecoder_input(&decoder));
|
8982
8512
|
|
8983
8513
|
upb_def **ret = NULL;
|
8984
8514
|
|
8985
8515
|
if (!ok) goto cleanup;
|
8986
|
-
upb_def **defs = upb_descreader_getdefs(reader, owner, n);
|
8516
|
+
upb_def **defs = upb_descreader_getdefs(&reader, owner, n);
|
8987
8517
|
ret = malloc(sizeof(upb_def*) * (*n));
|
8988
8518
|
memcpy(ret, defs, sizeof(upb_def*) * (*n));
|
8989
8519
|
|
8990
8520
|
cleanup:
|
8991
|
-
|
8521
|
+
upb_pbdecoder_uninit(&decoder);
|
8522
|
+
upb_descreader_uninit(&reader);
|
8992
8523
|
upb_handlers_unref(reader_h, &reader_h);
|
8993
8524
|
upb_pbdecodermethod_unref(decoder_m, &decoder_m);
|
8994
8525
|
return ret;
|
@@ -9053,14 +8584,6 @@ bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
|
|
9053
8584
|
#include <string.h>
|
9054
8585
|
|
9055
8586
|
|
9056
|
-
struct upb_textprinter {
|
9057
|
-
upb_sink input_;
|
9058
|
-
upb_bytessink *output_;
|
9059
|
-
int indent_depth_;
|
9060
|
-
bool single_line_;
|
9061
|
-
void *subc;
|
9062
|
-
};
|
9063
|
-
|
9064
8587
|
#define CHECK(x) if ((x) < 0) goto err;
|
9065
8588
|
|
9066
8589
|
static const char *shortname(const char *longname) {
|
@@ -9278,6 +8801,24 @@ err:
|
|
9278
8801
|
return false;
|
9279
8802
|
}
|
9280
8803
|
|
8804
|
+
|
8805
|
+
/* Public API *****************************************************************/
|
8806
|
+
|
8807
|
+
void upb_textprinter_init(upb_textprinter *p, const upb_handlers *h) {
|
8808
|
+
p->single_line_ = false;
|
8809
|
+
p->indent_depth_ = 0;
|
8810
|
+
upb_sink_reset(&p->input_, h, p);
|
8811
|
+
}
|
8812
|
+
|
8813
|
+
void upb_textprinter_uninit(upb_textprinter *p) {
|
8814
|
+
UPB_UNUSED(p);
|
8815
|
+
}
|
8816
|
+
|
8817
|
+
void upb_textprinter_reset(upb_textprinter *p, bool single_line) {
|
8818
|
+
p->single_line_ = single_line;
|
8819
|
+
p->indent_depth_ = 0;
|
8820
|
+
}
|
8821
|
+
|
9281
8822
|
static void onmreg(const void *c, upb_handlers *h) {
|
9282
8823
|
UPB_UNUSED(c);
|
9283
8824
|
const upb_msgdef *m = upb_handlers_msgdef(h);
|
@@ -9337,26 +8878,6 @@ static void onmreg(const void *c, upb_handlers *h) {
|
|
9337
8878
|
}
|
9338
8879
|
}
|
9339
8880
|
|
9340
|
-
static void textprinter_reset(upb_textprinter *p, bool single_line) {
|
9341
|
-
p->single_line_ = single_line;
|
9342
|
-
p->indent_depth_ = 0;
|
9343
|
-
}
|
9344
|
-
|
9345
|
-
|
9346
|
-
/* Public API *****************************************************************/
|
9347
|
-
|
9348
|
-
upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
|
9349
|
-
upb_bytessink *output) {
|
9350
|
-
upb_textprinter *p = upb_env_malloc(env, sizeof(upb_textprinter));
|
9351
|
-
if (!p) return NULL;
|
9352
|
-
|
9353
|
-
p->output_ = output;
|
9354
|
-
upb_sink_reset(&p->input_, h, p);
|
9355
|
-
textprinter_reset(p, false);
|
9356
|
-
|
9357
|
-
return p;
|
9358
|
-
}
|
9359
|
-
|
9360
8881
|
const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
|
9361
8882
|
const void *owner) {
|
9362
8883
|
return upb_handlers_newfrozen(m, owner, &onmreg, NULL);
|
@@ -9364,6 +8885,11 @@ const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
|
|
9364
8885
|
|
9365
8886
|
upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; }
|
9366
8887
|
|
8888
|
+
bool upb_textprinter_resetoutput(upb_textprinter *p, upb_bytessink *output) {
|
8889
|
+
p->output_ = output;
|
8890
|
+
return true;
|
8891
|
+
}
|
8892
|
+
|
9367
8893
|
void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) {
|
9368
8894
|
p->single_line_ = single_line;
|
9369
8895
|
}
|
@@ -9526,71 +9052,6 @@ upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) {
|
|
9526
9052
|
#include <errno.h>
|
9527
9053
|
|
9528
9054
|
|
9529
|
-
#define UPB_JSON_MAX_DEPTH 64
|
9530
|
-
|
9531
|
-
typedef struct {
|
9532
|
-
upb_sink sink;
|
9533
|
-
|
9534
|
-
// The current message in which we're parsing, and the field whose value we're
|
9535
|
-
// expecting next.
|
9536
|
-
const upb_msgdef *m;
|
9537
|
-
const upb_fielddef *f;
|
9538
|
-
|
9539
|
-
// We are in a repeated-field context, ready to emit mapentries as
|
9540
|
-
// submessages. This flag alters the start-of-object (open-brace) behavior to
|
9541
|
-
// begin a sequence of mapentry messages rather than a single submessage.
|
9542
|
-
bool is_map;
|
9543
|
-
|
9544
|
-
// We are in a map-entry message context. This flag is set when parsing the
|
9545
|
-
// value field of a single map entry and indicates to all value-field parsers
|
9546
|
-
// (subobjects, strings, numbers, and bools) that the map-entry submessage
|
9547
|
-
// should end as soon as the value is parsed.
|
9548
|
-
bool is_mapentry;
|
9549
|
-
|
9550
|
-
// If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent
|
9551
|
-
// message's map field that we're currently parsing. This differs from |f|
|
9552
|
-
// because |f| is the field in the *current* message (i.e., the map-entry
|
9553
|
-
// message itself), not the parent's field that leads to this map.
|
9554
|
-
const upb_fielddef *mapfield;
|
9555
|
-
} upb_jsonparser_frame;
|
9556
|
-
|
9557
|
-
struct upb_json_parser {
|
9558
|
-
upb_env *env;
|
9559
|
-
upb_byteshandler input_handler_;
|
9560
|
-
upb_bytessink input_;
|
9561
|
-
|
9562
|
-
// Stack to track the JSON scopes we are in.
|
9563
|
-
upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH];
|
9564
|
-
upb_jsonparser_frame *top;
|
9565
|
-
upb_jsonparser_frame *limit;
|
9566
|
-
|
9567
|
-
upb_status *status;
|
9568
|
-
|
9569
|
-
// Ragel's internal parsing stack for the parsing state machine.
|
9570
|
-
int current_state;
|
9571
|
-
int parser_stack[UPB_JSON_MAX_DEPTH];
|
9572
|
-
int parser_top;
|
9573
|
-
|
9574
|
-
// The handle for the current buffer.
|
9575
|
-
const upb_bufhandle *handle;
|
9576
|
-
|
9577
|
-
// Accumulate buffer. See details in parser.rl.
|
9578
|
-
const char *accumulated;
|
9579
|
-
size_t accumulated_len;
|
9580
|
-
char *accumulate_buf;
|
9581
|
-
size_t accumulate_buf_size;
|
9582
|
-
|
9583
|
-
// Multi-part text data. See details in parser.rl.
|
9584
|
-
int multipart_state;
|
9585
|
-
upb_selector_t string_selector;
|
9586
|
-
|
9587
|
-
// Input capture. See details in parser.rl.
|
9588
|
-
const char *capture;
|
9589
|
-
|
9590
|
-
// Intermediate result of parsing a unicode escape sequence.
|
9591
|
-
uint32_t digit;
|
9592
|
-
};
|
9593
|
-
|
9594
9055
|
#define PARSER_CHECK_RETURN(x) if (!(x)) return false
|
9595
9056
|
|
9596
9057
|
// Used to signal that a capture has been suspended.
|
@@ -9793,13 +9254,12 @@ static void accumulate_clear(upb_json_parser *p) {
|
|
9793
9254
|
|
9794
9255
|
// Used internally by accumulate_append().
|
9795
9256
|
static bool accumulate_realloc(upb_json_parser *p, size_t need) {
|
9796
|
-
size_t
|
9797
|
-
size_t new_size = UPB_MAX(old_size, 128);
|
9257
|
+
size_t new_size = UPB_MAX(p->accumulate_buf_size, 128);
|
9798
9258
|
while (new_size < need) {
|
9799
9259
|
new_size = saturating_multiply(new_size, 2);
|
9800
9260
|
}
|
9801
9261
|
|
9802
|
-
void *mem =
|
9262
|
+
void *mem = realloc(p->accumulate_buf, new_size);
|
9803
9263
|
if (!mem) {
|
9804
9264
|
upb_status_seterrmsg(p->status, "Out of memory allocating buffer.");
|
9805
9265
|
return false;
|
@@ -10548,11 +10008,11 @@ static void end_object(upb_json_parser *p) {
|
|
10548
10008
|
// final state once, when the closing '"' is seen.
|
10549
10009
|
|
10550
10010
|
|
10551
|
-
#line
|
10011
|
+
#line 1085 "upb/json/parser.rl"
|
10552
10012
|
|
10553
10013
|
|
10554
10014
|
|
10555
|
-
#line
|
10015
|
+
#line 997 "upb/json/parser.c"
|
10556
10016
|
static const char _json_actions[] = {
|
10557
10017
|
0, 1, 0, 1, 2, 1, 3, 1,
|
10558
10018
|
5, 1, 6, 1, 7, 1, 8, 1,
|
@@ -10694,6 +10154,8 @@ static const char _json_trans_actions[] = {
|
|
10694
10154
|
};
|
10695
10155
|
|
10696
10156
|
static const int json_start = 1;
|
10157
|
+
static const int json_first_final = 56;
|
10158
|
+
static const int json_error = 0;
|
10697
10159
|
|
10698
10160
|
static const int json_en_number_machine = 10;
|
10699
10161
|
static const int json_en_string_machine = 19;
|
@@ -10701,7 +10163,7 @@ static const int json_en_value_machine = 27;
|
|
10701
10163
|
static const int json_en_main = 1;
|
10702
10164
|
|
10703
10165
|
|
10704
|
-
#line
|
10166
|
+
#line 1088 "upb/json/parser.rl"
|
10705
10167
|
|
10706
10168
|
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
|
10707
10169
|
const upb_bufhandle *handle) {
|
@@ -10721,7 +10183,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
|
|
10721
10183
|
capture_resume(parser, buf);
|
10722
10184
|
|
10723
10185
|
|
10724
|
-
#line
|
10186
|
+
#line 1168 "upb/json/parser.c"
|
10725
10187
|
{
|
10726
10188
|
int _klen;
|
10727
10189
|
unsigned int _trans;
|
@@ -10796,118 +10258,118 @@ _match:
|
|
10796
10258
|
switch ( *_acts++ )
|
10797
10259
|
{
|
10798
10260
|
case 0:
|
10799
|
-
#line
|
10261
|
+
#line 1000 "upb/json/parser.rl"
|
10800
10262
|
{ p--; {cs = stack[--top]; goto _again;} }
|
10801
10263
|
break;
|
10802
10264
|
case 1:
|
10803
|
-
#line
|
10265
|
+
#line 1001 "upb/json/parser.rl"
|
10804
10266
|
{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
|
10805
10267
|
break;
|
10806
10268
|
case 2:
|
10807
|
-
#line
|
10269
|
+
#line 1005 "upb/json/parser.rl"
|
10808
10270
|
{ start_text(parser, p); }
|
10809
10271
|
break;
|
10810
10272
|
case 3:
|
10811
|
-
#line
|
10273
|
+
#line 1006 "upb/json/parser.rl"
|
10812
10274
|
{ CHECK_RETURN_TOP(end_text(parser, p)); }
|
10813
10275
|
break;
|
10814
10276
|
case 4:
|
10815
|
-
#line
|
10277
|
+
#line 1012 "upb/json/parser.rl"
|
10816
10278
|
{ start_hex(parser); }
|
10817
10279
|
break;
|
10818
10280
|
case 5:
|
10819
|
-
#line
|
10281
|
+
#line 1013 "upb/json/parser.rl"
|
10820
10282
|
{ hexdigit(parser, p); }
|
10821
10283
|
break;
|
10822
10284
|
case 6:
|
10823
|
-
#line
|
10285
|
+
#line 1014 "upb/json/parser.rl"
|
10824
10286
|
{ CHECK_RETURN_TOP(end_hex(parser)); }
|
10825
10287
|
break;
|
10826
10288
|
case 7:
|
10827
|
-
#line
|
10289
|
+
#line 1020 "upb/json/parser.rl"
|
10828
10290
|
{ CHECK_RETURN_TOP(escape(parser, p)); }
|
10829
10291
|
break;
|
10830
10292
|
case 8:
|
10831
|
-
#line
|
10293
|
+
#line 1026 "upb/json/parser.rl"
|
10832
10294
|
{ p--; {cs = stack[--top]; goto _again;} }
|
10833
10295
|
break;
|
10834
10296
|
case 9:
|
10835
|
-
#line
|
10297
|
+
#line 1029 "upb/json/parser.rl"
|
10836
10298
|
{ {stack[top++] = cs; cs = 19; goto _again;} }
|
10837
10299
|
break;
|
10838
10300
|
case 10:
|
10839
|
-
#line
|
10301
|
+
#line 1031 "upb/json/parser.rl"
|
10840
10302
|
{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
|
10841
10303
|
break;
|
10842
10304
|
case 11:
|
10843
|
-
#line
|
10305
|
+
#line 1036 "upb/json/parser.rl"
|
10844
10306
|
{ start_member(parser); }
|
10845
10307
|
break;
|
10846
10308
|
case 12:
|
10847
|
-
#line
|
10309
|
+
#line 1037 "upb/json/parser.rl"
|
10848
10310
|
{ CHECK_RETURN_TOP(end_membername(parser)); }
|
10849
10311
|
break;
|
10850
10312
|
case 13:
|
10851
|
-
#line
|
10313
|
+
#line 1040 "upb/json/parser.rl"
|
10852
10314
|
{ end_member(parser); }
|
10853
10315
|
break;
|
10854
10316
|
case 14:
|
10855
|
-
#line
|
10317
|
+
#line 1046 "upb/json/parser.rl"
|
10856
10318
|
{ start_object(parser); }
|
10857
10319
|
break;
|
10858
10320
|
case 15:
|
10859
|
-
#line
|
10321
|
+
#line 1049 "upb/json/parser.rl"
|
10860
10322
|
{ end_object(parser); }
|
10861
10323
|
break;
|
10862
10324
|
case 16:
|
10863
|
-
#line
|
10325
|
+
#line 1055 "upb/json/parser.rl"
|
10864
10326
|
{ CHECK_RETURN_TOP(start_array(parser)); }
|
10865
10327
|
break;
|
10866
10328
|
case 17:
|
10867
|
-
#line
|
10329
|
+
#line 1059 "upb/json/parser.rl"
|
10868
10330
|
{ end_array(parser); }
|
10869
10331
|
break;
|
10870
10332
|
case 18:
|
10871
|
-
#line
|
10333
|
+
#line 1064 "upb/json/parser.rl"
|
10872
10334
|
{ start_number(parser, p); }
|
10873
10335
|
break;
|
10874
10336
|
case 19:
|
10875
|
-
#line
|
10337
|
+
#line 1065 "upb/json/parser.rl"
|
10876
10338
|
{ CHECK_RETURN_TOP(end_number(parser, p)); }
|
10877
10339
|
break;
|
10878
10340
|
case 20:
|
10879
|
-
#line
|
10341
|
+
#line 1067 "upb/json/parser.rl"
|
10880
10342
|
{ CHECK_RETURN_TOP(start_stringval(parser)); }
|
10881
10343
|
break;
|
10882
10344
|
case 21:
|
10883
|
-
#line
|
10345
|
+
#line 1068 "upb/json/parser.rl"
|
10884
10346
|
{ CHECK_RETURN_TOP(end_stringval(parser)); }
|
10885
10347
|
break;
|
10886
10348
|
case 22:
|
10887
|
-
#line
|
10349
|
+
#line 1070 "upb/json/parser.rl"
|
10888
10350
|
{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
|
10889
10351
|
break;
|
10890
10352
|
case 23:
|
10891
|
-
#line
|
10353
|
+
#line 1072 "upb/json/parser.rl"
|
10892
10354
|
{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
|
10893
10355
|
break;
|
10894
10356
|
case 24:
|
10895
|
-
#line
|
10357
|
+
#line 1074 "upb/json/parser.rl"
|
10896
10358
|
{ /* null value */ }
|
10897
10359
|
break;
|
10898
10360
|
case 25:
|
10899
|
-
#line
|
10361
|
+
#line 1076 "upb/json/parser.rl"
|
10900
10362
|
{ CHECK_RETURN_TOP(start_subobject(parser)); }
|
10901
10363
|
break;
|
10902
10364
|
case 26:
|
10903
|
-
#line
|
10365
|
+
#line 1077 "upb/json/parser.rl"
|
10904
10366
|
{ end_subobject(parser); }
|
10905
10367
|
break;
|
10906
10368
|
case 27:
|
10907
|
-
#line
|
10369
|
+
#line 1082 "upb/json/parser.rl"
|
10908
10370
|
{ p--; {cs = stack[--top]; goto _again;} }
|
10909
10371
|
break;
|
10910
|
-
#line
|
10372
|
+
#line 1354 "upb/json/parser.c"
|
10911
10373
|
}
|
10912
10374
|
}
|
10913
10375
|
|
@@ -10920,7 +10382,7 @@ _again:
|
|
10920
10382
|
_out: {}
|
10921
10383
|
}
|
10922
10384
|
|
10923
|
-
#line
|
10385
|
+
#line 1107 "upb/json/parser.rl"
|
10924
10386
|
|
10925
10387
|
if (p != pe) {
|
10926
10388
|
upb_status_seterrf(parser->status, "Parse error at %s\n", p);
|
@@ -10939,17 +10401,29 @@ error:
|
|
10939
10401
|
bool end(void *closure, const void *hd) {
|
10940
10402
|
UPB_UNUSED(closure);
|
10941
10403
|
UPB_UNUSED(hd);
|
10942
|
-
|
10943
|
-
// Prevent compile warning on unused static constants.
|
10944
|
-
UPB_UNUSED(json_start);
|
10945
|
-
UPB_UNUSED(json_en_number_machine);
|
10946
|
-
UPB_UNUSED(json_en_string_machine);
|
10947
|
-
UPB_UNUSED(json_en_value_machine);
|
10948
|
-
UPB_UNUSED(json_en_main);
|
10949
10404
|
return true;
|
10950
10405
|
}
|
10951
10406
|
|
10952
|
-
|
10407
|
+
|
10408
|
+
/* Public API *****************************************************************/
|
10409
|
+
|
10410
|
+
void upb_json_parser_init(upb_json_parser *p, upb_status *status) {
|
10411
|
+
p->limit = p->stack + UPB_JSON_MAX_DEPTH;
|
10412
|
+
p->accumulate_buf = NULL;
|
10413
|
+
p->accumulate_buf_size = 0;
|
10414
|
+
upb_byteshandler_init(&p->input_handler_);
|
10415
|
+
upb_byteshandler_setstring(&p->input_handler_, parse, NULL);
|
10416
|
+
upb_byteshandler_setendstr(&p->input_handler_, end, NULL);
|
10417
|
+
upb_bytessink_reset(&p->input_, &p->input_handler_, p);
|
10418
|
+
p->status = status;
|
10419
|
+
}
|
10420
|
+
|
10421
|
+
void upb_json_parser_uninit(upb_json_parser *p) {
|
10422
|
+
upb_byteshandler_uninit(&p->input_handler_);
|
10423
|
+
free(p->accumulate_buf);
|
10424
|
+
}
|
10425
|
+
|
10426
|
+
void upb_json_parser_reset(upb_json_parser *p) {
|
10953
10427
|
p->top = p->stack;
|
10954
10428
|
p->top->f = NULL;
|
10955
10429
|
p->top->is_map = false;
|
@@ -10959,48 +10433,25 @@ static void json_parser_reset(upb_json_parser *p) {
|
|
10959
10433
|
int top;
|
10960
10434
|
// Emit Ragel initialization of the parser.
|
10961
10435
|
|
10962
|
-
#line
|
10436
|
+
#line 1418 "upb/json/parser.c"
|
10963
10437
|
{
|
10964
10438
|
cs = json_start;
|
10965
10439
|
top = 0;
|
10966
10440
|
}
|
10967
10441
|
|
10968
|
-
#line
|
10442
|
+
#line 1157 "upb/json/parser.rl"
|
10969
10443
|
p->current_state = cs;
|
10970
10444
|
p->parser_top = top;
|
10971
10445
|
accumulate_clear(p);
|
10972
10446
|
p->multipart_state = MULTIPART_INACTIVE;
|
10973
10447
|
p->capture = NULL;
|
10974
|
-
p->accumulated = NULL;
|
10975
10448
|
}
|
10976
10449
|
|
10977
|
-
|
10978
|
-
|
10979
|
-
|
10980
|
-
|
10981
|
-
|
10982
|
-
const size_t size_before = upb_env_bytesallocated(env);
|
10983
|
-
#endif
|
10984
|
-
upb_json_parser *p = upb_env_malloc(env, sizeof(upb_json_parser));
|
10985
|
-
if (!p) return false;
|
10986
|
-
|
10987
|
-
p->env = env;
|
10988
|
-
p->limit = p->stack + UPB_JSON_MAX_DEPTH;
|
10989
|
-
p->accumulate_buf = NULL;
|
10990
|
-
p->accumulate_buf_size = 0;
|
10991
|
-
upb_byteshandler_init(&p->input_handler_);
|
10992
|
-
upb_byteshandler_setstring(&p->input_handler_, parse, NULL);
|
10993
|
-
upb_byteshandler_setendstr(&p->input_handler_, end, NULL);
|
10994
|
-
upb_bytessink_reset(&p->input_, &p->input_handler_, p);
|
10995
|
-
|
10996
|
-
json_parser_reset(p);
|
10997
|
-
upb_sink_reset(&p->top->sink, output->handlers, output->closure);
|
10998
|
-
p->top->m = upb_handlers_msgdef(output->handlers);
|
10999
|
-
|
11000
|
-
// If this fails, uncomment and increase the value in parser.h.
|
11001
|
-
// fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before);
|
11002
|
-
assert(upb_env_bytesallocated(env) - size_before <= UPB_JSON_PARSER_SIZE);
|
11003
|
-
return p;
|
10450
|
+
void upb_json_parser_resetoutput(upb_json_parser *p, upb_sink *sink) {
|
10451
|
+
upb_json_parser_reset(p);
|
10452
|
+
upb_sink_reset(&p->top->sink, sink->handlers, sink->closure);
|
10453
|
+
p->top->m = upb_handlers_msgdef(sink->handlers);
|
10454
|
+
p->accumulated = NULL;
|
11004
10455
|
}
|
11005
10456
|
|
11006
10457
|
upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
|
@@ -11022,27 +10473,6 @@ upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
|
|
11022
10473
|
#include <string.h>
|
11023
10474
|
#include <stdint.h>
|
11024
10475
|
|
11025
|
-
struct upb_json_printer {
|
11026
|
-
upb_sink input_;
|
11027
|
-
// BytesSink closure.
|
11028
|
-
void *subc_;
|
11029
|
-
upb_bytessink *output_;
|
11030
|
-
|
11031
|
-
// We track the depth so that we know when to emit startstr/endstr on the
|
11032
|
-
// output.
|
11033
|
-
int depth_;
|
11034
|
-
|
11035
|
-
// Have we emitted the first element? This state is necessary to emit commas
|
11036
|
-
// without leaving a trailing comma in arrays/maps. We keep this state per
|
11037
|
-
// frame depth.
|
11038
|
-
//
|
11039
|
-
// Why max_depth * 2? UPB_MAX_HANDLER_DEPTH counts depth as nested messages.
|
11040
|
-
// We count frames (contexts in which we separate elements by commas) as both
|
11041
|
-
// repeated fields and messages (maps), and the worst case is a
|
11042
|
-
// message->repeated field->submessage->repeated field->... nesting.
|
11043
|
-
bool first_elem_[UPB_MAX_HANDLER_DEPTH * 2];
|
11044
|
-
};
|
11045
|
-
|
11046
10476
|
// StringPiece; a pointer plus a length.
|
11047
10477
|
typedef struct {
|
11048
10478
|
const char *ptr;
|
@@ -11190,7 +10620,7 @@ static bool putkey(void *closure, const void *handler_data) {
|
|
11190
10620
|
return true;
|
11191
10621
|
}
|
11192
10622
|
|
11193
|
-
#define CHKFMT(val) if ((val) ==
|
10623
|
+
#define CHKFMT(val) if ((val) == -1) return false;
|
11194
10624
|
#define CHK(val) if (!(val)) return false;
|
11195
10625
|
|
11196
10626
|
#define TYPE_HANDLERS(type, fmt_func) \
|
@@ -11759,29 +11189,25 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
|
|
11759
11189
|
#undef TYPE
|
11760
11190
|
}
|
11761
11191
|
|
11762
|
-
|
11192
|
+
/* Public API *****************************************************************/
|
11193
|
+
|
11194
|
+
void upb_json_printer_init(upb_json_printer *p, const upb_handlers *h) {
|
11195
|
+
p->output_ = NULL;
|
11763
11196
|
p->depth_ = 0;
|
11197
|
+
upb_sink_reset(&p->input_, h, p);
|
11764
11198
|
}
|
11765
11199
|
|
11200
|
+
void upb_json_printer_uninit(upb_json_printer *p) {
|
11201
|
+
UPB_UNUSED(p);
|
11202
|
+
}
|
11766
11203
|
|
11767
|
-
|
11768
|
-
|
11769
|
-
|
11770
|
-
upb_bytessink *output) {
|
11771
|
-
#ifndef NDEBUG
|
11772
|
-
size_t size_before = upb_env_bytesallocated(e);
|
11773
|
-
#endif
|
11774
|
-
|
11775
|
-
upb_json_printer *p = upb_env_malloc(e, sizeof(upb_json_printer));
|
11776
|
-
if (!p) return NULL;
|
11204
|
+
void upb_json_printer_reset(upb_json_printer *p) {
|
11205
|
+
p->depth_ = 0;
|
11206
|
+
}
|
11777
11207
|
|
11208
|
+
void upb_json_printer_resetoutput(upb_json_printer *p, upb_bytessink *output) {
|
11209
|
+
upb_json_printer_reset(p);
|
11778
11210
|
p->output_ = output;
|
11779
|
-
json_printer_reset(p);
|
11780
|
-
upb_sink_reset(&p->input_, h, p);
|
11781
|
-
|
11782
|
-
// If this fails, increase the value in printer.h.
|
11783
|
-
assert(upb_env_bytesallocated(e) - size_before <= UPB_JSON_PRINTER_SIZE);
|
11784
|
-
return p;
|
11785
11211
|
}
|
11786
11212
|
|
11787
11213
|
upb_sink *upb_json_printer_input(upb_json_printer *p) {
|