google-protobuf 3.0.0.alpha.3 → 3.0.0.alpha.3.1.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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) {
|