diff --git a/.gitignore b/.gitignore index 0d4a242a0..96208d95d 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,7 @@ py.typed *.dmg.md5 .DS_Store +# temp files +.tmp* +.venv + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8d1ab246a..f273e799a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -93,7 +93,7 @@ jobs: - script: | # setuptools 67.0.0 is not working as of now (pypa/setuptools#4885) - python -m pip install --upgrade pip "setuptools<76.0.0" wheel + python -m pip install --upgrade pip "setuptools<76.0.0" wheel tomli displayName: 'Update pip, setuptools and wheel' - script: | diff --git a/build.sh b/build.sh index 908c7df76..b93a2ac6a 100755 --- a/build.sh +++ b/build.sh @@ -40,6 +40,7 @@ HAVE_PNG=0 HAVE_CURL=0 HAVE_EXPAT=0 HAVE_GIT2=1 +HAVE_LSTREAM=1 RUBYINCLUDE="" RUBYINCLUDE2="" @@ -213,6 +214,9 @@ while [ "$*" != "" ]; do -nolibgit2) HAVE_GIT2=0 ;; + -nolstream) + HAVE_LSTREAM=0 + ;; -qt5) echo "*** WARNING: -qt5 option is ignored - Qt version is auto-detected now." ;; @@ -270,6 +274,7 @@ while [ "$*" != "" ]; do echo " -libexpat Use libexpat instead of QtXml" echo " -libpng Use libpng instead of Qt for PNG generation" echo " -nolibgit2 Do not include libgit2 for Git package support" + echo " -nolstream Do not include the LStream plugin" echo "" echo "Environment Variables:" echo "" @@ -503,6 +508,9 @@ fi if [ $HAVE_GIT2 != 0 ]; then echo " Uses libgit2 for Git access" fi +if [ $HAVE_LSTREAM != 0 ]; then + echo " Includes LStream plugin" +fi if [ "$RPATH" = "" ]; then RPATH="$BIN" fi @@ -587,6 +595,7 @@ echo " HAVE_CURL=$HAVE_CURL" echo " HAVE_PNG=$HAVE_PNG" echo " HAVE_EXPAT=$HAVE_EXPAT" echo " HAVE_GIT2=$HAVE_GIT2" +echo " HAVE_LSTREAM=$HAVE_LSTREAM" echo " RPATH=$RPATH" mkdir -p $BUILD @@ -660,6 +669,7 @@ qmake_options=( HAVE_EXPAT="$HAVE_EXPAT" HAVE_PNG="$HAVE_PNG" HAVE_GIT2="$HAVE_GIT2" + HAVE_LSTREAM="$HAVE_LSTREAM" PREFIX="$BIN" RPATH="$RPATH" KLAYOUT_VERSION="$KLAYOUT_VERSION" diff --git a/pyproject.toml b/pyproject.toml index aee59ff0c..a488932ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools"] +requires = ["setuptools", "tomli"] build-backend = "setuptools.build_meta" [tool.cibuildwheel] diff --git a/setup.py b/setup.py index df2b859fd..6f3415574 100644 --- a/setup.py +++ b/setup.py @@ -68,6 +68,7 @@ import distutils.command.build_ext import setuptools.command.build_ext from setuptools.command.build_ext import build_ext as _build_ext import multiprocessing +import tomli # for Jenkins we do not want to be greedy multicore = os.getenv("KLAYOUT_SETUP_MULTICORE") @@ -253,6 +254,10 @@ setuptools.command.build_ext.link_shared_object = always_link_shared_object # ---------------------------------------------------------------------------------------- +# TODO: +# * Pull this from module-specific configuration files? +# * Include dependencies: "extra_objects", "include_dirs" + class Config(object): """ @@ -282,6 +287,128 @@ class Config(object): self.root = "klayout" + self.src_paths = { } + self.modules = [] + + def module(self, name, src_path): + """ + Declares a module with the given name and source path + + If a file called "pysetup.toml" is found in that + path, it is read and a Library or Extension module + is created. + + Structure of TOML is: + [library] or [extension]: + name = "" + depends = [ list of module names this extension depends on ] + defines = [ list of [name, value] pairs of defines for this module ] + submodules = [ additional parent modules: klayout..mod_name ] + includes = [ additional include paths, "/a/b/..." is absolute in src, "a/b/..." is relative to module source ] + sources = [ additional source paths, see 'includes', takes '*.cc' from there ] + cxxflags = [ additional compiler options ] + cxxflags-gcc = [ additional compiler options for gcc ] + cxxflags-msvc = [ additional compiler options for msvc ] + cxxflags-win32 = [ additional compiler options for Windows ] + cxxflags-linux = [ additional compiler options for Linux ] + cxxflags-darwin = [ additional compiler options for MacOS ] + Compiler option "$libpng_cflags" is replaced by the libpng build flags + ldflags* = [ additional linker options (*=same suffixes as cxxflags) ] + Linker option "$libpng_ldflags" is replaced by the libpng linker flags + libraries* = [ additional libraries (*=same suffixes as cxxflags) ] + """ + + pysetup_file = os.path.join(src_path, "pysetup.toml") + if not os.path.isfile(pysetup_file): + raise RuntimeError("Cannot find 'pysetup.toml' in " + src_path) + + with open(pysetup_file, "rb") as f: + pysetup = tomli.load(f) + + header = {} + is_library = None + if "library" in pysetup: + is_library = True + header = pysetup["library"] + elif "extension" in pysetup: + is_library = False + header = pysetup["extension"] + else: + raise RuntimeError("Invalid format - library or extension section expected in " + pysetup_file) + + header_name = header.get("name", None) + if name is not None and header_name is not None and name != header_name: + raise RuntimeError("Module name and specified name in setup file do not match in " + pysetup_file + ": " + header_name + " vs. " + name) + elif name is None: + if header_name is None: + raise RuntimeError("No module name specified in " + pysetup_file) + name = header_name + + depends = header.get("depends", []) + for d in depends: + # can't resolve now -> maybe later + if d not in self.src_paths: + return False + + print("Adding module " + name + " from pysetup file " + pysetup_file + " ...") + + self.src_paths[name] = src_path + + defines = header.get("defines", []) + submodules = header.get("submodules", []) + includes = header.get("includes", []) + source_paths = header.get("sources", []) + + mod_path = ".".join([ self.root ] + submodules + [ name ]) + include_dirs = [ self.src_path(m) for m in depends ] + [ src_path ] + extra_objects = [ self.path_of(m) for m in depends ] + define_macros = self.macros() + [ tuple(d) for d in defines ] + + sources = self.sources(name) + for i in source_paths: + p = i.split("/") + if len(p) > 0 and p[0] == "": + del p[0] + else: + p = [ src_path ] + p + p.append("*.cc") + sources += glob.glob(os.path.join(*p)) + + for i in includes: + p = i.split("/") + if len(p) > 0 and p[0] == "": + del p[0] + else: + p = [ src_path ] + p + include_dirs.append(os.path.join(*p)) + + if is_library: + ext = Library(mod_path, + define_macros=define_macros, + include_dirs=include_dirs, + extra_objects=extra_objects, + language="c++", + libraries=self.libraries(header), + extra_link_args=self.link_args(header, True), + extra_compile_args=self.compile_args(header), + sources=sources) + self.add_extension(ext) + else: + ext = Extension(mod_path, + define_macros=define_macros, + include_dirs=include_dirs, + extra_objects=extra_objects, + extra_link_args=self.link_args(header, False), + extra_compile_args=self.compile_args(header), + sources=sources) + + self.modules.append(ext) + + return True + + def src_path(self, name): + return self.src_paths[name] + def add_extension(self, ext): self.build_ext_cmd.ext_map[ext.name] = ext @@ -312,65 +439,85 @@ class Config(object): ext_filename = ext_filename.replace(".so", ".dylib") return ext_filename - def path_of(self, mod, mod_src_path): + def path_of(self, mod): """ Returns the build path of the library for a given module """ if platform.system() == "Windows": # On Windows, the library to link is the import library (dll_name, dll_ext) = os.path.splitext(self.libname_of(mod)) - return os.path.join(self.build_temp, mod_src_path, dll_name + ".lib") + return os.path.join(self.build_temp, self.src_path(mod), dll_name + ".lib") else: return os.path.join(self.build_platlib, self.root, self.libname_of(mod)) - def compile_args(self, mod): + def sources(self, mod): + """ + Gets the source files for the given module and root source path + """ + return glob.glob(os.path.join(self.src_path(mod), "*.cc")) + + def compile_args(self, options): """ Gets additional compiler arguments """ - args: List[str] + args = [] + args += options.get("cxxflags", []) if platform.system() == "Windows": bits = os.getenv("KLAYOUT_BITS") if bits: - args = [ + args += [ quote_path("-I" + os.path.join(bits, "zlib", "include")), quote_path("-I" + os.path.join(bits, "ptw", "include")), quote_path("-I" + os.path.join(bits, "png", "include")), quote_path("-I" + os.path.join(bits, "expat", "include")), quote_path("-I" + os.path.join(bits, "curl", "include")), ] - else: - args = [] + args += options.get("cxxflags-msvc", []) + args += options.get("cxxflags-win32", []) else: args = [ "-Wno-strict-aliasing", # Avoids many "type-punned pointer" warnings "-std=c++11", # because we use unordered_map/unordered_set ] - if platform.system() == "Darwin" and mod == "_tl": - if check_libpng(): - args += libpng_cflags() - return args + args += options.get("cxxflags-gcc", []) + if platform.system() == "Darwin": + args += options.get("cxxflags-darwin", []) + else: + args += options.get("cxxflags-linux", []) - def libraries(self, mod): + result = [] + for a in args: + if a == "$libpng_cflags": + if check_libpng(): + result += libpng_cflags() + else: + result.append(a) + return result + + def libraries(self, options): """ Gets the libraries to add """ + libs = [] + libs += options.get("libraries", []) if platform.system() == "Windows": - if mod == "_tl": - return ["libcurl", "expat", "pthreadVCE2", "zlib", "wsock32", "libpng16"] - elif platform.system() == "Darwin": - if mod == "_tl": - libs = ["curl", "expat"] # libpng is included by libpng_ldflags - return libs + libs += options.get("libraries-msvc", []) + libs += options.get("libraries-win32", []) else: - if mod == "_tl": - libs = ["curl", "expat", "png"] - return libs - return [] + libs += options.get("libraries-gcc", []) + if platform.system() == "Darwin": + libs += options.get("libraries-darwin", []) + else: + libs += options.get("libraries-linux", []) + return libs - def link_args(self, mod): + def link_args(self, options, is_library): """ Gets additional linker arguments """ + mod = options["name"] + args = [] + args += options.get("ldflags", []) if platform.system() == "Windows": args = ["/DLL"] bits = os.getenv("KLAYOUT_BITS") @@ -382,20 +529,20 @@ class Config(object): quote_path("/LIBPATH:" + os.path.join(bits, "expat", "libraries")), quote_path("/LIBPATH:" + os.path.join(bits, "curl", "libraries")), ] - return args + args += options.get("ldflags-msvc", []) + args += options.get("ldflags-win32", []) elif platform.system() == "Darwin": # For the dependency modules, make sure we produce a dylib. # We can only link against such, but the bundles produced otherwise. args = [] - if mod[0] == "_": + if is_library: args += [ "-Wl,-dylib", "-Wl,-install_name,@rpath/%s" % self.libname_of(mod, is_lib=True), ] args += ["-Wl,-rpath,@loader_path/"] - if mod == "_tl" and check_libpng(): - args += libpng_ldflags() - return args + args += options.get("ldflags-gcc", []) + args += options.get("ldflags-darwin", []) else: # this makes the libraries suitable for linking with a path - # i.e. from path_of('_tl'). Without this option, the path @@ -404,16 +551,23 @@ class Config(object): # build path and the loader will fail. args = [] args += ["-Wl,-soname," + self.libname_of(mod, is_lib=True)] - if "_dbpi" not in mod: - loader_path = "$ORIGIN" - else: - loader_path = "$ORIGIN/.." - args += ["-Wl,-rpath," + loader_path] + loader_path = ["$ORIGIN"] + [".."]*len(options.get("submodules", [])) + args += ["-Wl,-rpath," + "/".join(loader_path)] # default linux shared object compilation uses the '-g' flag, # which generates unnecessary debug information # removing with strip-all during the linking stage args += ["-Wl,--strip-all"] - return args + args += options.get("ldflags-gcc", []) + args += options.get("ldflags-linux", []) + + result = [] + for a in args: + if a == "$libpng_ldflags": + if check_libpng(): + result += libpng_ldflags() + else: + result.append(a) + return result def macros(self): """ @@ -423,6 +577,7 @@ class Config(object): ("HAVE_CURL", 1), ("HAVE_EXPAT", 1), ("HAVE_PNG", 1), + ("KLAYOUT_VERSION", self.version()), ("KLAYOUT_MAJOR_VERSION", self.major_version()), ("KLAYOUT_MINOR_VERSION", self.minor_version()), ("GSI_ALIAS_INSPECT", 1), @@ -488,535 +643,28 @@ class Config(object): config = Config() -# ------------------------------------------------------------------ -# _tl dependency library - -_tl_path = os.path.join("src", "tl", "tl") -_tl_sources = set(glob.glob(os.path.join(_tl_path, "*.cc"))) - -# Exclude sources which are compatible with Qt only -# Caveat, in source distribution tarballs from pypi, these files will -# not exist. So we need an error-free discard method instead of list's remove. -_tl_sources.discard(os.path.join(_tl_path, "tlHttpStreamQt.cc")) -_tl_sources.discard(os.path.join(_tl_path, "tlHttpStreamNoQt.cc")) -_tl_sources.discard(os.path.join(_tl_path, "tlFileSystemWatcher.cc")) -_tl_sources.discard(os.path.join(_tl_path, "tlDeferredExecutionQt.cc")) - -_tl = Library( - config.root + "._tl", - define_macros=config.macros() + [("MAKE_TL_LIBRARY", 1)], - language="c++", - libraries=config.libraries("_tl"), - extra_link_args=config.link_args("_tl"), - extra_compile_args=config.compile_args("_tl"), - sources=list(_tl_sources), -) - -config.add_extension(_tl) - -# ------------------------------------------------------------------ -# _gsi dependency library - -_gsi_path = os.path.join("src", "gsi", "gsi") -_gsi_sources = set(glob.glob(os.path.join(_gsi_path, "*.cc"))) - -_gsi = Library( - config.root + "._gsi", - define_macros=config.macros() + [("MAKE_GSI_LIBRARY", 1)], - include_dirs=[_tl_path], - extra_objects=[config.path_of("_tl", _tl_path)], - language="c++", - libraries=config.libraries('_gsi'), - extra_link_args=config.link_args("_gsi"), - extra_compile_args=config.compile_args("_gsi"), - sources=list(_gsi_sources), -) -config.add_extension(_gsi) - -# ------------------------------------------------------------------ -# _pya dependency library - -_pya_path = os.path.join("src", "pya", "pya") -_pya_sources = set(glob.glob(os.path.join(_pya_path, "*.cc"))) - -_version_path = os.path.join("src", "version") - -_pya = Library( - config.root + "._pya", - define_macros=config.macros() + [("MAKE_PYA_LIBRARY", 1), ("KLAYOUT_VERSION", config.version())], - include_dirs=[_version_path, _tl_path, _gsi_path], - extra_objects=[config.path_of("_tl", _tl_path), config.path_of("_gsi", _gsi_path)], - language="c++", - libraries=config.libraries('_pya'), - extra_link_args=config.link_args("_pya"), - extra_compile_args=config.compile_args("_pya"), - sources=list(_pya_sources), -) -config.add_extension(_pya) - -# ------------------------------------------------------------------ -# _rba dependency library (dummy) - -_rba_path = os.path.join("src", "rbastub") -_rba_sources = set(glob.glob(os.path.join(_rba_path, "*.cc"))) - -_rba = Library( - config.root + '._rba', - define_macros=config.macros() + [('MAKE_RBA_LIBRARY', 1)], - include_dirs=[_tl_path, _gsi_path], - extra_objects=[config.path_of('_tl', _tl_path), config.path_of('_gsi', _gsi_path)], - language='c++', - libraries=config.libraries('_rba'), - extra_link_args=config.link_args('_rba'), - extra_compile_args=config.compile_args('_rba'), - sources=list(_rba_sources) -) -config.add_extension(_rba) - -# ------------------------------------------------------------------ -# _db dependency library - -_db_path = os.path.join("src", "db", "db") -_db_sources = set(glob.glob(os.path.join(_db_path, "*.cc"))) - -_db = Library( - config.root + "._db", - define_macros=config.macros() + [("MAKE_DB_LIBRARY", 1)], - include_dirs=[_tl_path, _gsi_path, _db_path], - extra_objects=[config.path_of("_tl", _tl_path), config.path_of("_gsi", _gsi_path)], - language="c++", - libraries=config.libraries('_db'), - extra_link_args=config.link_args("_db"), - extra_compile_args=config.compile_args("_db"), - sources=list(_db_sources), -) -config.add_extension(_db) - -# ------------------------------------------------------------------ -# _pex dependency library - -_pex_path = os.path.join("src", "pex", "pex") -_pex_sources = set(glob.glob(os.path.join(_pex_path, "*.cc"))) - -_pex = Library( - config.root + "._pex", - define_macros=config.macros() + [("MAKE_PEX_LIBRARY", 1)], - include_dirs=[_tl_path, _gsi_path, _db_path, _pex_path], - extra_objects=[config.path_of("_tl", _tl_path), config.path_of("_gsi", _gsi_path), config.path_of("_db", _db_path)], - language="c++", - libraries=config.libraries('_pex'), - extra_link_args=config.link_args("_pex"), - extra_compile_args=config.compile_args("_pex"), - sources=list(_pex_sources), -) -config.add_extension(_pex) - -# ------------------------------------------------------------------ -# _lib dependency library - -_lib_path = os.path.join("src", "lib", "lib") -_lib_sources = set(glob.glob(os.path.join(_lib_path, "*.cc"))) - -_lib = Library( - config.root + "._lib", - define_macros=config.macros() + [("MAKE_LIB_LIBRARY", 1)], - include_dirs=[_tl_path, _gsi_path, _db_path, _lib_path], - extra_objects=[ - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_db", _db_path), - ], - language="c++", - libraries=config.libraries('_lib'), - extra_link_args=config.link_args("_lib"), - extra_compile_args=config.compile_args("_lib"), - sources=list(_lib_sources), -) -config.add_extension(_lib) - -# ------------------------------------------------------------------ -# _rdb dependency library - -_rdb_path = os.path.join("src", "rdb", "rdb") -_rdb_sources = set(glob.glob(os.path.join(_rdb_path, "*.cc"))) - -_rdb = Library( - config.root + "._rdb", - define_macros=config.macros() + [("MAKE_RDB_LIBRARY", 1)], - include_dirs=[_db_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_db", _db_path), - ], - language="c++", - libraries=config.libraries('_rdb'), - extra_link_args=config.link_args("_rdb"), - extra_compile_args=config.compile_args("_rdb"), - sources=list(_rdb_sources), -) -config.add_extension(_rdb) - -# ------------------------------------------------------------------ -# _laybasic dependency library - -_laybasic_path = os.path.join("src", "laybasic", "laybasic") -_laybasic_sources = set(glob.glob(os.path.join(_laybasic_path, "*.cc"))) - -_laybasic = Library( - config.root + '._laybasic', - define_macros=config.macros() + [('MAKE_LAYBASIC_LIBRARY', 1)], - include_dirs=[_rdb_path, _db_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of('_rdb', _rdb_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_db', _db_path) - ], - language='c++', - libraries=config.libraries('_laybasic'), - extra_link_args=config.link_args('_laybasic'), - extra_compile_args=config.compile_args('_laybasic'), - sources=list(_laybasic_sources) -) -config.add_extension(_laybasic) - -# ------------------------------------------------------------------ -# _layview dependency library - -_layview_path = os.path.join("src", "layview", "layview") -_layview_sources = set(glob.glob(os.path.join(_layview_path, "*.cc"))) - -_layview = Library( - config.root + '._layview', - define_macros=config.macros() + [('MAKE_LAYVIEW_LIBRARY', 1)], - include_dirs=[_laybasic_path, _rdb_path, _db_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of('_laybasic', _laybasic_path), - config.path_of('_rdb', _rdb_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_db', _db_path) - ], - language='c++', - libraries=config.libraries('_layview'), - extra_link_args=config.link_args('_layview'), - extra_compile_args=config.compile_args('_layview'), - sources=list(_layview_sources) -) -config.add_extension(_layview) - -# ------------------------------------------------------------------ -# _lym dependency library - -_lym_path = os.path.join("src", "lym", "lym") -_lym_sources = set(glob.glob(os.path.join(_lym_path, "*.cc"))) - -_lym = Library( - config.root + '._lym', - define_macros=config.macros() + [('MAKE_LYM_LIBRARY', 1)], - include_dirs=[_pya_path, _rba_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of('_rba', _rba_path), - config.path_of('_pya', _pya_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path) - ], - language='c++', - libraries=config.libraries('_lym'), - extra_link_args=config.link_args('_lym'), - extra_compile_args=config.compile_args('_lym'), - sources=list(_lym_sources) -) -config.add_extension(_lym) - -# ------------------------------------------------------------------ -# _ant dependency library - -_ant_path = os.path.join("src", "ant", "ant") -_ant_sources = set(glob.glob(os.path.join(_ant_path, "*.cc"))) - -_ant = Library( - config.root + '._ant', - define_macros=config.macros() + [('MAKE_ANT_LIBRARY', 1)], - include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of('_laybasic', _laybasic_path), - config.path_of('_layview', _layview_path), - config.path_of('_rdb', _rdb_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_db', _db_path) - ], - language='c++', - libraries=config.libraries('_ant'), - extra_link_args=config.link_args('_ant'), - extra_compile_args=config.compile_args('_ant'), - sources=list(_ant_sources) -) -config.add_extension(_ant) - -# ------------------------------------------------------------------ -# _img dependency library - -_img_path = os.path.join("src", "img", "img") -_img_sources = set(glob.glob(os.path.join(_img_path, "*.cc"))) - -_img = Library( - config.root + '._img', - define_macros=config.macros() + [('MAKE_IMG_LIBRARY', 1)], - include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of('_laybasic', _laybasic_path), - config.path_of('_layview', _layview_path), - config.path_of('_rdb', _rdb_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_db', _db_path) - ], - language='c++', - libraries=config.libraries('_img'), - extra_link_args=config.link_args('_img'), - extra_compile_args=config.compile_args('_img'), - sources=list(_img_sources) -) -config.add_extension(_img) - -# ------------------------------------------------------------------ -# _edt dependency library - -_edt_path = os.path.join("src", "edt", "edt") -_edt_sources = set(glob.glob(os.path.join(_edt_path, "*.cc"))) - -_edt = Library( - config.root + '._edt', - define_macros=config.macros() + [('MAKE_EDT_LIBRARY', 1)], - include_dirs=[_laybasic_path, _layview_path, _rdb_path, _db_path, _tl_path, _gsi_path], - extra_objects=[ - config.path_of('_laybasic', _laybasic_path), - config.path_of('_layview', _layview_path), - config.path_of('_rdb', _rdb_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_db', _db_path) - ], - language='c++', - libraries=config.libraries('_edt'), - extra_link_args=config.link_args('_edt'), - extra_compile_args=config.compile_args('_edt'), - sources=list(_edt_sources) -) -config.add_extension(_edt) - -# ------------------------------------------------------------------ -# dependency libraries from db_plugins - -db_plugins = [] - -dbpi_dirs = glob.glob(os.path.join("src", "plugins", "*", "db_plugin")) -dbpi_dirs += glob.glob(os.path.join("src", "plugins", "*", "*", "db_plugin")) - -for pi in dbpi_dirs: - - mod_name = "_" + os.path.split(os.path.split(pi)[-2])[-1] + "_dbpi" - - pi_sources = glob.glob(os.path.join(pi, "*.cc")) - pi_sources += glob.glob(os.path.join(pi, "contrib", "*.cc")) - - pi_ext = Library( - config.root + ".db_plugins." + mod_name, - define_macros=config.macros() + [("MAKE_DB_PLUGIN_LIBRARY", 1)], - include_dirs=[ - pi, - os.path.join("src", "plugins", "common"), - _db_path, - _tl_path, - _gsi_path, - ], - extra_objects=[ - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_db", _db_path), - ], - language="c++", - extra_link_args=config.link_args(mod_name), - extra_compile_args=config.compile_args(mod_name), - sources=pi_sources, - ) - - db_plugins.append(pi_ext) - config.add_extension(pi_ext) - -# ------------------------------------------------------------------ -# tl extension library - -tl_path = os.path.join("src", "pymod", "tl") -tl_sources = set(glob.glob(os.path.join(tl_path, "*.cc"))) - -tl = Extension( - config.root + ".tlcore", - define_macros=config.macros(), - include_dirs=[_tl_path, _gsi_path, _pya_path], - extra_objects=[ - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_pya", _pya_path), - ], - extra_link_args=config.link_args("tlcore"), - extra_compile_args=config.compile_args("tlcore"), - sources=list(tl_sources), -) - -# ------------------------------------------------------------------ -# db extension library - -db_path = os.path.join("src", "pymod", "db") -db_sources = set(glob.glob(os.path.join(db_path, "*.cc"))) - -db = Extension( - config.root + ".dbcore", - define_macros=config.macros(), - include_dirs=[_db_path, _tl_path, _gsi_path, _pya_path], - extra_objects=[ - config.path_of("_db", _db_path), - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_pya", _pya_path), - ], - extra_link_args=config.link_args("dbcore"), - extra_compile_args=config.compile_args("dbcore"), - sources=list(db_sources), -) - -# ------------------------------------------------------------------ -# pex extension library - -pex_path = os.path.join("src", "pymod", "pex") -pex_sources = set(glob.glob(os.path.join(pex_path, "*.cc"))) - -pex = Extension( - config.root + ".pexcore", - define_macros=config.macros(), - include_dirs=[_db_path, _tl_path, _gsi_path, _pya_path, _pex_path], - extra_objects=[ - config.path_of("_db", _db_path), - config.path_of("_pex", _pex_path), - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_pya", _pya_path), - ], - extra_link_args=config.link_args("pexcore"), - extra_compile_args=config.compile_args("pexcore"), - sources=list(pex_sources), -) - -# ------------------------------------------------------------------ -# lib extension library - -lib_path = os.path.join("src", "pymod", "lib") -lib_sources = set(glob.glob(os.path.join(lib_path, "*.cc"))) - -lib = Extension( - config.root + ".libcore", - define_macros=config.macros(), - include_dirs=[_lib_path, _tl_path, _gsi_path, _pya_path], - extra_objects=[ - config.path_of("_lib", _lib_path), - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_pya", _pya_path), - ], - extra_link_args=config.link_args("libcore"), - extra_compile_args=config.compile_args("libcore"), - sources=list(lib_sources), -) - -# ------------------------------------------------------------------ -# rdb extension library - -rdb_path = os.path.join("src", "pymod", "rdb") -rdb_sources = set(glob.glob(os.path.join(rdb_path, "*.cc"))) - -rdb = Extension( - config.root + ".rdbcore", - define_macros=config.macros(), - include_dirs=[_rdb_path, _tl_path, _gsi_path, _pya_path], - extra_objects=[ - config.path_of("_rdb", _rdb_path), - config.path_of("_tl", _tl_path), - config.path_of("_gsi", _gsi_path), - config.path_of("_pya", _pya_path), - ], - extra_link_args=config.link_args("rdbcore"), - extra_compile_args=config.compile_args("rdbcore"), - sources=list(rdb_sources), -) - -# ------------------------------------------------------------------ -# lay extension library - -lay_path = os.path.join("src", "pymod", "lay") -lay_sources = set(glob.glob(os.path.join(lay_path, "*.cc"))) - -lay = Extension(config.root + '.laycore', - define_macros=config.macros(), - include_dirs=[_laybasic_path, - _layview_path, - _img_path, - _ant_path, - _edt_path, - _lym_path, - _tl_path, - _gsi_path, - _pya_path], - extra_objects=[config.path_of('_laybasic', _laybasic_path), - config.path_of('_layview', _layview_path), - config.path_of('_img', _img_path), - config.path_of('_ant', _ant_path), - config.path_of('_edt', _edt_path), - config.path_of('_lym', _lym_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_pya', _pya_path)], - extra_link_args=config.link_args('laycore'), - extra_compile_args=config.compile_args('laycore'), - sources=list(lay_sources)) - -# ------------------------------------------------------------------ -# pya extension library (all inclusive, basis of pya module) - -pyacore_path = os.path.join("src", "pymod", "pya") -pyacore_sources = set(glob.glob(os.path.join(pyacore_path, "*.cc"))) - -pya = Extension(config.root + '.pyacore', - define_macros=config.macros(), - include_dirs=[_laybasic_path, - _layview_path, - _lib_path, - _db_path, - _rdb_path, - _img_path, - _ant_path, - _edt_path, - _lym_path, - _tl_path, - _gsi_path, - _pya_path], - extra_objects=[config.path_of('_laybasic', _laybasic_path), - config.path_of('_layview', _layview_path), - config.path_of('_lib', _lib_path), - config.path_of('_db', _db_path), - config.path_of('_rdb', _rdb_path), - config.path_of('_img', _img_path), - config.path_of('_ant', _ant_path), - config.path_of('_edt', _edt_path), - config.path_of('_lym', _lym_path), - config.path_of('_tl', _tl_path), - config.path_of('_gsi', _gsi_path), - config.path_of('_pya', _pya_path)], - extra_link_args=config.link_args('pyacore'), - extra_compile_args=config.compile_args('pyacore'), - sources=list(pyacore_sources)) +# Collect the module spec files with dependent modules coming after +# the dependencies: + +mod_specs = glob.glob(os.path.join("src", "*", "pysetup.toml")) +mod_specs += glob.glob(os.path.join("src", "*", "*", "pysetup.toml")) +mod_specs += glob.glob(os.path.join("src", "*", "*", "*", "pysetup.toml")) +mod_specs += glob.glob(os.path.join("src", "*", "*", "*", "*", "pysetup.toml")) + +todo = mod_specs +while len(todo) > 0: + + not_done = [] + for ms in todo: + p = list(os.path.split(ms)) + p.pop() + if not config.module(None, os.path.join(*p)): + not_done.append(ms) + + if len(not_done) == len(todo): + raise RuntimeError("Dependency resolution failed - circular dependencies?") + + todo = not_done # ------------------------------------------------------------------ # Core setup function @@ -1032,7 +680,7 @@ if __name__ == "__main__": description="KLayout standalone Python package", long_description="This package is a standalone distribution of KLayout's Python API.\n\nFor more details see here: https://www.klayout.org/klayout-pypi", author="Matthias Koefferlein", - author_email="matthias@klayout.de", + author_email="matthias@klayout.org", classifiers=[ # Recommended classifiers "Programming Language :: Python :: 2", @@ -1051,8 +699,6 @@ if __name__ == "__main__": package_data={config.root: ["src/pymod/distutils_src/klayout/*.pyi"]}, data_files=[(config.root, ["src/pymod/distutils_src/klayout/py.typed"])], include_package_data=True, - ext_modules=[_tl, _gsi, _pya, _rba, _db, _pex, _lib, _rdb, _lym, _laybasic, _layview, _ant, _edt, _img] - + db_plugins - + [tl, db, pex, lib, rdb, lay, pya], + ext_modules=config.modules, cmdclass={'build_ext': klayout_build_ext} ) diff --git a/src/ant/ant/pysetup.toml b/src/ant/ant/pysetup.toml new file mode 100644 index 000000000..e6ee15d61 --- /dev/null +++ b/src/ant/ant/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_ant" + defines = [["MAKE_ANT_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db", "_rdb", "_laybasic", "_layview"] + diff --git a/src/buddies/src/bd/bd.pro b/src/buddies/src/bd/bd.pro index 2deeb870f..d3b3faa09 100644 --- a/src/buddies/src/bd/bd.pro +++ b/src/buddies/src/bd/bd.pro @@ -14,6 +14,7 @@ SOURCES = \ strm2cif.cc \ strm2gds.cc \ strm2oas.cc \ + strm2lstr.cc \ strmclip.cc \ strm2dxf.cc \ strm2gdstxt.cc \ diff --git a/src/buddies/src/bd/bdWriterOptions.cc b/src/buddies/src/bd/bdWriterOptions.cc index 2886aef92..251b7b66a 100644 --- a/src/buddies/src/bd/bdWriterOptions.cc +++ b/src/buddies/src/bd/bdWriterOptions.cc @@ -84,11 +84,16 @@ GenericWriterOptions::init_from_options (const db::SaveLayoutOptions &save_optio m_magic_lambda = 1.0; m_dxf_polygon_mode = save_options.get_option_by_name ("dxf_polygon_mode").to_int (); + + m_lstream_compression_level = save_options.get_option_by_name ("lstream_compression_level").to_int (); + m_lstream_recompress = save_options.get_option_by_name ("lstream_recompress").to_bool (); + m_lstream_permissive = save_options.get_option_by_name ("lstream_permissive").to_bool (); } const std::string GenericWriterOptions::gds2_format_name = "GDS2"; const std::string GenericWriterOptions::gds2text_format_name = "GDS2Text"; // no special options const std::string GenericWriterOptions::oasis_format_name = "OASIS"; +const std::string GenericWriterOptions::lstream_format_name = "LStream"; const std::string GenericWriterOptions::dxf_format_name = "DXF"; const std::string GenericWriterOptions::cif_format_name = "CIF"; const std::string GenericWriterOptions::mag_format_name = "MAG"; @@ -277,6 +282,34 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin } + if (format.empty () || format == lstream_format_name) { + + // Add LStream format options + std::string group = "[Output options - LStream specific]"; + + cmd << tl::arg (group + + "-oc|--lstr-compression-level=level", &m_lstream_compression_level, "Specifies the LStream compression level", + "This level describes how hard the LStream writer will try to compress the shapes " + "using shape arrays. Building shape arrays may take some time and requires some memory. " + "The default compression level is 2.\n" + "* 0 - no shape array building\n" + "* 1 - nearest neighbor shape array formation\n" + "* 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well\n" + ) + << tl::arg (group + + "#--lstr-recompress", &m_lstream_recompress, "Compresses shape arrays again", + "With this option, shape arrays will be expanded and recompressed. This may result in a better " + "compression ratio, but at the cost of slower execution." + ) + << tl::arg (group + + "#--lstr-permissive", &m_lstream_permissive, "Permissive mode", + "In permissive mode, certain forbidden objects are reported as warnings, not as errors: " + "paths with odd width, polygons with less than three points etc." + ) + ; + + } + if (format.empty () || format == dxf_format_name) { // Add DXF format options @@ -418,6 +451,10 @@ GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db:: save_options.set_option_by_name ("dxf_polygon_mode", m_dxf_polygon_mode); + save_options.set_option_by_name ("lstream_compression_level", m_lstream_compression_level); + save_options.set_option_by_name ("lstream_recompress", m_lstream_recompress); + save_options.set_option_by_name ("lstream_permissive", m_lstream_permissive); + save_options.set_option_by_name ("mag_lambda", m_magic_lambda); save_options.set_option_by_name ("mag_tech", m_magic_tech); diff --git a/src/buddies/src/bd/bdWriterOptions.h b/src/buddies/src/bd/bdWriterOptions.h index 6ebf61f99..fc55c933e 100644 --- a/src/buddies/src/bd/bdWriterOptions.h +++ b/src/buddies/src/bd/bdWriterOptions.h @@ -108,6 +108,7 @@ public: static const std::string gds2_format_name; static const std::string gds2text_format_name; static const std::string oasis_format_name; + static const std::string lstream_format_name; static const std::string cif_format_name; static const std::string dxf_format_name; static const std::string mag_format_name; @@ -148,6 +149,10 @@ private: int m_dxf_polygon_mode; + int m_lstream_compression_level; + bool m_lstream_recompress; + bool m_lstream_permissive; + void set_oasis_substitution_char (const std::string &text); void init_from_options (const db::SaveLayoutOptions &options); }; diff --git a/src/buddies/src/bd/strm2lstr.cc b/src/buddies/src/bd/strm2lstr.cc new file mode 100644 index 000000000..d6a427005 --- /dev/null +++ b/src/buddies/src/bd/strm2lstr.cc @@ -0,0 +1,29 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "bdConverterMain.h" +#include "bdWriterOptions.h" + +BD_PUBLIC int strm2lstr (int argc, char *argv[]) +{ + return bd::converter_main (argc, argv, bd::GenericWriterOptions::lstream_format_name); +} diff --git a/src/buddies/src/src.pro b/src/buddies/src/src.pro index eb9777725..9cccfd2cf 100644 --- a/src/buddies/src/src.pro +++ b/src/buddies/src/src.pro @@ -8,6 +8,7 @@ SUBDIRS = \ strm2gds \ strm2gdstxt \ strm2oas \ + strm2lstr \ strm2mag \ strm2txt \ strmclip \ @@ -20,6 +21,7 @@ strm2dxf.depends += bd strm2gds.depends += bd strm2gdstxt.depends += bd strm2oas.depends += bd +strm2lstr.depends += bd strm2mag.depends += bd strm2txt.depends += bd strmclip.depends += bd diff --git a/src/buddies/src/strm2lstr/strm2lstr.pro b/src/buddies/src/strm2lstr/strm2lstr.pro new file mode 100644 index 000000000..e04ca961a --- /dev/null +++ b/src/buddies/src/strm2lstr/strm2lstr.pro @@ -0,0 +1,2 @@ + +include($$PWD/../buddy_app.pri) diff --git a/src/buddies/unit_tests/bdConverterTests.cc b/src/buddies/unit_tests/bdConverterTests.cc index cfbd51e03..9e789de9c 100644 --- a/src/buddies/unit_tests/bdConverterTests.cc +++ b/src/buddies/unit_tests/bdConverterTests.cc @@ -187,6 +187,31 @@ TEST(6) db::compare_layouts (this, layout, input_au, db::WriteGDS2); } +// Testing the converter main implementation (LStream) +TEST(7) +{ + std::string input = tl::testdata (); + input += "/gds/t10.gds"; + + std::string output = this->tmp_file (); + + const char *argv[] = { "x", input.c_str (), output.c_str () }; + + EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::lstream_format_name), 0); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::LoadLayoutOptions options; + db::Reader reader (stream); + reader.read (layout, options); + EXPECT_EQ (reader.format (), "LStream"); + } + + db::compare_layouts (this, layout, input, db::NoNormalization); +} + // Large LEF/DEF to OAS converter test TEST(10) { diff --git a/src/db/db/dbLibrary.cc b/src/db/db/dbLibrary.cc index a21736702..3c4c20097 100644 --- a/src/db/db/dbLibrary.cc +++ b/src/db/db/dbLibrary.cc @@ -149,7 +149,15 @@ void Library::rename (const std::string &name) { if (name != get_name () && db::LibraryManager::initialized ()) { + + std::pair n2l = db::LibraryManager::instance ().lib_by_name (name, get_technologies ()); + if (n2l.first && n2l.second != get_id ()) { + // remove any existing library that has our target name/tech combination + db::LibraryManager::instance ().delete_lib (db::LibraryManager::instance ().lib (n2l.second)); + } + db::LibraryManager::instance ().rename (get_id (), name); + } } diff --git a/src/db/db/dbPLC.cc b/src/db/db/dbPLC.cc index 07b7b8fa5..8fb64104d 100644 --- a/src/db/db/dbPLC.cc +++ b/src/db/db/dbPLC.cc @@ -110,6 +110,17 @@ Vertex::is_outside () const return false; } +bool +Vertex::is_on_outline () const +{ + for (auto e = mp_edges.begin (); e != mp_edges.end (); ++e) { + if ((*e)->is_segment ()) { + return true; + } + } + return false; +} + void Vertex::set_is_precious (bool f, unsigned int id) { diff --git a/src/db/db/dbPLC.h b/src/db/db/dbPLC.h index 6a65e61d1..275277c70 100644 --- a/src/db/db/dbPLC.h +++ b/src/db/db/dbPLC.h @@ -96,6 +96,11 @@ public: */ bool is_outside () const; + /** + * @brief Gets a value indicating whether is on the outline - i.e. one edge is a segment + */ + bool is_on_outline () const; + /** * @brief Gets a list of polygons that are attached to this vertex */ diff --git a/src/db/db/dbPLCConvexDecomposition.cc b/src/db/db/dbPLCConvexDecomposition.cc index 17b664cb5..17a482462 100644 --- a/src/db/db/dbPLCConvexDecomposition.cc +++ b/src/db/db/dbPLCConvexDecomposition.cc @@ -31,6 +31,8 @@ #include #include +// #define DEBUG_DUMP_ESSENTIAL_EDGES + namespace db { @@ -286,65 +288,134 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C // them one-by-one, but using them in length order, from the std::unordered_set essential_edges; + std::unordered_set concave_vertexes_seen; - typedef std::list > angles_and_edges_list; - angles_and_edges_list angles_and_edges; - std::vector sorted_edges; + while (! concave_vertexes.empty ()) { - for (auto cc = concave_vertexes.begin (); cc != concave_vertexes.end (); ++cc) { + typedef std::list > angles_and_edges_list; + angles_and_edges_list angles_and_edges; + std::vector sorted_edges; - angles_and_edges.clear (); - const Vertex *v0 = cc->corner; + std::unordered_set new_inner_vertexes; - const Edge *e = cc->incoming; - while (e) { + for (auto cc = concave_vertexes.begin (); cc != concave_vertexes.end (); ++cc) { - const Polygon *t = e->v2 () == v0 ? e->right () : e->left (); - tl_assert (t != 0); + angles_and_edges.clear (); + const Vertex *v0 = cc->corner; - const Edge *en = t->next_edge (e, v0); - tl_assert (en != 0); + concave_vertexes_seen.insert (v0); - db::DVector v1 = e->edge ().d () * (e->v1 () == v0 ? 1.0 : -1.0); - db::DVector v2 = en->edge ().d () * (en->v1 () == v0 ? 1.0 : -1.0); + const Edge *e = cc->incoming; + while (e) { - double angle = atan2 (db::vprod (v1, v2), db::sprod (v1, v2)); + const Polygon *t = e->v2 () == v0 ? e->right () : e->left (); + tl_assert (t != 0); - e = (en == cc->outgoing) ? 0 : en; - angles_and_edges.push_back (std::make_pair (angle, e)); + const Edge *en = t->next_edge (e, v0); + tl_assert (en != 0); + + db::DVector v1 = e->edge ().d () * (e->v1 () == v0 ? 1.0 : -1.0); + db::DVector v2 = en->edge ().d () * (en->v1 () == v0 ? 1.0 : -1.0); + + double angle = atan2 (db::vprod (v1, v2), db::sprod (v1, v2)); + + e = (en == cc->outgoing) ? 0 : en; + angles_and_edges.push_back (std::make_pair (angle, e)); + + } + + sorted_edges.clear (); + + for (auto i = angles_and_edges.begin (); i != angles_and_edges.end (); ++i) { + if (i->second) { + sorted_edges.push_back (i); + } + } + + std::sort (sorted_edges.begin (), sorted_edges.end (), SortAngleAndEdgesByEdgeLength ()); + + for (auto i = sorted_edges.end (); i != sorted_edges.begin (); ) { + --i; + angles_and_edges_list::iterator ii = *i; + angles_and_edges_list::iterator iin = ii; + ++iin; + if (ii->first + iin->first < (split_edges ? M_PI + db::epsilon : M_PI - db::epsilon)) { + // not an essential edge -> remove + iin->first += ii->first; + angles_and_edges.erase (ii); + } + } + + for (auto i = angles_and_edges.begin (); i != angles_and_edges.end (); ++i) { + if (i->second) { + essential_edges.insert (i->second); + // record new endpoints of essential edges which are inside the polygon - i.e. they + // have a segment attached. Below we will turn them into new concave "corners" and + // continue deriving essential edges from there. + if (! i->second->v1 ()->is_on_outline () && concave_vertexes_seen.find (i->second->v1 ()) == concave_vertexes_seen.end ()) { + new_inner_vertexes.insert (i->second->v1 ()); + } + if (! i->second->v2 ()->is_on_outline () && concave_vertexes_seen.find (i->second->v2 ()) == concave_vertexes_seen.end ()) { + new_inner_vertexes.insert (i->second->v2 ()); + } + } + } } - sorted_edges.clear (); + // new inner vertexes (i.e. endpoints of essential edges inside the polygon) are treated as new convex vertexes - for (auto i = angles_and_edges.begin (); i != angles_and_edges.end (); ++i) { - if (i->second) { - sorted_edges.push_back (i); - } - } + concave_vertexes.clear (); - std::sort (sorted_edges.begin (), sorted_edges.end (), SortAngleAndEdgesByEdgeLength ()); + for (auto i = new_inner_vertexes.begin (); i != new_inner_vertexes.end (); ++i) { - for (auto i = sorted_edges.end (); i != sorted_edges.begin (); ) { - --i; - angles_and_edges_list::iterator ii = *i; - angles_and_edges_list::iterator iin = ii; - ++iin; - if (ii->first + iin->first < (split_edges ? M_PI + db::epsilon : M_PI - db::epsilon)) { - // not an essential edge -> remove - iin->first += ii->first; - angles_and_edges.erase (ii); - } - } + const Vertex *v0 = *i; + auto ie = v0->begin_edges (); + for ( ; ie != v0->end_edges () && essential_edges.find (*ie) == essential_edges.end (); ++ie) + ; + tl_assert (ie != v0->end_edges ()); + const Edge *e = *ie; - for (auto i = angles_and_edges.begin (); i != angles_and_edges.end (); ++i) { - if (i->second) { - essential_edges.insert (i->second); - } + const Edge *en = e; + + do { + + const Edge *enn = en; + + // look for the next edge (clockwise) which is an essential edge + do { + const Polygon *t = enn->v2 () == v0 ? enn->right () : enn->left (); + tl_assert (t != 0); + enn = t->next_edge (enn, v0); + tl_assert (enn != 0); + } while (enn != en && essential_edges.find (enn) == essential_edges.end ()); + + db::DEdge e1 (*en->other (v0), *v0); + db::DEdge e2 (*v0, *enn->other (v0)); + + // vp > 0: concave, vp < 0: convex + int vp_sign = db::vprod_sign (e1, e2); + if (vp_sign > 0 || en == enn /*folding back*/) { + concave_vertexes.push_back (ConcaveCorner (v0, en, enn)); + } + + en = enn; + + } while (en != e); } } +#if defined(DEBUG_DUMP_ESSENTIAL_EDGES) + // dump the essential edges for debugging + db::Edges edges; + for (auto e = essential_edges.begin (); e != essential_edges.end (); ++e) { + db::DEdge de = (*e)->edge (); + edges.insert (db::VCplxTrans (1000.0) * de); + } + edges.write ("debug_dump_essential_edges.gds"); +#endif + // Combine triangles, but don't cross essential edges std::unordered_set left_triangles; diff --git a/src/db/db/dbPLCConvexDecomposition.h b/src/db/db/dbPLCConvexDecomposition.h index d236a29ef..8e1c6ba3b 100644 --- a/src/db/db/dbPLCConvexDecomposition.h +++ b/src/db/db/dbPLCConvexDecomposition.h @@ -136,14 +136,14 @@ private: // .. nothing yet .. } - ConcaveCorner (Vertex *_corner, Edge *_incoming, Edge *_outgoing) + ConcaveCorner (const Vertex *_corner, const Edge *_incoming, const Edge *_outgoing) : corner (_corner), incoming (_incoming), outgoing (_outgoing) { // .. nothing yet .. } - Vertex *corner; - Edge *incoming, *outgoing; + const Vertex *corner; + const Edge *incoming, *outgoing; }; void hertel_mehlhorn_decomposition (Triangulation &tris, const ConvexDecompositionParameters ¶m); diff --git a/src/db/db/dbSaveLayoutOptions.cc b/src/db/db/dbSaveLayoutOptions.cc index a7f990a67..3bdfdbf7c 100644 --- a/src/db/db/dbSaveLayoutOptions.cc +++ b/src/db/db/dbSaveLayoutOptions.cc @@ -275,9 +275,15 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector >::const_iterator l = all_layers.begin (); l != all_layers.end (); ++l) { + for (auto l = all_layers.begin (); l != all_layers.end (); ++l) { + layers.push_back (*l); + } + + } else if (lm == LP_OnlyNumbered) { + + for (auto l = all_layers.begin (); l != all_layers.end (); ++l) { if (l->second.layer >= 0 && l->second.datatype >= 0) { layers.push_back (*l); } @@ -285,7 +291,7 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector >::const_iterator l = all_layers.begin (); l != all_layers.end (); ++l) { + for (auto l = all_layers.begin (); l != all_layers.end (); ++l) { if (! l->second.name.empty ()) { layers.push_back (*l); } @@ -293,7 +299,7 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector >::const_iterator l = all_layers.begin (); l != all_layers.end (); ++l) { + for (auto l = all_layers.begin (); l != all_layers.end (); ++l) { layers.push_back (*l); if (l->second.name.empty ()) { layers.back ().second = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype); @@ -304,7 +310,7 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector >::const_iterator l = all_layers.begin (); l != all_layers.end (); ++l) { + for (auto l = all_layers.begin (); l != all_layers.end (); ++l) { layers.push_back (*l); if (l->second.name.empty ()) { layers.back ().second = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype); diff --git a/src/db/db/dbSaveLayoutOptions.h b/src/db/db/dbSaveLayoutOptions.h index 9916cf4c0..2279cb850 100644 --- a/src/db/db/dbSaveLayoutOptions.h +++ b/src/db/db/dbSaveLayoutOptions.h @@ -405,7 +405,8 @@ public: LP_OnlyNamed = 1, LP_AssignName = 2, LP_AssignNameWithPriority = 3, - LP_AssignNumber = 4 + LP_AssignNumber = 4, + LP_AsIs = 5 }; /** diff --git a/src/db/db/pysetup.toml b/src/db/db/pysetup.toml new file mode 100644 index 000000000..6d5b3c15e --- /dev/null +++ b/src/db/db/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_db" + defines = [["MAKE_DB_LIBRARY", 1]] + depends = ["_tl", "_gsi"] + diff --git a/src/db/unit_tests/dbPLCConvexDecompositionTests.cc b/src/db/unit_tests/dbPLCConvexDecompositionTests.cc index 22b8282b6..c1118a764 100644 --- a/src/db/unit_tests/dbPLCConvexDecompositionTests.cc +++ b/src/db/unit_tests/dbPLCConvexDecompositionTests.cc @@ -23,6 +23,8 @@ #include "dbPLCConvexDecomposition.h" #include "dbWriter.h" +#include "dbReader.h" +#include "dbLayout.h" #include "dbRegionProcessors.h" #include "dbTestSupport.h" #include "tlUnitTest.h" @@ -144,3 +146,80 @@ TEST(problematic_polygon) db::compare_layouts (_this, *ly, tl::testdata () + "/algo/hm_decomposition_au5.gds"); } +TEST(problematic_polygon2) +{ + db::Point contour[] = { + db::Point (-2100, 200), + db::Point (-2100, 2000), + db::Point (-500, 2000), + db::Point (-500, 1700), + db::Point (-849, 1700), + db::Point (-947, 1690), + db::Point (-1043, 1671), + db::Point (-1137, 1643), + db::Point (-1228, 1605), + db::Point (-1315, 1559), + db::Point (-1396, 1504), + db::Point (-1472, 1442), + db::Point (-1542, 1372), + db::Point (-1604, 1296), + db::Point (-1659, 1215), + db::Point (-1705, 1128), + db::Point (-1743, 1037), + db::Point (-1771, 943), + db::Point (-1790, 847), + db::Point (-1800, 749), + db::Point (-1800, 200) + }; + + db::Polygon poly; + poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0])); + + double dbu = 0.001; + + db::plc::ConvexDecompositionParameters param; + param.with_segments = false; + param.split_edges = false; + param.tri_param.max_area = 1000000; + param.tri_param.min_b = 0.5; + + db::plc::Graph plc; + TestableConvexDecomposition decomp (&plc); + + decomp.decompose (poly, param, dbu); + + std::unique_ptr ly (plc.to_layout ()); + db::compare_layouts (_this, *ly, tl::testdata () + "/algo/hm_decomposition_au6.gds"); +} + +TEST(polygon_with_holes) +{ + db::Layout ly; + tl::InputStream s (tl::testdata () + "/algo/hm_decomposition_7.gds"); + db::Reader reader (s); + reader.read (ly); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + const db::Cell &top = ly.cell (*ly.begin_top_down ()); + + db::Region r (db::RecursiveShapeIterator (ly, top, l1)); + r.merge (); + db::Polygon poly = *r.begin (); + + double dbu = 0.001; + + db::plc::ConvexDecompositionParameters param; + param.with_segments = false; + param.split_edges = false; + param.tri_param.max_area = 1000000; + param.tri_param.min_b = 0.5; + + db::plc::Graph plc; + TestableConvexDecomposition decomp (&plc); + + decomp.decompose (poly, param, dbu); + + std::unique_ptr ly_out (plc.to_layout ()); + db::compare_layouts (_this, *ly_out, tl::testdata () + "/algo/hm_decomposition_au7.gds"); +} + diff --git a/src/edt/edt/pysetup.toml b/src/edt/edt/pysetup.toml new file mode 100644 index 000000000..ccb264c4f --- /dev/null +++ b/src/edt/edt/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_edt" + defines = [["MAKE_EDT_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db", "_rdb", "_laybasic", "_layview"] + diff --git a/src/gsi/gsi/pysetup.toml b/src/gsi/gsi/pysetup.toml new file mode 100644 index 000000000..0343b6dd7 --- /dev/null +++ b/src/gsi/gsi/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_gsi" + defines = [["MAKE_GSI_LIBRARY", 1]] + depends = ["_tl"] + diff --git a/src/img/img/pysetup.toml b/src/img/img/pysetup.toml new file mode 100644 index 000000000..a166899e9 --- /dev/null +++ b/src/img/img/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_img" + defines = [["MAKE_IMG_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db", "_rdb", "_laybasic", "_layview"] + diff --git a/src/laybasic/laybasic/laySnap.cc b/src/laybasic/laybasic/laySnap.cc index 2726c981f..c588a1703 100644 --- a/src/laybasic/laybasic/laySnap.cc +++ b/src/laybasic/laybasic/laySnap.cc @@ -613,7 +613,7 @@ private: if (shape->is_polygon ()) { for (db::Shape::polygon_edge_iterator e = shape->begin_edge (); ! e.at_end (); ++e) { - test_edge (t * *e); + test_edge_with_center (t * *e); } } else if (shape->is_path ()) { @@ -649,16 +649,20 @@ private: } test_edge (db::DEdge (*p, pts [0])); + } } else if (shape->is_box ()) { const db::Box &box = shape->box (); - test_edge (t * db::Edge (box.p1 (), db::Point (box.left (), box.top ()))); - test_edge (t * db::Edge (db::Point (box.left (), box.top ()), box.p2 ())); - test_edge (t * db::Edge (box.p2 (), db::Point (box.right (), box.bottom ()))); - test_edge (t * db::Edge (db::Point (box.right (), box.bottom ()), box.p1 ())); + test_edge_with_center (t * db::Edge (box.p1 (), db::Point (box.left (), box.top ()))); + test_edge_with_center (t * db::Edge (db::Point (box.left (), box.top ()), box.p2 ())); + test_edge_with_center (t * db::Edge (box.p2 (), db::Point (box.right (), box.bottom ()))); + test_edge_with_center (t * db::Edge (db::Point (box.right (), box.bottom ()), box.p1 ())); + + // test for box center + test_edge (t * db::Edge (box.center (), box.center ())); } else if (shape->is_point ()) { @@ -697,6 +701,22 @@ private: } + void + test_edge_with_center (const db::DEdge &edg) + { + if (m_with_vertex && ! edg.is_degenerate ()) { + + db::DPoint c = edg.p1 () + (edg.p2 () - edg.p1 ()) * 0.5; + + if (m_region.contains (c)) { + closest (c); + } + + } + + test_edge (edg); + } + void test_edge (const db::DEdge &edg) { diff --git a/src/laybasic/laybasic/pysetup.toml b/src/laybasic/laybasic/pysetup.toml new file mode 100644 index 000000000..2970f1887 --- /dev/null +++ b/src/laybasic/laybasic/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_laybasic" + defines = [["MAKE_LAYBASIC_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db", "_rdb"] + diff --git a/src/laybasic/unit_tests/laySnapTests.cc b/src/laybasic/unit_tests/laySnapTests.cc index 00a9271a6..e208e8fe9 100644 --- a/src/laybasic/unit_tests/laySnapTests.cc +++ b/src/laybasic/unit_tests/laySnapTests.cc @@ -58,8 +58,12 @@ TEST(1) EXPECT_EQ (res.object_snap, lay::PointSnapToObjectResult::NoObject); EXPECT_EQ (res.snapped_point.to_string (), "1.505,1.505"); - res = lay::obj_snap (&view, db::DPoint (0.505, 0.505), db::DVector (), 0.1); + res = lay::obj_snap (&view, db::DPoint (0.805, 0.205), db::DVector (), 0.1); EXPECT_EQ (res.object_snap, lay::PointSnapToObjectResult::ObjectEdge); + EXPECT_EQ (res.snapped_point.to_string (), "0.8,0.2"); + + res = lay::obj_snap (&view, db::DPoint (0.505, 0.505), db::DVector (), 0.1); + EXPECT_EQ (res.object_snap, lay::PointSnapToObjectResult::ObjectUnspecific); // center point of edge EXPECT_EQ (res.snapped_point.to_string (), "0.5,0.5"); res = lay::obj_snap (&view, db::DPoint (0.485, 0.505), db::DVector (0.01, 0.01), 0.1); @@ -83,9 +87,9 @@ TEST(1) EXPECT_EQ (res.object_snap, lay::PointSnapToObjectResult::ObjectVertex); EXPECT_EQ (res.snapped_point.to_string (), "0,1"); - res = lay::obj_snap (&view, db::DPoint (1.000, 0.505), db::DPoint (0.505, 0.500), db::DVector (), lay::AC_Horizontal, 0.1); + res = lay::obj_snap (&view, db::DPoint (1.000, 0.605), db::DPoint (0.405, 0.600), db::DVector (), lay::AC_Horizontal, 0.1); EXPECT_EQ (res.object_snap, lay::PointSnapToObjectResult::ObjectEdge); - EXPECT_EQ (res.snapped_point.to_string (), "0.495,0.505"); + EXPECT_EQ (res.snapped_point.to_string (), "0.395,0.605"); // projected snapping res = lay::obj_snap (&view, db::DPoint (1.000, 0.505), db::DPoint (0.005, 1.005), db::DVector (), lay::AC_Horizontal, 0.1); @@ -132,21 +136,32 @@ TEST(1) EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0.355,0.645;0,0.29)"); res2 = lay::obj_snap2 (&view, db::DPoint (0.5, 0.5), db::DVector (), 0.005, 1.0); + EXPECT_EQ (res2.any, true); + EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0.5,0.5;0.5,0.5)"); + + res2 = lay::obj_snap2 (&view, db::DPoint (0.6, 0.4), db::DVector (), 0.005, 1.0); EXPECT_EQ (res2.any, false); EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0;0,0)"); res2 = lay::obj_snap2 (&view, db::DPoint (0.005, 0.5), db::DVector (), 0.005, 1.0); EXPECT_EQ (res2.any, true); - EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0.5;0.5,0.5)"); + EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0.5;0,0.5)"); - res2 = lay::obj_snap2 (&view, db::DPoint (0.0, 0.5), db::DVector (), 0.005, 1.0); + res2 = lay::obj_snap2 (&view, db::DPoint (0.005, 0.4), db::DVector (), 0.005, 1.0); + EXPECT_EQ (res2.any, true); + EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0.4;0.6,0.4)"); + + res2 = lay::obj_snap2 (&view, db::DPoint (0.0, 0.4), db::DVector (), 0.005, 1.0); EXPECT_EQ (res2.any, false); EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0;0,0)"); res2 = lay::obj_snap2 (&view, db::DPoint (-0.2, 0.5), db::DVector (), 0.005, 1.0); + EXPECT_EQ (res2.any, true); + EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0.5;0,0.5)"); + + res2 = lay::obj_snap2 (&view, db::DPoint (-0.2, 0.4), db::DVector (), 0.005, 1.0); EXPECT_EQ (res2.any, false); EXPECT_EQ (db::DEdge (res2.first, res2.second).to_string (), "(0,0;0,0)"); - } // .. TODO: implement .. diff --git a/src/layview/layview/pysetup.toml b/src/layview/layview/pysetup.toml new file mode 100644 index 000000000..9ccb9f065 --- /dev/null +++ b/src/layview/layview/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_layview" + defines = [["MAKE_LAYVIEW_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db", "_rdb", "_laybasic"] + diff --git a/src/lib/lib/pysetup.toml b/src/lib/lib/pysetup.toml new file mode 100644 index 000000000..a89de4a01 --- /dev/null +++ b/src/lib/lib/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_lib" + defines = [["MAKE_LIB_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db"] + diff --git a/src/lym/lym/pysetup.toml b/src/lym/lym/pysetup.toml new file mode 100644 index 000000000..abb141f06 --- /dev/null +++ b/src/lym/lym/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_lym" + defines = [["MAKE_LYM_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_rba", "_pya"] + diff --git a/src/pex/pex/pysetup.toml b/src/pex/pex/pysetup.toml new file mode 100644 index 000000000..41dd952c5 --- /dev/null +++ b/src/pex/pex/pysetup.toml @@ -0,0 +1,6 @@ + +[library] + name = "_pex" + defines = [["MAKE_PEX_LIBRARY", 1]] + depends = ["_tl", "_gsi", "_db"] + diff --git a/src/plugins/streamers/cif/db_plugin/dbCIF.cc b/src/plugins/streamers/cif/db_plugin/dbCIF.cc index 3aff1e5f7..69ed925fb 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIF.cc +++ b/src/plugins/streamers/cif/db_plugin/dbCIF.cc @@ -72,6 +72,14 @@ public: // by the stream and won't trigger a reset of the stream which is not available // on some sources. std::string head = s.read_all (4000); + + // CIF files must not contain null characters + for (auto c = head.begin (); c != head.end (); ++c) { + if (*c == 0) { + return false; + } + } + int n = 0; tl::Extractor ex (head.c_str ()); diff --git a/src/plugins/streamers/cif/db_plugin/pysetup.toml b/src/plugins/streamers/cif/db_plugin/pysetup.toml new file mode 100644 index 000000000..472d6593d --- /dev/null +++ b/src/plugins/streamers/cif/db_plugin/pysetup.toml @@ -0,0 +1,8 @@ + +[library] + name = "_cif_dbpi" + defines = [["MAKE_DB_PLUGIN_LIBRARY", 1]] + depends = ["_tl", "_db", "_gsi"] + includes = ["/src/plugins/common"] + submodules = ["db_plugins"] + diff --git a/src/plugins/streamers/dxf/db_plugin/pysetup.toml b/src/plugins/streamers/dxf/db_plugin/pysetup.toml new file mode 100644 index 000000000..881131099 --- /dev/null +++ b/src/plugins/streamers/dxf/db_plugin/pysetup.toml @@ -0,0 +1,8 @@ + +[library] + name = "_dxf_dbpi" + defines = [["MAKE_DB_PLUGIN_LIBRARY", 1]] + depends = ["_tl", "_db", "_gsi"] + includes = ["/src/plugins/common"] + submodules = ["db_plugins"] + diff --git a/src/plugins/streamers/gds2/db_plugin/pysetup.toml b/src/plugins/streamers/gds2/db_plugin/pysetup.toml new file mode 100644 index 000000000..dc79ea549 --- /dev/null +++ b/src/plugins/streamers/gds2/db_plugin/pysetup.toml @@ -0,0 +1,9 @@ + +[library] + name = "_gds2_dbpi" + defines = [["MAKE_DB_PLUGIN_LIBRARY", 1]] + depends = ["_tl", "_db", "_gsi"] + includes = ["/src/plugins/common"] + submodules = ["db_plugins"] + sources = ["contrib"] + diff --git a/src/plugins/streamers/lefdef/db_plugin/pysetup.toml b/src/plugins/streamers/lefdef/db_plugin/pysetup.toml new file mode 100644 index 000000000..a94f7b8d9 --- /dev/null +++ b/src/plugins/streamers/lefdef/db_plugin/pysetup.toml @@ -0,0 +1,8 @@ + +[library] + name = "_lefdef_dbpi" + defines = [["MAKE_DB_PLUGIN_LIBRARY", 1]] + depends = ["_tl", "_db", "_gsi"] + includes = ["/src/plugins/common"] + submodules = ["db_plugins"] + diff --git a/src/plugins/streamers/lstream/db_plugin/README.md b/src/plugins/streamers/lstream/db_plugin/README.md new file mode 100644 index 000000000..98e9a5cbb --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/README.md @@ -0,0 +1,16 @@ + +# LStream plugin sources + +This plugin employs Cap'n'Proto (https://capnproto.org/) to implement +the serialization layer. + +The schema files are provided in an already compiled form. +The provided sources use Cap'n'Proto compiler version 1.0.1. + +Use the `capnp_compile.sh` script to compile the schema files +into C++. It requires "capnp" version 1.0.1. + +The original LStream sources are kept somewhere else. +Use `fetch.sh` to sync these external sources with the local +ones. + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/capnp.pri b/src/plugins/streamers/lstream/db_plugin/capnp/capnp.pri new file mode 100644 index 000000000..234504d30 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/capnp.pri @@ -0,0 +1,25 @@ + +HEADERS=\ + capnp/cell.capnp.h \ + capnp/geometry.capnp.h \ + capnp/header.capnp.h \ + capnp/layoutView.capnp.h \ + capnp/library.capnp.h \ + capnp/metaData.capnp.h \ + capnp/metaDataView.capnp.h \ + capnp/propertySet.capnp.h \ + capnp/repetition.capnp.h \ + capnp/variant.capnp.h \ + +SOURCES=\ + capnp/cell.capnp.cc \ + capnp/geometry.capnp.cc \ + capnp/header.capnp.cc \ + capnp/layoutView.capnp.cc \ + capnp/library.capnp.cc \ + capnp/metaData.capnp.cc \ + capnp/metaDataView.capnp.cc \ + capnp/propertySet.capnp.cc \ + capnp/repetition.capnp.cc \ + capnp/variant.capnp.cc \ + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/cell.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/cell.capnp.cc new file mode 100644 index 000000000..0692e027a --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/cell.capnp.cc @@ -0,0 +1,77 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: cell.capnp + +#include "cell.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<35> b_f29d05b618de9054 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 84, 144, 222, 24, 182, 5, 157, 242, + 11, 0, 0, 0, 1, 0, 0, 0, + 239, 93, 77, 24, 100, 238, 216, 191, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 130, 0, 0, 0, + 25, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 101, 108, 108, 46, 99, 97, 112, + 110, 112, 58, 67, 101, 108, 108, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 36, 0, 0, 0, 2, 0, 1, 0, + 118, 105, 101, 119, 73, 100, 115, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_f29d05b618de9054 = b_f29d05b618de9054.words; +#if !CAPNP_LITE +static const uint16_t m_f29d05b618de9054[] = {0}; +static const uint16_t i_f29d05b618de9054[] = {0}; +const ::capnp::_::RawSchema s_f29d05b618de9054 = { + 0xf29d05b618de9054, b_f29d05b618de9054.words, 35, nullptr, m_f29d05b618de9054, + 0, 1, i_f29d05b618de9054, nullptr, nullptr, { &s_f29d05b618de9054, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace cell { + +// Cell +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Cell::_capnpPrivate::dataWordSize; +constexpr uint16_t Cell::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Cell::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Cell::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/cell.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/cell.capnp.h new file mode 100644 index 000000000..8f94bba2a --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/cell.capnp.h @@ -0,0 +1,172 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: cell.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(f29d05b618de9054); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace cell { + +struct Cell { + Cell() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f29d05b618de9054, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class Cell::Reader { +public: + typedef Cell Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasViewIds() const; + inline ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Reader getViewIds() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Cell::Builder { +public: + typedef Cell Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasViewIds(); + inline ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Builder getViewIds(); + inline void setViewIds( ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Reader value); + inline void setViewIds(::kj::ArrayPtr value); + inline ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Builder initViewIds(unsigned int size); + inline void adoptViewIds(::capnp::Orphan< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>> disownViewIds(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Cell::Pipeline { +public: + typedef Cell Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline bool Cell::Reader::hasViewIds() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Cell::Builder::hasViewIds() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Reader Cell::Reader::getViewIds() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Builder Cell::Builder::getViewIds() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Cell::Builder::setViewIds( ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline void Cell::Builder::setViewIds(::kj::ArrayPtr value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>::Builder Cell::Builder::initViewIds(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Cell::Builder::adoptViewIds( + ::capnp::Orphan< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>> Cell::Builder::disownViewIds() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint16_t, ::capnp::Kind::PRIMITIVE>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/geometry.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/geometry.capnp.cc new file mode 100644 index 000000000..9128556f7 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/geometry.capnp.cc @@ -0,0 +1,1078 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: geometry.capnp + +#include "geometry.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<51> b_cca8143497519117 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 23, 145, 81, 151, 52, 20, 168, 204, + 15, 0, 0, 0, 2, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 50, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 199, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 70, + 105, 120, 80, 111, 105, 110, 116, 84, + 114, 97, 110, 115, 102, 111, 114, 109, + 97, 116, 105, 111, 110, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 32, 0, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 89, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 65, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 48, 0, 0, 0, 0, 0, 0, + 114, 57, 48, 0, 0, 0, 0, 0, + 114, 49, 56, 48, 0, 0, 0, 0, + 114, 50, 55, 48, 0, 0, 0, 0, + 109, 48, 0, 0, 0, 0, 0, 0, + 109, 52, 53, 0, 0, 0, 0, 0, + 109, 57, 48, 0, 0, 0, 0, 0, + 109, 49, 51, 53, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_cca8143497519117 = b_cca8143497519117.words; +#if !CAPNP_LITE +static const uint16_t m_cca8143497519117[] = {4, 7, 5, 6, 0, 2, 3, 1}; +const ::capnp::_::RawSchema s_cca8143497519117 = { + 0xcca8143497519117, b_cca8143497519117.words, 51, nullptr, m_cca8143497519117, + 0, 8, nullptr, nullptr, nullptr, { &s_cca8143497519117, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +CAPNP_DEFINE_ENUM(FixPointTransformation_cca8143497519117, cca8143497519117); +static const ::capnp::_::AlignedData<47> b_c3ea9d0d831017a9 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 15, 0, 0, 0, 1, 0, 2, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 178, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 86, + 101, 99, 116, 111, 114, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 100, 120, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 121, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c3ea9d0d831017a9 = b_c3ea9d0d831017a9.words; +#if !CAPNP_LITE +static const uint16_t m_c3ea9d0d831017a9[] = {0, 1}; +static const uint16_t i_c3ea9d0d831017a9[] = {0, 1}; +const ::capnp::_::RawSchema s_c3ea9d0d831017a9 = { + 0xc3ea9d0d831017a9, b_c3ea9d0d831017a9.words, 47, nullptr, m_c3ea9d0d831017a9, + 0, 2, i_c3ea9d0d831017a9, nullptr, nullptr, { &s_c3ea9d0d831017a9, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_a216252a878a7c50 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 80, 124, 138, 135, 42, 37, 22, 162, + 15, 0, 0, 0, 1, 0, 2, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 170, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 80, + 111, 105, 110, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 120, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_a216252a878a7c50 = b_a216252a878a7c50.words; +#if !CAPNP_LITE +static const uint16_t m_a216252a878a7c50[] = {0, 1}; +static const uint16_t i_a216252a878a7c50[] = {0, 1}; +const ::capnp::_::RawSchema s_a216252a878a7c50 = { + 0xa216252a878a7c50, b_a216252a878a7c50.words, 47, nullptr, m_a216252a878a7c50, + 0, 2, i_a216252a878a7c50, nullptr, nullptr, { &s_a216252a878a7c50, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_b07a0bb15b04919e = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 158, 145, 4, 91, 177, 11, 122, 176, + 15, 0, 0, 0, 1, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 154, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 66, + 111, 120, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 112, 49, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 80, 124, 138, 135, 42, 37, 22, 162, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 101, 108, 116, 97, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b07a0bb15b04919e = b_b07a0bb15b04919e.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_b07a0bb15b04919e[] = { + &s_a216252a878a7c50, + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_b07a0bb15b04919e[] = {1, 0}; +static const uint16_t i_b07a0bb15b04919e[] = {0, 1}; +const ::capnp::_::RawSchema s_b07a0bb15b04919e = { + 0xb07a0bb15b04919e, b_b07a0bb15b04919e.words, 47, d_b07a0bb15b04919e, m_b07a0bb15b04919e, + 2, 2, i_b07a0bb15b04919e, nullptr, nullptr, { &s_b07a0bb15b04919e, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_d3ad7560ad4c7c5a = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 90, 124, 76, 173, 96, 117, 173, 211, + 15, 0, 0, 0, 1, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 162, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 69, + 100, 103, 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 112, 49, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 80, 124, 138, 135, 42, 37, 22, 162, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 101, 108, 116, 97, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_d3ad7560ad4c7c5a = b_d3ad7560ad4c7c5a.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_d3ad7560ad4c7c5a[] = { + &s_a216252a878a7c50, + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_d3ad7560ad4c7c5a[] = {1, 0}; +static const uint16_t i_d3ad7560ad4c7c5a[] = {0, 1}; +const ::capnp::_::RawSchema s_d3ad7560ad4c7c5a = { + 0xd3ad7560ad4c7c5a, b_d3ad7560ad4c7c5a.words, 47, d_d3ad7560ad4c7c5a, m_d3ad7560ad4c7c5a, + 2, 2, i_d3ad7560ad4c7c5a, nullptr, nullptr, { &s_d3ad7560ad4c7c5a, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_dc8843c995bed8b6 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 182, 216, 190, 149, 201, 67, 136, 220, + 15, 0, 0, 0, 1, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 194, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 69, + 100, 103, 101, 80, 97, 105, 114, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 101, 49, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 90, 124, 76, 173, 96, 117, 173, 211, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 50, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 90, 124, 76, 173, 96, 117, 173, 211, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_dc8843c995bed8b6 = b_dc8843c995bed8b6.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_dc8843c995bed8b6[] = { + &s_d3ad7560ad4c7c5a, +}; +static const uint16_t m_dc8843c995bed8b6[] = {0, 1}; +static const uint16_t i_dc8843c995bed8b6[] = {0, 1}; +const ::capnp::_::RawSchema s_dc8843c995bed8b6 = { + 0xdc8843c995bed8b6, b_dc8843c995bed8b6.words, 47, d_dc8843c995bed8b6, m_dc8843c995bed8b6, + 1, 2, i_dc8843c995bed8b6, nullptr, nullptr, { &s_dc8843c995bed8b6, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<51> b_8566986b2d886668 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 104, 102, 136, 45, 107, 152, 102, 133, + 15, 0, 0, 0, 1, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 186, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 67, + 111, 110, 116, 111, 117, 114, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 68, 0, 0, 0, 2, 0, 1, 0, + 112, 49, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 80, 124, 138, 135, 42, 37, 22, 162, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 101, 108, 116, 97, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_8566986b2d886668 = b_8566986b2d886668.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_8566986b2d886668[] = { + &s_a216252a878a7c50, + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_8566986b2d886668[] = {1, 0}; +static const uint16_t i_8566986b2d886668[] = {0, 1}; +const ::capnp::_::RawSchema s_8566986b2d886668 = { + 0x8566986b2d886668, b_8566986b2d886668.words, 51, d_8566986b2d886668, m_8566986b2d886668, + 2, 2, i_8566986b2d886668, nullptr, nullptr, { &s_8566986b2d886668, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<33> b_818abff899400735 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 53, 7, 64, 153, 248, 191, 138, 129, + 15, 0, 0, 0, 1, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 83, + 105, 109, 112, 108, 101, 80, 111, 108, + 121, 103, 111, 110, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 20, 0, 0, 0, 2, 0, 1, 0, + 104, 117, 108, 108, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 104, 102, 136, 45, 107, 152, 102, 133, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_818abff899400735 = b_818abff899400735.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_818abff899400735[] = { + &s_8566986b2d886668, +}; +static const uint16_t m_818abff899400735[] = {0}; +static const uint16_t i_818abff899400735[] = {0}; +const ::capnp::_::RawSchema s_818abff899400735 = { + 0x818abff899400735, b_818abff899400735.words, 33, d_818abff899400735, m_818abff899400735, + 1, 1, i_818abff899400735, nullptr, nullptr, { &s_818abff899400735, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<51> b_87a09f9a2b840501 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 1, 5, 132, 43, 154, 159, 160, 135, + 15, 0, 0, 0, 1, 0, 0, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 186, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 80, + 111, 108, 121, 103, 111, 110, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 68, 0, 0, 0, 2, 0, 1, 0, + 104, 117, 108, 108, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 104, 102, 136, 45, 107, 152, 102, 133, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 111, 108, 101, 115, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 104, 102, 136, 45, 107, 152, 102, 133, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_87a09f9a2b840501 = b_87a09f9a2b840501.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_87a09f9a2b840501[] = { + &s_8566986b2d886668, +}; +static const uint16_t m_87a09f9a2b840501[] = {1, 0}; +static const uint16_t i_87a09f9a2b840501[] = {0, 1}; +const ::capnp::_::RawSchema s_87a09f9a2b840501 = { + 0x87a09f9a2b840501, b_87a09f9a2b840501.words, 51, d_87a09f9a2b840501, m_87a09f9a2b840501, + 1, 2, i_87a09f9a2b840501, nullptr, nullptr, { &s_87a09f9a2b840501, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<100> b_c9439219800da364 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 100, 163, 13, 128, 25, 146, 67, 201, + 15, 0, 0, 0, 1, 0, 4, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 162, 0, 0, 0, + 29, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 31, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 80, + 97, 116, 104, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 125, 31, 23, 238, 165, 247, 31, 173, + 1, 0, 0, 0, 114, 0, 0, 0, + 69, 120, 116, 101, 110, 115, 105, 111, + 110, 84, 121, 112, 101, 0, 0, 0, + 20, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 125, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 120, 0, 0, 0, 3, 0, 1, 0, + 132, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 3, 0, 1, 0, + 140, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 137, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 136, 0, 0, 0, 3, 0, 1, 0, + 148, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 145, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 144, 0, 0, 0, 3, 0, 1, 0, + 156, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 153, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 1, 0, + 164, 0, 0, 0, 2, 0, 1, 0, + 115, 112, 105, 110, 101, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 104, 102, 136, 45, 107, 152, 102, 133, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 97, 108, 102, 87, 105, 100, 116, + 104, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 101, 103, 105, 110, 69, 120, 116, + 101, 110, 115, 105, 111, 110, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 110, 100, 69, 120, 116, 101, 110, + 115, 105, 111, 110, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 120, 116, 101, 110, 115, 105, 111, + 110, 84, 121, 112, 101, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 125, 31, 23, 238, 165, 247, 31, 173, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c9439219800da364 = b_c9439219800da364.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c9439219800da364[] = { + &s_8566986b2d886668, + &s_ad1ff7a5ee171f7d, +}; +static const uint16_t m_c9439219800da364[] = {2, 3, 4, 1, 0}; +static const uint16_t i_c9439219800da364[] = {0, 1, 2, 3, 4}; +const ::capnp::_::RawSchema s_c9439219800da364 = { + 0xc9439219800da364, b_c9439219800da364.words, 100, d_c9439219800da364, m_c9439219800da364, + 2, 5, i_c9439219800da364, nullptr, nullptr, { &s_c9439219800da364, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<36> b_ad1ff7a5ee171f7d = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 125, 31, 23, 238, 165, 247, 31, 173, + 20, 0, 0, 0, 2, 0, 0, 0, + 100, 163, 13, 128, 25, 146, 67, 201, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 18, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 80, + 97, 116, 104, 46, 69, 120, 116, 101, + 110, 115, 105, 111, 110, 84, 121, 112, + 101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 16, 0, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 108, 117, 115, 104, 0, 0, 0, + 115, 113, 117, 97, 114, 101, 0, 0, + 114, 111, 117, 110, 100, 0, 0, 0, + 118, 97, 114, 105, 97, 98, 108, 101, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ad1ff7a5ee171f7d = b_ad1ff7a5ee171f7d.words; +#if !CAPNP_LITE +static const uint16_t m_ad1ff7a5ee171f7d[] = {0, 2, 1, 3}; +const ::capnp::_::RawSchema s_ad1ff7a5ee171f7d = { + 0xad1ff7a5ee171f7d, b_ad1ff7a5ee171f7d.words, 36, nullptr, m_ad1ff7a5ee171f7d, + 0, 4, nullptr, nullptr, nullptr, { &s_ad1ff7a5ee171f7d, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +CAPNP_DEFINE_ENUM(ExtensionType_ad1ff7a5ee171f7d, ad1ff7a5ee171f7d); +static const ::capnp::_::AlignedData<136> b_c8862d8266738466 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 102, 132, 115, 102, 130, 45, 134, 200, + 15, 0, 0, 0, 1, 0, 3, 0, + 144, 168, 97, 167, 251, 32, 66, 129, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 170, 0, 0, 0, + 29, 0, 0, 0, 39, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 143, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 76, + 97, 98, 101, 108, 0, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 1, 0, + 201, 23, 29, 140, 125, 229, 92, 148, + 9, 0, 0, 0, 90, 0, 0, 0, + 161, 138, 148, 82, 221, 117, 164, 156, + 9, 0, 0, 0, 90, 0, 0, 0, + 72, 65, 108, 105, 103, 110, 109, 101, + 110, 116, 0, 0, 0, 0, 0, 0, + 86, 65, 108, 105, 103, 110, 109, 101, + 110, 116, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 181, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 180, 0, 0, 0, 3, 0, 1, 0, + 192, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 189, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 188, 0, 0, 0, 3, 0, 1, 0, + 200, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 197, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 196, 0, 0, 0, 3, 0, 1, 0, + 208, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 205, 0, 0, 0, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 204, 0, 0, 0, 3, 0, 1, 0, + 216, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 212, 0, 0, 0, 3, 0, 1, 0, + 224, 0, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 221, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 220, 0, 0, 0, 3, 0, 1, 0, + 232, 0, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 229, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 224, 0, 0, 0, 3, 0, 1, 0, + 236, 0, 0, 0, 2, 0, 1, 0, + 112, 111, 115, 105, 116, 105, 111, 110, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 80, 124, 138, 135, 42, 37, 22, 162, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 111, 114, 105, 101, 110, 116, 97, 116, + 105, 111, 110, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 23, 145, 81, 151, 52, 20, 168, 204, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 116, 114, 105, 110, 103, 73, 100, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 111, 114, 105, 122, 111, 110, 116, + 97, 108, 65, 108, 105, 103, 110, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 201, 23, 29, 140, 125, 229, 92, 148, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 101, 114, 116, 105, 99, 97, 108, + 65, 108, 105, 103, 110, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 161, 138, 148, 82, 221, 117, 164, 156, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 112, 108, 97, 121, 79, + 102, 102, 115, 101, 116, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 105, 122, 101, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c8862d8266738466 = b_c8862d8266738466.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c8862d8266738466[] = { + &s_945ce57d8c1d17c9, + &s_9ca475dd52948aa1, + &s_a216252a878a7c50, + &s_c3ea9d0d831017a9, + &s_cca8143497519117, +}; +static const uint16_t m_c8862d8266738466[] = {5, 3, 1, 0, 6, 2, 4}; +static const uint16_t i_c8862d8266738466[] = {0, 1, 2, 3, 4, 5, 6}; +const ::capnp::_::RawSchema s_c8862d8266738466 = { + 0xc8862d8266738466, b_c8862d8266738466.words, 136, d_c8862d8266738466, m_c8862d8266738466, + 5, 7, i_c8862d8266738466, nullptr, nullptr, { &s_c8862d8266738466, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<30> b_945ce57d8c1d17c9 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 201, 23, 29, 140, 125, 229, 92, 148, + 21, 0, 0, 0, 2, 0, 0, 0, + 102, 132, 115, 102, 130, 45, 134, 200, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 2, 1, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 79, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 76, + 97, 98, 101, 108, 46, 72, 65, 108, + 105, 103, 110, 109, 101, 110, 116, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 101, 102, 116, 0, 0, 0, 0, + 99, 101, 110, 116, 101, 114, 0, 0, + 114, 105, 103, 104, 116, 0, 0, 0, } +}; +::capnp::word const* const bp_945ce57d8c1d17c9 = b_945ce57d8c1d17c9.words; +#if !CAPNP_LITE +static const uint16_t m_945ce57d8c1d17c9[] = {1, 0, 2}; +const ::capnp::_::RawSchema s_945ce57d8c1d17c9 = { + 0x945ce57d8c1d17c9, b_945ce57d8c1d17c9.words, 30, nullptr, m_945ce57d8c1d17c9, + 0, 3, nullptr, nullptr, nullptr, { &s_945ce57d8c1d17c9, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +CAPNP_DEFINE_ENUM(HAlignment_945ce57d8c1d17c9, 945ce57d8c1d17c9); +static const ::capnp::_::AlignedData<30> b_9ca475dd52948aa1 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 161, 138, 148, 82, 221, 117, 164, 156, + 21, 0, 0, 0, 2, 0, 0, 0, + 102, 132, 115, 102, 130, 45, 134, 200, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 2, 1, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 79, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 111, 109, 101, 116, 114, 121, + 46, 99, 97, 112, 110, 112, 58, 76, + 97, 98, 101, 108, 46, 86, 65, 108, + 105, 103, 110, 109, 101, 110, 116, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 111, 116, 116, 111, 109, 0, 0, + 99, 101, 110, 116, 101, 114, 0, 0, + 116, 111, 112, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9ca475dd52948aa1 = b_9ca475dd52948aa1.words; +#if !CAPNP_LITE +static const uint16_t m_9ca475dd52948aa1[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_9ca475dd52948aa1 = { + 0x9ca475dd52948aa1, b_9ca475dd52948aa1.words, 30, nullptr, m_9ca475dd52948aa1, + 0, 3, nullptr, nullptr, nullptr, { &s_9ca475dd52948aa1, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +CAPNP_DEFINE_ENUM(VAlignment_9ca475dd52948aa1, 9ca475dd52948aa1); +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace geometry { + +// Vector +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Vector::_capnpPrivate::dataWordSize; +constexpr uint16_t Vector::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Vector::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Vector::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Point +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Point::_capnpPrivate::dataWordSize; +constexpr uint16_t Point::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Point::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Point::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Box +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Box::_capnpPrivate::dataWordSize; +constexpr uint16_t Box::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Box::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Box::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Edge +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Edge::_capnpPrivate::dataWordSize; +constexpr uint16_t Edge::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Edge::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Edge::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// EdgePair +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t EdgePair::_capnpPrivate::dataWordSize; +constexpr uint16_t EdgePair::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind EdgePair::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* EdgePair::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Contour +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Contour::_capnpPrivate::dataWordSize; +constexpr uint16_t Contour::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Contour::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Contour::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// SimplePolygon +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t SimplePolygon::_capnpPrivate::dataWordSize; +constexpr uint16_t SimplePolygon::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind SimplePolygon::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* SimplePolygon::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Polygon +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Polygon::_capnpPrivate::dataWordSize; +constexpr uint16_t Polygon::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Polygon::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Polygon::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Path +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Path::_capnpPrivate::dataWordSize; +constexpr uint16_t Path::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Path::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Path::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Label +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Label::_capnpPrivate::dataWordSize; +constexpr uint16_t Label::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Label::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Label::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/geometry.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/geometry.capnp.h new file mode 100644 index 000000000..ca6a3b5ab --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/geometry.capnp.h @@ -0,0 +1,1883 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: geometry.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(cca8143497519117); +enum class FixPointTransformation_cca8143497519117: uint16_t { + R0, + R90, + R180, + R270, + M0, + M45, + M90, + M135, +}; +CAPNP_DECLARE_ENUM(FixPointTransformation, cca8143497519117); +CAPNP_DECLARE_SCHEMA(c3ea9d0d831017a9); +CAPNP_DECLARE_SCHEMA(a216252a878a7c50); +CAPNP_DECLARE_SCHEMA(b07a0bb15b04919e); +CAPNP_DECLARE_SCHEMA(d3ad7560ad4c7c5a); +CAPNP_DECLARE_SCHEMA(dc8843c995bed8b6); +CAPNP_DECLARE_SCHEMA(8566986b2d886668); +CAPNP_DECLARE_SCHEMA(818abff899400735); +CAPNP_DECLARE_SCHEMA(87a09f9a2b840501); +CAPNP_DECLARE_SCHEMA(c9439219800da364); +CAPNP_DECLARE_SCHEMA(ad1ff7a5ee171f7d); +enum class ExtensionType_ad1ff7a5ee171f7d: uint16_t { + FLUSH, + SQUARE, + ROUND, + VARIABLE, +}; +CAPNP_DECLARE_ENUM(ExtensionType, ad1ff7a5ee171f7d); +CAPNP_DECLARE_SCHEMA(c8862d8266738466); +CAPNP_DECLARE_SCHEMA(945ce57d8c1d17c9); +enum class HAlignment_945ce57d8c1d17c9: uint16_t { + LEFT, + CENTER, + RIGHT, +}; +CAPNP_DECLARE_ENUM(HAlignment, 945ce57d8c1d17c9); +CAPNP_DECLARE_SCHEMA(9ca475dd52948aa1); +enum class VAlignment_9ca475dd52948aa1: uint16_t { + BOTTOM, + CENTER, + TOP, +}; +CAPNP_DECLARE_ENUM(VAlignment, 9ca475dd52948aa1); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace geometry { + +typedef ::capnp::schemas::FixPointTransformation_cca8143497519117 FixPointTransformation; + +struct Vector { + Vector() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c3ea9d0d831017a9, 2, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Point { + Point() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a216252a878a7c50, 2, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Box { + Box() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b07a0bb15b04919e, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Edge { + Edge() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d3ad7560ad4c7c5a, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct EdgePair { + EdgePair() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(dc8843c995bed8b6, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Contour { + Contour() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8566986b2d886668, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct SimplePolygon { + SimplePolygon() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(818abff899400735, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Polygon { + Polygon() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(87a09f9a2b840501, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Path { + Path() = delete; + + class Reader; + class Builder; + class Pipeline; + typedef ::capnp::schemas::ExtensionType_ad1ff7a5ee171f7d ExtensionType; + + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c9439219800da364, 4, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Label { + Label() = delete; + + class Reader; + class Builder; + class Pipeline; + typedef ::capnp::schemas::HAlignment_945ce57d8c1d17c9 HAlignment; + + typedef ::capnp::schemas::VAlignment_9ca475dd52948aa1 VAlignment; + + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c8862d8266738466, 3, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class Vector::Reader { +public: + typedef Vector Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::int64_t getDx() const; + + inline ::int64_t getDy() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Vector::Builder { +public: + typedef Vector Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::int64_t getDx(); + inline void setDx( ::int64_t value); + + inline ::int64_t getDy(); + inline void setDy( ::int64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Vector::Pipeline { +public: + typedef Vector Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Point::Reader { +public: + typedef Point Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::int64_t getX() const; + + inline ::int64_t getY() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Point::Builder { +public: + typedef Point Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::int64_t getX(); + inline void setX( ::int64_t value); + + inline ::int64_t getY(); + inline void setY( ::int64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Point::Pipeline { +public: + typedef Point Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Box::Reader { +public: + typedef Box Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasP1() const; + inline ::stream::geometry::Point::Reader getP1() const; + + inline bool hasDelta() const; + inline ::stream::geometry::Vector::Reader getDelta() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Box::Builder { +public: + typedef Box Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasP1(); + inline ::stream::geometry::Point::Builder getP1(); + inline void setP1( ::stream::geometry::Point::Reader value); + inline ::stream::geometry::Point::Builder initP1(); + inline void adoptP1(::capnp::Orphan< ::stream::geometry::Point>&& value); + inline ::capnp::Orphan< ::stream::geometry::Point> disownP1(); + + inline bool hasDelta(); + inline ::stream::geometry::Vector::Builder getDelta(); + inline void setDelta( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initDelta(); + inline void adoptDelta(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownDelta(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Box::Pipeline { +public: + typedef Box Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Point::Pipeline getP1(); + inline ::stream::geometry::Vector::Pipeline getDelta(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Edge::Reader { +public: + typedef Edge Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasP1() const; + inline ::stream::geometry::Point::Reader getP1() const; + + inline bool hasDelta() const; + inline ::stream::geometry::Vector::Reader getDelta() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Edge::Builder { +public: + typedef Edge Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasP1(); + inline ::stream::geometry::Point::Builder getP1(); + inline void setP1( ::stream::geometry::Point::Reader value); + inline ::stream::geometry::Point::Builder initP1(); + inline void adoptP1(::capnp::Orphan< ::stream::geometry::Point>&& value); + inline ::capnp::Orphan< ::stream::geometry::Point> disownP1(); + + inline bool hasDelta(); + inline ::stream::geometry::Vector::Builder getDelta(); + inline void setDelta( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initDelta(); + inline void adoptDelta(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownDelta(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Edge::Pipeline { +public: + typedef Edge Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Point::Pipeline getP1(); + inline ::stream::geometry::Vector::Pipeline getDelta(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class EdgePair::Reader { +public: + typedef EdgePair Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasE1() const; + inline ::stream::geometry::Edge::Reader getE1() const; + + inline bool hasE2() const; + inline ::stream::geometry::Edge::Reader getE2() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class EdgePair::Builder { +public: + typedef EdgePair Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasE1(); + inline ::stream::geometry::Edge::Builder getE1(); + inline void setE1( ::stream::geometry::Edge::Reader value); + inline ::stream::geometry::Edge::Builder initE1(); + inline void adoptE1(::capnp::Orphan< ::stream::geometry::Edge>&& value); + inline ::capnp::Orphan< ::stream::geometry::Edge> disownE1(); + + inline bool hasE2(); + inline ::stream::geometry::Edge::Builder getE2(); + inline void setE2( ::stream::geometry::Edge::Reader value); + inline ::stream::geometry::Edge::Builder initE2(); + inline void adoptE2(::capnp::Orphan< ::stream::geometry::Edge>&& value); + inline ::capnp::Orphan< ::stream::geometry::Edge> disownE2(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class EdgePair::Pipeline { +public: + typedef EdgePair Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Edge::Pipeline getE1(); + inline ::stream::geometry::Edge::Pipeline getE2(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Contour::Reader { +public: + typedef Contour Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasP1() const; + inline ::stream::geometry::Point::Reader getP1() const; + + inline bool hasDeltas() const; + inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader getDeltas() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Contour::Builder { +public: + typedef Contour Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasP1(); + inline ::stream::geometry::Point::Builder getP1(); + inline void setP1( ::stream::geometry::Point::Reader value); + inline ::stream::geometry::Point::Builder initP1(); + inline void adoptP1(::capnp::Orphan< ::stream::geometry::Point>&& value); + inline ::capnp::Orphan< ::stream::geometry::Point> disownP1(); + + inline bool hasDeltas(); + inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder getDeltas(); + inline void setDeltas( ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder initDeltas(unsigned int size); + inline void adoptDeltas(::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>> disownDeltas(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Contour::Pipeline { +public: + typedef Contour Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Point::Pipeline getP1(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class SimplePolygon::Reader { +public: + typedef SimplePolygon Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasHull() const; + inline ::stream::geometry::Contour::Reader getHull() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class SimplePolygon::Builder { +public: + typedef SimplePolygon Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasHull(); + inline ::stream::geometry::Contour::Builder getHull(); + inline void setHull( ::stream::geometry::Contour::Reader value); + inline ::stream::geometry::Contour::Builder initHull(); + inline void adoptHull(::capnp::Orphan< ::stream::geometry::Contour>&& value); + inline ::capnp::Orphan< ::stream::geometry::Contour> disownHull(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class SimplePolygon::Pipeline { +public: + typedef SimplePolygon Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Contour::Pipeline getHull(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Polygon::Reader { +public: + typedef Polygon Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasHull() const; + inline ::stream::geometry::Contour::Reader getHull() const; + + inline bool hasHoles() const; + inline ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Reader getHoles() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Polygon::Builder { +public: + typedef Polygon Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasHull(); + inline ::stream::geometry::Contour::Builder getHull(); + inline void setHull( ::stream::geometry::Contour::Reader value); + inline ::stream::geometry::Contour::Builder initHull(); + inline void adoptHull(::capnp::Orphan< ::stream::geometry::Contour>&& value); + inline ::capnp::Orphan< ::stream::geometry::Contour> disownHull(); + + inline bool hasHoles(); + inline ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Builder getHoles(); + inline void setHoles( ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Builder initHoles(unsigned int size); + inline void adoptHoles(::capnp::Orphan< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>> disownHoles(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Polygon::Pipeline { +public: + typedef Polygon Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Contour::Pipeline getHull(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Path::Reader { +public: + typedef Path Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasSpine() const; + inline ::stream::geometry::Contour::Reader getSpine() const; + + inline ::uint64_t getHalfWidth() const; + + inline ::int64_t getBeginExtension() const; + + inline ::int64_t getEndExtension() const; + + inline ::stream::geometry::Path::ExtensionType getExtensionType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Path::Builder { +public: + typedef Path Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasSpine(); + inline ::stream::geometry::Contour::Builder getSpine(); + inline void setSpine( ::stream::geometry::Contour::Reader value); + inline ::stream::geometry::Contour::Builder initSpine(); + inline void adoptSpine(::capnp::Orphan< ::stream::geometry::Contour>&& value); + inline ::capnp::Orphan< ::stream::geometry::Contour> disownSpine(); + + inline ::uint64_t getHalfWidth(); + inline void setHalfWidth( ::uint64_t value); + + inline ::int64_t getBeginExtension(); + inline void setBeginExtension( ::int64_t value); + + inline ::int64_t getEndExtension(); + inline void setEndExtension( ::int64_t value); + + inline ::stream::geometry::Path::ExtensionType getExtensionType(); + inline void setExtensionType( ::stream::geometry::Path::ExtensionType value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Path::Pipeline { +public: + typedef Path Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Contour::Pipeline getSpine(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Label::Reader { +public: + typedef Label Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasPosition() const; + inline ::stream::geometry::Point::Reader getPosition() const; + + inline ::stream::geometry::FixPointTransformation getOrientation() const; + + inline ::uint64_t getStringId() const; + + inline ::stream::geometry::Label::HAlignment getHorizontalAlign() const; + + inline ::stream::geometry::Label::VAlignment getVerticalAlign() const; + + inline bool hasDisplayOffset() const; + inline ::stream::geometry::Vector::Reader getDisplayOffset() const; + + inline ::uint64_t getSize() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Label::Builder { +public: + typedef Label Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasPosition(); + inline ::stream::geometry::Point::Builder getPosition(); + inline void setPosition( ::stream::geometry::Point::Reader value); + inline ::stream::geometry::Point::Builder initPosition(); + inline void adoptPosition(::capnp::Orphan< ::stream::geometry::Point>&& value); + inline ::capnp::Orphan< ::stream::geometry::Point> disownPosition(); + + inline ::stream::geometry::FixPointTransformation getOrientation(); + inline void setOrientation( ::stream::geometry::FixPointTransformation value); + + inline ::uint64_t getStringId(); + inline void setStringId( ::uint64_t value); + + inline ::stream::geometry::Label::HAlignment getHorizontalAlign(); + inline void setHorizontalAlign( ::stream::geometry::Label::HAlignment value); + + inline ::stream::geometry::Label::VAlignment getVerticalAlign(); + inline void setVerticalAlign( ::stream::geometry::Label::VAlignment value); + + inline bool hasDisplayOffset(); + inline ::stream::geometry::Vector::Builder getDisplayOffset(); + inline void setDisplayOffset( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initDisplayOffset(); + inline void adoptDisplayOffset(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownDisplayOffset(); + + inline ::uint64_t getSize(); + inline void setSize( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Label::Pipeline { +public: + typedef Label Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Point::Pipeline getPosition(); + inline ::stream::geometry::Vector::Pipeline getDisplayOffset(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::int64_t Vector::Reader::getDx() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Vector::Builder::getDx() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Vector::Builder::setDx( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::int64_t Vector::Reader::getDy() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Vector::Builder::getDy() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Vector::Builder::setDy( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::int64_t Point::Reader::getX() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Point::Builder::getX() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Point::Builder::setX( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::int64_t Point::Reader::getY() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Point::Builder::getY() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Point::Builder::setY( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Box::Reader::hasP1() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Box::Builder::hasP1() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Point::Reader Box::Reader::getP1() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Point::Builder Box::Builder::getP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Point::Pipeline Box::Pipeline::getP1() { + return ::stream::geometry::Point::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Box::Builder::setP1( ::stream::geometry::Point::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Point::Builder Box::Builder::initP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Box::Builder::adoptP1( + ::capnp::Orphan< ::stream::geometry::Point>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Point> Box::Builder::disownP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Box::Reader::hasDelta() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Box::Builder::hasDelta() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader Box::Reader::getDelta() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder Box::Builder::getDelta() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Vector::Pipeline Box::Pipeline::getDelta() { + return ::stream::geometry::Vector::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Box::Builder::setDelta( ::stream::geometry::Vector::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder Box::Builder::initDelta() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Box::Builder::adoptDelta( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> Box::Builder::disownDelta() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Edge::Reader::hasP1() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Edge::Builder::hasP1() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Point::Reader Edge::Reader::getP1() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Point::Builder Edge::Builder::getP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Point::Pipeline Edge::Pipeline::getP1() { + return ::stream::geometry::Point::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Edge::Builder::setP1( ::stream::geometry::Point::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Point::Builder Edge::Builder::initP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Edge::Builder::adoptP1( + ::capnp::Orphan< ::stream::geometry::Point>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Point> Edge::Builder::disownP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Edge::Reader::hasDelta() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Edge::Builder::hasDelta() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader Edge::Reader::getDelta() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder Edge::Builder::getDelta() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Vector::Pipeline Edge::Pipeline::getDelta() { + return ::stream::geometry::Vector::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Edge::Builder::setDelta( ::stream::geometry::Vector::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder Edge::Builder::initDelta() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Edge::Builder::adoptDelta( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> Edge::Builder::disownDelta() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool EdgePair::Reader::hasE1() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool EdgePair::Builder::hasE1() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Edge::Reader EdgePair::Reader::getE1() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Edge::Builder EdgePair::Builder::getE1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Edge::Pipeline EdgePair::Pipeline::getE1() { + return ::stream::geometry::Edge::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void EdgePair::Builder::setE1( ::stream::geometry::Edge::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Edge::Builder EdgePair::Builder::initE1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void EdgePair::Builder::adoptE1( + ::capnp::Orphan< ::stream::geometry::Edge>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Edge> EdgePair::Builder::disownE1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool EdgePair::Reader::hasE2() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool EdgePair::Builder::hasE2() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Edge::Reader EdgePair::Reader::getE2() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Edge::Builder EdgePair::Builder::getE2() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Edge::Pipeline EdgePair::Pipeline::getE2() { + return ::stream::geometry::Edge::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void EdgePair::Builder::setE2( ::stream::geometry::Edge::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Edge::Builder EdgePair::Builder::initE2() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void EdgePair::Builder::adoptE2( + ::capnp::Orphan< ::stream::geometry::Edge>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Edge> EdgePair::Builder::disownE2() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Edge>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Contour::Reader::hasP1() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Contour::Builder::hasP1() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Point::Reader Contour::Reader::getP1() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Point::Builder Contour::Builder::getP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Point::Pipeline Contour::Pipeline::getP1() { + return ::stream::geometry::Point::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Contour::Builder::setP1( ::stream::geometry::Point::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Point::Builder Contour::Builder::initP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Contour::Builder::adoptP1( + ::capnp::Orphan< ::stream::geometry::Point>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Point> Contour::Builder::disownP1() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Contour::Reader::hasDeltas() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Contour::Builder::hasDeltas() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader Contour::Reader::getDeltas() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder Contour::Builder::getDeltas() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Contour::Builder::setDeltas( ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder Contour::Builder::initDeltas(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Contour::Builder::adoptDeltas( + ::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>> Contour::Builder::disownDeltas() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool SimplePolygon::Reader::hasHull() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool SimplePolygon::Builder::hasHull() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Contour::Reader SimplePolygon::Reader::getHull() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Contour::Builder SimplePolygon::Builder::getHull() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Contour::Pipeline SimplePolygon::Pipeline::getHull() { + return ::stream::geometry::Contour::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void SimplePolygon::Builder::setHull( ::stream::geometry::Contour::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Contour::Builder SimplePolygon::Builder::initHull() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void SimplePolygon::Builder::adoptHull( + ::capnp::Orphan< ::stream::geometry::Contour>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Contour> SimplePolygon::Builder::disownHull() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Polygon::Reader::hasHull() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Polygon::Builder::hasHull() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Contour::Reader Polygon::Reader::getHull() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Contour::Builder Polygon::Builder::getHull() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Contour::Pipeline Polygon::Pipeline::getHull() { + return ::stream::geometry::Contour::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Polygon::Builder::setHull( ::stream::geometry::Contour::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Contour::Builder Polygon::Builder::initHull() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Polygon::Builder::adoptHull( + ::capnp::Orphan< ::stream::geometry::Contour>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Contour> Polygon::Builder::disownHull() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Polygon::Reader::hasHoles() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Polygon::Builder::hasHoles() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Reader Polygon::Reader::getHoles() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Builder Polygon::Builder::getHoles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Polygon::Builder::setHoles( ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>::Builder Polygon::Builder::initHoles(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Polygon::Builder::adoptHoles( + ::capnp::Orphan< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>> Polygon::Builder::disownHoles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Contour, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Path::Reader::hasSpine() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Path::Builder::hasSpine() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Contour::Reader Path::Reader::getSpine() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Contour::Builder Path::Builder::getSpine() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Contour::Pipeline Path::Pipeline::getSpine() { + return ::stream::geometry::Contour::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Path::Builder::setSpine( ::stream::geometry::Contour::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Contour::Builder Path::Builder::initSpine() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Path::Builder::adoptSpine( + ::capnp::Orphan< ::stream::geometry::Contour>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Contour> Path::Builder::disownSpine() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Contour>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Path::Reader::getHalfWidth() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Path::Builder::getHalfWidth() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Path::Builder::setHalfWidth( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::int64_t Path::Reader::getBeginExtension() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Path::Builder::getBeginExtension() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Path::Builder::setBeginExtension( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::int64_t Path::Reader::getEndExtension() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Path::Builder::getEndExtension() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Path::Builder::setEndExtension( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::stream::geometry::Path::ExtensionType Path::Reader::getExtensionType() const { + return _reader.getDataField< ::stream::geometry::Path::ExtensionType>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS); +} + +inline ::stream::geometry::Path::ExtensionType Path::Builder::getExtensionType() { + return _builder.getDataField< ::stream::geometry::Path::ExtensionType>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS); +} +inline void Path::Builder::setExtensionType( ::stream::geometry::Path::ExtensionType value) { + _builder.setDataField< ::stream::geometry::Path::ExtensionType>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS, value); +} + +inline bool Label::Reader::hasPosition() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Label::Builder::hasPosition() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Point::Reader Label::Reader::getPosition() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Point::Builder Label::Builder::getPosition() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Point::Pipeline Label::Pipeline::getPosition() { + return ::stream::geometry::Point::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Label::Builder::setPosition( ::stream::geometry::Point::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Point::Builder Label::Builder::initPosition() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Label::Builder::adoptPosition( + ::capnp::Orphan< ::stream::geometry::Point>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Point>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Point> Label::Builder::disownPosition() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Point>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::stream::geometry::FixPointTransformation Label::Reader::getOrientation() const { + return _reader.getDataField< ::stream::geometry::FixPointTransformation>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::stream::geometry::FixPointTransformation Label::Builder::getOrientation() { + return _builder.getDataField< ::stream::geometry::FixPointTransformation>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Label::Builder::setOrientation( ::stream::geometry::FixPointTransformation value) { + _builder.setDataField< ::stream::geometry::FixPointTransformation>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Label::Reader::getStringId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Label::Builder::getStringId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Label::Builder::setStringId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::stream::geometry::Label::HAlignment Label::Reader::getHorizontalAlign() const { + return _reader.getDataField< ::stream::geometry::Label::HAlignment>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::stream::geometry::Label::HAlignment Label::Builder::getHorizontalAlign() { + return _builder.getDataField< ::stream::geometry::Label::HAlignment>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Label::Builder::setHorizontalAlign( ::stream::geometry::Label::HAlignment value) { + _builder.setDataField< ::stream::geometry::Label::HAlignment>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::stream::geometry::Label::VAlignment Label::Reader::getVerticalAlign() const { + return _reader.getDataField< ::stream::geometry::Label::VAlignment>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::stream::geometry::Label::VAlignment Label::Builder::getVerticalAlign() { + return _builder.getDataField< ::stream::geometry::Label::VAlignment>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Label::Builder::setVerticalAlign( ::stream::geometry::Label::VAlignment value) { + _builder.setDataField< ::stream::geometry::Label::VAlignment>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Label::Reader::hasDisplayOffset() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Label::Builder::hasDisplayOffset() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader Label::Reader::getDisplayOffset() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder Label::Builder::getDisplayOffset() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Vector::Pipeline Label::Pipeline::getDisplayOffset() { + return ::stream::geometry::Vector::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Label::Builder::setDisplayOffset( ::stream::geometry::Vector::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder Label::Builder::initDisplayOffset() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Label::Builder::adoptDisplayOffset( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> Label::Builder::disownDisplayOffset() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Label::Reader::getSize() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Label::Builder::getSize() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Label::Builder::setSize( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/header.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/header.capnp.cc new file mode 100644 index 000000000..6845e61f4 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/header.capnp.cc @@ -0,0 +1,202 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: header.capnp + +#include "header.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<48> b_ca6137cc23ea16e8 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 232, 22, 234, 35, 204, 55, 97, 202, + 13, 0, 0, 0, 1, 0, 0, 0, + 36, 255, 84, 206, 94, 231, 245, 197, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 101, 97, 100, 101, 114, 46, 99, + 97, 112, 110, 112, 58, 76, 105, 98, + 114, 97, 114, 121, 83, 112, 101, 99, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 121, 112, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ca6137cc23ea16e8 = b_ca6137cc23ea16e8.words; +#if !CAPNP_LITE +static const uint16_t m_ca6137cc23ea16e8[] = {0, 1}; +static const uint16_t i_ca6137cc23ea16e8[] = {0, 1}; +const ::capnp::_::RawSchema s_ca6137cc23ea16e8 = { + 0xca6137cc23ea16e8, b_ca6137cc23ea16e8.words, 48, nullptr, m_ca6137cc23ea16e8, + 0, 2, i_ca6137cc23ea16e8, nullptr, nullptr, { &s_ca6137cc23ea16e8, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<85> b_a72897b14bf79c6b = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 107, 156, 247, 75, 177, 151, 40, 167, + 13, 0, 0, 0, 1, 0, 0, 0, + 36, 255, 84, 206, 94, 231, 245, 197, + 4, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 162, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 101, 97, 100, 101, 114, 46, 99, + 97, 112, 110, 112, 58, 72, 101, 97, + 100, 101, 114, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 3, 0, 1, 0, + 116, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 113, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 0, 0, 0, 3, 0, 1, 0, + 124, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 120, 0, 0, 0, 3, 0, 1, 0, + 148, 0, 0, 0, 2, 0, 1, 0, + 109, 101, 116, 97, 68, 97, 116, 97, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 56, 212, 213, 232, 233, 209, 66, 147, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 103, 101, 110, 101, 114, 97, 116, 111, + 114, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 101, 99, 104, 110, 111, 108, 111, + 103, 121, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 105, 101, + 115, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 232, 22, 234, 35, 204, 55, 97, 202, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_a72897b14bf79c6b = b_a72897b14bf79c6b.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_a72897b14bf79c6b[] = { + &s_9342d1e9e8d5d438, + &s_ca6137cc23ea16e8, +}; +static const uint16_t m_a72897b14bf79c6b[] = {1, 3, 0, 2}; +static const uint16_t i_a72897b14bf79c6b[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_a72897b14bf79c6b = { + 0xa72897b14bf79c6b, b_a72897b14bf79c6b.words, 85, d_a72897b14bf79c6b, m_a72897b14bf79c6b, + 2, 4, i_a72897b14bf79c6b, nullptr, nullptr, { &s_a72897b14bf79c6b, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace header { + +// LibrarySpec +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t LibrarySpec::_capnpPrivate::dataWordSize; +constexpr uint16_t LibrarySpec::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind LibrarySpec::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* LibrarySpec::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Header +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Header::_capnpPrivate::dataWordSize; +constexpr uint16_t Header::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Header::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Header::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/header.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/header.capnp.h new file mode 100644 index 000000000..14515b513 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/header.capnp.h @@ -0,0 +1,481 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: header.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "metaData.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(ca6137cc23ea16e8); +CAPNP_DECLARE_SCHEMA(a72897b14bf79c6b); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace header { + +struct LibrarySpec { + LibrarySpec() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ca6137cc23ea16e8, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Header { + Header() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a72897b14bf79c6b, 0, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class LibrarySpec::Reader { +public: + typedef LibrarySpec Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline bool hasType() const; + inline ::capnp::Text::Reader getType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class LibrarySpec::Builder { +public: + typedef LibrarySpec Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline bool hasType(); + inline ::capnp::Text::Builder getType(); + inline void setType( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initType(unsigned int size); + inline void adoptType(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownType(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class LibrarySpec::Pipeline { +public: + typedef LibrarySpec Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Header::Reader { +public: + typedef Header Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasMetaData() const; + inline ::stream::metaData::MetaData::Reader getMetaData() const; + + inline bool hasGenerator() const; + inline ::capnp::Text::Reader getGenerator() const; + + inline bool hasTechnology() const; + inline ::capnp::Text::Reader getTechnology() const; + + inline bool hasLibraries() const; + inline ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Reader getLibraries() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Header::Builder { +public: + typedef Header Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasMetaData(); + inline ::stream::metaData::MetaData::Builder getMetaData(); + inline void setMetaData( ::stream::metaData::MetaData::Reader value); + inline ::stream::metaData::MetaData::Builder initMetaData(); + inline void adoptMetaData(::capnp::Orphan< ::stream::metaData::MetaData>&& value); + inline ::capnp::Orphan< ::stream::metaData::MetaData> disownMetaData(); + + inline bool hasGenerator(); + inline ::capnp::Text::Builder getGenerator(); + inline void setGenerator( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initGenerator(unsigned int size); + inline void adoptGenerator(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownGenerator(); + + inline bool hasTechnology(); + inline ::capnp::Text::Builder getTechnology(); + inline void setTechnology( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initTechnology(unsigned int size); + inline void adoptTechnology(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownTechnology(); + + inline bool hasLibraries(); + inline ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Builder getLibraries(); + inline void setLibraries( ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Builder initLibraries(unsigned int size); + inline void adoptLibraries(::capnp::Orphan< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>> disownLibraries(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Header::Pipeline { +public: + typedef Header Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::metaData::MetaData::Pipeline getMetaData(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline bool LibrarySpec::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool LibrarySpec::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader LibrarySpec::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder LibrarySpec::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void LibrarySpec::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder LibrarySpec::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void LibrarySpec::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> LibrarySpec::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LibrarySpec::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool LibrarySpec::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader LibrarySpec::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder LibrarySpec::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void LibrarySpec::Builder::setType( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder LibrarySpec::Builder::initType(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void LibrarySpec::Builder::adoptType( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> LibrarySpec::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Header::Reader::hasMetaData() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Header::Builder::hasMetaData() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::metaData::MetaData::Reader Header::Reader::getMetaData() const { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::metaData::MetaData::Builder Header::Builder::getMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::metaData::MetaData::Pipeline Header::Pipeline::getMetaData() { + return ::stream::metaData::MetaData::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Header::Builder::setMetaData( ::stream::metaData::MetaData::Reader value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::metaData::MetaData::Builder Header::Builder::initMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Header::Builder::adoptMetaData( + ::capnp::Orphan< ::stream::metaData::MetaData>&& value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::metaData::MetaData> Header::Builder::disownMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Header::Reader::hasGenerator() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Header::Builder::hasGenerator() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Header::Reader::getGenerator() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Header::Builder::getGenerator() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Header::Builder::setGenerator( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Header::Builder::initGenerator(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Header::Builder::adoptGenerator( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Header::Builder::disownGenerator() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Header::Reader::hasTechnology() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Header::Builder::hasTechnology() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Header::Reader::getTechnology() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Header::Builder::getTechnology() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Header::Builder::setTechnology( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Header::Builder::initTechnology(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), size); +} +inline void Header::Builder::adoptTechnology( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Header::Builder::disownTechnology() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Header::Reader::hasLibraries() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Header::Builder::hasLibraries() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Reader Header::Reader::getLibraries() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Builder Header::Builder::getLibraries() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Header::Builder::setLibraries( ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>::Builder Header::Builder::initLibraries(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Header::Builder::adoptLibraries( + ::capnp::Orphan< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>> Header::Builder::disownLibraries() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::header::LibrarySpec, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/layoutView.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/layoutView.capnp.cc new file mode 100644 index 000000000..25054f5d6 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/layoutView.capnp.cc @@ -0,0 +1,1184 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: layoutView.capnp + +#include "layoutView.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<36> b_9b5b2a4703ca5f35 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 53, 95, 202, 3, 71, 42, 91, 155, + 17, 0, 0, 0, 1, 0, 0, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 0, 15, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 83, 105, 110, 103, 108, 101, 79, + 98, 106, 101, 99, 116, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 20, 0, 0, 0, 2, 0, 1, 0, + 98, 97, 115, 105, 99, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 53, 95, 202, 3, 71, 42, 91, 155, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 58, 0, 0, 0, + 79, 98, 106, 101, 99, 116, 0, 0, } +}; +::capnp::word const* const bp_9b5b2a4703ca5f35 = b_9b5b2a4703ca5f35.words; +#if !CAPNP_LITE +static const uint16_t m_9b5b2a4703ca5f35[] = {0}; +static const uint16_t i_9b5b2a4703ca5f35[] = {0}; +const ::capnp::_::RawSchema s_9b5b2a4703ca5f35 = { + 0x9b5b2a4703ca5f35, b_9b5b2a4703ca5f35.words, 36, nullptr, m_9b5b2a4703ca5f35, + 0, 1, i_9b5b2a4703ca5f35, nullptr, nullptr, { &s_9b5b2a4703ca5f35, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<52> b_b750d92ac62b9fc2 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 194, 159, 43, 198, 42, 217, 80, 183, + 17, 0, 0, 0, 1, 0, 1, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 149, 0, 0, 0, 15, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 79, 98, 106, 101, 99, 116, 65, + 114, 114, 97, 121, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 56, 0, 0, 0, 2, 0, 1, 0, + 98, 97, 115, 105, 99, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 194, 159, 43, 198, 42, 217, 80, 183, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 73, 100, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 58, 0, 0, 0, + 79, 98, 106, 101, 99, 116, 0, 0, } +}; +::capnp::word const* const bp_b750d92ac62b9fc2 = b_b750d92ac62b9fc2.words; +#if !CAPNP_LITE +static const uint16_t m_b750d92ac62b9fc2[] = {0, 1}; +static const uint16_t i_b750d92ac62b9fc2[] = {0, 1}; +const ::capnp::_::RawSchema s_b750d92ac62b9fc2 = { + 0xb750d92ac62b9fc2, b_b750d92ac62b9fc2.words, 52, nullptr, m_b750d92ac62b9fc2, + 0, 2, i_b750d92ac62b9fc2, nullptr, nullptr, { &s_b750d92ac62b9fc2, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<53> b_abac22840c889893 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 147, 152, 136, 12, 132, 34, 172, 171, + 17, 0, 0, 0, 1, 0, 1, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 21, 0, 0, 0, 50, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 153, 0, 0, 0, 15, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 79, 98, 106, 101, 99, 116, 87, + 105, 116, 104, 80, 114, 111, 112, 101, + 114, 116, 105, 101, 115, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 56, 0, 0, 0, 2, 0, 1, 0, + 98, 97, 115, 105, 99, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 147, 152, 136, 12, 132, 34, 172, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 73, 100, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 58, 0, 0, 0, + 79, 98, 106, 101, 99, 116, 0, 0, } +}; +::capnp::word const* const bp_abac22840c889893 = b_abac22840c889893.words; +#if !CAPNP_LITE +static const uint16_t m_abac22840c889893[] = {0, 1}; +static const uint16_t i_abac22840c889893[] = {0, 1}; +const ::capnp::_::RawSchema s_abac22840c889893 = { + 0xabac22840c889893, b_abac22840c889893.words, 53, nullptr, m_abac22840c889893, + 0, 2, i_abac22840c889893, nullptr, nullptr, { &s_abac22840c889893, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<161> b_b24841000c998eed = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 17, 0, 0, 0, 1, 0, 0, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 4, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 21, 0, 0, 0, 66, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 2, 0, 0, 15, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 79, 98, 106, 101, 99, 116, 67, + 111, 110, 116, 97, 105, 110, 101, 114, + 70, 111, 114, 84, 121, 112, 101, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 168, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 165, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 164, 0, 0, 0, 3, 0, 1, 0, + 240, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 232, 0, 0, 0, 3, 0, 1, 0, + 52, 1, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 1, 0, 0, 170, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 52, 1, 0, 0, 3, 0, 1, 0, + 176, 1, 0, 0, 2, 0, 1, 0, + 98, 97, 115, 105, 99, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 53, 95, 202, 3, 71, 42, 91, 155, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 53, 95, 202, 3, 71, 42, 91, 155, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 119, 105, 116, 104, 80, 114, 111, 112, + 101, 114, 116, 105, 101, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 147, 152, 136, 12, 132, 34, 172, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 147, 152, 136, 12, 132, 34, 172, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 114, 114, 97, 121, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 194, 159, 43, 198, 42, 217, 80, 183, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 194, 159, 43, 198, 42, 217, 80, 183, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 114, 114, 97, 121, 115, 87, 105, + 116, 104, 80, 114, 111, 112, 101, 114, + 116, 105, 101, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 147, 152, 136, 12, 132, 34, 172, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 147, 152, 136, 12, 132, 34, 172, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 194, 159, 43, 198, 42, 217, 80, 183, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 194, 159, 43, 198, 42, 217, 80, 183, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 58, 0, 0, 0, + 79, 98, 106, 101, 99, 116, 0, 0, } +}; +::capnp::word const* const bp_b24841000c998eed = b_b24841000c998eed.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_b24841000c998eed[] = { + &s_9b5b2a4703ca5f35, + &s_abac22840c889893, + &s_b750d92ac62b9fc2, +}; +static const uint16_t m_b24841000c998eed[] = {2, 3, 0, 1}; +static const uint16_t i_b24841000c998eed[] = {0, 1, 2, 3}; +KJ_CONSTEXPR(const) ::capnp::_::RawBrandedSchema::Dependency bd_b24841000c998eed[] = { + { 16777216, ::stream::layoutView::SingleObject< ::capnp::AnyPointer>::_capnpPrivate::brand() }, + { 16777217, ::stream::layoutView::ObjectWithProperties< ::capnp::AnyPointer>::_capnpPrivate::brand() }, + { 16777218, ::stream::layoutView::ObjectArray< ::capnp::AnyPointer>::_capnpPrivate::brand() }, + { 16777219, ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray< ::capnp::AnyPointer>>::_capnpPrivate::brand() }, +}; +const ::capnp::_::RawSchema s_b24841000c998eed = { + 0xb24841000c998eed, b_b24841000c998eed.words, 161, d_b24841000c998eed, m_b24841000c998eed, + 3, 4, i_b24841000c998eed, nullptr, nullptr, { &s_b24841000c998eed, nullptr, bd_b24841000c998eed, 0, sizeof(bd_b24841000c998eed) / sizeof(bd_b24841000c998eed[0]), nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<271> b_df03c9c3399688cd = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 205, 136, 150, 57, 195, 201, 3, 223, + 17, 0, 0, 0, 1, 0, 1, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 9, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 186, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 55, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 76, 97, 121, 101, 114, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 40, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 1, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 1, 0, 0, 3, 0, 1, 0, + 16, 1, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 1, 0, 0, 3, 0, 1, 0, + 40, 1, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 37, 1, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 1, 0, 0, 3, 0, 1, 0, + 92, 1, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 89, 1, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 1, 0, 0, 3, 0, 1, 0, + 148, 1, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 145, 1, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 144, 1, 0, 0, 3, 0, 1, 0, + 204, 1, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 201, 1, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 196, 1, 0, 0, 3, 0, 1, 0, + 0, 2, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 253, 1, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 248, 1, 0, 0, 3, 0, 1, 0, + 52, 2, 0, 0, 2, 0, 1, 0, + 7, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 2, 0, 0, 3, 0, 1, 0, + 104, 2, 0, 0, 2, 0, 1, 0, + 8, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 1, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 2, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 2, 0, 0, 3, 0, 1, 0, + 160, 2, 0, 0, 2, 0, 1, 0, + 9, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 1, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 157, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 152, 2, 0, 0, 3, 0, 1, 0, + 212, 2, 0, 0, 2, 0, 1, 0, + 108, 97, 121, 101, 114, 73, 100, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 231, 25, 189, 226, 172, 15, 124, 146, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 111, 120, 101, 115, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 158, 145, 4, 91, 177, 11, 122, 176, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 111, 108, 121, 103, 111, 110, 115, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 1, 5, 132, 43, 154, 159, 160, 135, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 105, 109, 112, 108, 101, 80, 111, + 108, 121, 103, 111, 110, 115, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 53, 7, 64, 153, 248, 191, 138, 129, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 97, 116, 104, 115, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 100, 163, 13, 128, 25, 146, 67, 201, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 98, 101, 108, 115, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 102, 132, 115, 102, 130, 45, 134, 200, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 100, 103, 101, 115, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 90, 124, 76, 173, 96, 117, 173, 211, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 100, 103, 101, 80, 97, 105, 114, + 115, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 182, 216, 190, 149, 201, 67, 136, 220, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 111, 105, 110, 116, 115, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 80, 124, 138, 135, 42, 37, 22, 162, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_df03c9c3399688cd = b_df03c9c3399688cd.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_df03c9c3399688cd[] = { + &s_927c0face2bd19e7, + &s_b24841000c998eed, +}; +static const uint16_t m_df03c9c3399688cd[] = {2, 8, 7, 6, 0, 5, 9, 3, 1, 4}; +static const uint16_t i_df03c9c3399688cd[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +KJ_CONSTEXPR(const) ::capnp::_::RawBrandedSchema::Dependency bd_df03c9c3399688cd[] = { + { 16777218, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::_capnpPrivate::brand() }, + { 16777219, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::_capnpPrivate::brand() }, + { 16777220, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::_capnpPrivate::brand() }, + { 16777221, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::_capnpPrivate::brand() }, + { 16777222, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::_capnpPrivate::brand() }, + { 16777223, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::_capnpPrivate::brand() }, + { 16777224, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::_capnpPrivate::brand() }, + { 16777225, ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::_capnpPrivate::brand() }, +}; +const ::capnp::_::RawSchema s_df03c9c3399688cd = { + 0xdf03c9c3399688cd, b_df03c9c3399688cd.words, 271, d_df03c9c3399688cd, m_df03c9c3399688cd, + 2, 10, i_df03c9c3399688cd, nullptr, nullptr, { &s_df03c9c3399688cd, nullptr, bd_df03c9c3399688cd, 0, sizeof(bd_df03c9c3399688cd) / sizeof(bd_df03c9c3399688cd[0]), nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<44> b_9de3506f30432621 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 33, 38, 67, 48, 111, 80, 227, 157, + 17, 0, 0, 0, 1, 0, 3, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 34, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 67, 101, 108, 108, 84, 114, 97, + 110, 115, 102, 111, 114, 109, 97, 116, + 105, 111, 110, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 27, 153, 207, 104, 20, 138, 134, + 49, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 112, 108, 97, 99, 101, + 109, 101, 110, 116, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 114, 97, 110, 115, 102, 111, 114, + 109, 97, 116, 105, 111, 110, 0, 0, } +}; +::capnp::word const* const bp_9de3506f30432621 = b_9de3506f30432621.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9de3506f30432621[] = { + &s_868a1468cf991b01, + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_9de3506f30432621[] = {0, 1}; +static const uint16_t i_9de3506f30432621[] = {0, 1}; +const ::capnp::_::RawSchema s_9de3506f30432621 = { + 0x9de3506f30432621, b_9de3506f30432621.words, 44, d_9de3506f30432621, m_9de3506f30432621, + 2, 2, i_9de3506f30432621, nullptr, nullptr, { &s_9de3506f30432621, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<36> b_868a1468cf991b01 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 1, 27, 153, 207, 104, 20, 138, 134, + 36, 0, 0, 0, 1, 0, 3, 0, + 33, 38, 67, 48, 111, 80, 227, 157, + 1, 0, 7, 0, 1, 0, 2, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 154, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 37, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 67, 101, 108, 108, 84, 114, 97, + 110, 115, 102, 111, 114, 109, 97, 116, + 105, 111, 110, 46, 116, 114, 97, 110, + 115, 102, 111, 114, 109, 97, 116, 105, + 111, 110, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 36, 242, 221, 64, 12, 162, 87, 191, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 254, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 255, 157, 205, 186, 125, 130, 84, 241, + 17, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 105, 109, 112, 108, 101, 0, 0, + 99, 111, 109, 112, 108, 101, 120, 0, } +}; +::capnp::word const* const bp_868a1468cf991b01 = b_868a1468cf991b01.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_868a1468cf991b01[] = { + &s_9de3506f30432621, + &s_bf57a20c40ddf224, + &s_f154827dbacd9dff, +}; +static const uint16_t m_868a1468cf991b01[] = {1, 0}; +static const uint16_t i_868a1468cf991b01[] = {0, 1}; +const ::capnp::_::RawSchema s_868a1468cf991b01 = { + 0x868a1468cf991b01, b_868a1468cf991b01.words, 36, d_868a1468cf991b01, m_868a1468cf991b01, + 3, 2, i_868a1468cf991b01, nullptr, nullptr, { &s_868a1468cf991b01, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<37> b_bf57a20c40ddf224 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 36, 242, 221, 64, 12, 162, 87, 191, + 51, 0, 0, 0, 1, 0, 3, 0, + 1, 27, 153, 207, 104, 20, 138, 134, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 210, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 67, 101, 108, 108, 84, 114, 97, + 110, 115, 102, 111, 114, 109, 97, 116, + 105, 111, 110, 46, 116, 114, 97, 110, + 115, 102, 111, 114, 109, 97, 116, 105, + 111, 110, 46, 115, 105, 109, 112, 108, + 101, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 24, 0, 0, 0, 2, 0, 1, 0, + 111, 114, 105, 101, 110, 116, 97, 116, + 105, 111, 110, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 23, 145, 81, 151, 52, 20, 168, 204, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_bf57a20c40ddf224 = b_bf57a20c40ddf224.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_bf57a20c40ddf224[] = { + &s_868a1468cf991b01, + &s_cca8143497519117, +}; +static const uint16_t m_bf57a20c40ddf224[] = {0}; +static const uint16_t i_bf57a20c40ddf224[] = {0}; +const ::capnp::_::RawSchema s_bf57a20c40ddf224 = { + 0xbf57a20c40ddf224, b_bf57a20c40ddf224.words, 37, d_bf57a20c40ddf224, m_bf57a20c40ddf224, + 2, 1, i_bf57a20c40ddf224, nullptr, nullptr, { &s_bf57a20c40ddf224, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<66> b_f154827dbacd9dff = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 255, 157, 205, 186, 125, 130, 84, 241, + 51, 0, 0, 0, 1, 0, 3, 0, + 1, 27, 153, 207, 104, 20, 138, 134, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 218, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 67, 101, 108, 108, 84, 114, 97, + 110, 115, 102, 111, 114, 109, 97, 116, + 105, 111, 110, 46, 116, 114, 97, 110, + 115, 102, 111, 114, 109, 97, 116, 105, + 111, 110, 46, 99, 111, 109, 112, 108, + 101, 120, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 68, 0, 0, 0, 3, 0, 1, 0, + 80, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 77, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 97, 110, 103, 108, 101, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 105, 114, 114, 111, 114, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 99, 97, 108, 101, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_f154827dbacd9dff = b_f154827dbacd9dff.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_f154827dbacd9dff[] = { + &s_868a1468cf991b01, +}; +static const uint16_t m_f154827dbacd9dff[] = {0, 1, 2}; +static const uint16_t i_f154827dbacd9dff[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_f154827dbacd9dff = { + 0xf154827dbacd9dff, b_f154827dbacd9dff.words, 66, d_f154827dbacd9dff, m_f154827dbacd9dff, + 1, 3, i_f154827dbacd9dff, nullptr, nullptr, { &s_f154827dbacd9dff, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<49> b_a41ef417a8cd6629 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 41, 102, 205, 168, 23, 244, 30, 164, + 17, 0, 0, 0, 1, 0, 1, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 67, 101, 108, 108, 73, 110, 115, + 116, 97, 110, 99, 101, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 56, 0, 0, 0, 2, 0, 1, 0, + 99, 101, 108, 108, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 114, 97, 110, 115, 102, 111, 114, + 109, 97, 116, 105, 111, 110, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 33, 38, 67, 48, 111, 80, 227, 157, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_a41ef417a8cd6629 = b_a41ef417a8cd6629.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_a41ef417a8cd6629[] = { + &s_9de3506f30432621, +}; +static const uint16_t m_a41ef417a8cd6629[] = {0, 1}; +static const uint16_t i_a41ef417a8cd6629[] = {0, 1}; +const ::capnp::_::RawSchema s_a41ef417a8cd6629 = { + 0xa41ef417a8cd6629, b_a41ef417a8cd6629.words, 49, d_a41ef417a8cd6629, m_a41ef417a8cd6629, + 1, 2, i_a41ef417a8cd6629, nullptr, nullptr, { &s_a41ef417a8cd6629, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<102> b_b86aa231e67a92b2 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 178, 146, 122, 230, 49, 162, 106, 184, + 17, 0, 0, 0, 1, 0, 0, 0, + 224, 52, 174, 54, 16, 132, 58, 151, + 4, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 226, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 111, 117, 116, 86, 105, + 101, 119, 46, 99, 97, 112, 110, 112, + 58, 76, 97, 121, 111, 117, 116, 86, + 105, 101, 119, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 0, 0, 0, 3, 0, 1, 0, + 128, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 125, 0, 0, 0, 162, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 3, 0, 1, 0, + 156, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 153, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 1, 0, + 212, 0, 0, 0, 2, 0, 1, 0, + 98, 111, 117, 110, 100, 105, 110, 103, + 66, 111, 120, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 158, 145, 4, 91, 177, 11, 122, 176, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 101, 114, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 205, 136, 150, 57, 195, 201, 3, 223, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 115, 116, 97, 110, 99, 101, + 82, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 231, 25, 189, 226, 172, 15, 124, 146, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 115, 116, 97, 110, 99, 101, + 115, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 31, 0, 0, 0, + 4, 0, 0, 0, 2, 0, 1, 0, + 237, 142, 153, 12, 0, 65, 72, 178, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 23, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 41, 102, 205, 168, 23, 244, 30, 164, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b86aa231e67a92b2 = b_b86aa231e67a92b2.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_b86aa231e67a92b2[] = { + &s_927c0face2bd19e7, + &s_b07a0bb15b04919e, + &s_b24841000c998eed, + &s_df03c9c3399688cd, +}; +static const uint16_t m_b86aa231e67a92b2[] = {0, 2, 3, 1}; +static const uint16_t i_b86aa231e67a92b2[] = {0, 1, 2, 3}; +KJ_CONSTEXPR(const) ::capnp::_::RawBrandedSchema::Dependency bd_b86aa231e67a92b2[] = { + { 16777219, ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::_capnpPrivate::brand() }, +}; +const ::capnp::_::RawSchema s_b86aa231e67a92b2 = { + 0xb86aa231e67a92b2, b_b86aa231e67a92b2.words, 102, d_b86aa231e67a92b2, m_b86aa231e67a92b2, + 4, 4, i_b86aa231e67a92b2, nullptr, nullptr, { &s_b86aa231e67a92b2, nullptr, bd_b86aa231e67a92b2, 0, sizeof(bd_b86aa231e67a92b2) / sizeof(bd_b86aa231e67a92b2[0]), nullptr }, true +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace layoutView { + +// Layer +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Layer::_capnpPrivate::dataWordSize; +constexpr uint16_t Layer::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Layer::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Layer::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellTransformation +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellTransformation::_capnpPrivate::dataWordSize; +constexpr uint16_t CellTransformation::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellTransformation::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellTransformation::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellTransformation::Transformation +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellTransformation::Transformation::_capnpPrivate::dataWordSize; +constexpr uint16_t CellTransformation::Transformation::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellTransformation::Transformation::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellTransformation::Transformation::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellTransformation::Transformation::Simple +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellTransformation::Transformation::Simple::_capnpPrivate::dataWordSize; +constexpr uint16_t CellTransformation::Transformation::Simple::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellTransformation::Transformation::Simple::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellTransformation::Transformation::Simple::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellTransformation::Transformation::Complex +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellTransformation::Transformation::Complex::_capnpPrivate::dataWordSize; +constexpr uint16_t CellTransformation::Transformation::Complex::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellTransformation::Transformation::Complex::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellTransformation::Transformation::Complex::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellInstance +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellInstance::_capnpPrivate::dataWordSize; +constexpr uint16_t CellInstance::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellInstance::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellInstance::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// LayoutView +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t LayoutView::_capnpPrivate::dataWordSize; +constexpr uint16_t LayoutView::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind LayoutView::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* LayoutView::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/layoutView.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/layoutView.capnp.h new file mode 100644 index 000000000..357ef6836 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/layoutView.capnp.h @@ -0,0 +1,2582 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: layoutView.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "geometry.capnp.h" +#include "repetition.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(9b5b2a4703ca5f35); +CAPNP_DECLARE_SCHEMA(b750d92ac62b9fc2); +CAPNP_DECLARE_SCHEMA(abac22840c889893); +CAPNP_DECLARE_SCHEMA(b24841000c998eed); +CAPNP_DECLARE_SCHEMA(df03c9c3399688cd); +CAPNP_DECLARE_SCHEMA(9de3506f30432621); +CAPNP_DECLARE_SCHEMA(868a1468cf991b01); +CAPNP_DECLARE_SCHEMA(bf57a20c40ddf224); +CAPNP_DECLARE_SCHEMA(f154827dbacd9dff); +CAPNP_DECLARE_SCHEMA(a41ef417a8cd6629); +CAPNP_DECLARE_SCHEMA(b86aa231e67a92b2); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace layoutView { + +template +struct SingleObject { + SingleObject() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9b5b2a4703ca5f35, 0, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, Object>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +template +struct ObjectArray { + ObjectArray() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b750d92ac62b9fc2, 1, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, Object>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +template +struct ObjectWithProperties { + ObjectWithProperties() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(abac22840c889893, 1, 1) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, Object>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +template +struct ObjectContainerForType { + ObjectContainerForType() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b24841000c998eed, 0, 4) + #if !CAPNP_LITE + static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; + static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; + static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; + static const ::capnp::_::RawBrandedSchema specificBrand; + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, Object>::brand(); } + #endif // !CAPNP_LITE + }; +}; + +struct Layer { + Layer() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(df03c9c3399688cd, 1, 9) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellTransformation { + CellTransformation() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Transformation; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9de3506f30432621, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellTransformation::Transformation { + Transformation() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + SIMPLE, + COMPLEX, + }; + struct Simple; + struct Complex; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(868a1468cf991b01, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellTransformation::Transformation::Simple { + Simple() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bf57a20c40ddf224, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellTransformation::Transformation::Complex { + Complex() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f154827dbacd9dff, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellInstance { + CellInstance() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a41ef417a8cd6629, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct LayoutView { + LayoutView() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b86aa231e67a92b2, 0, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +template +class SingleObject::Reader { +public: + typedef SingleObject Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename SingleObject::Reader asGeneric() { + return typename SingleObject::Reader(_reader); + } + + inline bool hasBasic() const; + inline ::capnp::ReaderFor getBasic() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class SingleObject::Builder { +public: + typedef SingleObject Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename SingleObject::Builder asGeneric() { + return typename SingleObject::Builder(_builder); + } + + inline bool hasBasic(); + inline ::capnp::BuilderFor getBasic(); + inline void setBasic( ::capnp::ReaderFor value); + inline ::capnp::BuilderFor initBasic(); + inline ::capnp::BuilderFor initBasic(unsigned int size); + inline void adoptBasic(::capnp::Orphan&& value); + inline ::capnp::Orphan disownBasic(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class SingleObject::Pipeline { +public: + typedef SingleObject Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor getBasic(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template +class ObjectArray::Reader { +public: + typedef ObjectArray Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename ObjectArray::Reader asGeneric() { + return typename ObjectArray::Reader(_reader); + } + + inline bool hasBasic() const; + inline ::capnp::ReaderFor getBasic() const; + + inline ::uint64_t getRepetitionId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class ObjectArray::Builder { +public: + typedef ObjectArray Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename ObjectArray::Builder asGeneric() { + return typename ObjectArray::Builder(_builder); + } + + inline bool hasBasic(); + inline ::capnp::BuilderFor getBasic(); + inline void setBasic( ::capnp::ReaderFor value); + inline ::capnp::BuilderFor initBasic(); + inline ::capnp::BuilderFor initBasic(unsigned int size); + inline void adoptBasic(::capnp::Orphan&& value); + inline ::capnp::Orphan disownBasic(); + + inline ::uint64_t getRepetitionId(); + inline void setRepetitionId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class ObjectArray::Pipeline { +public: + typedef ObjectArray Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor getBasic(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template +class ObjectWithProperties::Reader { +public: + typedef ObjectWithProperties Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename ObjectWithProperties::Reader asGeneric() { + return typename ObjectWithProperties::Reader(_reader); + } + + inline bool hasBasic() const; + inline ::capnp::ReaderFor getBasic() const; + + inline ::uint64_t getPropertySetId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class ObjectWithProperties::Builder { +public: + typedef ObjectWithProperties Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename ObjectWithProperties::Builder asGeneric() { + return typename ObjectWithProperties::Builder(_builder); + } + + inline bool hasBasic(); + inline ::capnp::BuilderFor getBasic(); + inline void setBasic( ::capnp::ReaderFor value); + inline ::capnp::BuilderFor initBasic(); + inline ::capnp::BuilderFor initBasic(unsigned int size); + inline void adoptBasic(::capnp::Orphan&& value); + inline ::capnp::Orphan disownBasic(); + + inline ::uint64_t getPropertySetId(); + inline void setPropertySetId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class ObjectWithProperties::Pipeline { +public: + typedef ObjectWithProperties Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::PipelineFor getBasic(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +template +class ObjectContainerForType::Reader { +public: + typedef ObjectContainerForType Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + template + typename ObjectContainerForType::Reader asGeneric() { + return typename ObjectContainerForType::Reader(_reader); + } + + inline bool hasBasic() const; + inline typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Reader getBasic() const; + + inline bool hasWithProperties() const; + inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Reader getWithProperties() const; + + inline bool hasArrays() const; + inline typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Reader getArrays() const; + + inline bool hasArraysWithProperties() const; + inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Reader getArraysWithProperties() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +template +class ObjectContainerForType::Builder { +public: + typedef ObjectContainerForType Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + template + typename ObjectContainerForType::Builder asGeneric() { + return typename ObjectContainerForType::Builder(_builder); + } + + inline bool hasBasic(); + inline typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Builder getBasic(); + inline void setBasic(typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Reader value); + inline typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Builder initBasic(unsigned int size); + inline void adoptBasic(::capnp::Orphan< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>> disownBasic(); + + inline bool hasWithProperties(); + inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Builder getWithProperties(); + inline void setWithProperties(typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Reader value); + inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Builder initWithProperties(unsigned int size); + inline void adoptWithProperties(::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>> disownWithProperties(); + + inline bool hasArrays(); + inline typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Builder getArrays(); + inline void setArrays(typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Reader value); + inline typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Builder initArrays(unsigned int size); + inline void adoptArrays(::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>> disownArrays(); + + inline bool hasArraysWithProperties(); + inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Builder getArraysWithProperties(); + inline void setArraysWithProperties(typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Reader value); + inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Builder initArraysWithProperties(unsigned int size); + inline void adoptArraysWithProperties(::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>> disownArraysWithProperties(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +template +class ObjectContainerForType::Pipeline { +public: + typedef ObjectContainerForType Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Layer::Reader { +public: + typedef Layer Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getLayerId() const; + + inline bool hasRepetitions() const; + inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader getRepetitions() const; + + inline bool hasBoxes() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Reader getBoxes() const; + + inline bool hasPolygons() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Reader getPolygons() const; + + inline bool hasSimplePolygons() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Reader getSimplePolygons() const; + + inline bool hasPaths() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Reader getPaths() const; + + inline bool hasLabels() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Reader getLabels() const; + + inline bool hasEdges() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Reader getEdges() const; + + inline bool hasEdgePairs() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Reader getEdgePairs() const; + + inline bool hasPoints() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Reader getPoints() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Layer::Builder { +public: + typedef Layer Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getLayerId(); + inline void setLayerId( ::uint64_t value); + + inline bool hasRepetitions(); + inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder getRepetitions(); + inline void setRepetitions( ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder initRepetitions(unsigned int size); + inline void adoptRepetitions(::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>> disownRepetitions(); + + inline bool hasBoxes(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Builder getBoxes(); + inline void setBoxes( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Builder initBoxes(); + inline void adoptBoxes(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>> disownBoxes(); + + inline bool hasPolygons(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Builder getPolygons(); + inline void setPolygons( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Builder initPolygons(); + inline void adoptPolygons(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>> disownPolygons(); + + inline bool hasSimplePolygons(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Builder getSimplePolygons(); + inline void setSimplePolygons( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Builder initSimplePolygons(); + inline void adoptSimplePolygons(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>> disownSimplePolygons(); + + inline bool hasPaths(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Builder getPaths(); + inline void setPaths( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Builder initPaths(); + inline void adoptPaths(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>> disownPaths(); + + inline bool hasLabels(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Builder getLabels(); + inline void setLabels( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Builder initLabels(); + inline void adoptLabels(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>> disownLabels(); + + inline bool hasEdges(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Builder getEdges(); + inline void setEdges( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Builder initEdges(); + inline void adoptEdges(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>> disownEdges(); + + inline bool hasEdgePairs(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Builder getEdgePairs(); + inline void setEdgePairs( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Builder initEdgePairs(); + inline void adoptEdgePairs(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>> disownEdgePairs(); + + inline bool hasPoints(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Builder getPoints(); + inline void setPoints( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Builder initPoints(); + inline void adoptPoints(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>> disownPoints(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Layer::Pipeline { +public: + typedef Layer Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Pipeline getBoxes(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Pipeline getPolygons(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Pipeline getSimplePolygons(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Pipeline getPaths(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Pipeline getLabels(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Pipeline getEdges(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Pipeline getEdgePairs(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Pipeline getPoints(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellTransformation::Reader { +public: + typedef CellTransformation Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasDisplacement() const; + inline ::stream::geometry::Vector::Reader getDisplacement() const; + + inline typename Transformation::Reader getTransformation() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellTransformation::Builder { +public: + typedef CellTransformation Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasDisplacement(); + inline ::stream::geometry::Vector::Builder getDisplacement(); + inline void setDisplacement( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initDisplacement(); + inline void adoptDisplacement(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownDisplacement(); + + inline typename Transformation::Builder getTransformation(); + inline typename Transformation::Builder initTransformation(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellTransformation::Pipeline { +public: + typedef CellTransformation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Vector::Pipeline getDisplacement(); + inline typename Transformation::Pipeline getTransformation(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellTransformation::Transformation::Reader { +public: + typedef Transformation Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isSimple() const; + inline typename Simple::Reader getSimple() const; + + inline bool isComplex() const; + inline typename Complex::Reader getComplex() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellTransformation::Transformation::Builder { +public: + typedef Transformation Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isSimple(); + inline typename Simple::Builder getSimple(); + inline typename Simple::Builder initSimple(); + + inline bool isComplex(); + inline typename Complex::Builder getComplex(); + inline typename Complex::Builder initComplex(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellTransformation::Transformation::Pipeline { +public: + typedef Transformation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellTransformation::Transformation::Simple::Reader { +public: + typedef Simple Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::stream::geometry::FixPointTransformation getOrientation() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellTransformation::Transformation::Simple::Builder { +public: + typedef Simple Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::stream::geometry::FixPointTransformation getOrientation(); + inline void setOrientation( ::stream::geometry::FixPointTransformation value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellTransformation::Transformation::Simple::Pipeline { +public: + typedef Simple Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellTransformation::Transformation::Complex::Reader { +public: + typedef Complex Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline double getAngle() const; + + inline bool getMirror() const; + + inline double getScale() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellTransformation::Transformation::Complex::Builder { +public: + typedef Complex Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline double getAngle(); + inline void setAngle(double value); + + inline bool getMirror(); + inline void setMirror(bool value); + + inline double getScale(); + inline void setScale(double value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellTransformation::Transformation::Complex::Pipeline { +public: + typedef Complex Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellInstance::Reader { +public: + typedef CellInstance Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getCellId() const; + + inline bool hasTransformation() const; + inline ::stream::layoutView::CellTransformation::Reader getTransformation() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellInstance::Builder { +public: + typedef CellInstance Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getCellId(); + inline void setCellId( ::uint64_t value); + + inline bool hasTransformation(); + inline ::stream::layoutView::CellTransformation::Builder getTransformation(); + inline void setTransformation( ::stream::layoutView::CellTransformation::Reader value); + inline ::stream::layoutView::CellTransformation::Builder initTransformation(); + inline void adoptTransformation(::capnp::Orphan< ::stream::layoutView::CellTransformation>&& value); + inline ::capnp::Orphan< ::stream::layoutView::CellTransformation> disownTransformation(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellInstance::Pipeline { +public: + typedef CellInstance Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::layoutView::CellTransformation::Pipeline getTransformation(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class LayoutView::Reader { +public: + typedef LayoutView Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasBoundingBox() const; + inline ::stream::geometry::Box::Reader getBoundingBox() const; + + inline bool hasLayers() const; + inline ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Reader getLayers() const; + + inline bool hasInstanceRepetitions() const; + inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader getInstanceRepetitions() const; + + inline bool hasInstances() const; + inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Reader getInstances() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class LayoutView::Builder { +public: + typedef LayoutView Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasBoundingBox(); + inline ::stream::geometry::Box::Builder getBoundingBox(); + inline void setBoundingBox( ::stream::geometry::Box::Reader value); + inline ::stream::geometry::Box::Builder initBoundingBox(); + inline void adoptBoundingBox(::capnp::Orphan< ::stream::geometry::Box>&& value); + inline ::capnp::Orphan< ::stream::geometry::Box> disownBoundingBox(); + + inline bool hasLayers(); + inline ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Builder getLayers(); + inline void setLayers( ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Builder initLayers(unsigned int size); + inline void adoptLayers(::capnp::Orphan< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>> disownLayers(); + + inline bool hasInstanceRepetitions(); + inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder getInstanceRepetitions(); + inline void setInstanceRepetitions( ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder initInstanceRepetitions(unsigned int size); + inline void adoptInstanceRepetitions(::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>> disownInstanceRepetitions(); + + inline bool hasInstances(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Builder getInstances(); + inline void setInstances( ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Reader value); + inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Builder initInstances(); + inline void adoptInstances(::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>&& value); + inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>> disownInstances(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class LayoutView::Pipeline { +public: + typedef LayoutView Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Box::Pipeline getBoundingBox(); + inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Pipeline getInstances(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +template +inline bool SingleObject::Reader::hasBasic() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool SingleObject::Builder::hasBasic() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline ::capnp::ReaderFor SingleObject::Reader::getBasic() const { + return ::capnp::_::PointerHelpers::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor SingleObject::Builder::getBasic() { + return ::capnp::_::PointerHelpers::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline ::capnp::PipelineFor SingleObject::Pipeline::getBasic() { + return ::capnp::PipelineFor(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template +inline void SingleObject::Builder::setBasic( ::capnp::ReaderFor value) { + ::capnp::_::PointerHelpers::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +template +inline ::capnp::BuilderFor SingleObject::Builder::initBasic() { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor SingleObject::Builder::initBasic(unsigned int size) { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +template +inline void SingleObject::Builder::adoptBasic( + ::capnp::Orphan&& value) { + ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan SingleObject::Builder::disownBasic() { + return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +// SingleObject +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr uint16_t SingleObject::_capnpPrivate::dataWordSize; +template +constexpr uint16_t SingleObject::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr ::capnp::Kind SingleObject::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* SingleObject::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +const ::capnp::_::RawBrandedSchema::Scope SingleObject::_capnpPrivate::brandScopes[] = { + { 0x9b5b2a4703ca5f35, brandBindings + 0, 1, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding SingleObject::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema SingleObject::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_9b5b2a4703ca5f35, brandScopes, nullptr, + 1, 0, nullptr +}; +#endif // !CAPNP_LITE + +template +inline bool ObjectArray::Reader::hasBasic() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool ObjectArray::Builder::hasBasic() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline ::capnp::ReaderFor ObjectArray::Reader::getBasic() const { + return ::capnp::_::PointerHelpers::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor ObjectArray::Builder::getBasic() { + return ::capnp::_::PointerHelpers::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline ::capnp::PipelineFor ObjectArray::Pipeline::getBasic() { + return ::capnp::PipelineFor(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template +inline void ObjectArray::Builder::setBasic( ::capnp::ReaderFor value) { + ::capnp::_::PointerHelpers::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +template +inline ::capnp::BuilderFor ObjectArray::Builder::initBasic() { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor ObjectArray::Builder::initBasic(unsigned int size) { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +template +inline void ObjectArray::Builder::adoptBasic( + ::capnp::Orphan&& value) { + ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan ObjectArray::Builder::disownBasic() { + return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +template +inline ::uint64_t ObjectArray::Reader::getRepetitionId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +template +inline ::uint64_t ObjectArray::Builder::getRepetitionId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +template +inline void ObjectArray::Builder::setRepetitionId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +// ObjectArray +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr uint16_t ObjectArray::_capnpPrivate::dataWordSize; +template +constexpr uint16_t ObjectArray::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr ::capnp::Kind ObjectArray::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* ObjectArray::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +const ::capnp::_::RawBrandedSchema::Scope ObjectArray::_capnpPrivate::brandScopes[] = { + { 0xb750d92ac62b9fc2, brandBindings + 0, 1, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding ObjectArray::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema ObjectArray::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_b750d92ac62b9fc2, brandScopes, nullptr, + 1, 0, nullptr +}; +#endif // !CAPNP_LITE + +template +inline bool ObjectWithProperties::Reader::hasBasic() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool ObjectWithProperties::Builder::hasBasic() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline ::capnp::ReaderFor ObjectWithProperties::Reader::getBasic() const { + return ::capnp::_::PointerHelpers::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor ObjectWithProperties::Builder::getBasic() { + return ::capnp::_::PointerHelpers::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +template +inline ::capnp::PipelineFor ObjectWithProperties::Pipeline::getBasic() { + return ::capnp::PipelineFor(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +template +inline void ObjectWithProperties::Builder::setBasic( ::capnp::ReaderFor value) { + ::capnp::_::PointerHelpers::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +template +inline ::capnp::BuilderFor ObjectWithProperties::Builder::initBasic() { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline ::capnp::BuilderFor ObjectWithProperties::Builder::initBasic(unsigned int size) { + return ::capnp::_::PointerHelpers::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +template +inline void ObjectWithProperties::Builder::adoptBasic( + ::capnp::Orphan&& value) { + ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan ObjectWithProperties::Builder::disownBasic() { + return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +template +inline ::uint64_t ObjectWithProperties::Reader::getPropertySetId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +template +inline ::uint64_t ObjectWithProperties::Builder::getPropertySetId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +template +inline void ObjectWithProperties::Builder::setPropertySetId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +// ObjectWithProperties +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr uint16_t ObjectWithProperties::_capnpPrivate::dataWordSize; +template +constexpr uint16_t ObjectWithProperties::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr ::capnp::Kind ObjectWithProperties::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* ObjectWithProperties::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +const ::capnp::_::RawBrandedSchema::Scope ObjectWithProperties::_capnpPrivate::brandScopes[] = { + { 0xabac22840c889893, brandBindings + 0, 1, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding ObjectWithProperties::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema ObjectWithProperties::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_abac22840c889893, brandScopes, nullptr, + 1, 0, nullptr +}; +#endif // !CAPNP_LITE + +template +inline bool ObjectContainerForType::Reader::hasBasic() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline bool ObjectContainerForType::Builder::hasBasic() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +template +inline typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Reader ObjectContainerForType::Reader::getBasic() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::getBasic() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +template +inline void ObjectContainerForType::Builder::setBasic(typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +template +inline typename ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::initBasic(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +template +inline void ObjectContainerForType::Builder::adoptBasic( + ::capnp::Orphan< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>> ObjectContainerForType::Builder::disownBasic() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::SingleObject, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +template +inline bool ObjectContainerForType::Reader::hasWithProperties() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +template +inline bool ObjectContainerForType::Builder::hasWithProperties() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Reader ObjectContainerForType::Reader::getWithProperties() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::getWithProperties() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +template +inline void ObjectContainerForType::Builder::setWithProperties(typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::initWithProperties(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +template +inline void ObjectContainerForType::Builder::adoptWithProperties( + ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>> ObjectContainerForType::Builder::disownWithProperties() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +template +inline bool ObjectContainerForType::Reader::hasArrays() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +template +inline bool ObjectContainerForType::Builder::hasArrays() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Reader ObjectContainerForType::Reader::getArrays() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::getArrays() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +template +inline void ObjectContainerForType::Builder::setArrays(typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::initArrays(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), size); +} +template +inline void ObjectContainerForType::Builder::adoptArrays( + ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>> ObjectContainerForType::Builder::disownArrays() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectArray, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +template +inline bool ObjectContainerForType::Reader::hasArraysWithProperties() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +template +inline bool ObjectContainerForType::Builder::hasArraysWithProperties() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Reader ObjectContainerForType::Reader::getArraysWithProperties() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::getArraysWithProperties() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +template +inline void ObjectContainerForType::Builder::setArraysWithProperties(typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +template +inline typename ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>::Builder ObjectContainerForType::Builder::initArraysWithProperties(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +template +inline void ObjectContainerForType::Builder::adoptArraysWithProperties( + ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +template +inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>> ObjectContainerForType::Builder::disownArraysWithProperties() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +// ObjectContainerForType +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr uint16_t ObjectContainerForType::_capnpPrivate::dataWordSize; +template +constexpr uint16_t ObjectContainerForType::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +constexpr ::capnp::Kind ObjectContainerForType::_capnpPrivate::kind; +template +constexpr ::capnp::_::RawSchema const* ObjectContainerForType::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +template +const ::capnp::_::RawBrandedSchema::Scope ObjectContainerForType::_capnpPrivate::brandScopes[] = { + { 0xb24841000c998eed, brandBindings + 0, 1, false}, +}; +template +const ::capnp::_::RawBrandedSchema::Binding ObjectContainerForType::_capnpPrivate::brandBindings[] = { + ::capnp::_::brandBindingFor(), +}; +template +const ::capnp::_::RawBrandedSchema::Dependency ObjectContainerForType::_capnpPrivate::brandDependencies[] = { + { 16777216, ::stream::layoutView::SingleObject::_capnpPrivate::brand() }, + { 16777217, ::stream::layoutView::ObjectWithProperties::_capnpPrivate::brand() }, + { 16777218, ::stream::layoutView::ObjectArray::_capnpPrivate::brand() }, + { 16777219, ::stream::layoutView::ObjectWithProperties< ::stream::layoutView::ObjectArray>::_capnpPrivate::brand() }, +}; +template +const ::capnp::_::RawBrandedSchema ObjectContainerForType::_capnpPrivate::specificBrand = { + &::capnp::schemas::s_b24841000c998eed, brandScopes, brandDependencies, + 1, 4, nullptr +}; +#endif // !CAPNP_LITE + +inline ::uint64_t Layer::Reader::getLayerId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Layer::Builder::getLayerId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Layer::Builder::setLayerId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Layer::Reader::hasRepetitions() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasRepetitions() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader Layer::Reader::getRepetitions() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder Layer::Builder::getRepetitions() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::setRepetitions( ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder Layer::Builder::initRepetitions(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Layer::Builder::adoptRepetitions( + ::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>> Layer::Builder::disownRepetitions() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasBoxes() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasBoxes() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Reader Layer::Reader::getBoxes() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Builder Layer::Builder::getBoxes() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Pipeline Layer::Pipeline::getBoxes() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setBoxes( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>::Builder Layer::Builder::initBoxes() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptBoxes( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>> Layer::Builder::disownBoxes() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Box>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasPolygons() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasPolygons() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Reader Layer::Reader::getPolygons() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Builder Layer::Builder::getPolygons() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Pipeline Layer::Pipeline::getPolygons() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setPolygons( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>::Builder Layer::Builder::initPolygons() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptPolygons( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>> Layer::Builder::disownPolygons() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Polygon>>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasSimplePolygons() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasSimplePolygons() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Reader Layer::Reader::getSimplePolygons() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Builder Layer::Builder::getSimplePolygons() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Pipeline Layer::Pipeline::getSimplePolygons() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setSimplePolygons( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>::Builder Layer::Builder::initSimplePolygons() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptSimplePolygons( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>> Layer::Builder::disownSimplePolygons() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::SimplePolygon>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasPaths() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasPaths() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Reader Layer::Reader::getPaths() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Builder Layer::Builder::getPaths() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Pipeline Layer::Pipeline::getPaths() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Pipeline(_typeless.getPointerField(4)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setPaths( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>::Builder Layer::Builder::initPaths() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptPaths( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>> Layer::Builder::disownPaths() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Path>>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasLabels() const { + return !_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasLabels() { + return !_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Reader Layer::Reader::getLabels() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>::get(_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Builder Layer::Builder::getLabels() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>::get(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Pipeline Layer::Pipeline::getLabels() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Pipeline(_typeless.getPointerField(5)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setLabels( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>::set(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>::Builder Layer::Builder::initLabels() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>::init(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptLabels( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>::adopt(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>> Layer::Builder::disownLabels() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Label>>::disown(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasEdges() const { + return !_reader.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasEdges() { + return !_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Reader Layer::Reader::getEdges() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>::get(_reader.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Builder Layer::Builder::getEdges() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>::get(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Pipeline Layer::Pipeline::getEdges() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Pipeline(_typeless.getPointerField(6)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setEdges( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>::set(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>::Builder Layer::Builder::initEdges() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>::init(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptEdges( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>::adopt(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>> Layer::Builder::disownEdges() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Edge>>::disown(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasEdgePairs() const { + return !_reader.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasEdgePairs() { + return !_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Reader Layer::Reader::getEdgePairs() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>::get(_reader.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Builder Layer::Builder::getEdgePairs() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>::get(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Pipeline Layer::Pipeline::getEdgePairs() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Pipeline(_typeless.getPointerField(7)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setEdgePairs( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>::set(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>::Builder Layer::Builder::initEdgePairs() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>::init(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptEdgePairs( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>::adopt(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>> Layer::Builder::disownEdgePairs() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::EdgePair>>::disown(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} + +inline bool Layer::Reader::hasPoints() const { + return !_reader.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS).isNull(); +} +inline bool Layer::Builder::hasPoints() { + return !_builder.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Reader Layer::Reader::getPoints() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>::get(_reader.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Builder Layer::Builder::getPoints() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>::get(_builder.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Pipeline Layer::Pipeline::getPoints() { + return ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Pipeline(_typeless.getPointerField(8)); +} +#endif // !CAPNP_LITE +inline void Layer::Builder::setPoints( ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>::set(_builder.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>::Builder Layer::Builder::initPoints() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>::init(_builder.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS)); +} +inline void Layer::Builder::adoptPoints( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>::adopt(_builder.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>> Layer::Builder::disownPoints() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::geometry::Point>>::disown(_builder.getPointerField( + ::capnp::bounded<8>() * ::capnp::POINTERS)); +} + +inline bool CellTransformation::Reader::hasDisplacement() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellTransformation::Builder::hasDisplacement() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader CellTransformation::Reader::getDisplacement() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder CellTransformation::Builder::getDisplacement() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Vector::Pipeline CellTransformation::Pipeline::getDisplacement() { + return ::stream::geometry::Vector::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void CellTransformation::Builder::setDisplacement( ::stream::geometry::Vector::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder CellTransformation::Builder::initDisplacement() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellTransformation::Builder::adoptDisplacement( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> CellTransformation::Builder::disownDisplacement() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline typename CellTransformation::Transformation::Reader CellTransformation::Reader::getTransformation() const { + return typename CellTransformation::Transformation::Reader(_reader); +} +inline typename CellTransformation::Transformation::Builder CellTransformation::Builder::getTransformation() { + return typename CellTransformation::Transformation::Builder(_builder); +} +#if !CAPNP_LITE +inline typename CellTransformation::Transformation::Pipeline CellTransformation::Pipeline::getTransformation() { + return typename CellTransformation::Transformation::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename CellTransformation::Transformation::Builder CellTransformation::Builder::initTransformation() { + _builder.setDataField< ::uint16_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename CellTransformation::Transformation::Builder(_builder); +} +inline ::stream::layoutView::CellTransformation::Transformation::Which CellTransformation::Transformation::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline ::stream::layoutView::CellTransformation::Transformation::Which CellTransformation::Transformation::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline bool CellTransformation::Transformation::Reader::isSimple() const { + return which() == CellTransformation::Transformation::SIMPLE; +} +inline bool CellTransformation::Transformation::Builder::isSimple() { + return which() == CellTransformation::Transformation::SIMPLE; +} +inline typename CellTransformation::Transformation::Simple::Reader CellTransformation::Transformation::Reader::getSimple() const { + KJ_IREQUIRE((which() == CellTransformation::Transformation::SIMPLE), + "Must check which() before get()ing a union member."); + return typename CellTransformation::Transformation::Simple::Reader(_reader); +} +inline typename CellTransformation::Transformation::Simple::Builder CellTransformation::Transformation::Builder::getSimple() { + KJ_IREQUIRE((which() == CellTransformation::Transformation::SIMPLE), + "Must check which() before get()ing a union member."); + return typename CellTransformation::Transformation::Simple::Builder(_builder); +} +inline typename CellTransformation::Transformation::Simple::Builder CellTransformation::Transformation::Builder::initSimple() { + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, CellTransformation::Transformation::SIMPLE); + _builder.setDataField< ::uint16_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); + return typename CellTransformation::Transformation::Simple::Builder(_builder); +} +inline bool CellTransformation::Transformation::Reader::isComplex() const { + return which() == CellTransformation::Transformation::COMPLEX; +} +inline bool CellTransformation::Transformation::Builder::isComplex() { + return which() == CellTransformation::Transformation::COMPLEX; +} +inline typename CellTransformation::Transformation::Complex::Reader CellTransformation::Transformation::Reader::getComplex() const { + KJ_IREQUIRE((which() == CellTransformation::Transformation::COMPLEX), + "Must check which() before get()ing a union member."); + return typename CellTransformation::Transformation::Complex::Reader(_reader); +} +inline typename CellTransformation::Transformation::Complex::Builder CellTransformation::Transformation::Builder::getComplex() { + KJ_IREQUIRE((which() == CellTransformation::Transformation::COMPLEX), + "Must check which() before get()ing a union member."); + return typename CellTransformation::Transformation::Complex::Builder(_builder); +} +inline typename CellTransformation::Transformation::Complex::Builder CellTransformation::Transformation::Builder::initComplex() { + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, CellTransformation::Transformation::COMPLEX); + _builder.setDataField(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename CellTransformation::Transformation::Complex::Builder(_builder); +} +inline ::stream::geometry::FixPointTransformation CellTransformation::Transformation::Simple::Reader::getOrientation() const { + return _reader.getDataField< ::stream::geometry::FixPointTransformation>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::stream::geometry::FixPointTransformation CellTransformation::Transformation::Simple::Builder::getOrientation() { + return _builder.getDataField< ::stream::geometry::FixPointTransformation>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CellTransformation::Transformation::Simple::Builder::setOrientation( ::stream::geometry::FixPointTransformation value) { + _builder.setDataField< ::stream::geometry::FixPointTransformation>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline double CellTransformation::Transformation::Complex::Reader::getAngle() const { + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline double CellTransformation::Transformation::Complex::Builder::getAngle() { + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void CellTransformation::Transformation::Complex::Builder::setAngle(double value) { + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool CellTransformation::Transformation::Complex::Reader::getMirror() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool CellTransformation::Transformation::Complex::Builder::getMirror() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CellTransformation::Transformation::Complex::Builder::setMirror(bool value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline double CellTransformation::Transformation::Complex::Reader::getScale() const { + return _reader.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline double CellTransformation::Transformation::Complex::Builder::getScale() { + return _builder.getDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void CellTransformation::Transformation::Complex::Builder::setScale(double value) { + _builder.setDataField( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t CellInstance::Reader::getCellId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CellInstance::Builder::getCellId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CellInstance::Builder::setCellId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CellInstance::Reader::hasTransformation() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellInstance::Builder::hasTransformation() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::CellTransformation::Reader CellInstance::Reader::getTransformation() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::CellTransformation>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::CellTransformation::Builder CellInstance::Builder::getTransformation() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::CellTransformation>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::CellTransformation::Pipeline CellInstance::Pipeline::getTransformation() { + return ::stream::layoutView::CellTransformation::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void CellInstance::Builder::setTransformation( ::stream::layoutView::CellTransformation::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::CellTransformation>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::CellTransformation::Builder CellInstance::Builder::initTransformation() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::CellTransformation>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellInstance::Builder::adoptTransformation( + ::capnp::Orphan< ::stream::layoutView::CellTransformation>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::CellTransformation>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::CellTransformation> CellInstance::Builder::disownTransformation() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::CellTransformation>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LayoutView::Reader::hasBoundingBox() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool LayoutView::Builder::hasBoundingBox() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Box::Reader LayoutView::Reader::getBoundingBox() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Box>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Box::Builder LayoutView::Builder::getBoundingBox() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Box>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Box::Pipeline LayoutView::Pipeline::getBoundingBox() { + return ::stream::geometry::Box::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void LayoutView::Builder::setBoundingBox( ::stream::geometry::Box::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Box>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Box::Builder LayoutView::Builder::initBoundingBox() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Box>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void LayoutView::Builder::adoptBoundingBox( + ::capnp::Orphan< ::stream::geometry::Box>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Box>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Box> LayoutView::Builder::disownBoundingBox() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Box>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LayoutView::Reader::hasLayers() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool LayoutView::Builder::hasLayers() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Reader LayoutView::Reader::getLayers() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Builder LayoutView::Builder::getLayers() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void LayoutView::Builder::setLayers( ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>::Builder LayoutView::Builder::initLayers(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void LayoutView::Builder::adoptLayers( + ::capnp::Orphan< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>> LayoutView::Builder::disownLayers() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::layoutView::Layer, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool LayoutView::Reader::hasInstanceRepetitions() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool LayoutView::Builder::hasInstanceRepetitions() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader LayoutView::Reader::getInstanceRepetitions() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder LayoutView::Builder::getInstanceRepetitions() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void LayoutView::Builder::setInstanceRepetitions( ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>::Builder LayoutView::Builder::initInstanceRepetitions(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), size); +} +inline void LayoutView::Builder::adoptInstanceRepetitions( + ::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>> LayoutView::Builder::disownInstanceRepetitions() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::repetition::Repetition, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool LayoutView::Reader::hasInstances() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool LayoutView::Builder::hasInstances() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Reader LayoutView::Reader::getInstances() const { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Builder LayoutView::Builder::getInstances() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Pipeline LayoutView::Pipeline::getInstances() { + return ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void LayoutView::Builder::setInstances( ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Reader value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>::Builder LayoutView::Builder::initInstances() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void LayoutView::Builder::adoptInstances( + ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>&& value) { + ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>> LayoutView::Builder::disownInstances() { + return ::capnp::_::PointerHelpers< ::stream::layoutView::ObjectContainerForType< ::stream::layoutView::CellInstance>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/library.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/library.capnp.cc new file mode 100644 index 000000000..0afb1d6fc --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/library.capnp.cc @@ -0,0 +1,1378 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: library.capnp + +#include "library.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<58> b_c46c5bf141864625 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 37, 70, 134, 65, 241, 91, 108, 196, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 10, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 80, 114, + 111, 112, 101, 114, 116, 121, 78, 97, + 109, 101, 115, 84, 97, 98, 108, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 68, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 65, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 0, 3, 0, 1, 0, + 88, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 115, 112, 97, 99, + 101, 115, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 97, 109, 101, 115, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 39, 237, 161, 237, 211, 31, 151, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c46c5bf141864625 = b_c46c5bf141864625.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c46c5bf141864625[] = { + &s_ab971fd3eda1ed27, +}; +static const uint16_t m_c46c5bf141864625[] = {1, 0}; +static const uint16_t i_c46c5bf141864625[] = {0, 1}; +const ::capnp::_::RawSchema s_c46c5bf141864625 = { + 0xc46c5bf141864625, b_c46c5bf141864625.words, 58, d_c46c5bf141864625, m_c46c5bf141864625, + 1, 2, i_c46c5bf141864625, nullptr, nullptr, { &s_c46c5bf141864625, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<38> b_ee09fcfabb513627 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 39, 54, 81, 187, 250, 252, 9, 238, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 80, 114, + 111, 112, 101, 114, 116, 105, 101, 115, + 84, 97, 98, 108, 101, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 127, 1, 166, 154, 37, 26, 159, 238, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ee09fcfabb513627 = b_ee09fcfabb513627.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ee09fcfabb513627[] = { + &s_ee9f1a259aa6017f, +}; +static const uint16_t m_ee09fcfabb513627[] = {0}; +static const uint16_t i_ee09fcfabb513627[] = {0}; +const ::capnp::_::RawSchema s_ee09fcfabb513627 = { + 0xee09fcfabb513627, b_ee09fcfabb513627.words, 38, d_ee09fcfabb513627, m_ee09fcfabb513627, + 1, 1, i_ee09fcfabb513627, nullptr, nullptr, { &s_ee09fcfabb513627, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<38> b_d725313a8d21b8e2 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 226, 184, 33, 141, 58, 49, 37, 215, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 84, 101, + 120, 116, 83, 116, 114, 105, 110, 103, + 115, 84, 97, 98, 108, 101, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 116, 101, 120, 116, 83, 116, 114, 105, + 110, 103, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_d725313a8d21b8e2 = b_d725313a8d21b8e2.words; +#if !CAPNP_LITE +static const uint16_t m_d725313a8d21b8e2[] = {0}; +static const uint16_t i_d725313a8d21b8e2[] = {0}; +const ::capnp::_::RawSchema s_d725313a8d21b8e2 = { + 0xd725313a8d21b8e2, b_d725313a8d21b8e2.words, 38, nullptr, m_d725313a8d21b8e2, + 0, 1, i_d725313a8d21b8e2, nullptr, nullptr, { &s_d725313a8d21b8e2, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<34> b_dad4c55e50376300 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 0, 99, 55, 80, 94, 197, 212, 218, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 76, 105, + 98, 114, 97, 114, 121, 82, 101, 102, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 24, 0, 0, 0, 2, 0, 1, 0, + 108, 105, 98, 114, 97, 114, 121, 78, + 97, 109, 101, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_dad4c55e50376300 = b_dad4c55e50376300.words; +#if !CAPNP_LITE +static const uint16_t m_dad4c55e50376300[] = {0}; +static const uint16_t i_dad4c55e50376300[] = {0}; +const ::capnp::_::RawSchema s_dad4c55e50376300 = { + 0xdad4c55e50376300, b_dad4c55e50376300.words, 34, nullptr, m_dad4c55e50376300, + 0, 1, i_dad4c55e50376300, nullptr, nullptr, { &s_dad4c55e50376300, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<37> b_ede757f03a358434 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 52, 132, 53, 58, 240, 87, 231, 237, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 210, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 76, 105, + 98, 114, 97, 114, 121, 82, 101, 102, + 115, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 36, 0, 0, 0, 2, 0, 1, 0, + 114, 101, 102, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 99, 55, 80, 94, 197, 212, 218, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ede757f03a358434 = b_ede757f03a358434.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ede757f03a358434[] = { + &s_dad4c55e50376300, +}; +static const uint16_t m_ede757f03a358434[] = {0}; +static const uint16_t i_ede757f03a358434[] = {0}; +const ::capnp::_::RawSchema s_ede757f03a358434 = { + 0xede757f03a358434, b_ede757f03a358434.words, 37, d_ede757f03a358434, m_ede757f03a358434, + 1, 1, i_ede757f03a358434, nullptr, nullptr, { &s_ede757f03a358434, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<37> b_fc84113793087554 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 84, 117, 8, 147, 55, 17, 132, 252, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 67, 101, + 108, 108, 80, 97, 114, 97, 109, 101, + 116, 101, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 36, 0, 0, 0, 2, 0, 1, 0, + 118, 97, 108, 117, 101, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 154, 209, 130, 42, 180, 62, 22, 197, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_fc84113793087554 = b_fc84113793087554.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_fc84113793087554[] = { + &s_c5163eb42a82d19a, +}; +static const uint16_t m_fc84113793087554[] = {0}; +static const uint16_t i_fc84113793087554[] = {0}; +const ::capnp::_::RawSchema s_fc84113793087554 = { + 0xfc84113793087554, b_fc84113793087554.words, 37, d_fc84113793087554, m_fc84113793087554, + 1, 1, i_fc84113793087554, nullptr, nullptr, { &s_fc84113793087554, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<96> b_ddf4af51c3f3ec0c = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 12, 236, 243, 195, 81, 175, 244, 221, + 14, 0, 0, 0, 1, 0, 2, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 3, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 186, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 31, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 67, 101, + 108, 108, 83, 112, 101, 99, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 20, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 125, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 120, 0, 0, 0, 3, 0, 1, 0, + 132, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 3, 0, 1, 0, + 140, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 137, 0, 0, 0, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 136, 0, 0, 0, 3, 0, 1, 0, + 148, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 145, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 144, 0, 0, 0, 3, 0, 1, 0, + 156, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 153, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 1, 0, + 164, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 82, + 101, 102, 73, 100, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 67, + 101, 108, 108, 78, 97, 109, 101, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 97, 114, 97, 109, 101, 116, 101, + 114, 115, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 84, 117, 8, 147, 55, 17, 132, 252, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 73, 100, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ddf4af51c3f3ec0c = b_ddf4af51c3f3ec0c.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ddf4af51c3f3ec0c[] = { + &s_fc84113793087554, +}; +static const uint16_t m_ddf4af51c3f3ec0c[] = {2, 1, 0, 3, 4}; +static const uint16_t i_ddf4af51c3f3ec0c[] = {0, 1, 2, 3, 4}; +const ::capnp::_::RawSchema s_ddf4af51c3f3ec0c = { + 0xddf4af51c3f3ec0c, b_ddf4af51c3f3ec0c.words, 96, d_ddf4af51c3f3ec0c, m_ddf4af51c3f3ec0c, + 1, 5, i_ddf4af51c3f3ec0c, nullptr, nullptr, { &s_ddf4af51c3f3ec0c, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<38> b_bcfe199063ea7b38 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 56, 123, 234, 99, 144, 25, 254, 188, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 67, 101, + 108, 108, 83, 112, 101, 99, 115, 84, + 97, 98, 108, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 99, 101, 108, 108, 83, 112, 101, 99, + 115, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 12, 236, 243, 195, 81, 175, 244, 221, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_bcfe199063ea7b38 = b_bcfe199063ea7b38.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_bcfe199063ea7b38[] = { + &s_ddf4af51c3f3ec0c, +}; +static const uint16_t m_bcfe199063ea7b38[] = {0}; +static const uint16_t i_bcfe199063ea7b38[] = {0}; +const ::capnp::_::RawSchema s_bcfe199063ea7b38 = { + 0xbcfe199063ea7b38, b_bcfe199063ea7b38.words, 38, d_bcfe199063ea7b38, m_bcfe199063ea7b38, + 1, 1, i_bcfe199063ea7b38, nullptr, nullptr, { &s_bcfe199063ea7b38, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<54> b_fe4e983184475e0c = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 12, 94, 71, 132, 49, 152, 78, 254, + 14, 0, 0, 0, 1, 0, 1, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 34, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 67, 101, + 108, 108, 72, 105, 101, 114, 97, 114, + 99, 104, 121, 84, 114, 101, 101, 78, + 111, 100, 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 72, 0, 0, 0, 2, 0, 1, 0, + 99, 101, 108, 108, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 104, 105, 108, 100, 67, 101, 108, + 108, 73, 100, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_fe4e983184475e0c = b_fe4e983184475e0c.words; +#if !CAPNP_LITE +static const uint16_t m_fe4e983184475e0c[] = {0, 1}; +static const uint16_t i_fe4e983184475e0c[] = {0, 1}; +const ::capnp::_::RawSchema s_fe4e983184475e0c = { + 0xfe4e983184475e0c, b_fe4e983184475e0c.words, 54, nullptr, m_fe4e983184475e0c, + 0, 2, i_fe4e983184475e0c, nullptr, nullptr, { &s_fe4e983184475e0c, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<54> b_d4dd6a6bda115c0d = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 13, 92, 17, 218, 107, 106, 221, 212, + 14, 0, 0, 0, 1, 0, 1, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 2, 1, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 67, 101, + 108, 108, 72, 105, 101, 114, 97, 114, + 99, 104, 121, 84, 114, 101, 101, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 56, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 110, 117, 109, 98, 101, 114, 79, 102, + 84, 111, 112, 67, 101, 108, 108, 115, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 111, 100, 101, 115, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 12, 94, 71, 132, 49, 152, 78, 254, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_d4dd6a6bda115c0d = b_d4dd6a6bda115c0d.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_d4dd6a6bda115c0d[] = { + &s_fe4e983184475e0c, +}; +static const uint16_t m_d4dd6a6bda115c0d[] = {1, 0}; +static const uint16_t i_d4dd6a6bda115c0d[] = {0, 1}; +const ::capnp::_::RawSchema s_d4dd6a6bda115c0d = { + 0xd4dd6a6bda115c0d, b_d4dd6a6bda115c0d.words, 54, d_d4dd6a6bda115c0d, m_d4dd6a6bda115c0d, + 1, 2, i_d4dd6a6bda115c0d, nullptr, nullptr, { &s_d4dd6a6bda115c0d, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<71> b_a9ebdd95511b4025 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 37, 64, 27, 81, 149, 221, 235, 169, + 14, 0, 0, 0, 1, 0, 1, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 76, 97, + 121, 101, 114, 69, 110, 116, 114, 121, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 167, 231, 184, 74, 134, 26, 184, 216, + 1, 0, 0, 0, 66, 0, 0, 0, + 80, 117, 114, 112, 111, 115, 101, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 68, 0, 0, 0, 3, 0, 1, 0, + 96, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 93, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 0, 0, 0, 3, 0, 1, 0, + 100, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 108, 97, 121, 101, 114, 78, 117, 109, + 98, 101, 114, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 117, 114, 112, 111, 115, 101, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 167, 231, 184, 74, 134, 26, 184, 216, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_a9ebdd95511b4025 = b_a9ebdd95511b4025.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_a9ebdd95511b4025[] = { + &s_d8b81a864ab8e7a7, +}; +static const uint16_t m_a9ebdd95511b4025[] = {0, 1, 2}; +static const uint16_t i_a9ebdd95511b4025[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_a9ebdd95511b4025 = { + 0xa9ebdd95511b4025, b_a9ebdd95511b4025.words, 71, d_a9ebdd95511b4025, m_a9ebdd95511b4025, + 1, 3, i_a9ebdd95511b4025, nullptr, nullptr, { &s_a9ebdd95511b4025, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<69> b_d8b81a864ab8e7a7 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 167, 231, 184, 74, 134, 26, 184, 216, + 25, 0, 0, 0, 2, 0, 0, 0, + 37, 64, 27, 81, 149, 221, 235, 169, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 10, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 39, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 76, 97, + 121, 101, 114, 69, 110, 116, 114, 121, + 46, 80, 117, 114, 112, 111, 115, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 48, 0, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 137, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 113, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 93, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, + 65, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 114, 97, 119, 105, 110, 103, 0, + 102, 105, 108, 108, 0, 0, 0, 0, + 115, 108, 111, 116, 0, 0, 0, 0, + 112, 105, 110, 0, 0, 0, 0, 0, + 98, 111, 117, 110, 100, 97, 114, 121, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 101, 120, 116, 0, 0, 0, 0, + 99, 111, 109, 109, 101, 110, 116, 0, + 98, 108, 111, 99, 107, 97, 103, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 119, 105, 114, 101, 0, 0, 0, 0, + 101, 114, 114, 111, 114, 115, 0, 0, + 104, 97, 110, 100, 108, 101, 115, 0, + 115, 121, 109, 98, 111, 108, 0, 0, } +}; +::capnp::word const* const bp_d8b81a864ab8e7a7 = b_d8b81a864ab8e7a7.words; +#if !CAPNP_LITE +static const uint16_t m_d8b81a864ab8e7a7[] = {7, 4, 6, 0, 9, 1, 10, 3, 2, 11, 5, 8}; +const ::capnp::_::RawSchema s_d8b81a864ab8e7a7 = { + 0xd8b81a864ab8e7a7, b_d8b81a864ab8e7a7.words, 69, nullptr, m_d8b81a864ab8e7a7, + 0, 12, nullptr, nullptr, nullptr, { &s_d8b81a864ab8e7a7, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +CAPNP_DEFINE_ENUM(Purpose_d8b81a864ab8e7a7, d8b81a864ab8e7a7); +static const ::capnp::_::AlignedData<38> b_c5ef335f814ab0b2 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 178, 176, 74, 129, 95, 51, 239, 197, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 76, 97, + 121, 101, 114, 84, 97, 98, 108, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 108, 97, 121, 101, 114, 69, 110, 116, + 114, 105, 101, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 37, 64, 27, 81, 149, 221, 235, 169, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c5ef335f814ab0b2 = b_c5ef335f814ab0b2.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c5ef335f814ab0b2[] = { + &s_a9ebdd95511b4025, +}; +static const uint16_t m_c5ef335f814ab0b2[] = {0}; +static const uint16_t i_c5ef335f814ab0b2[] = {0}; +const ::capnp::_::RawSchema s_c5ef335f814ab0b2 = { + 0xc5ef335f814ab0b2, b_c5ef335f814ab0b2.words, 38, d_c5ef335f814ab0b2, m_c5ef335f814ab0b2, + 1, 1, i_c5ef335f814ab0b2, nullptr, nullptr, { &s_c5ef335f814ab0b2, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<111> b_b946e5061a9b8d1c = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 28, 141, 155, 26, 6, 229, 70, 185, + 14, 0, 0, 0, 1, 0, 2, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 4, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 186, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 87, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 86, 105, + 101, 119, 83, 112, 101, 99, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 24, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 153, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 148, 0, 0, 0, 3, 0, 1, 0, + 160, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 157, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 152, 0, 0, 0, 3, 0, 1, 0, + 164, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 161, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 160, 0, 0, 0, 3, 0, 1, 0, + 172, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 169, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 168, 0, 0, 0, 3, 0, 1, 0, + 180, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 177, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 176, 0, 0, 0, 3, 0, 1, 0, + 188, 0, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 185, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 184, 0, 0, 0, 3, 0, 1, 0, + 196, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 108, 97, 115, 115, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 115, 111, 108, 117, 116, 105, + 111, 110, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 97, 121, 101, 114, 84, 97, 98, + 108, 101, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 178, 176, 74, 129, 95, 51, 239, 197, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 73, 100, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 101, 116, 97, 68, 97, 116, 97, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 56, 212, 213, 232, 233, 209, 66, 147, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b946e5061a9b8d1c = b_b946e5061a9b8d1c.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_b946e5061a9b8d1c[] = { + &s_9342d1e9e8d5d438, + &s_c5ef335f814ab0b2, +}; +static const uint16_t m_b946e5061a9b8d1c[] = {1, 3, 5, 0, 4, 2}; +static const uint16_t i_b946e5061a9b8d1c[] = {0, 1, 2, 3, 4, 5}; +const ::capnp::_::RawSchema s_b946e5061a9b8d1c = { + 0xb946e5061a9b8d1c, b_b946e5061a9b8d1c.words, 111, d_b946e5061a9b8d1c, m_b946e5061a9b8d1c, + 2, 6, i_b946e5061a9b8d1c, nullptr, nullptr, { &s_b946e5061a9b8d1c, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<38> b_97396382a8297146 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 70, 113, 41, 168, 130, 99, 57, 151, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 86, 105, + 101, 119, 83, 112, 101, 99, 115, 84, + 97, 98, 108, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 118, 105, 101, 119, 83, 112, 101, 99, + 115, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 28, 141, 155, 26, 6, 229, 70, 185, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_97396382a8297146 = b_97396382a8297146.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_97396382a8297146[] = { + &s_b946e5061a9b8d1c, +}; +static const uint16_t m_97396382a8297146[] = {0}; +static const uint16_t i_97396382a8297146[] = {0}; +const ::capnp::_::RawSchema s_97396382a8297146 = { + 0x97396382a8297146, b_97396382a8297146.words, 38, d_97396382a8297146, m_97396382a8297146, + 1, 1, i_97396382a8297146, nullptr, nullptr, { &s_97396382a8297146, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<148> b_9abf2a90a0f9332c = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 44, 51, 249, 160, 144, 42, 191, 154, + 14, 0, 0, 0, 1, 0, 0, 0, + 136, 200, 254, 36, 24, 30, 147, 134, + 8, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 178, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 199, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 46, + 99, 97, 112, 110, 112, 58, 76, 105, + 98, 114, 97, 114, 121, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 32, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 209, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 208, 0, 0, 0, 3, 0, 1, 0, + 220, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 217, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 216, 0, 0, 0, 3, 0, 1, 0, + 228, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 225, 0, 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 3, 0, 1, 0, + 240, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 236, 0, 0, 0, 3, 0, 1, 0, + 248, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 245, 0, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 248, 0, 0, 0, 3, 0, 1, 0, + 4, 1, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 3, 0, 1, 0, + 12, 1, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 1, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 1, 0, 0, 3, 0, 1, 0, + 20, 1, 0, 0, 2, 0, 1, 0, + 7, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 1, 0, 0, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 1, 0, 0, 3, 0, 1, 0, + 32, 1, 0, 0, 2, 0, 1, 0, + 109, 101, 116, 97, 68, 97, 116, 97, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 56, 212, 213, 232, 233, 209, 66, 147, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 98, 114, 97, 114, 121, 82, + 101, 102, 115, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 52, 132, 53, 58, 240, 87, 231, 237, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 78, 97, 109, 101, 115, 84, 97, 98, + 108, 101, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 37, 70, 134, 65, 241, 91, 108, 196, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 105, + 101, 115, 84, 97, 98, 108, 101, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 39, 54, 81, 187, 250, 252, 9, 238, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 101, 120, 116, 83, 116, 114, 105, + 110, 103, 115, 84, 97, 98, 108, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 226, 184, 33, 141, 58, 49, 37, 215, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 105, 101, 119, 83, 112, 101, 99, + 115, 84, 97, 98, 108, 101, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 70, 113, 41, 168, 130, 99, 57, 151, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 101, 108, 108, 83, 112, 101, 99, + 115, 84, 97, 98, 108, 101, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 56, 123, 234, 99, 144, 25, 254, 188, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 101, 108, 108, 72, 105, 101, 114, + 97, 114, 99, 104, 121, 84, 114, 101, + 101, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 13, 92, 17, 218, 107, 106, 221, 212, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9abf2a90a0f9332c = b_9abf2a90a0f9332c.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9abf2a90a0f9332c[] = { + &s_9342d1e9e8d5d438, + &s_97396382a8297146, + &s_bcfe199063ea7b38, + &s_c46c5bf141864625, + &s_d4dd6a6bda115c0d, + &s_d725313a8d21b8e2, + &s_ede757f03a358434, + &s_ee09fcfabb513627, +}; +static const uint16_t m_9abf2a90a0f9332c[] = {7, 6, 1, 0, 3, 2, 4, 5}; +static const uint16_t i_9abf2a90a0f9332c[] = {0, 1, 2, 3, 4, 5, 6, 7}; +const ::capnp::_::RawSchema s_9abf2a90a0f9332c = { + 0x9abf2a90a0f9332c, b_9abf2a90a0f9332c.words, 148, d_9abf2a90a0f9332c, m_9abf2a90a0f9332c, + 8, 8, i_9abf2a90a0f9332c, nullptr, nullptr, { &s_9abf2a90a0f9332c, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace library { + +// PropertyNamesTable +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t PropertyNamesTable::_capnpPrivate::dataWordSize; +constexpr uint16_t PropertyNamesTable::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind PropertyNamesTable::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* PropertyNamesTable::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// PropertiesTable +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t PropertiesTable::_capnpPrivate::dataWordSize; +constexpr uint16_t PropertiesTable::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind PropertiesTable::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* PropertiesTable::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// TextStringsTable +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t TextStringsTable::_capnpPrivate::dataWordSize; +constexpr uint16_t TextStringsTable::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind TextStringsTable::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* TextStringsTable::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// LibraryRef +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t LibraryRef::_capnpPrivate::dataWordSize; +constexpr uint16_t LibraryRef::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind LibraryRef::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* LibraryRef::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// LibraryRefs +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t LibraryRefs::_capnpPrivate::dataWordSize; +constexpr uint16_t LibraryRefs::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind LibraryRefs::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* LibraryRefs::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellParameters +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellParameters::_capnpPrivate::dataWordSize; +constexpr uint16_t CellParameters::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellParameters::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellParameters::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellSpec +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellSpec::_capnpPrivate::dataWordSize; +constexpr uint16_t CellSpec::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellSpec::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellSpec::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellSpecsTable +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellSpecsTable::_capnpPrivate::dataWordSize; +constexpr uint16_t CellSpecsTable::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellSpecsTable::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellSpecsTable::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellHierarchyTreeNode +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellHierarchyTreeNode::_capnpPrivate::dataWordSize; +constexpr uint16_t CellHierarchyTreeNode::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellHierarchyTreeNode::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellHierarchyTreeNode::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CellHierarchyTree +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CellHierarchyTree::_capnpPrivate::dataWordSize; +constexpr uint16_t CellHierarchyTree::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CellHierarchyTree::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CellHierarchyTree::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// LayerEntry +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t LayerEntry::_capnpPrivate::dataWordSize; +constexpr uint16_t LayerEntry::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind LayerEntry::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* LayerEntry::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// LayerTable +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t LayerTable::_capnpPrivate::dataWordSize; +constexpr uint16_t LayerTable::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind LayerTable::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* LayerTable::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// ViewSpec +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t ViewSpec::_capnpPrivate::dataWordSize; +constexpr uint16_t ViewSpec::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind ViewSpec::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* ViewSpec::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// ViewSpecsTable +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t ViewSpecsTable::_capnpPrivate::dataWordSize; +constexpr uint16_t ViewSpecsTable::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind ViewSpecsTable::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* ViewSpecsTable::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Library +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Library::_capnpPrivate::dataWordSize; +constexpr uint16_t Library::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Library::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Library::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/library.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/library.capnp.h new file mode 100644 index 000000000..0f0f74534 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/library.capnp.h @@ -0,0 +1,2856 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: library.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "metaData.capnp.h" +#include "propertySet.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(c46c5bf141864625); +CAPNP_DECLARE_SCHEMA(ee09fcfabb513627); +CAPNP_DECLARE_SCHEMA(d725313a8d21b8e2); +CAPNP_DECLARE_SCHEMA(dad4c55e50376300); +CAPNP_DECLARE_SCHEMA(ede757f03a358434); +CAPNP_DECLARE_SCHEMA(fc84113793087554); +CAPNP_DECLARE_SCHEMA(ddf4af51c3f3ec0c); +CAPNP_DECLARE_SCHEMA(bcfe199063ea7b38); +CAPNP_DECLARE_SCHEMA(fe4e983184475e0c); +CAPNP_DECLARE_SCHEMA(d4dd6a6bda115c0d); +CAPNP_DECLARE_SCHEMA(a9ebdd95511b4025); +CAPNP_DECLARE_SCHEMA(d8b81a864ab8e7a7); +enum class Purpose_d8b81a864ab8e7a7: uint16_t { + DRAWING, + FILL, + SLOT, + PIN, + BOUNDARY, + TEXT, + COMMENT, + BLOCKAGE, + WIRE, + ERRORS, + HANDLES, + SYMBOL, +}; +CAPNP_DECLARE_ENUM(Purpose, d8b81a864ab8e7a7); +CAPNP_DECLARE_SCHEMA(c5ef335f814ab0b2); +CAPNP_DECLARE_SCHEMA(b946e5061a9b8d1c); +CAPNP_DECLARE_SCHEMA(97396382a8297146); +CAPNP_DECLARE_SCHEMA(9abf2a90a0f9332c); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace library { + +struct PropertyNamesTable { + PropertyNamesTable() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c46c5bf141864625, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct PropertiesTable { + PropertiesTable() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ee09fcfabb513627, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct TextStringsTable { + TextStringsTable() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d725313a8d21b8e2, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct LibraryRef { + LibraryRef() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(dad4c55e50376300, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct LibraryRefs { + LibraryRefs() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ede757f03a358434, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellParameters { + CellParameters() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(fc84113793087554, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellSpec { + CellSpec() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ddf4af51c3f3ec0c, 2, 3) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellSpecsTable { + CellSpecsTable() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bcfe199063ea7b38, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellHierarchyTreeNode { + CellHierarchyTreeNode() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(fe4e983184475e0c, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CellHierarchyTree { + CellHierarchyTree() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d4dd6a6bda115c0d, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct LayerEntry { + LayerEntry() = delete; + + class Reader; + class Builder; + class Pipeline; + typedef ::capnp::schemas::Purpose_d8b81a864ab8e7a7 Purpose; + + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a9ebdd95511b4025, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct LayerTable { + LayerTable() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c5ef335f814ab0b2, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct ViewSpec { + ViewSpec() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b946e5061a9b8d1c, 2, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct ViewSpecsTable { + ViewSpecsTable() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(97396382a8297146, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Library { + Library() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9abf2a90a0f9332c, 0, 8) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class PropertyNamesTable::Reader { +public: + typedef PropertyNamesTable Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasNamespaces() const; + inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader getNamespaces() const; + + inline bool hasNames() const; + inline ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Reader getNames() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class PropertyNamesTable::Builder { +public: + typedef PropertyNamesTable Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasNamespaces(); + inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder getNamespaces(); + inline void setNamespaces( ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader value); + inline void setNamespaces(::kj::ArrayPtr value); + inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder initNamespaces(unsigned int size); + inline void adoptNamespaces(::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>> disownNamespaces(); + + inline bool hasNames(); + inline ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Builder getNames(); + inline void setNames( ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Builder initNames(unsigned int size); + inline void adoptNames(::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>> disownNames(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class PropertyNamesTable::Pipeline { +public: + typedef PropertyNamesTable Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class PropertiesTable::Reader { +public: + typedef PropertiesTable Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasPropertySets() const; + inline ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Reader getPropertySets() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class PropertiesTable::Builder { +public: + typedef PropertiesTable Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasPropertySets(); + inline ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Builder getPropertySets(); + inline void setPropertySets( ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Builder initPropertySets(unsigned int size); + inline void adoptPropertySets(::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>> disownPropertySets(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class PropertiesTable::Pipeline { +public: + typedef PropertiesTable Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class TextStringsTable::Reader { +public: + typedef TextStringsTable Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasTextStrings() const; + inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader getTextStrings() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class TextStringsTable::Builder { +public: + typedef TextStringsTable Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasTextStrings(); + inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder getTextStrings(); + inline void setTextStrings( ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader value); + inline void setTextStrings(::kj::ArrayPtr value); + inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder initTextStrings(unsigned int size); + inline void adoptTextStrings(::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>> disownTextStrings(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class TextStringsTable::Pipeline { +public: + typedef TextStringsTable Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class LibraryRef::Reader { +public: + typedef LibraryRef Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasLibraryName() const; + inline ::capnp::Text::Reader getLibraryName() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class LibraryRef::Builder { +public: + typedef LibraryRef Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasLibraryName(); + inline ::capnp::Text::Builder getLibraryName(); + inline void setLibraryName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initLibraryName(unsigned int size); + inline void adoptLibraryName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownLibraryName(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class LibraryRef::Pipeline { +public: + typedef LibraryRef Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class LibraryRefs::Reader { +public: + typedef LibraryRefs Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasRefs() const; + inline ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Reader getRefs() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class LibraryRefs::Builder { +public: + typedef LibraryRefs Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasRefs(); + inline ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Builder getRefs(); + inline void setRefs( ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Builder initRefs(unsigned int size); + inline void adoptRefs(::capnp::Orphan< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>> disownRefs(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class LibraryRefs::Pipeline { +public: + typedef LibraryRefs Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellParameters::Reader { +public: + typedef CellParameters Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasValues() const; + inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader getValues() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellParameters::Builder { +public: + typedef CellParameters Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasValues(); + inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder getValues(); + inline void setValues( ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder initValues(unsigned int size); + inline void adoptValues(::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>> disownValues(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellParameters::Pipeline { +public: + typedef CellParameters Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellSpec::Reader { +public: + typedef CellSpec Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint64_t getLibraryRefId() const; + + inline bool hasLibraryCellName() const; + inline ::capnp::Text::Reader getLibraryCellName() const; + + inline bool hasParameters() const; + inline ::stream::library::CellParameters::Reader getParameters() const; + + inline ::uint64_t getPropertySetId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellSpec::Builder { +public: + typedef CellSpec Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint64_t getLibraryRefId(); + inline void setLibraryRefId( ::uint64_t value); + + inline bool hasLibraryCellName(); + inline ::capnp::Text::Builder getLibraryCellName(); + inline void setLibraryCellName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initLibraryCellName(unsigned int size); + inline void adoptLibraryCellName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownLibraryCellName(); + + inline bool hasParameters(); + inline ::stream::library::CellParameters::Builder getParameters(); + inline void setParameters( ::stream::library::CellParameters::Reader value); + inline ::stream::library::CellParameters::Builder initParameters(); + inline void adoptParameters(::capnp::Orphan< ::stream::library::CellParameters>&& value); + inline ::capnp::Orphan< ::stream::library::CellParameters> disownParameters(); + + inline ::uint64_t getPropertySetId(); + inline void setPropertySetId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellSpec::Pipeline { +public: + typedef CellSpec Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::library::CellParameters::Pipeline getParameters(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellSpecsTable::Reader { +public: + typedef CellSpecsTable Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasCellSpecs() const; + inline ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Reader getCellSpecs() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellSpecsTable::Builder { +public: + typedef CellSpecsTable Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasCellSpecs(); + inline ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Builder getCellSpecs(); + inline void setCellSpecs( ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Builder initCellSpecs(unsigned int size); + inline void adoptCellSpecs(::capnp::Orphan< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>> disownCellSpecs(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellSpecsTable::Pipeline { +public: + typedef CellSpecsTable Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellHierarchyTreeNode::Reader { +public: + typedef CellHierarchyTreeNode Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getCellId() const; + + inline bool hasChildCellIds() const; + inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader getChildCellIds() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellHierarchyTreeNode::Builder { +public: + typedef CellHierarchyTreeNode Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getCellId(); + inline void setCellId( ::uint64_t value); + + inline bool hasChildCellIds(); + inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder getChildCellIds(); + inline void setChildCellIds( ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader value); + inline void setChildCellIds(::kj::ArrayPtr value); + inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder initChildCellIds(unsigned int size); + inline void adoptChildCellIds(::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>> disownChildCellIds(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellHierarchyTreeNode::Pipeline { +public: + typedef CellHierarchyTreeNode Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CellHierarchyTree::Reader { +public: + typedef CellHierarchyTree Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getNumberOfTopCells() const; + + inline bool hasNodes() const; + inline ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Reader getNodes() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CellHierarchyTree::Builder { +public: + typedef CellHierarchyTree Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getNumberOfTopCells(); + inline void setNumberOfTopCells( ::uint64_t value); + + inline bool hasNodes(); + inline ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Builder getNodes(); + inline void setNodes( ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Builder initNodes(unsigned int size); + inline void adoptNodes(::capnp::Orphan< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>> disownNodes(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CellHierarchyTree::Pipeline { +public: + typedef CellHierarchyTree Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class LayerEntry::Reader { +public: + typedef LayerEntry Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasLayerNumbers() const; + inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader getLayerNumbers() const; + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::stream::library::LayerEntry::Purpose getPurpose() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class LayerEntry::Builder { +public: + typedef LayerEntry Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasLayerNumbers(); + inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder getLayerNumbers(); + inline void setLayerNumbers( ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader value); + inline void setLayerNumbers(::kj::ArrayPtr value); + inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder initLayerNumbers(unsigned int size); + inline void adoptLayerNumbers(::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>> disownLayerNumbers(); + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::stream::library::LayerEntry::Purpose getPurpose(); + inline void setPurpose( ::stream::library::LayerEntry::Purpose value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class LayerEntry::Pipeline { +public: + typedef LayerEntry Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class LayerTable::Reader { +public: + typedef LayerTable Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasLayerEntries() const; + inline ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Reader getLayerEntries() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class LayerTable::Builder { +public: + typedef LayerTable Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasLayerEntries(); + inline ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Builder getLayerEntries(); + inline void setLayerEntries( ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Builder initLayerEntries(unsigned int size); + inline void adoptLayerEntries(::capnp::Orphan< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>> disownLayerEntries(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class LayerTable::Pipeline { +public: + typedef LayerTable Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class ViewSpec::Reader { +public: + typedef ViewSpec Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline bool hasClass() const; + inline ::capnp::Text::Reader getClass() const; + + inline double getResolution() const; + + inline bool hasLayerTable() const; + inline ::stream::library::LayerTable::Reader getLayerTable() const; + + inline ::uint64_t getPropertySetId() const; + + inline bool hasMetaData() const; + inline ::stream::metaData::MetaData::Reader getMetaData() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class ViewSpec::Builder { +public: + typedef ViewSpec Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline bool hasClass(); + inline ::capnp::Text::Builder getClass(); + inline void setClass( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initClass(unsigned int size); + inline void adoptClass(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownClass(); + + inline double getResolution(); + inline void setResolution(double value); + + inline bool hasLayerTable(); + inline ::stream::library::LayerTable::Builder getLayerTable(); + inline void setLayerTable( ::stream::library::LayerTable::Reader value); + inline ::stream::library::LayerTable::Builder initLayerTable(); + inline void adoptLayerTable(::capnp::Orphan< ::stream::library::LayerTable>&& value); + inline ::capnp::Orphan< ::stream::library::LayerTable> disownLayerTable(); + + inline ::uint64_t getPropertySetId(); + inline void setPropertySetId( ::uint64_t value); + + inline bool hasMetaData(); + inline ::stream::metaData::MetaData::Builder getMetaData(); + inline void setMetaData( ::stream::metaData::MetaData::Reader value); + inline ::stream::metaData::MetaData::Builder initMetaData(); + inline void adoptMetaData(::capnp::Orphan< ::stream::metaData::MetaData>&& value); + inline ::capnp::Orphan< ::stream::metaData::MetaData> disownMetaData(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class ViewSpec::Pipeline { +public: + typedef ViewSpec Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::library::LayerTable::Pipeline getLayerTable(); + inline ::stream::metaData::MetaData::Pipeline getMetaData(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class ViewSpecsTable::Reader { +public: + typedef ViewSpecsTable Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasViewSpecs() const; + inline ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Reader getViewSpecs() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class ViewSpecsTable::Builder { +public: + typedef ViewSpecsTable Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasViewSpecs(); + inline ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Builder getViewSpecs(); + inline void setViewSpecs( ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Builder initViewSpecs(unsigned int size); + inline void adoptViewSpecs(::capnp::Orphan< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>> disownViewSpecs(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class ViewSpecsTable::Pipeline { +public: + typedef ViewSpecsTable Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Library::Reader { +public: + typedef Library Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasMetaData() const; + inline ::stream::metaData::MetaData::Reader getMetaData() const; + + inline bool hasLibraryRefs() const; + inline ::stream::library::LibraryRefs::Reader getLibraryRefs() const; + + inline bool hasPropertyNamesTable() const; + inline ::stream::library::PropertyNamesTable::Reader getPropertyNamesTable() const; + + inline bool hasPropertiesTable() const; + inline ::stream::library::PropertiesTable::Reader getPropertiesTable() const; + + inline bool hasTextStringsTable() const; + inline ::stream::library::TextStringsTable::Reader getTextStringsTable() const; + + inline bool hasViewSpecsTable() const; + inline ::stream::library::ViewSpecsTable::Reader getViewSpecsTable() const; + + inline bool hasCellSpecsTable() const; + inline ::stream::library::CellSpecsTable::Reader getCellSpecsTable() const; + + inline bool hasCellHierarchyTree() const; + inline ::stream::library::CellHierarchyTree::Reader getCellHierarchyTree() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Library::Builder { +public: + typedef Library Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasMetaData(); + inline ::stream::metaData::MetaData::Builder getMetaData(); + inline void setMetaData( ::stream::metaData::MetaData::Reader value); + inline ::stream::metaData::MetaData::Builder initMetaData(); + inline void adoptMetaData(::capnp::Orphan< ::stream::metaData::MetaData>&& value); + inline ::capnp::Orphan< ::stream::metaData::MetaData> disownMetaData(); + + inline bool hasLibraryRefs(); + inline ::stream::library::LibraryRefs::Builder getLibraryRefs(); + inline void setLibraryRefs( ::stream::library::LibraryRefs::Reader value); + inline ::stream::library::LibraryRefs::Builder initLibraryRefs(); + inline void adoptLibraryRefs(::capnp::Orphan< ::stream::library::LibraryRefs>&& value); + inline ::capnp::Orphan< ::stream::library::LibraryRefs> disownLibraryRefs(); + + inline bool hasPropertyNamesTable(); + inline ::stream::library::PropertyNamesTable::Builder getPropertyNamesTable(); + inline void setPropertyNamesTable( ::stream::library::PropertyNamesTable::Reader value); + inline ::stream::library::PropertyNamesTable::Builder initPropertyNamesTable(); + inline void adoptPropertyNamesTable(::capnp::Orphan< ::stream::library::PropertyNamesTable>&& value); + inline ::capnp::Orphan< ::stream::library::PropertyNamesTable> disownPropertyNamesTable(); + + inline bool hasPropertiesTable(); + inline ::stream::library::PropertiesTable::Builder getPropertiesTable(); + inline void setPropertiesTable( ::stream::library::PropertiesTable::Reader value); + inline ::stream::library::PropertiesTable::Builder initPropertiesTable(); + inline void adoptPropertiesTable(::capnp::Orphan< ::stream::library::PropertiesTable>&& value); + inline ::capnp::Orphan< ::stream::library::PropertiesTable> disownPropertiesTable(); + + inline bool hasTextStringsTable(); + inline ::stream::library::TextStringsTable::Builder getTextStringsTable(); + inline void setTextStringsTable( ::stream::library::TextStringsTable::Reader value); + inline ::stream::library::TextStringsTable::Builder initTextStringsTable(); + inline void adoptTextStringsTable(::capnp::Orphan< ::stream::library::TextStringsTable>&& value); + inline ::capnp::Orphan< ::stream::library::TextStringsTable> disownTextStringsTable(); + + inline bool hasViewSpecsTable(); + inline ::stream::library::ViewSpecsTable::Builder getViewSpecsTable(); + inline void setViewSpecsTable( ::stream::library::ViewSpecsTable::Reader value); + inline ::stream::library::ViewSpecsTable::Builder initViewSpecsTable(); + inline void adoptViewSpecsTable(::capnp::Orphan< ::stream::library::ViewSpecsTable>&& value); + inline ::capnp::Orphan< ::stream::library::ViewSpecsTable> disownViewSpecsTable(); + + inline bool hasCellSpecsTable(); + inline ::stream::library::CellSpecsTable::Builder getCellSpecsTable(); + inline void setCellSpecsTable( ::stream::library::CellSpecsTable::Reader value); + inline ::stream::library::CellSpecsTable::Builder initCellSpecsTable(); + inline void adoptCellSpecsTable(::capnp::Orphan< ::stream::library::CellSpecsTable>&& value); + inline ::capnp::Orphan< ::stream::library::CellSpecsTable> disownCellSpecsTable(); + + inline bool hasCellHierarchyTree(); + inline ::stream::library::CellHierarchyTree::Builder getCellHierarchyTree(); + inline void setCellHierarchyTree( ::stream::library::CellHierarchyTree::Reader value); + inline ::stream::library::CellHierarchyTree::Builder initCellHierarchyTree(); + inline void adoptCellHierarchyTree(::capnp::Orphan< ::stream::library::CellHierarchyTree>&& value); + inline ::capnp::Orphan< ::stream::library::CellHierarchyTree> disownCellHierarchyTree(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Library::Pipeline { +public: + typedef Library Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::metaData::MetaData::Pipeline getMetaData(); + inline ::stream::library::LibraryRefs::Pipeline getLibraryRefs(); + inline ::stream::library::PropertyNamesTable::Pipeline getPropertyNamesTable(); + inline ::stream::library::PropertiesTable::Pipeline getPropertiesTable(); + inline ::stream::library::TextStringsTable::Pipeline getTextStringsTable(); + inline ::stream::library::ViewSpecsTable::Pipeline getViewSpecsTable(); + inline ::stream::library::CellSpecsTable::Pipeline getCellSpecsTable(); + inline ::stream::library::CellHierarchyTree::Pipeline getCellHierarchyTree(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline bool PropertyNamesTable::Reader::hasNamespaces() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool PropertyNamesTable::Builder::hasNamespaces() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader PropertyNamesTable::Reader::getNamespaces() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder PropertyNamesTable::Builder::getNamespaces() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void PropertyNamesTable::Builder::setNamespaces( ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline void PropertyNamesTable::Builder::setNamespaces(::kj::ArrayPtr value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder PropertyNamesTable::Builder::initNamespaces(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void PropertyNamesTable::Builder::adoptNamespaces( + ::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>> PropertyNamesTable::Builder::disownNamespaces() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool PropertyNamesTable::Reader::hasNames() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool PropertyNamesTable::Builder::hasNames() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Reader PropertyNamesTable::Reader::getNames() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Builder PropertyNamesTable::Builder::getNames() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void PropertyNamesTable::Builder::setNames( ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>::Builder PropertyNamesTable::Builder::initNames(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void PropertyNamesTable::Builder::adoptNames( + ::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>> PropertyNamesTable::Builder::disownNames() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertyName, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool PropertiesTable::Reader::hasPropertySets() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool PropertiesTable::Builder::hasPropertySets() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Reader PropertiesTable::Reader::getPropertySets() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Builder PropertiesTable::Builder::getPropertySets() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void PropertiesTable::Builder::setPropertySets( ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>::Builder PropertiesTable::Builder::initPropertySets(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void PropertiesTable::Builder::adoptPropertySets( + ::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>> PropertiesTable::Builder::disownPropertySets() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::PropertySet, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool TextStringsTable::Reader::hasTextStrings() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool TextStringsTable::Builder::hasTextStrings() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader TextStringsTable::Reader::getTextStrings() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder TextStringsTable::Builder::getTextStrings() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void TextStringsTable::Builder::setTextStrings( ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline void TextStringsTable::Builder::setTextStrings(::kj::ArrayPtr value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>::Builder TextStringsTable::Builder::initTextStrings(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void TextStringsTable::Builder::adoptTextStrings( + ::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>> TextStringsTable::Builder::disownTextStrings() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::Text, ::capnp::Kind::BLOB>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LibraryRef::Reader::hasLibraryName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool LibraryRef::Builder::hasLibraryName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader LibraryRef::Reader::getLibraryName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder LibraryRef::Builder::getLibraryName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void LibraryRef::Builder::setLibraryName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder LibraryRef::Builder::initLibraryName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void LibraryRef::Builder::adoptLibraryName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> LibraryRef::Builder::disownLibraryName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LibraryRefs::Reader::hasRefs() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool LibraryRefs::Builder::hasRefs() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Reader LibraryRefs::Reader::getRefs() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Builder LibraryRefs::Builder::getRefs() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void LibraryRefs::Builder::setRefs( ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>::Builder LibraryRefs::Builder::initRefs(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void LibraryRefs::Builder::adoptRefs( + ::capnp::Orphan< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>> LibraryRefs::Builder::disownRefs() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LibraryRef, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CellParameters::Reader::hasValues() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellParameters::Builder::hasValues() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader CellParameters::Reader::getValues() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder CellParameters::Builder::getValues() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellParameters::Builder::setValues( ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder CellParameters::Builder::initValues(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CellParameters::Builder::adoptValues( + ::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>> CellParameters::Builder::disownValues() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CellSpec::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellSpec::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CellSpec::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CellSpec::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellSpec::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CellSpec::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CellSpec::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CellSpec::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CellSpec::Reader::getLibraryRefId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CellSpec::Builder::getLibraryRefId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CellSpec::Builder::setLibraryRefId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CellSpec::Reader::hasLibraryCellName() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool CellSpec::Builder::hasLibraryCellName() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CellSpec::Reader::getLibraryCellName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CellSpec::Builder::getLibraryCellName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void CellSpec::Builder::setLibraryCellName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CellSpec::Builder::initLibraryCellName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void CellSpec::Builder::adoptLibraryCellName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CellSpec::Builder::disownLibraryCellName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool CellSpec::Reader::hasParameters() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool CellSpec::Builder::hasParameters() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::CellParameters::Reader CellSpec::Reader::getParameters() const { + return ::capnp::_::PointerHelpers< ::stream::library::CellParameters>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::stream::library::CellParameters::Builder CellSpec::Builder::getParameters() { + return ::capnp::_::PointerHelpers< ::stream::library::CellParameters>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::CellParameters::Pipeline CellSpec::Pipeline::getParameters() { + return ::stream::library::CellParameters::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void CellSpec::Builder::setParameters( ::stream::library::CellParameters::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::CellParameters>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::stream::library::CellParameters::Builder CellSpec::Builder::initParameters() { + return ::capnp::_::PointerHelpers< ::stream::library::CellParameters>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void CellSpec::Builder::adoptParameters( + ::capnp::Orphan< ::stream::library::CellParameters>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::CellParameters>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::CellParameters> CellSpec::Builder::disownParameters() { + return ::capnp::_::PointerHelpers< ::stream::library::CellParameters>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CellSpec::Reader::getPropertySetId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CellSpec::Builder::getPropertySetId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void CellSpec::Builder::setPropertySetId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool CellSpecsTable::Reader::hasCellSpecs() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellSpecsTable::Builder::hasCellSpecs() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Reader CellSpecsTable::Reader::getCellSpecs() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Builder CellSpecsTable::Builder::getCellSpecs() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellSpecsTable::Builder::setCellSpecs( ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>::Builder CellSpecsTable::Builder::initCellSpecs(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CellSpecsTable::Builder::adoptCellSpecs( + ::capnp::Orphan< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>> CellSpecsTable::Builder::disownCellSpecs() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellSpec, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CellHierarchyTreeNode::Reader::getCellId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CellHierarchyTreeNode::Builder::getCellId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CellHierarchyTreeNode::Builder::setCellId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CellHierarchyTreeNode::Reader::hasChildCellIds() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellHierarchyTreeNode::Builder::hasChildCellIds() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader CellHierarchyTreeNode::Reader::getChildCellIds() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder CellHierarchyTreeNode::Builder::getChildCellIds() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellHierarchyTreeNode::Builder::setChildCellIds( ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline void CellHierarchyTreeNode::Builder::setChildCellIds(::kj::ArrayPtr value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder CellHierarchyTreeNode::Builder::initChildCellIds(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CellHierarchyTreeNode::Builder::adoptChildCellIds( + ::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>> CellHierarchyTreeNode::Builder::disownChildCellIds() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CellHierarchyTree::Reader::getNumberOfTopCells() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CellHierarchyTree::Builder::getNumberOfTopCells() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CellHierarchyTree::Builder::setNumberOfTopCells( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CellHierarchyTree::Reader::hasNodes() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CellHierarchyTree::Builder::hasNodes() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Reader CellHierarchyTree::Reader::getNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Builder CellHierarchyTree::Builder::getNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CellHierarchyTree::Builder::setNodes( ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>::Builder CellHierarchyTree::Builder::initNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CellHierarchyTree::Builder::adoptNodes( + ::capnp::Orphan< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>> CellHierarchyTree::Builder::disownNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::CellHierarchyTreeNode, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LayerEntry::Reader::hasLayerNumbers() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool LayerEntry::Builder::hasLayerNumbers() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader LayerEntry::Reader::getLayerNumbers() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder LayerEntry::Builder::getLayerNumbers() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void LayerEntry::Builder::setLayerNumbers( ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline void LayerEntry::Builder::setLayerNumbers(::kj::ArrayPtr value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>::Builder LayerEntry::Builder::initLayerNumbers(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void LayerEntry::Builder::adoptLayerNumbers( + ::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>> LayerEntry::Builder::disownLayerNumbers() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::uint64_t, ::capnp::Kind::PRIMITIVE>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool LayerEntry::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool LayerEntry::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader LayerEntry::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder LayerEntry::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void LayerEntry::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder LayerEntry::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void LayerEntry::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> LayerEntry::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::stream::library::LayerEntry::Purpose LayerEntry::Reader::getPurpose() const { + return _reader.getDataField< ::stream::library::LayerEntry::Purpose>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::stream::library::LayerEntry::Purpose LayerEntry::Builder::getPurpose() { + return _builder.getDataField< ::stream::library::LayerEntry::Purpose>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void LayerEntry::Builder::setPurpose( ::stream::library::LayerEntry::Purpose value) { + _builder.setDataField< ::stream::library::LayerEntry::Purpose>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool LayerTable::Reader::hasLayerEntries() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool LayerTable::Builder::hasLayerEntries() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Reader LayerTable::Reader::getLayerEntries() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Builder LayerTable::Builder::getLayerEntries() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void LayerTable::Builder::setLayerEntries( ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>::Builder LayerTable::Builder::initLayerEntries(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void LayerTable::Builder::adoptLayerEntries( + ::capnp::Orphan< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>> LayerTable::Builder::disownLayerEntries() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::LayerEntry, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool ViewSpec::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool ViewSpec::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader ViewSpec::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder ViewSpec::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void ViewSpec::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder ViewSpec::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void ViewSpec::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> ViewSpec::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool ViewSpec::Reader::hasClass() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool ViewSpec::Builder::hasClass() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader ViewSpec::Reader::getClass() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder ViewSpec::Builder::getClass() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void ViewSpec::Builder::setClass( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder ViewSpec::Builder::initClass(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void ViewSpec::Builder::adoptClass( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> ViewSpec::Builder::disownClass() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline double ViewSpec::Reader::getResolution() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline double ViewSpec::Builder::getResolution() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void ViewSpec::Builder::setResolution(double value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool ViewSpec::Reader::hasLayerTable() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool ViewSpec::Builder::hasLayerTable() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::LayerTable::Reader ViewSpec::Reader::getLayerTable() const { + return ::capnp::_::PointerHelpers< ::stream::library::LayerTable>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::stream::library::LayerTable::Builder ViewSpec::Builder::getLayerTable() { + return ::capnp::_::PointerHelpers< ::stream::library::LayerTable>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::LayerTable::Pipeline ViewSpec::Pipeline::getLayerTable() { + return ::stream::library::LayerTable::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void ViewSpec::Builder::setLayerTable( ::stream::library::LayerTable::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::LayerTable>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::stream::library::LayerTable::Builder ViewSpec::Builder::initLayerTable() { + return ::capnp::_::PointerHelpers< ::stream::library::LayerTable>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void ViewSpec::Builder::adoptLayerTable( + ::capnp::Orphan< ::stream::library::LayerTable>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::LayerTable>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::LayerTable> ViewSpec::Builder::disownLayerTable() { + return ::capnp::_::PointerHelpers< ::stream::library::LayerTable>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline ::uint64_t ViewSpec::Reader::getPropertySetId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t ViewSpec::Builder::getPropertySetId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void ViewSpec::Builder::setPropertySetId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool ViewSpec::Reader::hasMetaData() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool ViewSpec::Builder::hasMetaData() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::metaData::MetaData::Reader ViewSpec::Reader::getMetaData() const { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::stream::metaData::MetaData::Builder ViewSpec::Builder::getMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::metaData::MetaData::Pipeline ViewSpec::Pipeline::getMetaData() { + return ::stream::metaData::MetaData::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void ViewSpec::Builder::setMetaData( ::stream::metaData::MetaData::Reader value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::stream::metaData::MetaData::Builder ViewSpec::Builder::initMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void ViewSpec::Builder::adoptMetaData( + ::capnp::Orphan< ::stream::metaData::MetaData>&& value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::metaData::MetaData> ViewSpec::Builder::disownMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool ViewSpecsTable::Reader::hasViewSpecs() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool ViewSpecsTable::Builder::hasViewSpecs() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Reader ViewSpecsTable::Reader::getViewSpecs() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Builder ViewSpecsTable::Builder::getViewSpecs() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void ViewSpecsTable::Builder::setViewSpecs( ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>::Builder ViewSpecsTable::Builder::initViewSpecs(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void ViewSpecsTable::Builder::adoptViewSpecs( + ::capnp::Orphan< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>> ViewSpecsTable::Builder::disownViewSpecs() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::library::ViewSpec, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasMetaData() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasMetaData() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::metaData::MetaData::Reader Library::Reader::getMetaData() const { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::metaData::MetaData::Builder Library::Builder::getMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::metaData::MetaData::Pipeline Library::Pipeline::getMetaData() { + return ::stream::metaData::MetaData::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setMetaData( ::stream::metaData::MetaData::Reader value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::metaData::MetaData::Builder Library::Builder::initMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptMetaData( + ::capnp::Orphan< ::stream::metaData::MetaData>&& value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::metaData::MetaData> Library::Builder::disownMetaData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasLibraryRefs() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasLibraryRefs() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::LibraryRefs::Reader Library::Reader::getLibraryRefs() const { + return ::capnp::_::PointerHelpers< ::stream::library::LibraryRefs>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::library::LibraryRefs::Builder Library::Builder::getLibraryRefs() { + return ::capnp::_::PointerHelpers< ::stream::library::LibraryRefs>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::LibraryRefs::Pipeline Library::Pipeline::getLibraryRefs() { + return ::stream::library::LibraryRefs::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setLibraryRefs( ::stream::library::LibraryRefs::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::LibraryRefs>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::library::LibraryRefs::Builder Library::Builder::initLibraryRefs() { + return ::capnp::_::PointerHelpers< ::stream::library::LibraryRefs>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptLibraryRefs( + ::capnp::Orphan< ::stream::library::LibraryRefs>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::LibraryRefs>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::LibraryRefs> Library::Builder::disownLibraryRefs() { + return ::capnp::_::PointerHelpers< ::stream::library::LibraryRefs>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasPropertyNamesTable() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasPropertyNamesTable() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::PropertyNamesTable::Reader Library::Reader::getPropertyNamesTable() const { + return ::capnp::_::PointerHelpers< ::stream::library::PropertyNamesTable>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::stream::library::PropertyNamesTable::Builder Library::Builder::getPropertyNamesTable() { + return ::capnp::_::PointerHelpers< ::stream::library::PropertyNamesTable>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::PropertyNamesTable::Pipeline Library::Pipeline::getPropertyNamesTable() { + return ::stream::library::PropertyNamesTable::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setPropertyNamesTable( ::stream::library::PropertyNamesTable::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::PropertyNamesTable>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::stream::library::PropertyNamesTable::Builder Library::Builder::initPropertyNamesTable() { + return ::capnp::_::PointerHelpers< ::stream::library::PropertyNamesTable>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptPropertyNamesTable( + ::capnp::Orphan< ::stream::library::PropertyNamesTable>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::PropertyNamesTable>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::PropertyNamesTable> Library::Builder::disownPropertyNamesTable() { + return ::capnp::_::PointerHelpers< ::stream::library::PropertyNamesTable>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasPropertiesTable() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasPropertiesTable() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::PropertiesTable::Reader Library::Reader::getPropertiesTable() const { + return ::capnp::_::PointerHelpers< ::stream::library::PropertiesTable>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::stream::library::PropertiesTable::Builder Library::Builder::getPropertiesTable() { + return ::capnp::_::PointerHelpers< ::stream::library::PropertiesTable>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::PropertiesTable::Pipeline Library::Pipeline::getPropertiesTable() { + return ::stream::library::PropertiesTable::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setPropertiesTable( ::stream::library::PropertiesTable::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::PropertiesTable>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::stream::library::PropertiesTable::Builder Library::Builder::initPropertiesTable() { + return ::capnp::_::PointerHelpers< ::stream::library::PropertiesTable>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptPropertiesTable( + ::capnp::Orphan< ::stream::library::PropertiesTable>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::PropertiesTable>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::PropertiesTable> Library::Builder::disownPropertiesTable() { + return ::capnp::_::PointerHelpers< ::stream::library::PropertiesTable>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasTextStringsTable() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasTextStringsTable() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::TextStringsTable::Reader Library::Reader::getTextStringsTable() const { + return ::capnp::_::PointerHelpers< ::stream::library::TextStringsTable>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::stream::library::TextStringsTable::Builder Library::Builder::getTextStringsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::TextStringsTable>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::TextStringsTable::Pipeline Library::Pipeline::getTextStringsTable() { + return ::stream::library::TextStringsTable::Pipeline(_typeless.getPointerField(4)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setTextStringsTable( ::stream::library::TextStringsTable::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::TextStringsTable>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::stream::library::TextStringsTable::Builder Library::Builder::initTextStringsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::TextStringsTable>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptTextStringsTable( + ::capnp::Orphan< ::stream::library::TextStringsTable>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::TextStringsTable>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::TextStringsTable> Library::Builder::disownTextStringsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::TextStringsTable>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasViewSpecsTable() const { + return !_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasViewSpecsTable() { + return !_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::ViewSpecsTable::Reader Library::Reader::getViewSpecsTable() const { + return ::capnp::_::PointerHelpers< ::stream::library::ViewSpecsTable>::get(_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline ::stream::library::ViewSpecsTable::Builder Library::Builder::getViewSpecsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::ViewSpecsTable>::get(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::ViewSpecsTable::Pipeline Library::Pipeline::getViewSpecsTable() { + return ::stream::library::ViewSpecsTable::Pipeline(_typeless.getPointerField(5)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setViewSpecsTable( ::stream::library::ViewSpecsTable::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::ViewSpecsTable>::set(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), value); +} +inline ::stream::library::ViewSpecsTable::Builder Library::Builder::initViewSpecsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::ViewSpecsTable>::init(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptViewSpecsTable( + ::capnp::Orphan< ::stream::library::ViewSpecsTable>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::ViewSpecsTable>::adopt(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::ViewSpecsTable> Library::Builder::disownViewSpecsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::ViewSpecsTable>::disown(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasCellSpecsTable() const { + return !_reader.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasCellSpecsTable() { + return !_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::CellSpecsTable::Reader Library::Reader::getCellSpecsTable() const { + return ::capnp::_::PointerHelpers< ::stream::library::CellSpecsTable>::get(_reader.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} +inline ::stream::library::CellSpecsTable::Builder Library::Builder::getCellSpecsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::CellSpecsTable>::get(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::CellSpecsTable::Pipeline Library::Pipeline::getCellSpecsTable() { + return ::stream::library::CellSpecsTable::Pipeline(_typeless.getPointerField(6)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setCellSpecsTable( ::stream::library::CellSpecsTable::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::CellSpecsTable>::set(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS), value); +} +inline ::stream::library::CellSpecsTable::Builder Library::Builder::initCellSpecsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::CellSpecsTable>::init(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptCellSpecsTable( + ::capnp::Orphan< ::stream::library::CellSpecsTable>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::CellSpecsTable>::adopt(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::CellSpecsTable> Library::Builder::disownCellSpecsTable() { + return ::capnp::_::PointerHelpers< ::stream::library::CellSpecsTable>::disown(_builder.getPointerField( + ::capnp::bounded<6>() * ::capnp::POINTERS)); +} + +inline bool Library::Reader::hasCellHierarchyTree() const { + return !_reader.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS).isNull(); +} +inline bool Library::Builder::hasCellHierarchyTree() { + return !_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::library::CellHierarchyTree::Reader Library::Reader::getCellHierarchyTree() const { + return ::capnp::_::PointerHelpers< ::stream::library::CellHierarchyTree>::get(_reader.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} +inline ::stream::library::CellHierarchyTree::Builder Library::Builder::getCellHierarchyTree() { + return ::capnp::_::PointerHelpers< ::stream::library::CellHierarchyTree>::get(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::library::CellHierarchyTree::Pipeline Library::Pipeline::getCellHierarchyTree() { + return ::stream::library::CellHierarchyTree::Pipeline(_typeless.getPointerField(7)); +} +#endif // !CAPNP_LITE +inline void Library::Builder::setCellHierarchyTree( ::stream::library::CellHierarchyTree::Reader value) { + ::capnp::_::PointerHelpers< ::stream::library::CellHierarchyTree>::set(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS), value); +} +inline ::stream::library::CellHierarchyTree::Builder Library::Builder::initCellHierarchyTree() { + return ::capnp::_::PointerHelpers< ::stream::library::CellHierarchyTree>::init(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} +inline void Library::Builder::adoptCellHierarchyTree( + ::capnp::Orphan< ::stream::library::CellHierarchyTree>&& value) { + ::capnp::_::PointerHelpers< ::stream::library::CellHierarchyTree>::adopt(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::library::CellHierarchyTree> Library::Builder::disownCellHierarchyTree() { + return ::capnp::_::PointerHelpers< ::stream::library::CellHierarchyTree>::disown(_builder.getPointerField( + ::capnp::bounded<7>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/metaData.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/metaData.capnp.cc new file mode 100644 index 000000000..cae9f8d78 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/metaData.capnp.cc @@ -0,0 +1,171 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: metaData.capnp + +#include "metaData.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<64> b_cf35f955a29422a3 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 163, 34, 148, 162, 85, 249, 53, 207, + 15, 0, 0, 0, 1, 0, 0, 0, + 162, 141, 82, 244, 3, 18, 213, 145, + 3, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 101, 116, 97, 68, 97, 116, 97, + 46, 99, 97, 112, 110, 112, 58, 77, + 101, 116, 97, 68, 97, 116, 97, 69, + 110, 116, 114, 121, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 0, 0, 3, 0, 1, 0, + 88, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 101, 115, 99, 114, 105, 112, 116, + 105, 111, 110, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 108, 117, 101, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_cf35f955a29422a3 = b_cf35f955a29422a3.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_cf35f955a29422a3[] = { + &s_f96a70ebaebd19c6, +}; +static const uint16_t m_cf35f955a29422a3[] = {1, 0, 2}; +static const uint16_t i_cf35f955a29422a3[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_cf35f955a29422a3 = { + 0xcf35f955a29422a3, b_cf35f955a29422a3.words, 64, d_cf35f955a29422a3, m_cf35f955a29422a3, + 1, 3, i_cf35f955a29422a3, nullptr, nullptr, { &s_cf35f955a29422a3, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<36> b_9342d1e9e8d5d438 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 56, 212, 213, 232, 233, 209, 66, 147, + 15, 0, 0, 0, 1, 0, 0, 0, + 162, 141, 82, 244, 3, 18, 213, 145, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 194, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 101, 116, 97, 68, 97, 116, 97, + 46, 99, 97, 112, 110, 112, 58, 77, + 101, 116, 97, 68, 97, 116, 97, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 36, 0, 0, 0, 2, 0, 1, 0, + 101, 110, 116, 114, 105, 101, 115, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 163, 34, 148, 162, 85, 249, 53, 207, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9342d1e9e8d5d438 = b_9342d1e9e8d5d438.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9342d1e9e8d5d438[] = { + &s_cf35f955a29422a3, +}; +static const uint16_t m_9342d1e9e8d5d438[] = {0}; +static const uint16_t i_9342d1e9e8d5d438[] = {0}; +const ::capnp::_::RawSchema s_9342d1e9e8d5d438 = { + 0x9342d1e9e8d5d438, b_9342d1e9e8d5d438.words, 36, d_9342d1e9e8d5d438, m_9342d1e9e8d5d438, + 1, 1, i_9342d1e9e8d5d438, nullptr, nullptr, { &s_9342d1e9e8d5d438, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace metaData { + +// MetaDataEntry +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t MetaDataEntry::_capnpPrivate::dataWordSize; +constexpr uint16_t MetaDataEntry::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind MetaDataEntry::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* MetaDataEntry::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// MetaData +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t MetaData::_capnpPrivate::dataWordSize; +constexpr uint16_t MetaData::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind MetaData::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* MetaData::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/metaData.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/metaData.capnp.h new file mode 100644 index 000000000..213c4b9d6 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/metaData.capnp.h @@ -0,0 +1,393 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: metaData.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "variant.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(cf35f955a29422a3); +CAPNP_DECLARE_SCHEMA(9342d1e9e8d5d438); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace metaData { + +struct MetaDataEntry { + MetaDataEntry() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cf35f955a29422a3, 0, 3) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct MetaData { + MetaData() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9342d1e9e8d5d438, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class MetaDataEntry::Reader { +public: + typedef MetaDataEntry Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline bool hasDescription() const; + inline ::capnp::Text::Reader getDescription() const; + + inline bool hasValue() const; + inline ::stream::variant::Variant::Reader getValue() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class MetaDataEntry::Builder { +public: + typedef MetaDataEntry Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline bool hasDescription(); + inline ::capnp::Text::Builder getDescription(); + inline void setDescription( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initDescription(unsigned int size); + inline void adoptDescription(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownDescription(); + + inline bool hasValue(); + inline ::stream::variant::Variant::Builder getValue(); + inline void setValue( ::stream::variant::Variant::Reader value); + inline ::stream::variant::Variant::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::stream::variant::Variant>&& value); + inline ::capnp::Orphan< ::stream::variant::Variant> disownValue(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class MetaDataEntry::Pipeline { +public: + typedef MetaDataEntry Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::variant::Variant::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class MetaData::Reader { +public: + typedef MetaData Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasEntries() const; + inline ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Reader getEntries() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class MetaData::Builder { +public: + typedef MetaData Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasEntries(); + inline ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Builder getEntries(); + inline void setEntries( ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Builder initEntries(unsigned int size); + inline void adoptEntries(::capnp::Orphan< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>> disownEntries(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class MetaData::Pipeline { +public: + typedef MetaData Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline bool MetaDataEntry::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool MetaDataEntry::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader MetaDataEntry::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder MetaDataEntry::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void MetaDataEntry::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder MetaDataEntry::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void MetaDataEntry::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> MetaDataEntry::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool MetaDataEntry::Reader::hasDescription() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool MetaDataEntry::Builder::hasDescription() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader MetaDataEntry::Reader::getDescription() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder MetaDataEntry::Builder::getDescription() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void MetaDataEntry::Builder::setDescription( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder MetaDataEntry::Builder::initDescription(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void MetaDataEntry::Builder::adoptDescription( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> MetaDataEntry::Builder::disownDescription() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool MetaDataEntry::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool MetaDataEntry::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::variant::Variant::Reader MetaDataEntry::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::stream::variant::Variant::Builder MetaDataEntry::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::variant::Variant::Pipeline MetaDataEntry::Pipeline::getValue() { + return ::stream::variant::Variant::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void MetaDataEntry::Builder::setValue( ::stream::variant::Variant::Reader value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::stream::variant::Variant::Builder MetaDataEntry::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void MetaDataEntry::Builder::adoptValue( + ::capnp::Orphan< ::stream::variant::Variant>&& value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::variant::Variant> MetaDataEntry::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool MetaData::Reader::hasEntries() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool MetaData::Builder::hasEntries() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Reader MetaData::Reader::getEntries() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Builder MetaData::Builder::getEntries() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void MetaData::Builder::setEntries( ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>::Builder MetaData::Builder::initEntries(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void MetaData::Builder::adoptEntries( + ::capnp::Orphan< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>> MetaData::Builder::disownEntries() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::metaData::MetaDataEntry, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/metaDataView.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/metaDataView.capnp.cc new file mode 100644 index 000000000..bc5b61cca --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/metaDataView.capnp.cc @@ -0,0 +1,78 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: metaDataView.capnp + +#include "metaDataView.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<33> b_8ff3115ade0dced6 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 214, 206, 13, 222, 90, 17, 243, 143, + 19, 0, 0, 0, 1, 0, 0, 0, + 37, 235, 246, 245, 136, 214, 1, 244, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 2, 1, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 101, 116, 97, 68, 97, 116, 97, + 86, 105, 101, 119, 46, 99, 97, 112, + 110, 112, 58, 77, 101, 116, 97, 68, + 97, 116, 97, 86, 105, 101, 119, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 20, 0, 0, 0, 2, 0, 1, 0, + 100, 97, 116, 97, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 56, 212, 213, 232, 233, 209, 66, 147, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_8ff3115ade0dced6 = b_8ff3115ade0dced6.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_8ff3115ade0dced6[] = { + &s_9342d1e9e8d5d438, +}; +static const uint16_t m_8ff3115ade0dced6[] = {0}; +static const uint16_t i_8ff3115ade0dced6[] = {0}; +const ::capnp::_::RawSchema s_8ff3115ade0dced6 = { + 0x8ff3115ade0dced6, b_8ff3115ade0dced6.words, 33, d_8ff3115ade0dced6, m_8ff3115ade0dced6, + 1, 1, i_8ff3115ade0dced6, nullptr, nullptr, { &s_8ff3115ade0dced6, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace metaDataView { + +// MetaDataView +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t MetaDataView::_capnpPrivate::dataWordSize; +constexpr uint16_t MetaDataView::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind MetaDataView::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* MetaDataView::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/metaDataView.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/metaDataView.capnp.h new file mode 100644 index 000000000..c6a8968ab --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/metaDataView.capnp.h @@ -0,0 +1,174 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: metaDataView.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "metaData.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(8ff3115ade0dced6); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace metaDataView { + +struct MetaDataView { + MetaDataView() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8ff3115ade0dced6, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class MetaDataView::Reader { +public: + typedef MetaDataView Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasData() const; + inline ::stream::metaData::MetaData::Reader getData() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class MetaDataView::Builder { +public: + typedef MetaDataView Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasData(); + inline ::stream::metaData::MetaData::Builder getData(); + inline void setData( ::stream::metaData::MetaData::Reader value); + inline ::stream::metaData::MetaData::Builder initData(); + inline void adoptData(::capnp::Orphan< ::stream::metaData::MetaData>&& value); + inline ::capnp::Orphan< ::stream::metaData::MetaData> disownData(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class MetaDataView::Pipeline { +public: + typedef MetaDataView Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::metaData::MetaData::Pipeline getData(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline bool MetaDataView::Reader::hasData() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool MetaDataView::Builder::hasData() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::metaData::MetaData::Reader MetaDataView::Reader::getData() const { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::metaData::MetaData::Builder MetaDataView::Builder::getData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::metaData::MetaData::Pipeline MetaDataView::Pipeline::getData() { + return ::stream::metaData::MetaData::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void MetaDataView::Builder::setData( ::stream::metaData::MetaData::Reader value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::metaData::MetaData::Builder MetaDataView::Builder::initData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void MetaDataView::Builder::adoptData( + ::capnp::Orphan< ::stream::metaData::MetaData>&& value) { + ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::metaData::MetaData> MetaDataView::Builder::disownData() { + return ::capnp::_::PointerHelpers< ::stream::metaData::MetaData>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/propertySet.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/propertySet.capnp.cc new file mode 100644 index 000000000..1ef0950cd --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/propertySet.capnp.cc @@ -0,0 +1,232 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: propertySet.capnp + +#include "propertySet.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<49> b_ab971fd3eda1ed27 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 39, 237, 161, 237, 211, 31, 151, 171, + 18, 0, 0, 0, 1, 0, 1, 0, + 244, 191, 20, 32, 245, 192, 68, 163, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 46, 99, 97, 112, 110, + 112, 58, 80, 114, 111, 112, 101, 114, + 116, 121, 78, 97, 109, 101, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 56, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 115, 112, 97, 99, + 101, 73, 100, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ab971fd3eda1ed27 = b_ab971fd3eda1ed27.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ab971fd3eda1ed27[] = { + &s_f96a70ebaebd19c6, +}; +static const uint16_t m_ab971fd3eda1ed27[] = {1, 0}; +static const uint16_t i_ab971fd3eda1ed27[] = {0, 1}; +const ::capnp::_::RawSchema s_ab971fd3eda1ed27 = { + 0xab971fd3eda1ed27, b_ab971fd3eda1ed27.words, 49, d_ab971fd3eda1ed27, m_ab971fd3eda1ed27, + 1, 2, i_ab971fd3eda1ed27, nullptr, nullptr, { &s_ab971fd3eda1ed27, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<48> b_c5163eb42a82d19a = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 154, 209, 130, 42, 180, 62, 22, 197, + 18, 0, 0, 0, 1, 0, 1, 0, + 244, 191, 20, 32, 245, 192, 68, 163, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 46, 99, 97, 112, 110, + 112, 58, 78, 97, 109, 101, 100, 86, + 97, 108, 117, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 108, 117, 101, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c5163eb42a82d19a = b_c5163eb42a82d19a.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c5163eb42a82d19a[] = { + &s_f96a70ebaebd19c6, +}; +static const uint16_t m_c5163eb42a82d19a[] = {0, 1}; +static const uint16_t i_c5163eb42a82d19a[] = {0, 1}; +const ::capnp::_::RawSchema s_c5163eb42a82d19a = { + 0xc5163eb42a82d19a, b_c5163eb42a82d19a.words, 48, d_c5163eb42a82d19a, m_c5163eb42a82d19a, + 1, 2, i_c5163eb42a82d19a, nullptr, nullptr, { &s_c5163eb42a82d19a, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<38> b_ee9f1a259aa6017f = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 127, 1, 166, 154, 37, 26, 159, 238, + 18, 0, 0, 0, 1, 0, 0, 0, + 244, 191, 20, 32, 245, 192, 68, 163, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 111, 112, 101, 114, 116, 121, + 83, 101, 116, 46, 99, 97, 112, 110, + 112, 58, 80, 114, 111, 112, 101, 114, + 116, 121, 83, 101, 116, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 112, 114, 111, 112, 101, 114, 116, 105, + 101, 115, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 154, 209, 130, 42, 180, 62, 22, 197, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ee9f1a259aa6017f = b_ee9f1a259aa6017f.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ee9f1a259aa6017f[] = { + &s_c5163eb42a82d19a, +}; +static const uint16_t m_ee9f1a259aa6017f[] = {0}; +static const uint16_t i_ee9f1a259aa6017f[] = {0}; +const ::capnp::_::RawSchema s_ee9f1a259aa6017f = { + 0xee9f1a259aa6017f, b_ee9f1a259aa6017f.words, 38, d_ee9f1a259aa6017f, m_ee9f1a259aa6017f, + 1, 1, i_ee9f1a259aa6017f, nullptr, nullptr, { &s_ee9f1a259aa6017f, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace propertySet { + +// PropertyName +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t PropertyName::_capnpPrivate::dataWordSize; +constexpr uint16_t PropertyName::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind PropertyName::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* PropertyName::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// NamedValue +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t NamedValue::_capnpPrivate::dataWordSize; +constexpr uint16_t NamedValue::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind NamedValue::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* NamedValue::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// PropertySet +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t PropertySet::_capnpPrivate::dataWordSize; +constexpr uint16_t PropertySet::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind PropertySet::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* PropertySet::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/propertySet.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/propertySet.capnp.h new file mode 100644 index 000000000..a663b9a8c --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/propertySet.capnp.h @@ -0,0 +1,480 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: propertySet.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "variant.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(ab971fd3eda1ed27); +CAPNP_DECLARE_SCHEMA(c5163eb42a82d19a); +CAPNP_DECLARE_SCHEMA(ee9f1a259aa6017f); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace propertySet { + +struct PropertyName { + PropertyName() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ab971fd3eda1ed27, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct NamedValue { + NamedValue() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c5163eb42a82d19a, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct PropertySet { + PropertySet() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ee9f1a259aa6017f, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class PropertyName::Reader { +public: + typedef PropertyName Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getNamespaceId() const; + + inline bool hasName() const; + inline ::stream::variant::Variant::Reader getName() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class PropertyName::Builder { +public: + typedef PropertyName Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getNamespaceId(); + inline void setNamespaceId( ::uint64_t value); + + inline bool hasName(); + inline ::stream::variant::Variant::Builder getName(); + inline void setName( ::stream::variant::Variant::Reader value); + inline ::stream::variant::Variant::Builder initName(); + inline void adoptName(::capnp::Orphan< ::stream::variant::Variant>&& value); + inline ::capnp::Orphan< ::stream::variant::Variant> disownName(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class PropertyName::Pipeline { +public: + typedef PropertyName Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::variant::Variant::Pipeline getName(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class NamedValue::Reader { +public: + typedef NamedValue Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getNameId() const; + + inline bool hasValue() const; + inline ::stream::variant::Variant::Reader getValue() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class NamedValue::Builder { +public: + typedef NamedValue Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getNameId(); + inline void setNameId( ::uint64_t value); + + inline bool hasValue(); + inline ::stream::variant::Variant::Builder getValue(); + inline void setValue( ::stream::variant::Variant::Reader value); + inline ::stream::variant::Variant::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::stream::variant::Variant>&& value); + inline ::capnp::Orphan< ::stream::variant::Variant> disownValue(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class NamedValue::Pipeline { +public: + typedef NamedValue Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::variant::Variant::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class PropertySet::Reader { +public: + typedef PropertySet Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasProperties() const; + inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader getProperties() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class PropertySet::Builder { +public: + typedef PropertySet Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasProperties(); + inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder getProperties(); + inline void setProperties( ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder initProperties(unsigned int size); + inline void adoptProperties(::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>> disownProperties(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class PropertySet::Pipeline { +public: + typedef PropertySet Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::uint64_t PropertyName::Reader::getNamespaceId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t PropertyName::Builder::getNamespaceId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void PropertyName::Builder::setNamespaceId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool PropertyName::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool PropertyName::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::variant::Variant::Reader PropertyName::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::variant::Variant::Builder PropertyName::Builder::getName() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::variant::Variant::Pipeline PropertyName::Pipeline::getName() { + return ::stream::variant::Variant::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void PropertyName::Builder::setName( ::stream::variant::Variant::Reader value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::variant::Variant::Builder PropertyName::Builder::initName() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void PropertyName::Builder::adoptName( + ::capnp::Orphan< ::stream::variant::Variant>&& value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::variant::Variant> PropertyName::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t NamedValue::Reader::getNameId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t NamedValue::Builder::getNameId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void NamedValue::Builder::setNameId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool NamedValue::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool NamedValue::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::variant::Variant::Reader NamedValue::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::variant::Variant::Builder NamedValue::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::variant::Variant::Pipeline NamedValue::Pipeline::getValue() { + return ::stream::variant::Variant::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void NamedValue::Builder::setValue( ::stream::variant::Variant::Reader value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::variant::Variant::Builder NamedValue::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void NamedValue::Builder::adoptValue( + ::capnp::Orphan< ::stream::variant::Variant>&& value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::variant::Variant> NamedValue::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool PropertySet::Reader::hasProperties() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool PropertySet::Builder::hasProperties() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader PropertySet::Reader::getProperties() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder PropertySet::Builder::getProperties() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void PropertySet::Builder::setProperties( ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>::Builder PropertySet::Builder::initProperties(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void PropertySet::Builder::adoptProperties( + ::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>> PropertySet::Builder::disownProperties() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::propertySet::NamedValue, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/repetition.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/repetition.capnp.cc new file mode 100644 index 000000000..f308580af --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/repetition.capnp.cc @@ -0,0 +1,452 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: repetition.capnp + +#include "repetition.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<79> b_9425aecc5b90c16e = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 110, 193, 144, 91, 204, 174, 37, 148, + 17, 0, 0, 0, 1, 0, 4, 0, + 55, 226, 130, 50, 37, 72, 69, 156, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 66, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 46, 99, 97, 112, 110, 112, + 58, 82, 101, 103, 117, 108, 97, 114, + 79, 114, 116, 104, 111, 82, 101, 112, + 101, 116, 105, 116, 105, 111, 110, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 0, 0, 0, 3, 0, 1, 0, + 112, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 3, 0, 1, 0, + 116, 0, 0, 0, 2, 0, 1, 0, + 100, 120, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 121, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 120, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 121, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9425aecc5b90c16e = b_9425aecc5b90c16e.words; +#if !CAPNP_LITE +static const uint16_t m_9425aecc5b90c16e[] = {0, 1, 2, 3}; +static const uint16_t i_9425aecc5b90c16e[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_9425aecc5b90c16e = { + 0x9425aecc5b90c16e, b_9425aecc5b90c16e.words, 79, nullptr, m_9425aecc5b90c16e, + 0, 4, i_9425aecc5b90c16e, nullptr, nullptr, { &s_9425aecc5b90c16e, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<79> b_8ad514566ec69992 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 146, 153, 198, 110, 86, 20, 213, 138, + 17, 0, 0, 0, 1, 0, 2, 0, + 55, 226, 130, 50, 37, 72, 69, 156, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 26, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 46, 99, 97, 112, 110, 112, + 58, 82, 101, 103, 117, 108, 97, 114, + 82, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 0, 0, 0, 3, 0, 1, 0, + 112, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 3, 0, 1, 0, + 116, 0, 0, 0, 2, 0, 1, 0, + 97, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 97, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 98, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_8ad514566ec69992 = b_8ad514566ec69992.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_8ad514566ec69992[] = { + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_8ad514566ec69992[] = {0, 1, 2, 3}; +static const uint16_t i_8ad514566ec69992[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_8ad514566ec69992 = { + 0x8ad514566ec69992, b_8ad514566ec69992.words, 79, d_8ad514566ec69992, m_8ad514566ec69992, + 1, 4, i_8ad514566ec69992, nullptr, nullptr, { &s_8ad514566ec69992, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<38> b_ba39d45a51b9e73b = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 59, 231, 185, 81, 90, 212, 57, 186, + 17, 0, 0, 0, 1, 0, 0, 0, + 55, 226, 130, 50, 37, 72, 69, 156, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 50, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 46, 99, 97, 112, 110, 112, + 58, 69, 110, 117, 109, 101, 114, 97, + 116, 101, 100, 82, 101, 112, 101, 116, + 105, 116, 105, 111, 110, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 36, 0, 0, 0, 2, 0, 1, 0, + 100, 101, 108, 116, 97, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ba39d45a51b9e73b = b_ba39d45a51b9e73b.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ba39d45a51b9e73b[] = { + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_ba39d45a51b9e73b[] = {0}; +static const uint16_t i_ba39d45a51b9e73b[] = {0}; +const ::capnp::_::RawSchema s_ba39d45a51b9e73b = { + 0xba39d45a51b9e73b, b_ba39d45a51b9e73b.words, 38, d_ba39d45a51b9e73b, m_ba39d45a51b9e73b, + 1, 1, i_ba39d45a51b9e73b, nullptr, nullptr, { &s_ba39d45a51b9e73b, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<26> b_927c0face2bd19e7 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 231, 25, 189, 226, 172, 15, 124, 146, + 17, 0, 0, 0, 1, 0, 1, 0, + 55, 226, 130, 50, 37, 72, 69, 156, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 226, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 46, 99, 97, 112, 110, 112, + 58, 82, 101, 112, 101, 116, 105, 116, + 105, 111, 110, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 221, 231, 117, 117, 81, 203, 55, 148, + 13, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 121, 112, 101, 115, 0, 0, 0, } +}; +::capnp::word const* const bp_927c0face2bd19e7 = b_927c0face2bd19e7.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_927c0face2bd19e7[] = { + &s_9437cb517575e7dd, +}; +static const uint16_t m_927c0face2bd19e7[] = {0}; +static const uint16_t i_927c0face2bd19e7[] = {0}; +const ::capnp::_::RawSchema s_927c0face2bd19e7 = { + 0x927c0face2bd19e7, b_927c0face2bd19e7.words, 26, d_927c0face2bd19e7, m_927c0face2bd19e7, + 1, 1, i_927c0face2bd19e7, nullptr, nullptr, { &s_927c0face2bd19e7, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<80> b_9437cb517575e7dd = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 221, 231, 117, 117, 81, 203, 55, 148, + 28, 0, 0, 0, 1, 0, 1, 0, + 231, 25, 189, 226, 172, 15, 124, 146, + 1, 0, 7, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 18, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 112, 101, 116, 105, 116, 105, + 111, 110, 46, 99, 97, 112, 110, 112, + 58, 82, 101, 112, 101, 116, 105, 116, + 105, 111, 110, 46, 116, 121, 112, 101, + 115, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 253, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 3, 0, 1, 0, + 116, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 252, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 113, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 0, 0, 0, 3, 0, 1, 0, + 124, 0, 0, 0, 2, 0, 1, 0, + 115, 105, 110, 103, 108, 101, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 169, 23, 16, 131, 13, 157, 234, 195, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 103, 117, 108, 97, 114, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 146, 153, 198, 110, 86, 20, 213, 138, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 103, 117, 108, 97, 114, 79, + 114, 116, 104, 111, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 110, 193, 144, 91, 204, 174, 37, 148, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 110, 117, 109, 101, 114, 97, 116, + 101, 100, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 59, 231, 185, 81, 90, 212, 57, 186, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9437cb517575e7dd = b_9437cb517575e7dd.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9437cb517575e7dd[] = { + &s_8ad514566ec69992, + &s_927c0face2bd19e7, + &s_9425aecc5b90c16e, + &s_ba39d45a51b9e73b, + &s_c3ea9d0d831017a9, +}; +static const uint16_t m_9437cb517575e7dd[] = {3, 1, 2, 0}; +static const uint16_t i_9437cb517575e7dd[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_9437cb517575e7dd = { + 0x9437cb517575e7dd, b_9437cb517575e7dd.words, 80, d_9437cb517575e7dd, m_9437cb517575e7dd, + 5, 4, i_9437cb517575e7dd, nullptr, nullptr, { &s_9437cb517575e7dd, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace repetition { + +// RegularOrthoRepetition +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t RegularOrthoRepetition::_capnpPrivate::dataWordSize; +constexpr uint16_t RegularOrthoRepetition::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind RegularOrthoRepetition::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* RegularOrthoRepetition::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// RegularRepetition +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t RegularRepetition::_capnpPrivate::dataWordSize; +constexpr uint16_t RegularRepetition::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind RegularRepetition::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* RegularRepetition::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// EnumeratedRepetition +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t EnumeratedRepetition::_capnpPrivate::dataWordSize; +constexpr uint16_t EnumeratedRepetition::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind EnumeratedRepetition::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* EnumeratedRepetition::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Repetition +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Repetition::_capnpPrivate::dataWordSize; +constexpr uint16_t Repetition::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Repetition::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Repetition::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Repetition::Types +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Repetition::Types::_capnpPrivate::dataWordSize; +constexpr uint16_t Repetition::Types::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Repetition::Types::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Repetition::Types::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/repetition.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/repetition.capnp.h new file mode 100644 index 000000000..a82e10f3d --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/repetition.capnp.h @@ -0,0 +1,1034 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: repetition.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + +#include "geometry.capnp.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(9425aecc5b90c16e); +CAPNP_DECLARE_SCHEMA(8ad514566ec69992); +CAPNP_DECLARE_SCHEMA(ba39d45a51b9e73b); +CAPNP_DECLARE_SCHEMA(927c0face2bd19e7); +CAPNP_DECLARE_SCHEMA(9437cb517575e7dd); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace repetition { + +struct RegularOrthoRepetition { + RegularOrthoRepetition() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9425aecc5b90c16e, 4, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct RegularRepetition { + RegularRepetition() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8ad514566ec69992, 2, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct EnumeratedRepetition { + EnumeratedRepetition() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ba39d45a51b9e73b, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Repetition { + Repetition() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Types; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(927c0face2bd19e7, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Repetition::Types { + Types() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + SINGLE, + REGULAR, + REGULAR_ORTHO, + ENUMERATED, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9437cb517575e7dd, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class RegularOrthoRepetition::Reader { +public: + typedef RegularOrthoRepetition Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::int64_t getDx() const; + + inline ::int64_t getDy() const; + + inline ::uint64_t getNx() const; + + inline ::uint64_t getNy() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class RegularOrthoRepetition::Builder { +public: + typedef RegularOrthoRepetition Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::int64_t getDx(); + inline void setDx( ::int64_t value); + + inline ::int64_t getDy(); + inline void setDy( ::int64_t value); + + inline ::uint64_t getNx(); + inline void setNx( ::uint64_t value); + + inline ::uint64_t getNy(); + inline void setNy( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class RegularOrthoRepetition::Pipeline { +public: + typedef RegularOrthoRepetition Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class RegularRepetition::Reader { +public: + typedef RegularRepetition Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasA() const; + inline ::stream::geometry::Vector::Reader getA() const; + + inline bool hasB() const; + inline ::stream::geometry::Vector::Reader getB() const; + + inline ::uint64_t getNa() const; + + inline ::uint64_t getNb() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class RegularRepetition::Builder { +public: + typedef RegularRepetition Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasA(); + inline ::stream::geometry::Vector::Builder getA(); + inline void setA( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initA(); + inline void adoptA(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownA(); + + inline bool hasB(); + inline ::stream::geometry::Vector::Builder getB(); + inline void setB( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initB(); + inline void adoptB(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownB(); + + inline ::uint64_t getNa(); + inline void setNa( ::uint64_t value); + + inline ::uint64_t getNb(); + inline void setNb( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class RegularRepetition::Pipeline { +public: + typedef RegularRepetition Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::geometry::Vector::Pipeline getA(); + inline ::stream::geometry::Vector::Pipeline getB(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class EnumeratedRepetition::Reader { +public: + typedef EnumeratedRepetition Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasDeltas() const; + inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader getDeltas() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class EnumeratedRepetition::Builder { +public: + typedef EnumeratedRepetition Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasDeltas(); + inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder getDeltas(); + inline void setDeltas( ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder initDeltas(unsigned int size); + inline void adoptDeltas(::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>> disownDeltas(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class EnumeratedRepetition::Pipeline { +public: + typedef EnumeratedRepetition Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Repetition::Reader { +public: + typedef Repetition Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline typename Types::Reader getTypes() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Repetition::Builder { +public: + typedef Repetition Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline typename Types::Builder getTypes(); + inline typename Types::Builder initTypes(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Repetition::Pipeline { +public: + typedef Repetition Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename Types::Pipeline getTypes(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Repetition::Types::Reader { +public: + typedef Types Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isSingle() const; + inline bool hasSingle() const; + inline ::stream::geometry::Vector::Reader getSingle() const; + + inline bool isRegular() const; + inline bool hasRegular() const; + inline ::stream::repetition::RegularRepetition::Reader getRegular() const; + + inline bool isRegularOrtho() const; + inline bool hasRegularOrtho() const; + inline ::stream::repetition::RegularOrthoRepetition::Reader getRegularOrtho() const; + + inline bool isEnumerated() const; + inline bool hasEnumerated() const; + inline ::stream::repetition::EnumeratedRepetition::Reader getEnumerated() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Repetition::Types::Builder { +public: + typedef Types Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isSingle(); + inline bool hasSingle(); + inline ::stream::geometry::Vector::Builder getSingle(); + inline void setSingle( ::stream::geometry::Vector::Reader value); + inline ::stream::geometry::Vector::Builder initSingle(); + inline void adoptSingle(::capnp::Orphan< ::stream::geometry::Vector>&& value); + inline ::capnp::Orphan< ::stream::geometry::Vector> disownSingle(); + + inline bool isRegular(); + inline bool hasRegular(); + inline ::stream::repetition::RegularRepetition::Builder getRegular(); + inline void setRegular( ::stream::repetition::RegularRepetition::Reader value); + inline ::stream::repetition::RegularRepetition::Builder initRegular(); + inline void adoptRegular(::capnp::Orphan< ::stream::repetition::RegularRepetition>&& value); + inline ::capnp::Orphan< ::stream::repetition::RegularRepetition> disownRegular(); + + inline bool isRegularOrtho(); + inline bool hasRegularOrtho(); + inline ::stream::repetition::RegularOrthoRepetition::Builder getRegularOrtho(); + inline void setRegularOrtho( ::stream::repetition::RegularOrthoRepetition::Reader value); + inline ::stream::repetition::RegularOrthoRepetition::Builder initRegularOrtho(); + inline void adoptRegularOrtho(::capnp::Orphan< ::stream::repetition::RegularOrthoRepetition>&& value); + inline ::capnp::Orphan< ::stream::repetition::RegularOrthoRepetition> disownRegularOrtho(); + + inline bool isEnumerated(); + inline bool hasEnumerated(); + inline ::stream::repetition::EnumeratedRepetition::Builder getEnumerated(); + inline void setEnumerated( ::stream::repetition::EnumeratedRepetition::Reader value); + inline ::stream::repetition::EnumeratedRepetition::Builder initEnumerated(); + inline void adoptEnumerated(::capnp::Orphan< ::stream::repetition::EnumeratedRepetition>&& value); + inline ::capnp::Orphan< ::stream::repetition::EnumeratedRepetition> disownEnumerated(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Repetition::Types::Pipeline { +public: + typedef Types Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::int64_t RegularOrthoRepetition::Reader::getDx() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::int64_t RegularOrthoRepetition::Builder::getDx() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void RegularOrthoRepetition::Builder::setDx( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::int64_t RegularOrthoRepetition::Reader::getDy() const { + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t RegularOrthoRepetition::Builder::getDy() { + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void RegularOrthoRepetition::Builder::setDy( ::int64_t value) { + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t RegularOrthoRepetition::Reader::getNx() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t RegularOrthoRepetition::Builder::getNx() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void RegularOrthoRepetition::Builder::setNx( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t RegularOrthoRepetition::Reader::getNy() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t RegularOrthoRepetition::Builder::getNy() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} +inline void RegularOrthoRepetition::Builder::setNy( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, value); +} + +inline bool RegularRepetition::Reader::hasA() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool RegularRepetition::Builder::hasA() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader RegularRepetition::Reader::getA() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder RegularRepetition::Builder::getA() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Vector::Pipeline RegularRepetition::Pipeline::getA() { + return ::stream::geometry::Vector::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void RegularRepetition::Builder::setA( ::stream::geometry::Vector::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder RegularRepetition::Builder::initA() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void RegularRepetition::Builder::adoptA( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> RegularRepetition::Builder::disownA() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool RegularRepetition::Reader::hasB() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool RegularRepetition::Builder::hasB() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader RegularRepetition::Reader::getB() const { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder RegularRepetition::Builder::getB() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::geometry::Vector::Pipeline RegularRepetition::Pipeline::getB() { + return ::stream::geometry::Vector::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void RegularRepetition::Builder::setB( ::stream::geometry::Vector::Reader value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder RegularRepetition::Builder::initB() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void RegularRepetition::Builder::adoptB( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> RegularRepetition::Builder::disownB() { + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint64_t RegularRepetition::Reader::getNa() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t RegularRepetition::Builder::getNa() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void RegularRepetition::Builder::setNa( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t RegularRepetition::Reader::getNb() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t RegularRepetition::Builder::getNb() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void RegularRepetition::Builder::setNb( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool EnumeratedRepetition::Reader::hasDeltas() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool EnumeratedRepetition::Builder::hasDeltas() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader EnumeratedRepetition::Reader::getDeltas() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder EnumeratedRepetition::Builder::getDeltas() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void EnumeratedRepetition::Builder::setDeltas( ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>::Builder EnumeratedRepetition::Builder::initDeltas(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void EnumeratedRepetition::Builder::adoptDeltas( + ::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>> EnumeratedRepetition::Builder::disownDeltas() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::geometry::Vector, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline typename Repetition::Types::Reader Repetition::Reader::getTypes() const { + return typename Repetition::Types::Reader(_reader); +} +inline typename Repetition::Types::Builder Repetition::Builder::getTypes() { + return typename Repetition::Types::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Repetition::Types::Pipeline Repetition::Pipeline::getTypes() { + return typename Repetition::Types::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Repetition::Types::Builder Repetition::Builder::initTypes() { + _builder.setDataField< ::uint16_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Repetition::Types::Builder(_builder); +} +inline ::stream::repetition::Repetition::Types::Which Repetition::Types::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::stream::repetition::Repetition::Types::Which Repetition::Types::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Repetition::Types::Reader::isSingle() const { + return which() == Repetition::Types::SINGLE; +} +inline bool Repetition::Types::Builder::isSingle() { + return which() == Repetition::Types::SINGLE; +} +inline bool Repetition::Types::Reader::hasSingle() const { + if (which() != Repetition::Types::SINGLE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Repetition::Types::Builder::hasSingle() { + if (which() != Repetition::Types::SINGLE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::geometry::Vector::Reader Repetition::Types::Reader::getSingle() const { + KJ_IREQUIRE((which() == Repetition::Types::SINGLE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::geometry::Vector::Builder Repetition::Types::Builder::getSingle() { + KJ_IREQUIRE((which() == Repetition::Types::SINGLE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::setSingle( ::stream::geometry::Vector::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::SINGLE); + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::geometry::Vector::Builder Repetition::Types::Builder::initSingle() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::SINGLE); + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::adoptSingle( + ::capnp::Orphan< ::stream::geometry::Vector>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::SINGLE); + ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::geometry::Vector> Repetition::Types::Builder::disownSingle() { + KJ_IREQUIRE((which() == Repetition::Types::SINGLE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::geometry::Vector>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Repetition::Types::Reader::isRegular() const { + return which() == Repetition::Types::REGULAR; +} +inline bool Repetition::Types::Builder::isRegular() { + return which() == Repetition::Types::REGULAR; +} +inline bool Repetition::Types::Reader::hasRegular() const { + if (which() != Repetition::Types::REGULAR) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Repetition::Types::Builder::hasRegular() { + if (which() != Repetition::Types::REGULAR) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::repetition::RegularRepetition::Reader Repetition::Types::Reader::getRegular() const { + KJ_IREQUIRE((which() == Repetition::Types::REGULAR), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularRepetition>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::repetition::RegularRepetition::Builder Repetition::Types::Builder::getRegular() { + KJ_IREQUIRE((which() == Repetition::Types::REGULAR), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularRepetition>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::setRegular( ::stream::repetition::RegularRepetition::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::REGULAR); + ::capnp::_::PointerHelpers< ::stream::repetition::RegularRepetition>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::repetition::RegularRepetition::Builder Repetition::Types::Builder::initRegular() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::REGULAR); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularRepetition>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::adoptRegular( + ::capnp::Orphan< ::stream::repetition::RegularRepetition>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::REGULAR); + ::capnp::_::PointerHelpers< ::stream::repetition::RegularRepetition>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::repetition::RegularRepetition> Repetition::Types::Builder::disownRegular() { + KJ_IREQUIRE((which() == Repetition::Types::REGULAR), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularRepetition>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Repetition::Types::Reader::isRegularOrtho() const { + return which() == Repetition::Types::REGULAR_ORTHO; +} +inline bool Repetition::Types::Builder::isRegularOrtho() { + return which() == Repetition::Types::REGULAR_ORTHO; +} +inline bool Repetition::Types::Reader::hasRegularOrtho() const { + if (which() != Repetition::Types::REGULAR_ORTHO) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Repetition::Types::Builder::hasRegularOrtho() { + if (which() != Repetition::Types::REGULAR_ORTHO) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::repetition::RegularOrthoRepetition::Reader Repetition::Types::Reader::getRegularOrtho() const { + KJ_IREQUIRE((which() == Repetition::Types::REGULAR_ORTHO), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularOrthoRepetition>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::repetition::RegularOrthoRepetition::Builder Repetition::Types::Builder::getRegularOrtho() { + KJ_IREQUIRE((which() == Repetition::Types::REGULAR_ORTHO), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularOrthoRepetition>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::setRegularOrtho( ::stream::repetition::RegularOrthoRepetition::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::REGULAR_ORTHO); + ::capnp::_::PointerHelpers< ::stream::repetition::RegularOrthoRepetition>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::repetition::RegularOrthoRepetition::Builder Repetition::Types::Builder::initRegularOrtho() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::REGULAR_ORTHO); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularOrthoRepetition>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::adoptRegularOrtho( + ::capnp::Orphan< ::stream::repetition::RegularOrthoRepetition>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::REGULAR_ORTHO); + ::capnp::_::PointerHelpers< ::stream::repetition::RegularOrthoRepetition>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::repetition::RegularOrthoRepetition> Repetition::Types::Builder::disownRegularOrtho() { + KJ_IREQUIRE((which() == Repetition::Types::REGULAR_ORTHO), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::RegularOrthoRepetition>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Repetition::Types::Reader::isEnumerated() const { + return which() == Repetition::Types::ENUMERATED; +} +inline bool Repetition::Types::Builder::isEnumerated() { + return which() == Repetition::Types::ENUMERATED; +} +inline bool Repetition::Types::Reader::hasEnumerated() const { + if (which() != Repetition::Types::ENUMERATED) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Repetition::Types::Builder::hasEnumerated() { + if (which() != Repetition::Types::ENUMERATED) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::repetition::EnumeratedRepetition::Reader Repetition::Types::Reader::getEnumerated() const { + KJ_IREQUIRE((which() == Repetition::Types::ENUMERATED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::EnumeratedRepetition>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::repetition::EnumeratedRepetition::Builder Repetition::Types::Builder::getEnumerated() { + KJ_IREQUIRE((which() == Repetition::Types::ENUMERATED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::EnumeratedRepetition>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::setEnumerated( ::stream::repetition::EnumeratedRepetition::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::ENUMERATED); + ::capnp::_::PointerHelpers< ::stream::repetition::EnumeratedRepetition>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::repetition::EnumeratedRepetition::Builder Repetition::Types::Builder::initEnumerated() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::ENUMERATED); + return ::capnp::_::PointerHelpers< ::stream::repetition::EnumeratedRepetition>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Repetition::Types::Builder::adoptEnumerated( + ::capnp::Orphan< ::stream::repetition::EnumeratedRepetition>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Repetition::Types::ENUMERATED); + ::capnp::_::PointerHelpers< ::stream::repetition::EnumeratedRepetition>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::repetition::EnumeratedRepetition> Repetition::Types::Builder::disownEnumerated() { + KJ_IREQUIRE((which() == Repetition::Types::ENUMERATED), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::stream::repetition::EnumeratedRepetition>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/variant.capnp.cc b/src/plugins/streamers/lstream/db_plugin/capnp/variant.capnp.cc new file mode 100644 index 000000000..a5f001e48 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/variant.capnp.cc @@ -0,0 +1,331 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: variant.capnp + +#include "variant.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<48> b_dcf203025f9c6db8 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 184, 109, 156, 95, 2, 3, 242, 220, + 14, 0, 0, 0, 1, 0, 0, 0, + 66, 164, 246, 229, 82, 216, 227, 146, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 114, 105, 97, 110, 116, 46, + 99, 97, 112, 110, 112, 58, 65, 114, + 114, 97, 121, 69, 110, 116, 114, 121, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 107, 101, 121, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 108, 117, 101, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_dcf203025f9c6db8 = b_dcf203025f9c6db8.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_dcf203025f9c6db8[] = { + &s_f96a70ebaebd19c6, +}; +static const uint16_t m_dcf203025f9c6db8[] = {0, 1}; +static const uint16_t i_dcf203025f9c6db8[] = {0, 1}; +const ::capnp::_::RawSchema s_dcf203025f9c6db8 = { + 0xdcf203025f9c6db8, b_dcf203025f9c6db8.words, 48, d_dcf203025f9c6db8, m_dcf203025f9c6db8, + 1, 2, i_dcf203025f9c6db8, nullptr, nullptr, { &s_dcf203025f9c6db8, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<25> b_f96a70ebaebd19c6 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 14, 0, 0, 0, 1, 0, 2, 0, + 66, 164, 246, 229, 82, 216, 227, 146, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 178, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 114, 105, 97, 110, 116, 46, + 99, 97, 112, 110, 112, 58, 86, 97, + 114, 105, 97, 110, 116, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 160, 103, 140, 31, 120, 18, 4, 135, + 13, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 108, 117, 101, 0, 0, 0, } +}; +::capnp::word const* const bp_f96a70ebaebd19c6 = b_f96a70ebaebd19c6.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_f96a70ebaebd19c6[] = { + &s_870412781f8c67a0, +}; +static const uint16_t m_f96a70ebaebd19c6[] = {0}; +static const uint16_t i_f96a70ebaebd19c6[] = {0}; +const ::capnp::_::RawSchema s_f96a70ebaebd19c6 = { + 0xf96a70ebaebd19c6, b_f96a70ebaebd19c6.words, 25, d_f96a70ebaebd19c6, m_f96a70ebaebd19c6, + 1, 1, i_f96a70ebaebd19c6, nullptr, nullptr, { &s_f96a70ebaebd19c6, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<160> b_870412781f8c67a0 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 160, 103, 140, 31, 120, 18, 4, 135, + 22, 0, 0, 0, 1, 0, 2, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 1, 0, 7, 0, 1, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 226, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 255, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 114, 105, 97, 110, 116, 46, + 99, 97, 112, 110, 112, 58, 86, 97, + 114, 105, 97, 110, 116, 46, 118, 97, + 108, 117, 101, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 232, 0, 0, 0, 3, 0, 1, 0, + 244, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 16, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 241, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 236, 0, 0, 0, 3, 0, 1, 0, + 248, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 253, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 245, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 3, 0, 1, 0, + 252, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 252, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 249, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 244, 0, 0, 0, 3, 0, 1, 0, + 0, 1, 0, 0, 2, 0, 1, 0, + 4, 0, 251, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 253, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 248, 0, 0, 0, 3, 0, 1, 0, + 4, 1, 0, 0, 2, 0, 1, 0, + 5, 0, 250, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 252, 0, 0, 0, 3, 0, 1, 0, + 8, 1, 0, 0, 2, 0, 1, 0, + 6, 0, 249, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 1, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 3, 0, 1, 0, + 28, 1, 0, 0, 2, 0, 1, 0, + 7, 0, 248, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 1, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 1, 0, 0, 3, 0, 1, 0, + 48, 1, 0, 0, 2, 0, 1, 0, + 8, 0, 247, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 1, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 1, 0, 0, 3, 0, 1, 0, + 52, 1, 0, 0, 2, 0, 1, 0, + 110, 105, 108, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 111, 111, 108, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 54, 52, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 54, 52, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 111, 117, 98, 108, 101, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 101, 120, 116, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 115, 116, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 198, 25, 189, 174, 235, 112, 106, 249, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 114, 114, 97, 121, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 184, 109, 156, 95, 2, 3, 242, 220, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 111, 98, 106, 101, 99, 116, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_870412781f8c67a0 = b_870412781f8c67a0.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_870412781f8c67a0[] = { + &s_dcf203025f9c6db8, + &s_f96a70ebaebd19c6, +}; +static const uint16_t m_870412781f8c67a0[] = {7, 1, 4, 3, 6, 0, 8, 5, 2}; +static const uint16_t i_870412781f8c67a0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; +const ::capnp::_::RawSchema s_870412781f8c67a0 = { + 0x870412781f8c67a0, b_870412781f8c67a0.words, 160, d_870412781f8c67a0, m_870412781f8c67a0, + 2, 9, i_870412781f8c67a0, nullptr, nullptr, { &s_870412781f8c67a0, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace stream { +namespace variant { + +// ArrayEntry +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t ArrayEntry::_capnpPrivate::dataWordSize; +constexpr uint16_t ArrayEntry::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind ArrayEntry::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* ArrayEntry::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Variant +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Variant::_capnpPrivate::dataWordSize; +constexpr uint16_t Variant::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Variant::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Variant::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Variant::Value +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Variant::Value::_capnpPrivate::dataWordSize; +constexpr uint16_t Variant::Value::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Variant::Value::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Variant::Value::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp/variant.capnp.h b/src/plugins/streamers/lstream/db_plugin/capnp/variant.capnp.h new file mode 100644 index 000000000..153299148 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp/variant.capnp.h @@ -0,0 +1,873 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: variant.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(dcf203025f9c6db8); +CAPNP_DECLARE_SCHEMA(f96a70ebaebd19c6); +CAPNP_DECLARE_SCHEMA(870412781f8c67a0); + +} // namespace schemas +} // namespace capnp + +namespace stream { +namespace variant { + +struct ArrayEntry { + ArrayEntry() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(dcf203025f9c6db8, 0, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Variant { + Variant() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Value; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f96a70ebaebd19c6, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Variant::Value { + Value() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + NIL, + BOOL, + UINT64, + INT64, + DOUBLE, + TEXT, + LIST, + ARRAY, + OBJECT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(870412781f8c67a0, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class ArrayEntry::Reader { +public: + typedef ArrayEntry Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasKey() const; + inline ::stream::variant::Variant::Reader getKey() const; + + inline bool hasValue() const; + inline ::stream::variant::Variant::Reader getValue() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class ArrayEntry::Builder { +public: + typedef ArrayEntry Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasKey(); + inline ::stream::variant::Variant::Builder getKey(); + inline void setKey( ::stream::variant::Variant::Reader value); + inline ::stream::variant::Variant::Builder initKey(); + inline void adoptKey(::capnp::Orphan< ::stream::variant::Variant>&& value); + inline ::capnp::Orphan< ::stream::variant::Variant> disownKey(); + + inline bool hasValue(); + inline ::stream::variant::Variant::Builder getValue(); + inline void setValue( ::stream::variant::Variant::Reader value); + inline ::stream::variant::Variant::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::stream::variant::Variant>&& value); + inline ::capnp::Orphan< ::stream::variant::Variant> disownValue(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class ArrayEntry::Pipeline { +public: + typedef ArrayEntry Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::stream::variant::Variant::Pipeline getKey(); + inline ::stream::variant::Variant::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Variant::Reader { +public: + typedef Variant Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline typename Value::Reader getValue() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Variant::Builder { +public: + typedef Variant Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline typename Value::Builder getValue(); + inline typename Value::Builder initValue(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Variant::Pipeline { +public: + typedef Variant Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename Value::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Variant::Value::Reader { +public: + typedef Value Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isNil() const; + inline ::capnp::Void getNil() const; + + inline bool isBool() const; + inline bool getBool() const; + + inline bool isUint64() const; + inline ::uint64_t getUint64() const; + + inline bool isInt64() const; + inline ::int64_t getInt64() const; + + inline bool isDouble() const; + inline double getDouble() const; + + inline bool isText() const; + inline bool hasText() const; + inline ::capnp::Text::Reader getText() const; + + inline bool isList() const; + inline bool hasList() const; + inline ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Reader getList() const; + + inline bool isArray() const; + inline bool hasArray() const; + inline ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Reader getArray() const; + + inline bool isObject() const; + inline bool hasObject() const; + inline ::capnp::Text::Reader getObject() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Variant::Value::Builder { +public: + typedef Value Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isNil(); + inline ::capnp::Void getNil(); + inline void setNil( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline bool getBool(); + inline void setBool(bool value); + + inline bool isUint64(); + inline ::uint64_t getUint64(); + inline void setUint64( ::uint64_t value); + + inline bool isInt64(); + inline ::int64_t getInt64(); + inline void setInt64( ::int64_t value); + + inline bool isDouble(); + inline double getDouble(); + inline void setDouble(double value); + + inline bool isText(); + inline bool hasText(); + inline ::capnp::Text::Builder getText(); + inline void setText( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initText(unsigned int size); + inline void adoptText(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownText(); + + inline bool isList(); + inline bool hasList(); + inline ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Builder getList(); + inline void setList( ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Builder initList(unsigned int size); + inline void adoptList(::capnp::Orphan< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>> disownList(); + + inline bool isArray(); + inline bool hasArray(); + inline ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Builder getArray(); + inline void setArray( ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Builder initArray(unsigned int size); + inline void adoptArray(::capnp::Orphan< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>> disownArray(); + + inline bool isObject(); + inline bool hasObject(); + inline ::capnp::Text::Builder getObject(); + inline void setObject( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initObject(unsigned int size); + inline void adoptObject(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownObject(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Variant::Value::Pipeline { +public: + typedef Value Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline bool ArrayEntry::Reader::hasKey() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool ArrayEntry::Builder::hasKey() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::variant::Variant::Reader ArrayEntry::Reader::getKey() const { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::stream::variant::Variant::Builder ArrayEntry::Builder::getKey() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::variant::Variant::Pipeline ArrayEntry::Pipeline::getKey() { + return ::stream::variant::Variant::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void ArrayEntry::Builder::setKey( ::stream::variant::Variant::Reader value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::stream::variant::Variant::Builder ArrayEntry::Builder::initKey() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void ArrayEntry::Builder::adoptKey( + ::capnp::Orphan< ::stream::variant::Variant>&& value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::variant::Variant> ArrayEntry::Builder::disownKey() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool ArrayEntry::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool ArrayEntry::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::stream::variant::Variant::Reader ArrayEntry::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::stream::variant::Variant::Builder ArrayEntry::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::stream::variant::Variant::Pipeline ArrayEntry::Pipeline::getValue() { + return ::stream::variant::Variant::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void ArrayEntry::Builder::setValue( ::stream::variant::Variant::Reader value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::stream::variant::Variant::Builder ArrayEntry::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void ArrayEntry::Builder::adoptValue( + ::capnp::Orphan< ::stream::variant::Variant>&& value) { + ::capnp::_::PointerHelpers< ::stream::variant::Variant>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::stream::variant::Variant> ArrayEntry::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::stream::variant::Variant>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline typename Variant::Value::Reader Variant::Reader::getValue() const { + return typename Variant::Value::Reader(_reader); +} +inline typename Variant::Value::Builder Variant::Builder::getValue() { + return typename Variant::Value::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Variant::Value::Pipeline Variant::Pipeline::getValue() { + return typename Variant::Value::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Variant::Value::Builder Variant::Builder::initValue() { + _builder.setDataField< ::uint16_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<16>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Variant::Value::Builder(_builder); +} +inline ::stream::variant::Variant::Value::Which Variant::Value::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::stream::variant::Variant::Value::Which Variant::Value::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Variant::Value::Reader::isNil() const { + return which() == Variant::Value::NIL; +} +inline bool Variant::Value::Builder::isNil() { + return which() == Variant::Value::NIL; +} +inline ::capnp::Void Variant::Value::Reader::getNil() const { + KJ_IREQUIRE((which() == Variant::Value::NIL), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Variant::Value::Builder::getNil() { + KJ_IREQUIRE((which() == Variant::Value::NIL), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Variant::Value::Builder::setNil( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::NIL); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Variant::Value::Reader::isBool() const { + return which() == Variant::Value::BOOL; +} +inline bool Variant::Value::Builder::isBool() { + return which() == Variant::Value::BOOL; +} +inline bool Variant::Value::Reader::getBool() const { + KJ_IREQUIRE((which() == Variant::Value::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS); +} + +inline bool Variant::Value::Builder::getBool() { + KJ_IREQUIRE((which() == Variant::Value::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS); +} +inline void Variant::Value::Builder::setBool(bool value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::BOOL); + _builder.setDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS, value); +} + +inline bool Variant::Value::Reader::isUint64() const { + return which() == Variant::Value::UINT64; +} +inline bool Variant::Value::Builder::isUint64() { + return which() == Variant::Value::UINT64; +} +inline ::uint64_t Variant::Value::Reader::getUint64() const { + KJ_IREQUIRE((which() == Variant::Value::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Variant::Value::Builder::getUint64() { + KJ_IREQUIRE((which() == Variant::Value::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Variant::Value::Builder::setUint64( ::uint64_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::UINT64); + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Variant::Value::Reader::isInt64() const { + return which() == Variant::Value::INT64; +} +inline bool Variant::Value::Builder::isInt64() { + return which() == Variant::Value::INT64; +} +inline ::int64_t Variant::Value::Reader::getInt64() const { + KJ_IREQUIRE((which() == Variant::Value::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Variant::Value::Builder::getInt64() { + KJ_IREQUIRE((which() == Variant::Value::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Variant::Value::Builder::setInt64( ::int64_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::INT64); + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Variant::Value::Reader::isDouble() const { + return which() == Variant::Value::DOUBLE; +} +inline bool Variant::Value::Builder::isDouble() { + return which() == Variant::Value::DOUBLE; +} +inline double Variant::Value::Reader::getDouble() const { + KJ_IREQUIRE((which() == Variant::Value::DOUBLE), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline double Variant::Value::Builder::getDouble() { + KJ_IREQUIRE((which() == Variant::Value::DOUBLE), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Variant::Value::Builder::setDouble(double value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::DOUBLE); + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Variant::Value::Reader::isText() const { + return which() == Variant::Value::TEXT; +} +inline bool Variant::Value::Builder::isText() { + return which() == Variant::Value::TEXT; +} +inline bool Variant::Value::Reader::hasText() const { + if (which() != Variant::Value::TEXT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Variant::Value::Builder::hasText() { + if (which() != Variant::Value::TEXT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Variant::Value::Reader::getText() const { + KJ_IREQUIRE((which() == Variant::Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Variant::Value::Builder::getText() { + KJ_IREQUIRE((which() == Variant::Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Variant::Value::Builder::setText( ::capnp::Text::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Variant::Value::Builder::initText(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::TEXT); + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Variant::Value::Builder::adoptText( + ::capnp::Orphan< ::capnp::Text>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Variant::Value::Builder::disownText() { + KJ_IREQUIRE((which() == Variant::Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Variant::Value::Reader::isList() const { + return which() == Variant::Value::LIST; +} +inline bool Variant::Value::Builder::isList() { + return which() == Variant::Value::LIST; +} +inline bool Variant::Value::Reader::hasList() const { + if (which() != Variant::Value::LIST) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Variant::Value::Builder::hasList() { + if (which() != Variant::Value::LIST) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Reader Variant::Value::Reader::getList() const { + KJ_IREQUIRE((which() == Variant::Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Builder Variant::Value::Builder::getList() { + KJ_IREQUIRE((which() == Variant::Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Variant::Value::Builder::setList( ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::LIST); + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>::Builder Variant::Value::Builder::initList(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::LIST); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Variant::Value::Builder::adoptList( + ::capnp::Orphan< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::LIST); + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>> Variant::Value::Builder::disownList() { + KJ_IREQUIRE((which() == Variant::Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::Variant, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Variant::Value::Reader::isArray() const { + return which() == Variant::Value::ARRAY; +} +inline bool Variant::Value::Builder::isArray() { + return which() == Variant::Value::ARRAY; +} +inline bool Variant::Value::Reader::hasArray() const { + if (which() != Variant::Value::ARRAY) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Variant::Value::Builder::hasArray() { + if (which() != Variant::Value::ARRAY) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Reader Variant::Value::Reader::getArray() const { + KJ_IREQUIRE((which() == Variant::Value::ARRAY), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Builder Variant::Value::Builder::getArray() { + KJ_IREQUIRE((which() == Variant::Value::ARRAY), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Variant::Value::Builder::setArray( ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::ARRAY); + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>::Builder Variant::Value::Builder::initArray(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::ARRAY); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Variant::Value::Builder::adoptArray( + ::capnp::Orphan< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::ARRAY); + ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>> Variant::Value::Builder::disownArray() { + KJ_IREQUIRE((which() == Variant::Value::ARRAY), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::stream::variant::ArrayEntry, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Variant::Value::Reader::isObject() const { + return which() == Variant::Value::OBJECT; +} +inline bool Variant::Value::Builder::isObject() { + return which() == Variant::Value::OBJECT; +} +inline bool Variant::Value::Reader::hasObject() const { + if (which() != Variant::Value::OBJECT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Variant::Value::Builder::hasObject() { + if (which() != Variant::Value::OBJECT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Variant::Value::Reader::getObject() const { + KJ_IREQUIRE((which() == Variant::Value::OBJECT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Variant::Value::Builder::getObject() { + KJ_IREQUIRE((which() == Variant::Value::OBJECT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Variant::Value::Builder::setObject( ::capnp::Text::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::OBJECT); + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Variant::Value::Builder::initObject(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::OBJECT); + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Variant::Value::Builder::adoptObject( + ::capnp::Orphan< ::capnp::Text>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Variant::Value::OBJECT); + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Variant::Value::Builder::disownObject() { + KJ_IREQUIRE((which() == Variant::Value::OBJECT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_compile.sh b/src/plugins/streamers/lstream/db_plugin/capnp_compile.sh new file mode 100755 index 000000000..dee49164b --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_compile.sh @@ -0,0 +1,48 @@ +#!/bin/bash -e + +capnp_version=$(capnp --version) +if [ "$capnp_version" != "Cap'n Proto version 1.0.1" ]; then + echo "ERROR: needs capnp version 1.0.1, got '$capnp_version'" + exit 1 +fi + +src=( + cell.capnp + geometry.capnp + header.capnp + layoutView.capnp + library.capnp + metaData.capnp + metaDataView.capnp + propertySet.capnp + repetition.capnp + variant.capnp +) + +srcdir=$(pwd)/capnp_src + +dest=$(pwd)/capnp +rm -rf $dest +mkdir $dest + +cd $srcdir +for f in ${src[@]}; do + echo "Compiling $f .." + capnp compile -o /usr/bin/capnpc-c++:$dest --src-prefix $dest -I $srcdir $f + mv $dest/$f.c++ $dest/$f.cc +done + +pri=$dest/capnp.pri +echo "" >$pri +echo "HEADERS=\\" >>$pri +for f in ${src[@]}; do + echo " capnp/$f.h \\" >>$pri +done +echo "" >>$pri + +echo "SOURCES=\\" >>$pri +for f in ${src[@]}; do + echo " capnp/$f.cc \\" >>$pri +done +echo "" >>$pri + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/cell.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/cell.capnp new file mode 100644 index 000000000..5e6e8e15e --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/cell.capnp @@ -0,0 +1,29 @@ +@0xbfd8ee64184d5def; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::cell"); + +# The Cell header + +struct Cell +{ + # Enumerates the views the cell provides. These are base-0 indexes + # into the Library::viewSpecsTable::viewSpecs list. The corresponding + # view messages follow this Cell message. + # + # In KLayout, a cell can have the following views: + # "layout": the shapes and instances (LayoutView message) + # "metaData": the cell's meta data (MetaDataView message) + # + # If "layout" is missing, the cell is a "ghost cell" - i.e. one + # which does not have a content yet. Such cells are treated specially, + # e.g. they do not appear as structures in GDS files. + # + # "metaData" is an optional view that holds arbitrary meta data + # (key/value pairs) per cell. + + viewIds @0 :List(UInt16); +} + +# Followed by "viewIds.size" messages with the view data + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/geometry.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/geometry.capnp new file mode 100644 index 000000000..fc2fd3eae --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/geometry.capnp @@ -0,0 +1,189 @@ +@0x814220fba761a890; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::geometry"); + +# Enumerates the possible orthogonal fixpoint transformations +enum FixPointTransformation { + r0 @0; # no rotation + r90 @1; # rotation by 90 degree counterclockwise + r180 @2; # rotation by 180 degree counterclockwise + r270 @3; # rotation by 270 degree counterclockwise + m0 @4; # mirror at x axis ("0 degree axis") + m45 @5; # mirror at positive x/y diagonal ("45 degree axis") + m90 @6; # mirror at y axis ("90 degree axis") + m135 @7; # mirror at negative x/y diagonal ("135 degree axis") +} + +# Implements a Vector +# A vector is a displacement or differences between points. +# In contrast to that, a point is a fixed position in 2d space. +# Coordinates are always expressed as 64 bit coordinates. +struct Vector +{ + dx @0 :Int64; + dy @1 :Int64; +} + +# A point +# A point describes a position. In constrast to the vector, +# the position is not the distance between two points. +# Coordinates are always expressed as 64 bit coordinates. +struct Point +{ + x @0 :Int64; + y @1 :Int64; +} + +# A rectangle +# Rectangles are implemented by a lower-left point and a vector +# connecting the upper-right point with the lower left one. +struct Box +{ + # delta.x or .y is >= 0 for normal boxes + # delta.x < 0 or delta.y indicates an empty box + p1 @0 :Point; + delta @1 :Vector; +} + +# An edge +# An edge is a connection between two points. +# Edges are implemented by on point and a vector connecting a +# second point with the first one. +struct Edge +{ + p1 @0 :Point; + delta @1 :Vector; +} + +# An edge pair +# An edge pair is the combination of two edges. Edge pairs are +# useful objects to describe DRC errors. +struct EdgePair +{ + e1 @0 :Edge; + e2 @1 :Edge; +} + +# A contour +# A contour is a sequence of points. Here, the contour is described +# by a first point and vectors connecting every point to it's +# successor. +struct Contour +{ + # p1 is the first point, deltas are the differences + # to the next point. I.e. + # points = { p1, p1+delta[0], p1+delta[0]+delta[1] ... } + p1 @0 :Point; + deltas @1 :List(Vector); +} + +# A simple polygon +# A simple polygon is made from one contour. The contour forms +# the hull of the polygon. First and last point are implicitly +# connected. +# The contour shall be orientated clockwise and should not +# be self-intersecting. If can be self-touching to make polygons +# with holes. +# The hull must have three points at least. +# No repeated points must be present and degenerated sequences +# such as reflecting edges or collinear edge pairs should be avoided, +# as they are not guaranteed to be preserved. +struct SimplePolygon +{ + hull @0 :Contour; +} + +# A polygon with holes +# Like the simple polygon, but adds holes to the polygon. +# The holes are described by contours as well as the hull. +# Hole contours must not be overlapping and shall be +# oriented counterclockwise. +# The same restrictions apply for the holes as for the hull +# contour. +struct Polygon +{ + hull @0 :Contour; + holes @1 :List(Contour); +} + +# A path +# A path is a list of points in form of a contour which +# are connected by a wide line. The width of the line +# is specified as the half-width to enforce on-gridness +# of the boundary of the path. The point sequence is +# called the path's "spine". +# The line ends can be configured to be flat, square, +# circular or round. +# The spine needs to have at least one point. +# Paths with single points are allowed. With square +# ends, this represents a square, with round ends this +# represents a circle. +struct Path +{ + # The spine + spine @0 :Contour; + + # The path's half width + halfWidth @1 :UInt64; + + # Extension at the start and end - + # only valid with extensionType "variable": + beginExtension @2 :Int64; + endExtension @3 :Int64; + + # The type of extension + extensionType @4 :ExtensionType; + + enum ExtensionType + { + flush @0; # flat + square @1; # square + round @2; # circular + variable @3; # variable (given by "beginExtension" and "endExtension") + } +} + +# A text +# "texts" are not called "Text" as not to collide with Cap'n'Proto's +# built-in "Text" type. +# A text is a label at a specific position. +struct Label +{ + # The position of the label + position @0 :Point; + + # The orientation of the label + orientation @1 :FixPointTransformation; + + # base-0 index in the Header::TextStringsTable list + stringId @2 :UInt64; + + # Alignment + horizontalAlign @3 :HAlignment; + verticalAlign @4 :VAlignment; + + # The offset by which the text is displayed relative to the + # position (this feature is ignored as of now) + displayOffset @5 :Vector; + + # Text height in DBU + size @6 :UInt64; + + # Horizontal alignment flags + enum HAlignment + { + left @0; + center @1; + right @2; + } + + # Vertical alignment flags + enum VAlignment + { + bottom @0; + center @1; + top @2; + } +} + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/header.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/header.capnp new file mode 100644 index 000000000..6ed84c665 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/header.capnp @@ -0,0 +1,40 @@ + +@0xc5f5e75ece54ff24; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::header"); + +using MetaData = import "metaData.capnp".MetaData; + +# A library dictionary entry +# These entries are used later to form the library list +struct LibrarySpec +{ + # The name of the library + name @0 :Text; + + # The type of library: + # The type carries information about the usage of the library. + # Types are: + # "layout": traverses "layout" views + # "schematic": traverses "schematic" views through "symbol" + # more t.b.d + type @1 :Text; +} + +# The global header +struct Header +{ + # File-global meta data + metaData @0 :MetaData; + + # The name of the tool that generated this file + generator @1 :Text; + + # The technology this stream is intended for + # This is an arbitrary string as of now. + technology @2 :Text; + + # The list of libraries contained in this stream + libraries @3 :List(LibrarySpec); +} \ No newline at end of file diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/layoutView.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/layoutView.capnp new file mode 100644 index 000000000..738c2d766 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/layoutView.capnp @@ -0,0 +1,139 @@ +@0x973a841036ae34e0; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::layoutView"); + +using Box = import "geometry.capnp".Box; +using Polygon = import "geometry.capnp".Polygon; +using SimplePolygon = import "geometry.capnp".SimplePolygon; +using Edge = import "geometry.capnp".Edge; +using EdgePair = import "geometry.capnp".EdgePair; +using Path = import "geometry.capnp".Path; +using Point = import "geometry.capnp".Point; +using Vector = import "geometry.capnp".Vector; +using Label = import "geometry.capnp".Label; +using FixPointTransformation = import "geometry.capnp".FixPointTransformation; +using Repetition = import "repetition.capnp".Repetition; + +struct SingleObject(Object) +{ + basic @0 :Object; +} + +struct ObjectArray(Object) +{ + basic @0 :Object; + + # "repetitionId" is 0 for single instance, otherwise it's a base-1 index in the + # "Layer::repetitions" list + repetitionId @1 :UInt64; +} + +struct ObjectWithProperties(Object) +{ + basic @0 :Object; + + # "propertySetId" is 0 for "no properties", otherwise it's a base-1 index in the + # "Header::propertiesTable::propertySets" list. + propertySetId @1 :UInt64; +} + +struct ObjectContainerForType(Object) +{ + basic @0 :List(SingleObject(Object)); # NOTE: can't be "List(Object)" simply + withProperties @1 :List(ObjectWithProperties(Object)); + arrays @2 :List(ObjectArray(Object)); + arraysWithProperties @3 :List(ObjectWithProperties(ObjectArray(Object))); +} + +# A layer +# A layer is a collection of objects - with repetitions and/or properties. +# "objects" can be geometrical objects such as boxes and others. +struct Layer +{ + # The layer index - this is a base-0 index into Library::layerTable::layerEntries + layerId @0 :UInt64; + + # The repetitions + # The "repetitionId" specified above is a base-1 index in that this. + repetitions @1 :List(Repetition); + + # Containers for the different objects the layer can be composed of. + # Every container can hold objects with properties and/or repetitions. + boxes @2 :ObjectContainerForType(Box); + polygons @3 :ObjectContainerForType(Polygon); + simplePolygons @4 :ObjectContainerForType(SimplePolygon); + paths @5 :ObjectContainerForType(Path); + labels @6 :ObjectContainerForType(Label); + edges @7 :ObjectContainerForType(Edge); + edgePairs @8 :ObjectContainerForType(EdgePair); + points @9 :ObjectContainerForType(Point); +} + +# Specifies a transformation for a cell +# Transformations can be "simple": such transformations +# do not allow arbitrary angle rotations or scaling. +# "complex" transformations on the other hand, support +# arbitrary angle rotations and scaling but come with +# potential issues with off-grid vertexes rendered +# by their resulting geometries. +# +# The order of the transformations in the simple cases is: +# 1. Apply simple.orientation +# 2. Apply displacement (shift) +# +# In the complex case the order is: +# 1. Multiplication by the "scale" factor +# 2. Mirror at x axis if "mirror" is true +# 3. Rotate by "angle" degrees counter-clockwise +# 4. Apply displacement (shift) + +struct CellTransformation +{ + displacement @0 :Vector; + + transformation :union { + simple :group { + orientation @1 : FixPointTransformation; + } + complex :group { + angle @2 :Float64; # rotation angle in degree + mirror @3 :Bool; # at x axis before rotation + scale @4 :Float64; # before rotation, mirror and displacement + } + } +} + +# A cell placement +struct CellInstance +{ + # This is a base-0 index into Library::cellSpecsTable::cellSpecs + cellId @0 :UInt64; + + # The transformation describes how the cell is placed + transformation @1 :CellTransformation; +} + +# The LayoutView class: +# This message represents the entire layout view of a cell +struct LayoutView +{ + # The cell bounding box + # This bounding box includes all geometries, including child cells + # but maybe larger than the actual size due to shapes not written + # to the stream. + boundingBox @0 :Box; + + # The layers present in the layout view + layers @1 :List(Layer); + + # The repetitions used for the cell instances + instanceRepetitions @2 :List(Repetition); + + # The cell instance container: lists cell instances with properties + # and/or repetitions. + # Regular array repetitions play a special role as they are preserved + # in edit mode. + instances @3 :ObjectContainerForType(CellInstance); +} + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/library.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/library.capnp new file mode 100644 index 000000000..e842dbf88 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/library.capnp @@ -0,0 +1,265 @@ +@0x86931e1824fec888; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::library"); + +using MetaData = import "metaData.capnp".MetaData; +using PropertySet = import "propertySet.capnp".PropertySet; +using PropertyName = import "propertySet.capnp".PropertyName; +using NamedValue = import "propertySet.capnp".NamedValue; +using Box = import "geometry.capnp".Box; + +using Variant = import "variant.capnp".Variant; + +# A table listing the names of the properties used in this library +struct PropertyNamesTable +{ + # Namespaces are intended to separate property names which are otherwise + # identical. Different applications or system can define their own namespace + # which acts as a prefix to the property names. + # The "namespaceId" used in PropertyName is a base-1 index in this table + namespaces @0 :List(Text); + + # Names with namespace Ids: + # The "nameId" used in PropertySet is a base-0 index in this table + names @1 :List(PropertyName); +} + +# A table of all property/name combinations used in this library: +# Shapes or other objects specifying properties do not carry a dictionary, +# but just state the "Id" of the property set, which is a pointer into +# this table. This serves the compactness goal of the format as properties +# are often repeated. +struct PropertiesTable +{ + # NOTE: the propertyId used in many places is 0 for "no property" + # otherwise "propertyId" is the base-1 index of the property set in this list + propertySets @0 :List(PropertySet); +} + +# A table of all text (label) strings used: +# A label object does not directly specify the text, but stores a +# base-0 index into this table. This also serves the compactness goal. +struct TextStringsTable +{ + textStrings @0 :List(Text); +} + +# A reference to a library: +# This is merely a pointer to an external entity. It is up to the +# application to resolve this reference. +struct LibraryRef +{ + libraryName @0 :Text; +} + +# A list of all library references +struct LibraryRefs +{ + refs @0 :List(LibraryRef); +} + +# A structure describing the parameters of a cell +# Cell parameters are name/value pairs. It is up to the application +# to provide a cell implementation and identify the parameters to use. +struct CellParameters +{ + values @0 :List(NamedValue); +} + +# A cell header: +# This structure describes a cell inside a library. A cell is primarily +# given by a name which must be unique inside the library. A cell can refer +# to a separate library and/or a parameterized cell. +# an any case, the cell's actual content is copied into the stream, so a +# consumer of a stream can obtain the actual geometry of a cell, instead +# of having to find the provider to build it. +struct CellSpec +{ + # The name of the cell in the current stream. This needs to be a unique name. + # This attribute is mandatory. If the cell refers to a library cell, the cell + # name inside the library can be different from the cell name. + name @0 :Text; + + # Specifies, whether the cell refers to a library. + # "libraryNameId" is 0 for a local cell (no library reference), otherwise it's a base-1 + # index into "Header::libraryRefs". + libraryRefId @1 :UInt64; + + # The name of the cell inside the library, if one is specified + libraryCellName @2 :Text; + + # The cell parameters, if the cell is a parameterized cell. + parameters @3 :CellParameters; + + # "propertySetId" is 0 for "no properties", otherwise it's a base-1 index in the + # "Header::propertiesTable::propertySets" list. + propertySetId @4 :UInt64; +} + +# A table of all cells +struct CellSpecsTable +{ + cellSpecs @0 :List(CellSpec); +} + +# A node in the hierarchy tree: +# The hierarchy tree lists all cells with their children. +struct CellHierarchyTreeNode +{ + # The cellId is a base-0 index in CellSpecsTable::cellSpecs + cellId @0 :UInt64; + + # Same for the child cell Ids + childCellIds @1 :List(UInt64); +} + +# The full hierarchy tree +struct CellHierarchyTree +{ + # The number of top cells (cells without a parent) + # As the "nodes" list is sorted top-down, the first + # "numberOfTopCells" cells are actually top cells. + numberOfTopCells @0 :UInt64; + + # top-down sorted cells + nodes @1 :List(CellHierarchyTreeNode); +} + +# A layer specification: +# A layer can be specified by a several layer numbers +# and/or a name. If no numbers are given, the name will +# identify the layer. Otherwise the numbers will identify +# the layer. +# Layers can be unnamed and unnumbered and layer specifications +# do not need to be unique. +# The purpose is a hint and additionally identifies the +# purpose of the shapes on the layer. +struct LayerEntry +{ + # layerNumbers = [] for no layer/datatype, + # [layer] for single layer/no datatype + # [layer, datatype] for GDS2 layer/datatype + layerNumbers @0 :List(UInt64); + name @1 :Text; + purpose @2 :Purpose; + + enum Purpose { + drawing @0; # default + fill @1; + slot @2; + pin @3; + boundary @4; + text @5; + comment @6; + blockage @7; + wire @8; + errors @9; + handles @10; + symbol @11; + } +} + +# All layer entries +struct LayerTable +{ + # The layerId used inside the LayoutView struct is a + # base-0 index into this table. + layerEntries @0 :List(LayerEntry); +} + +# A specification for a view +struct ViewSpec +{ + # The view name: the view name carries information about + # the usage - e.g. "layout", "metaData", "abstractLayout", "schematic", "symbol" ... + name @0 :Text; + + # The class representing the view + # For layout views, this is "LayoutView". + class @1 :Text; + + # The resolution: this is the number of database + # units per micrometer. This specification is favored + # over database unit in micrometers as this is usually + # an integer number. + # As of now, only layout views need this resolution value as they represent + # geometries in integer multiples of the resolution. + # If not used, this value should be zero. + resolution @2 :Float64; + + # The layer table: + # All layers used in this stream are listed here. + # Layers can be present without being used (in a sense of having shapes in them). + # On the contrary, layers must be listed here, before they can be used for shapes. + layerTable @3 :LayerTable; + + # View properties: + # "propertySetId" is 0 for "no properties", otherwise it's a base-1 index in the + # "Header::propertiesTable::propertySets" list. + # For layout views, this corresponds to OASIS file properties for example. + propertySetId @4 :UInt64; + + # Meta data attached to the view type + metaData @5 :MetaData; +} + +# A table of all views +struct ViewSpecsTable +{ + # The "viewIds" used in the "Cell" structure is a base-0 index into this + # list. + viewSpecs @0 :List(ViewSpec); +} + +# The header for a library +struct Library +{ + # Meta data: + # Meta data is a generic container for arbitrary data attached to the stream. + # In contrast to properties, meta data is available on cell and library level + # only and is intended for application specific data. + metaData @0 :MetaData; + + # Library names: + # The "libraryNameId" used in this scheme refers to this table + # as a base-1 index into it. A "libraryNameId" of 0 means "no library referenced". + libraryRefs @1 :LibraryRefs; + + # Property names: + # The "nameId" used in a number of places in the scheme refers + # to this table as a base-0 index into it. + propertyNamesTable @2 :PropertyNamesTable; + + # Properties tables: + # The "propertySetId" used in many places in this schema refers to + # this table as a base-1 index into it. A property set Id of 0 + # indicates "no properties". + propertiesTable @3 :PropertiesTable; + + # Text strings: + # This text string repository is mainly used by layout views for + # compact representation of text strings. + textStringsTable @4 :TextStringsTable; + + # View specs table: + # Defines the views with some additional attributes. Not all views + # listed here need to be used by the cells. Every cell selects + # views from this list. However, a cell cannot select a view that is + # not in this list. + viewSpecsTable @5 :ViewSpecsTable; + + # The cell specifications: + # The cell specifications describe the cell's origin and + # attributes of the cell. + cellSpecsTable @6 :CellSpecsTable; + + # The cell hierarchy tree: + # This tree is mandatory for pure layout streams. It provides + # quick access to the structure, so stream processing can be planned + # in some cases by just reading the header. + cellHierarchyTree @7 :CellHierarchyTree; +} + +# Followed by many "Cell" messages + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/metaData.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/metaData.capnp new file mode 100644 index 000000000..8c1ffcf5d --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/metaData.capnp @@ -0,0 +1,30 @@ +@0x91d51203f4528da2; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::metaData"); + +using Variant = import "variant.capnp".Variant; + +# An entry for meta data +struct MetaDataEntry +{ + # The key + name @0 :Text; + + # Some optional description text + description @1 :Text; + + # The value + value @2 :Variant; +} + +# The MetaData View class: +# This message represents the meta data view of cell. +# Meta data is a generic concept - basically a list of +# key/value pairs for custom payload, with not specific +# implied interpretation by the application. +struct MetaData +{ + entries @0 :List(MetaDataEntry); +} + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/metaDataView.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/metaDataView.capnp new file mode 100644 index 000000000..d35f36f96 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/metaDataView.capnp @@ -0,0 +1,14 @@ +@0xf401d688f5f6eb25; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::metaDataView"); + +using MetaData = import "metaData.capnp".MetaData; + +# A meta data view for a cell: +# A cell can add arbirary key/value information through this view. +struct MetaDataView +{ + data @0 :MetaData; +} + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/propertySet.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/propertySet.capnp new file mode 100644 index 000000000..dbde0cd68 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/propertySet.capnp @@ -0,0 +1,39 @@ +@0xa344c0f52014bff4; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::propertySet"); + +using Variant = import "variant.capnp".Variant; + +# The name of a shape or instance property +struct PropertyName +{ + # A "namespaceID" of 0 means "no namespace". Otherwise it's a base-1 index in the + # property namespace table in "header::propertyNamesTable::namespaces". + # The namespace is intended as a kind of prefix, uniquely identifying the name + # of the property, so that different owners can use the same name as long as the + # own the namespace. + namespaceId @0 :UInt64; + + # The "name": + # The property name does not need to be a string, but can be any type, + # specifically integer values. This way, properties can map GDS user properties. + name @1 :Variant; +} + +# A pair of name and value +struct NamedValue +{ + # The namdId is a base-0 index into Library::propertyNamesTable + nameId @0 :UInt64; + + # The value associated with the name + value @1 :Variant; +} + +# A set of name/value pairs forming the set of properties for a shape or instance +struct PropertySet +{ + properties @0 :List(NamedValue); +} + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/repetition.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/repetition.capnp new file mode 100644 index 000000000..4268aa79f --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/repetition.capnp @@ -0,0 +1,57 @@ +@0x9c4548253282e237; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::repetition"); + +using Vector = import "geometry.capnp".Vector; + +# A regular array with x and y spacing +# The displacements of an object are: +# disp = (ix*dx, iy*dy) +# where ix=0..nx-1 and iy=0..ny-1 +struct RegularOrthoRepetition +{ + dx @0 :Int64; + dy @1 :Int64; + nx @2 :UInt64; + ny @3 :UInt64; +} + +# A regular array with free step vectors which do not need to be orthogonal +# The displacements of an object are: +# disp = ia*a+ib*b +# where ia=0..na-1 and ib=0..nb-1 +struct RegularRepetition +{ + a @0 :Vector; + b @1 :Vector; + na @2 :UInt64; + nb @3 :UInt64; +} + +# A free repetition given by a set of displacements +struct EnumeratedRepetition +{ + # The number of instances represented by this repetition type is one + # more than the length of the list. The first entry is implicitly + # assumed to be (0,0) and is dropped. + # The list is given in incremental offsets. + # So the offsets are: + # offsets = { (0,0), delta[0], delta[0]+delta[1] ... } + deltas @0 :List(Vector); +} + +# A generic repetition object +# This union describes a set of object "placements". +# Placements are basically shifts of some original +# object by a given vector. +struct Repetition +{ + types :union { + single @0 :Vector; + regular @1 :RegularRepetition; + regularOrtho @2 :RegularOrthoRepetition; + enumerated @3 :EnumeratedRepetition; + } +} + diff --git a/src/plugins/streamers/lstream/db_plugin/capnp_src/variant.capnp b/src/plugins/streamers/lstream/db_plugin/capnp_src/variant.capnp new file mode 100644 index 000000000..8ef49ac9b --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/capnp_src/variant.capnp @@ -0,0 +1,27 @@ +@0x92e3d852e5f6a442; + +using Cxx = import "/capnp/c++.capnp"; +$Cxx.namespace("stream::variant"); + +# A helper struct to build a dictionary of key/value pairs +struct ArrayEntry +{ + key @0 :Variant; + value @1 :Variant; +} + +# A generic type representing a number of C++ types +struct Variant { + value :union { + nil @0 :Void; + bool @1 :Bool; + uint64 @2 :UInt64; + int64 @3 :Int64; + double @4 :Float64; + text @5 :Text; + list @6 :List(Variant); + array @7 :List(ArrayEntry); + object @8 :Text; + } +} + diff --git a/src/plugins/streamers/lstream/db_plugin/db_plugin.pro b/src/plugins/streamers/lstream/db_plugin/db_plugin.pro new file mode 100644 index 000000000..796f2494b --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/db_plugin.pro @@ -0,0 +1,28 @@ + +TARGET = lstream +DESTDIR = $$OUT_PWD/../../../../db_plugins + +include($$PWD/../../../db_plugin.pri) +include($$PWD/../lstream.pri) +include($$PWD/capnp/capnp.pri) + +INCLUDEPATH += capnp $$VERSION_INC +LIBS += -L$$DESTDIR/.. -lxcapnp -lxkj + +HEADERS += \ + lstrCompressed.h \ + lstrCompressor.h \ + lstrFormat.h \ + lstrPlugin.h \ + lstrReader.h \ + lstrWriter.h \ + +SOURCES += \ + gsiDeclLStream.cc \ + lstrCompressed.cc \ + lstrCompressor.cc \ + lstrFormat.cc \ + lstrPlugin.cc \ + lstrReader.cc \ + lstrWriter.cc \ + diff --git a/src/plugins/streamers/lstream/db_plugin/fetch.sh b/src/plugins/streamers/lstream/db_plugin/fetch.sh new file mode 100755 index 000000000..c0cc35f00 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/fetch.sh @@ -0,0 +1,19 @@ +#!/bin/bash -e + +rm -rf capnp_src +mkdir capnp_src +rm -f *.cc *.h + +tmp=.tmp +rm -rf $tmp +mkdir $tmp +cd $tmp + +git clone ssh://git@codeberg.org/klayoutmatthias/lstream.git . + +cp capnp/*.capnp ../capnp_src +cp db_plugin/*{cc,h} .. +cd .. + +./capnp_compile.sh + diff --git a/src/plugins/streamers/lstream/db_plugin/gsiDeclLStream.cc b/src/plugins/streamers/lstream/db_plugin/gsiDeclLStream.cc new file mode 100644 index 000000000..30a3746e1 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/gsiDeclLStream.cc @@ -0,0 +1,126 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrFormat.h" +#include "dbLoadLayoutOptions.h" +#include "dbSaveLayoutOptions.h" +#include "gsiDecl.h" + +namespace lstr +{ + +// --------------------------------------------------------------- +// gsi Implementation of specific methods of LoadLayoutOptions + +static void set_lstream_bbox_meta_info_key (db::LoadLayoutOptions *options, const std::string &key) +{ + options->get_options ().bbox_meta_info_key = key; +} + +static const std::string &get_lstream_bbox_meta_info_key (const db::LoadLayoutOptions *options) +{ + return options->get_options ().bbox_meta_info_key; +} + +// extend lay::LoadLayoutOptions with the OASIS options +static +gsi::ClassExt lstream_reader_options ( + gsi::method_ext ("lstream_bbox_meta_info_key=", &set_lstream_bbox_meta_info_key, gsi::arg ("key"), + "@brief If not an empty string, this attribute specifies the key under which the cell bounding box information is stored" + ) + + gsi::method_ext ("lstream_bbox_meta_info_key", &get_lstream_bbox_meta_info_key, + "@brief If not an empty string, this attribute specifies the key under which the cell bounding box information is stored" + ), + "" +); + +// --------------------------------------------------------------- +// gsi Implementation of specific methods + +static void set_lstream_compression (db::SaveLayoutOptions *options, int comp) +{ + options->get_options ().compression_level = comp; +} + +static int get_lstream_compression (const db::SaveLayoutOptions *options) +{ + return options->get_options ().compression_level; +} + +static void set_lstream_recompress (db::SaveLayoutOptions *options, bool f) +{ + options->get_options ().recompress = f; +} + +static bool get_lstream_recompress (const db::SaveLayoutOptions *options) +{ + return options->get_options ().recompress; +} + +static void set_lstream_permissive (db::SaveLayoutOptions *options, bool f) +{ + options->get_options ().permissive = f; +} + +static bool get_lstream_permissive (const db::SaveLayoutOptions *options) +{ + return options->get_options ().permissive; +} + +// extend lay::SaveLayoutOptions with the OASIS options +static +gsi::ClassExt lstream_writer_options ( + gsi::method_ext ("lstream_recompress=", &set_lstream_recompress, gsi::arg ("flag"), + "@brief Sets LStream recompression mode\n" + "If this flag is true, shape arrays already existing will be resolved and compression is applied " + "to the individual shapes again. If this flag is false (the default), shape arrays already existing " + "will be written as such.\n" + ) + + gsi::method_ext ("lstream_recompress?", &get_lstream_recompress, + "@brief Gets the LStream recompression mode\n" + "See \\oasis_recompress= method for a description of this predicate." + ) + + gsi::method_ext ("lstream_permissive=", &set_lstream_permissive, gsi::arg ("flag"), + "@brief Sets LStream permissive mode\n" + "If this flag is true, certain shapes which cannot be written to LStream are reported as warnings, " + "not as errors. For example, paths with odd width (are rounded).\n" + ) + + gsi::method_ext ("lstream_permissive?", &get_lstream_permissive, + "@brief Gets the LStream permissive mode\n" + "See \\oasis_permissive= method for a description of this predicate." + ) + + gsi::method_ext ("lstream_compression_level=", &set_lstream_compression, gsi::arg ("level"), + "@brief Set the LStream compression level\n" + "The LStream compression level is an integer number between 0 and 10. 0 basically is no compression, " + "1 produces shape arrays in a simple fashion. 2 and higher compression levels will use a more elaborate " + "algorithm to find shape arrays which uses 2nd and further neighbor distances. The higher the level, the " + "higher the memory requirements and run times.\n" + ) + + gsi::method_ext ("lstream_compression_level", &get_lstream_compression, + "@brief Get the LStream compression level\n" + "See \\oasis_compression_level= method for a description of the LStream compression level." + ), + "" +); + +} + diff --git a/src/plugins/streamers/lstream/db_plugin/lstrCompressed.cc b/src/plugins/streamers/lstream/db_plugin/lstrCompressed.cc new file mode 100644 index 000000000..09cb75aba --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrCompressed.cc @@ -0,0 +1,531 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrCompressed.h" + +#include "dbPluginCommon.h" +#include "dbShapes.h" +#include "dbHash.h" + +namespace lstr +{ + +Compressed::Compressed () + : m_next_id (0) +{ + // .. nothing yet .. +} + +uint64_t +Compressed::make_rep_id (const RegularArray &array, const std::vector &irregular) +{ + if (! array.is_null ()) { + + auto ia = m_array_to_rep_id.find (array); + if (ia != m_array_to_rep_id.end ()) { + return ia->second; + } else { + ++m_next_id; + m_array_to_rep_id.insert (std::make_pair (array, m_next_id)); + return m_next_id; + } + + } else if (! irregular.empty ()) { + + auto ii = m_irregular_to_rep_id.find (irregular); + if (ii != m_irregular_to_rep_id.end ()) { + return ii->second; + } else { + ++m_next_id; + m_irregular_to_rep_id.insert (std::make_pair (irregular, m_next_id)); + return m_next_id; + } + + } else { + + return 0; + + } +} + +template +void +Compressed::write_shape (const db::Shape &shape, const db::Vector &disp, RegularArray ®ular, std::vector &irregular_array) +{ + Obj sh; + shape.instantiate (sh); + if (! object_is_empty (sh)) { + sh.move (disp); + if (shape.prop_id () != 0) { + write (db::object_with_properties (sh, shape.prop_id ()), regular, irregular_array); + } else { + write (sh, regular, irregular_array); + } + } +} + +void +Compressed::compress_shapes (const db::Shapes &shapes, unsigned int level, bool recompress) +{ + RegularArray no_array; + std::vector no_irregular_array; + + Compressor path_compressor (level); + Compressor simple_polygon_compressor (level); + Compressor polygon_compressor (level); + Compressor edge_compressor (level); + Compressor edge_pair_compressor (level); + Compressor box_compressor (level); + Compressor text_compressor (level); + Compressor point_compressor (level); + + Compressor path_with_properties_compressor (level); + Compressor simple_polygon_with_properties_compressor (level); + Compressor polygon_with_properties_compressor (level); + Compressor edge_with_properties_compressor (level); + Compressor edge_pair_with_properties_compressor (level); + Compressor box_with_properties_compressor (level); + Compressor text_with_properties_compressor (level); + Compressor point_with_properties_compressor (level); + + for (db::ShapeIterator shape = shapes.begin (db::ShapeIterator::All); ! shape.at_end (); ) { + + if (level <= 0 || (! recompress && shape.in_array ())) { + + RegularArray array; + std::vector irregular_array; + + bool transfer_array = (shape.in_array () && level > 0); + db::Vector disp; + if (transfer_array) { + disp = create_repetition (shape.array (), array, irregular_array); + } + + if (shape->is_simple_polygon ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_polygon ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_path ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_text ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_edge ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_edge_pair ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_box ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_point ()) { + write_shape (*shape, disp, array, irregular_array); + } else if (shape->is_user_object ()) { + // ignore + } else { + tl_assert (false); // unknown shape type + } + + if (transfer_array) { + shape.finish_array (); + } + + } else { + + switch (shape->type ()) { + case db::Shape::Polygon: + + if (shape->has_prop_id ()) { + auto polygon = *shape->basic_ptr (db::PolygonWithProperties::tag ()); + polygon_with_properties_compressor.add (polygon); + } else { + auto polygon = *shape->basic_ptr (db::Polygon::tag ()); + polygon_compressor.add (polygon); + } + + break; + + case db::Shape::PolygonRef: + + if (shape->has_prop_id ()) { + auto polygon_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::PolygonWithProperties polygon (polygon_ref.obj (), polygon_ref.properties_id ()); + polygon_with_properties_compressor.add (polygon, polygon_ref.trans ().disp ()); + } else { + auto polygon_ref = *shape->basic_ptr (db::PolygonRef::tag ()); + polygon_compressor.add (polygon_ref.obj (), polygon_ref.trans ().disp ()); + } + + break; + + case db::Shape::PolygonPtrArrayMember: + + if (shape->has_prop_id ()) { + auto polygon_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::PolygonWithProperties polygon (polygon_ref.object ().obj (), polygon_ref.properties_id ()); + polygon_with_properties_compressor.add (polygon, shape->array_trans ().disp ()); + } else { + auto polygon_ref = *shape->basic_ptr (db::Shape::polygon_ptr_array_type::tag ()); + polygon_compressor.add (polygon_ref.object ().obj (), shape->array_trans ().disp ()); + } + + break; + + case db::Shape::SimplePolygon: + + if (shape->has_prop_id ()) { + auto simple_polygon = *shape->basic_ptr (db::SimplePolygonWithProperties::tag ()); + simple_polygon_with_properties_compressor.add (simple_polygon); + } else { + auto simple_polygon = *shape->basic_ptr (db::SimplePolygon::tag ()); + simple_polygon_compressor.add (simple_polygon); + } + + break; + + case db::Shape::SimplePolygonRef: + + if (shape->has_prop_id ()) { + auto polygon_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::SimplePolygonWithProperties polygon (polygon_ref.obj (), polygon_ref.properties_id ()); + simple_polygon_with_properties_compressor.add (polygon, polygon_ref.trans ().disp ()); + } else { + auto polygon_ref = *shape->basic_ptr (db::SimplePolygonRef::tag ()); + simple_polygon_compressor.add (polygon_ref.obj (), polygon_ref.trans ().disp ()); + } + + break; + + case db::Shape::SimplePolygonPtrArrayMember: + + if (shape->has_prop_id ()) { + auto simple_polygon_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::SimplePolygonWithProperties simple_polygon (simple_polygon_ref.object ().obj (), simple_polygon_ref.properties_id ()); + simple_polygon_with_properties_compressor.add (simple_polygon, shape->array_trans ().disp ()); + } else { + auto simple_polygon_ref = *shape->basic_ptr (db::Shape::simple_polygon_ptr_array_type::tag ()); + simple_polygon_compressor.add (simple_polygon_ref.object ().obj (), shape->array_trans ().disp ()); + } + + break; + + case db::Shape::Edge: + + if (shape->has_prop_id ()) { + auto edge = *shape->basic_ptr (db::EdgeWithProperties::tag ()); + edge_with_properties_compressor.add (edge); + } else { + auto edge = *shape->basic_ptr (db::Edge::tag ()); + edge_compressor.add (edge); + } + + break; + + case db::Shape::EdgePair: + + if (shape->has_prop_id ()) { + auto edge_pair = *shape->basic_ptr (db::EdgePairWithProperties::tag ()); + edge_pair_with_properties_compressor.add (edge_pair); + } else { + auto edge_pair = *shape->basic_ptr (db::EdgePair::tag ()); + edge_pair_compressor.add (edge_pair); + } + + break; + + case db::Shape::Path: + + if (shape->has_prop_id ()) { + auto path = *shape->basic_ptr (db::PathWithProperties::tag ()); + path_with_properties_compressor.add (path); + } else { + auto path = *shape->basic_ptr (db::Path::tag ()); + path_compressor.add (path); + } + + break; + + case db::Shape::PathRef: + + if (shape->has_prop_id ()) { + auto path_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::PathWithProperties path (path_ref.obj (), path_ref.properties_id ()); + path_with_properties_compressor.add (path, path_ref.trans ().disp ()); + } else { + const db::PathRef &path_ref = *shape->basic_ptr (db::PathRef::tag ()); + path_compressor.add (path_ref.obj (), path_ref.trans ().disp ()); + } + + break; + + case db::Shape::PathPtrArrayMember: + + if (shape->has_prop_id ()) { + auto path_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::PathWithProperties path (path_ref.object ().obj (), path_ref.properties_id ()); + path_with_properties_compressor.add (path, shape->array_trans ().disp ()); + } else { + const db::Shape::path_ptr_array_type &path_ref = *shape->basic_ptr (db::Shape::path_ptr_array_type::tag ()); + path_compressor.add (path_ref.object ().obj (), shape->array_trans ().disp ()); + } + + break; + + case db::Shape::Box: + + if (shape->has_prop_id ()) { + auto box = *shape->basic_ptr (db::BoxWithProperties::tag ()); + box_with_properties_compressor.add (box); + } else { + auto box = *shape->basic_ptr (db::Box::tag ()); + box_compressor.add (box); + } + + break; + + case db::Shape::Point: + + if (shape->has_prop_id ()) { + auto point = *shape->basic_ptr (db::PointWithProperties::tag ()); + point_with_properties_compressor.add (point); + } else { + auto point = *shape->basic_ptr (db::Point::tag ()); + point_compressor.add (point); + } + + break; + + case db::Shape::BoxArray: + case db::Shape::BoxArrayMember: + case db::Shape::ShortBox: + case db::Shape::ShortBoxArrayMember: + + if (shape->has_prop_id ()) { + db::BoxWithProperties box; + shape->instantiate (box); + box.properties_id (shape->prop_id ()); + box_with_properties_compressor.add (box); + } else { + db::Box box; + shape->instantiate (box); + box_compressor.add (box); + } + + break; + + case db::Shape::Text: + + if (shape->has_prop_id ()) { + auto text = *shape->basic_ptr (db::TextWithProperties::tag ()); + text_with_properties_compressor.add (text); + } else { + auto text = *shape->basic_ptr (db::Text::tag ()); + text_compressor.add (text); + } + + break; + + case db::Shape::TextRef: + + if (shape->has_prop_id ()) { + auto text_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::TextWithProperties text (text_ref.obj (), text_ref.properties_id ()); + text_with_properties_compressor.add (text, text_ref.trans ().disp ()); + } else { + auto text_ref = *shape->basic_ptr (db::TextRef::tag ()); + text_compressor.add (text_ref.obj (), text_ref.trans ().disp ()); + } + + break; + + case db::Shape::TextPtrArrayMember: + + if (shape->has_prop_id ()) { + auto text_ref = *shape->basic_ptr (db::object_with_properties::tag ()); + db::TextWithProperties text (text_ref.object ().obj (), text_ref.properties_id ()); + text_with_properties_compressor.add (text, shape->array_trans ().disp ()); + } else { + auto text_ref = *shape->basic_ptr (db::Shape::text_ptr_array_type::tag ()); + text_compressor.add (text_ref.object ().obj (), shape->array_trans ().disp ()); + } + + break; + + case db::Shape::UserObject: + // ignore. + break; + + default: + tl_assert (false); + } + + ++shape; + + } + + } + + path_compressor.flush (this); + simple_polygon_compressor.flush (this); + polygon_compressor.flush (this); + edge_compressor.flush (this); + edge_pair_compressor.flush (this); + box_compressor.flush (this); + point_compressor.flush (this); + text_compressor.flush (this); + + path_with_properties_compressor.flush (this); + simple_polygon_with_properties_compressor.flush (this); + polygon_with_properties_compressor.flush (this); + edge_with_properties_compressor.flush (this); + edge_pair_with_properties_compressor.flush (this); + box_with_properties_compressor.flush (this); + point_with_properties_compressor.flush (this); + text_with_properties_compressor.flush (this); +} + +template +static db::Vector +create_repetition_from_array (const Array *array, RegularArray ®ular, std::vector &irregular_array) +{ + db::Vector a, b; + unsigned long na = 0, nb = 0; + + if (array->is_iterated_array (&irregular_array)) { + + // Take out the first displacement and move that to the shape and sort the displacements. + // This way, sequences get normalized and there is a better chance of getting identical + // repetition vectors. + tl_assert (! irregular_array.empty ()); + db::Vector po = irregular_array.front (); + std::vector::iterator pw = irregular_array.begin(); + for (std::vector::iterator p = pw + 1; p != irregular_array.end (); ++p) { + *pw++ = *p - po; + } + irregular_array.erase (pw, irregular_array.end ()); + std::sort (irregular_array.begin (), irregular_array.end (), vector_cmp_x ()); + + return po; + + } else if (array->is_regular_array (a, b, na, nb)) { + + regular = RegularArray (a, b, size_t (na), size_t (nb)); + return db::Vector (); + + } else { + tl_assert (false); + } +} + +db::Vector +Compressed::create_repetition (const db::Shape &array_shape, RegularArray ®ular, std::vector &irregular_array) +{ + switch (array_shape.type ()) { + case db::Shape::PolygonPtrArray: + return create_repetition_from_array (array_shape.basic_ptr (db::Shape::polygon_ptr_array_type::tag ()), regular, irregular_array); + case db::Shape::SimplePolygonPtrArray: + return create_repetition_from_array (array_shape.basic_ptr (db::Shape::simple_polygon_ptr_array_type::tag ()), regular, irregular_array); + case db::Shape::PathPtrArray: + return create_repetition_from_array (array_shape.basic_ptr (db::Shape::path_ptr_array_type::tag ()), regular, irregular_array); + case db::Shape::BoxArray: + return create_repetition_from_array (array_shape.basic_ptr (db::Shape::box_array_type::tag ()), regular, irregular_array); + case db::Shape::ShortBoxArray: + return create_repetition_from_array (array_shape.basic_ptr (db::Shape::short_box_array_type::tag ()), regular, irregular_array); + case db::Shape::TextPtrArray: + return create_repetition_from_array (array_shape.basic_ptr (db::Shape::text_ptr_array_type::tag ()), regular, irregular_array); + default: + tl_assert (false); + break; + } +} + +void +Compressed::compress_instances (const db::Cell::const_iterator &begin_instances, const std::set &cells_to_write, unsigned int level) +{ + // use compression 0 for the instances - this preserves the arrays and does not create new ones, the + // remaining ones are compressed into irregular arrays + Compressor inst_compressor (0); + Compressor inst_with_properties_compressor (0); + + // Collect all instances + for (auto inst_iterator = begin_instances; ! inst_iterator.at_end (); ++inst_iterator) { + + if (cells_to_write.find (inst_iterator->cell_index ()) != cells_to_write.end ()) { + + db::properties_id_type prop_id = inst_iterator->prop_id (); + db::CellInstArray inst_array = inst_iterator->cell_inst (); + + if (level == 0 || inst_array.size () > 1) { + + // Recode the instance array into a regular array or irregular array spec (the latter hardly used) and + // a single instance. + RegularArray array; + std::vector irregular_array; + + db::Vector disp; + bool transfer_array = (inst_array.size () > 1 && level > 0); + if (transfer_array) { + disp = create_repetition_from_array (&inst_array, array, irregular_array); + } + + db::CellInstArray single_inst; + if (! inst_array.is_complex ()) { + single_inst = db::CellInstArray (inst_array.object (), db::Trans (-disp) * inst_array.front ()); + } else { + single_inst = db::CellInstArray (inst_array.object (), inst_array.complex_trans (db::Trans (-disp) * inst_array.front ())); + } + + // no compression -> just keep as is + if (prop_id != 0) { + write (db::CellInstArrayWithProperties (single_inst, prop_id), array, irregular_array); + } else { + write (single_inst, array, irregular_array); + } + + } else { + + // We have a single instance: reduce by displacement and compress into enumerated (irregular) arrays. + // As we configured the compressor with level 0, no regular array formation will happen here. This is + // good for instances as array instances are special. + db::Vector disp = inst_array.front ().disp (); + + db::CellInstArray single_inst; + if (! inst_array.is_complex ()) { + single_inst = db::CellInstArray (inst_array.object (), db::Trans (-disp) * inst_array.front ()); + } else { + single_inst = db::CellInstArray (inst_array.object (), inst_array.complex_trans (db::Trans (-disp) * inst_array.front ())); + } + + if (prop_id != 0) { + inst_with_properties_compressor.add (db::CellInstArrayWithProperties (single_inst, prop_id), disp); + } else { + inst_compressor.add (single_inst, disp); + } + + } + + } + + } + + inst_compressor.flush (this); + inst_with_properties_compressor.flush (this); +} + +} diff --git a/src/plugins/streamers/lstream/db_plugin/lstrCompressed.h b/src/plugins/streamers/lstream/db_plugin/lstrCompressed.h new file mode 100644 index 000000000..3671314c9 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrCompressed.h @@ -0,0 +1,295 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef HDR_lstrCompressed +#define HDR_lstrCompressed + +#include "lstrCompressor.h" + +#include "dbVector.h" +#include "dbBox.h" +#include "dbPath.h" +#include "dbEdge.h" +#include "dbEdgePair.h" +#include "dbPolygon.h" +#include "dbText.h" +#include "dbObjectWithProperties.h" +#include "dbCell.h" + +#include +#include + +namespace lstr +{ + +/** + * @brief A container for storing objects and compressing them using regular or irregular repetitions + * + * Use this object to compress db::Shapes or db::Instances containers. + * Use "Compressed::compress_shapes" to compress a Shapes container and + * "Compressed::compress_instances" to compress an Instances container. + * + * After feeding the objects to be compressed using one of these methods, + * you can access the compressed objects using "Compressed::get_container". + * These containers are separated by objects and carray plain objects + * (no compression), plain objects with properties (no compression either), + * array objects (object that have been compressed into regular or irregular + * arrays) and array objects with properties (the same, but also with + * properties). + * + * During compression, arrays are formed. The array definitions are kept + * in two lists: regular arrays and irregular (iterated or enumerated) + * arrays. The former can be obtained using "Compressed::begin/end_regular_arrays", + * the latter using "Compressed::begin/end_irregular_arrays". + * The total number of array objects can be obtained using + * "Compressed::num_arrays". + */ +class Compressed + : public CompressorDelivery +{ +public: + + /** + * @brief Represents compressed objects + * + * "plain" is a list of plain objects - those which have not been + * compressed. + * + * "with_properties" is a list of pairs of objects and properties + * Id. The properties Id is a concept from the db namespace and + * represents a property set by some opaque identifier. + * + * "array" is a list of pairs of objects and repetition specifications. + * The repetition is specified through an index (a uint64_t value). + * The index is given by the second value when you iterate the repetitions + * in "Compressed::begin_regular_arrays" or "Compressed::begin_irregular_arrays". + * + * "array_with_properties" is a list of pairs or pairs: "first.first" + * is the object, "first.second" the properties Id and "second" the + * repetition index (see "array"). + */ + template + struct compressed_container + { + std::list plain; + std::list > with_properties; + std::list > array; + std::list, uint64_t> > array_with_properties; + }; + + /** + * @brief Constructor + * + * Note that you need to create a fresh object to compress + * instances are shapes. There is no "clear" or "restart" method. + */ + Compressed (); + + /** + * @brief Compresses a shape container + * + * This method should be called on a fresh Compressed object only. + * + * @param shapes The shapes container to compress + * @param level Compression level (see below) + * @param recompress Indicates where to recompress (see below) + * + * "level" is a value the indicates the compression effort made for forming + * regular arrays. A value of "0" indicates that no arrays will be formed. + * "2" indicates "reasonable effort" to form arrays. Roughly, the value indicates + * how many neighbors to investigate for forming arrays. + * + * If "recompress" is true, existing arrays will be exploded and fed into + * the compression algorithm again. If false, they will be maintained. + */ + void compress_shapes (const db::Shapes &shapes, unsigned int level, bool recompress); + + /** + * @brief Compresses instances + * + * This method should be called on a fresh Compressed object only. + * + * @param begin_instances The instance iterator specifying the instances to compress + * @param cells_to_write A filter specifying the cells to write + * @param level Compression level (see "compress_shapes") + * + * "Cell::begin" can be used to generate the value for "instance_iterator". + * + * Instances for cells not in "cells_to_write" are not generated. + */ + void compress_instances (const db::Cell::const_iterator &begin_instances, const std::set &cells_to_write, unsigned int level); + + /** + * @brief Gets the compressed objects for a given object type + * + * Object types can be "db::Box", "db::Edge", "db::EdgePair", + * "db::Polygon", "db::SimplePolygon", "db::Path" or "db::Text" + * for Shapes and "db::CellInstArray" for instances. + * + * For "db::CellInstArray", the objects will be single instances + * and the array nature is reflected by the repetition type. + * + * Note that either "compress_shapes" or "compress_instances" has + * to be called before the container is available. + */ + template compressed_container &get_container (); + + /** + * @brief begin iterator for the regular arrays + * + * The iterator delivers a pair of regular array specifications and + * an index. The array specification is a RegularArray object that + * specifies the array axes, pitches and array dimensions. + * + * The second value is the repetition index, by which the compressed + * objects refer to that array. + * + * Note that either "compress_shapes" or "compress_instances" has + * to be called before the arrays are available. + */ + std::map::const_iterator begin_regular_arrays () const { return m_array_to_rep_id.begin (); } + + /** + * @brief end iterator for the regular arrays + */ + std::map::const_iterator end_regular_arrays () const { return m_array_to_rep_id.end (); } + + /** + * @brief begin iterator for the irregular arrays + * + * The iterator delivers a pair of irregular array specifications and + * an index. The array specification is a list of displacements that + * specify the placements of the object. + * + * The second value is the repetition index, by which the compressed + * objects refer to that array. + * + * Note that either "compress_shapes" or "compress_instances" has + * to be called before the arrays are available. + */ + std::map, uint64_t>::const_iterator begin_irregular_arrays () const { return m_irregular_to_rep_id.begin (); } + + /** + * @brief end iterator for the irregular arrays + */ + std::map, uint64_t>::const_iterator end_irregular_arrays () const { return m_irregular_to_rep_id.end (); } + + /** + * @brief Gets the total number of arrays stored in this object + * + * Note that either "compress_shapes" or "compress_instances" has + * to be called before the arrays are available. + */ + size_t num_arrays () const + { + return m_array_to_rep_id.size () + m_irregular_to_rep_id.size (); + } + +protected: + virtual void write (const db::Point &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::PointWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::Box &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::BoxWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::Edge &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::EdgeWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::EdgePair &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::EdgePairWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::Polygon &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::PolygonWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::SimplePolygon &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::SimplePolygonWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::Path &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::PathWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::Text &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::TextWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::CellInstArray &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + virtual void write (const db::CellInstArrayWithProperties &obj, const RegularArray &array, const disp_vector &irregular) { store (obj, array, irregular); } + +private: + compressed_container m_points; + compressed_container m_boxes; + compressed_container m_edges; + compressed_container m_edge_pairs; + compressed_container m_paths; + compressed_container m_polygons; + compressed_container m_simple_polygons; + compressed_container m_texts; + compressed_container m_instances; + + template + void store_no_props (const Obj &obj, const RegularArray &array, const std::vector &irregular) + { + compressed_container &cont = get_container (); + if (array.is_null () && irregular.empty ()) { + cont.plain.push_back (obj); + } else { + cont.array.push_back (std::make_pair (obj, make_rep_id (array, irregular))); + } + } + + template + void store (const Obj &obj, const RegularArray &array, const std::vector &irregular) + { + store_no_props (obj, array, irregular); + } + + template + void store (const db::object_with_properties &obj, const RegularArray &array, const std::vector &irregular) + { + compressed_container &cont = get_container (); + if (obj.properties_id () == 0) { + store_no_props (obj, array, irregular); + } else { + if (array.is_null () && irregular.empty ()) { + cont.with_properties.push_back (std::pair (obj, obj.properties_id ())); + } else { + cont.array_with_properties.push_back (std::make_pair (std::pair (obj, obj.properties_id ()), make_rep_id (array, irregular))); + } + } + } + + size_t m_next_id; + std::map m_array_to_rep_id; + std::map, uint64_t> m_irregular_to_rep_id; + + uint64_t make_rep_id (const RegularArray &array, const std::vector &irregular); + db::Vector create_repetition (const db::Shape &array, RegularArray ®ular, std::vector &irregular_array); + template + void write_shape(const db::Shape &shape, RegularArray ®ular, std::vector &irregular_array); + template + void write_shape(const db::Shape &shape, const db::Vector &disp, RegularArray ®ular, std::vector &irregular_array); +}; + +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_points; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_boxes; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_edges; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_edge_pairs; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_paths; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_polygons; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_simple_polygons; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_texts; } +template <> inline Compressed::compressed_container &Compressed::get_container () { return m_instances; } + +} + +#endif + diff --git a/src/plugins/streamers/lstream/db_plugin/lstrCompressor.cc b/src/plugins/streamers/lstream/db_plugin/lstrCompressor.cc new file mode 100644 index 000000000..658905b0e --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrCompressor.cc @@ -0,0 +1,405 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrCompressor.h" + +#include "dbPluginCommon.h" +#include "dbHash.h" + +namespace lstr +{ + +// --------------------------------------------------------------------------------- +// Utilities that prevent signed coordinate overflow + +template +inline R safe_scale (double sf, R value) +{ + double i = floor (sf * value + 0.5); + if (i < double (std::numeric_limits::min ())) { + throw tl::Exception ("Scaling failed: coordinate underflow"); + } + if (i > double (std::numeric_limits::max ())) { + throw tl::Exception ("Scaling failed: coordinate overflow"); + } + return R (i); +} + +template +inline R safe_diff (R a, R b) +{ + R d = a - b; + if ((a > b && d < 0) || (a < b && d > 0)) { + throw tl::Exception ("Signed coordinate difference overflow"); + } + return d; +} + +// --------------------------------------------------------------------------------- + +template +void +Compressor::flush (CompressorDelivery *writer) +{ + // produce the repetitions + + std::vector empty_irregular; + RegularArray empty_regular; + + disp_vector displacements; + typedef std::vector > > tmp_rep_vector; + tmp_rep_vector repetitions; + std::vector > rep_vector; + + for (auto n = m_normalized.begin (); n != m_normalized.end (); ++n) { + + rep_vector.clear (); + + // don't compress below a threshold of 10 shapes + if (m_level < 1 || n->second.size () < 10) { + + // Simple compression: just sort and make irregular repetitions + std::sort (n->second.begin (), n->second.end (), vector_cmp_x ()); + + } else { + + disp_vector::iterator d; + tmp_rep_vector::iterator rw; + + std::unordered_set xcoords, ycoords; + if (m_level > 1) { + for (d = n->second.begin (); d != n->second.end (); ++d) { + xcoords.insert (d->x ()); + ycoords.insert (d->y ()); + } + } + + bool xfirst = xcoords.size () < ycoords.size (); + + double simple_rep_cost = 0; + double array_cost = 0; + + // Try single-point compression to repetitions in the x and y direction. For the first + // direction, use the one with more distinct values. For this, a better compression is + // expected. + for (int xypass = 0; xypass <= 1; ++xypass) { + + bool xrep = (xfirst == (xypass == 0)); + + displacements.clear (); + repetitions.clear (); + + displacements.swap (n->second); + if (xrep) { + std::sort (displacements.begin (), displacements.end (), vector_cmp_x ()); + } else { + std::sort (displacements.begin (), displacements.end (), vector_cmp_y ()); + } + + if (xypass == 0 && m_level > 1) { + // Establish a baseline for the repetition cost + simple_rep_cost += cost_of (displacements.front ().x ()) + cost_of (displacements.front ().y ()); + for (d = displacements.begin () + 1; d != displacements.end (); ++d) { + simple_rep_cost += std::max (1.0, cost_of (double (d->x ()) - double (d[-1].x ())) + cost_of (double (d->y ()) - double (d[-1].y ()))); + } + } + + disp_vector::iterator dwindow = displacements.begin (); + for (d = displacements.begin (); d != displacements.end (); ) { + + if (m_level < 2) { + + disp_vector::iterator dd = d; + ++dd; + + db::Vector dxy; + int nxy = 1; + + if (dd != displacements.end ()) { + + dxy = xrep ? db::Vector (safe_diff (dd->x (), d->x ()), 0) : db::Vector (0, safe_diff (dd->y (), d->y ())); + while (dd != displacements.end () && *dd == dd[-1] + dxy) { + ++dd; + ++nxy; + } + + } + + // Note in level 1 optimization, no cost estimation is done, hence small arrays won't be removed. + // To compensate that, we use a minimum size of 3 items per array. + if (nxy < 3) { + + n->second.push_back (*d++); + + } else { + + repetitions.push_back (std::make_pair (*d, std::make_pair (xrep ? dxy.x () : dxy.y (), nxy))); + d = dd; + + } + + } else { + + // collect the nearest neighbor distances and counts for 2..level order neighbors + int nxy_max = 1; + unsigned int nn_max = 0; + + // move the window of identical x/y coordinates if necessary + if (d == dwindow) { + for (dwindow = d + 1; dwindow != displacements.end () && (xrep ? (dwindow->y () == d->y ()) : (dwindow->x () == d->x ())); ++dwindow) + ; + } + + for (unsigned int nn = 0; nn < m_level; ++nn) { + + disp_vector::iterator dd = d + (nn + 1); + if (dd >= dwindow) { + break; + } + + db::Vector dxy = xrep ? db::Vector (safe_diff (dd->x (), d->x ()), 0) : db::Vector (0, safe_diff (dd->y (), d->y ())); + + int nxy = 2; + while (dd != dwindow) { + disp_vector::iterator df = std::lower_bound (dd + 1, dwindow, *dd + dxy); + if (df == dwindow || *df != *dd + dxy) { + break; + } + ++nxy; + dd = df; + } + + if (nxy > nxy_max) { + nxy_max = nxy; + nn_max = nn; + } + + } + + if (nxy_max < 2) { + + // no candidate found - just keep that one + n->second.push_back (*d++); + + } else { + + // take out the ones of this sequence from the list + db::Vector dxy_max = xrep ? db::Vector (safe_diff ((d + nn_max + 1)->x (), d->x ()), 0) : db::Vector (0, safe_diff ((d + nn_max + 1)->y (), d->y ())); + + disp_vector::iterator ds = dwindow; + disp_vector::iterator dt = dwindow; + db::Vector df = *d + dxy_max * long (nxy_max - 1); + + do { + --ds; + if (*ds != df) { + *--dt = *ds; + } else { + df -= dxy_max; + } + } while (ds != d); + + repetitions.push_back (std::make_pair (*d, std::make_pair (xrep ? dxy_max.x () : dxy_max.y (), nxy_max))); + + d = dt; + + } + + } + + } + + // Apply some heuristic criterion that allows the algorithm to determine whether it's worth doing the compression + + // Try to compact these repetitions further, y direction first, then x direction + for (int xypass2 = 1; xypass2 >= 0; --xypass2) { + + if (xypass2) { + std::sort (repetitions.begin (), repetitions.end (), rep_vector_cmp ()); + } else { + std::sort (repetitions.begin (), repetitions.end (), rep_vector_cmp ()); + } + + rw = repetitions.begin (); + for (auto r = repetitions.begin (); r != repetitions.end (); ) { + + auto rr = r; + ++rr; + + db::Vector dxy2; + if (rr != repetitions.end ()) { + dxy2 = xypass2 ? db::Vector (0, safe_diff (rr->first.y (), r->first.y ())) : db::Vector (safe_diff (rr->first.x (), r->first.x ()), 0); + } + int nxy2 = 1; + + db::Vector dxy2n (dxy2); + while (rr != repetitions.end () && rr->second == r->second && rr->first == r->first + dxy2n) { + ++nxy2; + ++rr; + dxy2n += dxy2; + } + + if (nxy2 < 2 && xypass2) { + *rw++ = *r; + } else { + if (m_level < 2) { + Obj obj = n->first; + obj.move (r->first); + db::Vector a (xrep ? r->second.first : 0, xrep ? 0 : r->second.first); + writer->write (obj, RegularArray (a, dxy2, r->second.second, nxy2), empty_irregular); + } else { + db::Vector a (xrep ? r->second.first : 0, xrep ? 0 : r->second.first); + rep_vector.push_back (std::make_pair (r->first, RegularArray (a, dxy2, r->second.second, nxy2))); + } + } + + r = rr; + + } + + repetitions.erase (rw, repetitions.end ()); + + } + + } + + if (m_level > 1) { + + // Compute a cost for the repetitions + + if (! n->second.empty ()) { + // irregular repetition contribution + array_cost += cost_of (n->second.front ().x ()) + cost_of (n->second.front ().y ()); + for (auto d = n->second.begin () + 1; d != n->second.end (); ++d) { + array_cost += std::max(1.0, cost_of (d->x () - d[-1].x ()) + cost_of (d->y () - d[-1].y ())); + } + } + + bool array_set = false; + db::Vector a_ref, b_ref; + size_t in_ref = 0, im_ref = 0; + bool ref_set = false; + db::Coord x_ref = 0, y_ref = 0; + + for (auto r = rep_vector.begin (); r != rep_vector.end (); ++r) { + + db::Vector a, b; + size_t in = 0, im = 0; + + array_cost += 2; // two bytes for the shape + + // The cost of the first point (takes into account compression by reuse of one coordinate) + if (!ref_set || x_ref != r->first.x ()) { + array_cost += cost_of (r->first.x ()); + } + if (!ref_set || y_ref != r->first.y ()) { + array_cost += cost_of (r->first.y ()); + } + ref_set = true; + x_ref = r->first.x (); + y_ref = r->first.y (); + + // Cost of the repetition (takes into account reuse) + if (! array_set || a != a_ref || b != b_ref || in != in_ref || im != im_ref) { + array_set = true; + a_ref = a; + b_ref = b; + in_ref = in; + im_ref = im; + array_cost += cost_of (a.x ()) + cost_of (b.x ()) + cost_of (a.y ()) + cost_of (b.y ()) + cost_of (in) + cost_of (im); + } else { + array_cost += 1; // one byte + } + + // Note: the pointlist is reused, hence does not contribute + + } + + // And resolve the repetitions if it does not make sense to keep them + if (array_cost > simple_rep_cost) { + for (auto r = rep_vector.begin (); r != rep_vector.end (); ++r) { + for (size_t ia = 0; ia < r->second.na (); ++ia) { + for (size_t ib = 0; ib < r->second.nb (); ++ib) { + n->second.push_back (r->first + r->second.a () * long (ia) + r->second.b () * long (ib)); + } + } + } + rep_vector.clear (); + std::sort (n->second.begin (), n->second.end (), vector_cmp_x ()); + } + + } + + } + + for (auto r = rep_vector.begin (); r != rep_vector.end (); ++r) { + Obj obj = n->first; + obj.move (r->first); + writer->write (obj, r->second, empty_irregular); + } + + if (n->second.size () > 1) { + + // need to normalize? + db::Vector p0 = n->second.front (); + std::vector::iterator pw = n->second.begin(); + for (auto p = pw + 1; p != n->second.end (); ++p) { + *pw++ = *p - p0; + } + n->second.erase (pw, n->second.end ()); + + Obj obj = n->first; + obj.move (p0); + writer->write (obj, empty_regular, n->second); + + } else if (! n->second.empty ()) { + + Obj obj = n->first; + obj.move (n->second.front ()); + writer->write (obj, empty_regular, empty_irregular); + + } + + } +} + +// explicit instantiations +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; +template class Compressor; + +} diff --git a/src/plugins/streamers/lstream/db_plugin/lstrCompressor.h b/src/plugins/streamers/lstream/db_plugin/lstrCompressor.h new file mode 100644 index 000000000..9e57d23a6 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrCompressor.h @@ -0,0 +1,422 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef HDR_lstrCompressor +#define HDR_lstrCompressor + +#include "dbVector.h" +#include "dbBox.h" +#include "dbPath.h" +#include "dbEdge.h" +#include "dbEdgePair.h" +#include "dbPolygon.h" +#include "dbText.h" +#include "dbInstances.h" +#include "dbObjectWithProperties.h" + +#include +#include + +namespace lstr +{ + +const unsigned int max_lstreame_compression_level = 10; + +/** + * @brief Compare operator for points, distinct x clustered (with same y) + */ +struct vector_cmp_x +{ + bool operator() (const db::Vector &a, const db::Vector &b) const + { + if (a.y () != b.y ()) { + return a.y () < b.y (); + } else { + return a.x () < b.x (); + } + } +}; + +/** + * @brief Compare operator for points, distinct y clustered (with same x) + */ +struct vector_cmp_y +{ + bool operator() (const db::Vector &a, const db::Vector &b) const + { + if (a.x () != b.x ()) { + return a.x () < b.x (); + } else { + return a.y () < b.y (); + } + } +}; + +/** + * @brief Returns the cost value of a coordinate difference (or coordinate) + * The cost is used to estimate the size cost of a coordinate difference + * in the OASIS output. + * The cost is roughly the number of bytes required to represent the + * number. It does not consider gdelta compression, actual byte count or similar. + * + * TODO: this heuristics is taken from OASIS. I should be adapted to LStream. + */ +inline double cost_of (double d) +{ + int exp = 0; + frexp (d, &exp); + return double ((exp + 7) / 8); +} + +/** + * @brief A predicate describing whether an object is empty + * + * An object is "empty", if it does not have at least one reference point. + * For example, an empty box is empty. Such objects cannot be written and are + * stripped. + */ +template +static inline bool object_is_empty (const Object &) { return false; } +static inline bool object_is_empty (const db::Box &object) { return object.empty (); } +static inline bool object_is_empty (const db::Polygon &object) { return object.hull ().begin () == object.hull ().end (); } +static inline bool object_is_empty (const db::SimplePolygon &object) { return object.hull ().begin () == object.hull ().end (); } +static inline bool object_is_empty (const db::Path &object) { return object.begin () == object.end (); } + +/** + * @brief Normalization of the position of an object + */ +template +static inline db::Vector reduce_object (Object &object) +{ + db::Disp tr; + object.reduce (tr); + return tr.disp (); +} + +/** + * @brief Specialization for EdgePair which currently does not have "reduce" + */ +static inline db::Vector reduce_object_edge_pair (db::EdgePair &ep) +{ + db::EdgePair::vector_type d (ep.first ().p1 ()); + ep.move (-d); + return d; +} + +static inline db::Vector reduce_object (db::EdgePair &ep) +{ + return reduce_object_edge_pair (ep); +} + +static inline db::Vector reduce_object (db::EdgePairWithProperties &ep) +{ + return reduce_object_edge_pair (ep); +} + +/** + * @brief Specialization for EdgePair which currently does not have "reduce" + */ +static inline db::Vector reduce_object_point (db::Point &pt) +{ + db::Vector d = db::Vector (pt); + pt = db::Point (); + return d; +} + +static inline db::Vector reduce_object (db::Point &pt) +{ + return reduce_object_point (pt); +} + +static inline db::Vector reduce_object (db::PointWithProperties &pt) +{ + return reduce_object_point (pt); +} + +/** + * @brief Specialization for CellInstArray + */ +static inline db::Vector reduce_object_cell_inst_array (db::CellInstArray &ci) +{ + db::Vector d = ci.front ().disp (); + ci.move (-d); + return d; +} + +static inline db::Vector reduce_object (db::CellInstArray &ci) +{ + return reduce_object_cell_inst_array (ci); +} + +static inline db::Vector reduce_object (db::CellInstArrayWithProperties &ci) +{ + return reduce_object_cell_inst_array (ci); +} + +/** + * @brief Compare operator for points/abstract repetition pair with configurable point compare operator + */ +template +struct rep_vector_cmp +{ + bool operator () (const std::pair > &a, const std::pair > &b) + { + if (a.second != b.second) { + return a.second < b.second; + } + PC pc; + return pc (a.first, b.first); + } +}; + +/** + * @brief Represents a regular array + * + * A regular array is a set of displacements given by the + * formula + * + * d = ia*a + ib*b + * + * where "ia" is an integer running from 0 to na-1, "ib" is an integer + * running from 0 to nb-1 and "a" and "b" are two arbitrary vectors. + * + * The axes "a" and "b" do not need to be orthogonal in the general + * case, but they should not be collinear. + * + * "na" and "nb" are the dimensions of the array. + * + * An array can be "null", which means it does not represent any + * placements. + */ +class RegularArray +{ +public: + /** + * @brief Creates a null array + */ + RegularArray () + : m_na (0), m_nb (0) + { + // .. nothing yet .. + } + + /** + * @brief Creates an array with the given axes and dimensions + * + * @param a The "a" axis + * @param b The "b" axis + * @param na The "a" dimension + * @param nb The "b" dimension + */ + RegularArray (const db::Vector &a, const db::Vector &b, size_t na, size_t nb) + : m_a (a), m_b (b), m_na (na), m_nb (nb) + { + // .. nothing yet .. + } + + /** + * @brief Returns a value indicating whether the array is a null array + */ + bool is_null () const + { + return m_na == 0 || m_nb == 0; + } + + /** + * @brief Gets the a axis + */ + const db::Vector &a () const { return m_a; } + + /** + * @brief Gets the b axis + */ + const db::Vector &b () const { return m_b; } + + /** + * @brief Gets the a dimension + */ + size_t na () const { return m_na; } + + /** + * @brief Gets the b dimension + */ + size_t nb () const { return m_nb; } + + /** + * @brief The equality operator + */ + bool operator== (const RegularArray &other) const + { + return m_a == other.m_a && + m_b == other.m_b && + m_na == other.m_na && + m_nb == other.m_nb; + } + + /** + * @brief The less operator + * + * This operator is provided for strict weak ordering + * for us of the array as a key in std::map or std::set. + */ + bool operator< (const RegularArray &other) const + { + if (m_a != other.m_a) { + return m_a < other.m_a; + } + if (m_b != other.m_b) { + return m_b < other.m_b; + } + if (m_na != other.m_na) { + return m_na < other.m_na; + } + if (m_nb != other.m_nb) { + return m_nb < other.m_nb; + } + return false; + } + +private: + db::Vector m_a, m_b; + size_t m_na, m_nb; +}; + +/** + * @brief An interface by which the compressor delivers the results of the compression + * + * Note that we're lacking virtual templates, hence the large number of + * methods for every object type. + */ +class CompressorDelivery +{ +public: + typedef std::vector disp_vector; + + virtual ~CompressorDelivery () { } + + virtual void write (const db::Point &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::PointWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::Box &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::BoxWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::Edge &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::EdgeWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::EdgePair &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::EdgePairWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::Polygon &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::PolygonWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::SimplePolygon &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::SimplePolygonWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::Path &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::PathWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::Text &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::TextWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::CellInstArray &obj, const RegularArray &array, const disp_vector &irregular) = 0; + virtual void write (const db::CellInstArrayWithProperties &obj, const RegularArray &array, const disp_vector &irregular) = 0; +}; + +/** + * @brief The compressor object + * + * The task of the compressor object is to accept a serial stream + * of individual objects and arranging them into arrays as far as possible. + * + * Arrays can be regular (RegularArray) or enumerated (lists of placements). + * + * Individual objects are fed using the "add" method. Once all objects + * are fed "flush" can be used to deliver the compressed arrays to a + * "CompressorDelivery" object. + * + * Note that once "flush" is called, "add" should no longer be used. + * For compressing new objects, construct a fresh Compressor object. + */ +template +class Compressor +{ +public: + /** + * @brief Constructor + * + * @param level The compression level + * + * Allowed levels are: + * 0 - simple + * 1 - form simple arrays + * 2++ - search for 2nd, 3rd ... order neighbors + */ + Compressor (unsigned int level) + : m_level (level) + { + // .. nothing yet .. + } + + /** + * @brief Adds a new object with the given displacement + * + * The object is supposed to be reduced (positioned at 0,0) + * already and the displacement specifies where the object + * was sitting originally. + */ + void add (const Obj &obj, const db::Vector &disp) + { + if (! object_is_empty (obj)) { + m_normalized [obj].push_back (disp); + } + } + + /** + * @brief Adds an object with reduction + * + * The object added can sit anywhere. Before it is added, + * it is reduced (positioned at 0,0) and the displacement + * is recorded for array formation. + */ + void add (const Obj &obj) + { + if (! object_is_empty (obj)) { + Obj red (obj); + auto disp = reduce_object (red); + m_normalized [red].push_back (disp); + } + } + + /** + * @brief Generates arrays and delivers when to the delivery interface + * + * This method will can "deliver->write (Object, ...)" as many times as + * needed. + * + * Note that single objects may be delivered as well. These are encoded + * as null regular arrays and empty irregular placement lists. + */ + void flush (CompressorDelivery *delivery); + +private: + typedef std::vector disp_vector; + + std::unordered_map m_normalized; + unsigned int m_level; +}; + +} + +#endif + diff --git a/src/plugins/streamers/lstream/db_plugin/lstrFormat.cc b/src/plugins/streamers/lstream/db_plugin/lstrFormat.cc new file mode 100644 index 000000000..689efe010 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrFormat.cc @@ -0,0 +1,39 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrFormat.h" + +namespace lstr +{ + +WriterOptions::WriterOptions () + : compression_level (2), recompress (false), permissive (false) +{ + // .. nothing yet .. +} + +ReaderOptions::ReaderOptions () +{ + // .. nothing yet .. +} + +} diff --git a/src/plugins/streamers/lstream/db_plugin/lstrFormat.h b/src/plugins/streamers/lstream/db_plugin/lstrFormat.h new file mode 100644 index 000000000..624c9e1f2 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrFormat.h @@ -0,0 +1,131 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef HDR_lstrFormat +#define HDR_lstrFormat + +#include "dbPluginCommon.h" +#include "dbLoadLayoutOptions.h" +#include "dbSaveLayoutOptions.h" + +namespace lstr +{ + +/** + * @brief Structure that holds the LStream specific options for the reader + * NOTE: this structure is non-public linkage by intention. This way it's instantiated + * in all compile units and the shared object does not need to be linked. + */ +class DB_PLUGIN_PUBLIC ReaderOptions + : public db::FormatSpecificReaderOptions +{ +public: + /** + * @brief The constructor + */ + ReaderOptions (); + + /** + * @brief If not empty, this string specifies a key under which the bbox from the stream is stored in the cells + */ + std::string bbox_meta_info_key; + + /** + * @brief Implementation of FormatSpecificReaderOptions + */ + virtual db::FormatSpecificReaderOptions *clone () const + { + return new ReaderOptions (*this); + } + + /** + * @brief Implementation of FormatSpecificReaderOptions + */ + virtual const std::string &format_name () const + { + static const std::string n ("LStream"); + return n; + } +}; + +/** + * @brief Structure that holds the OASIS specific options for the Writer + * NOTE: this structure is non-public linkage by intention. This way it's instantiated + * in all compile units and the shared object does not need to be linked. + */ +class DB_PLUGIN_PUBLIC WriterOptions + : public db::FormatSpecificWriterOptions +{ +public: + /** + * @brief The constructor + */ + WriterOptions (); + + /** + * @brief OASIS writer compression level + * + * This level describes how hard the OASIS writer will try to compress the shapes + * using shape arrays. Building shape arrays may take some time and requires some memory. + * 0 - no shape array building + * 1 - nearest neighbor shape array formation + * 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well + */ + int compression_level; + + /** + * @brief Recompressions + * + * If the recompression flag is true, existing shape arrays will be resolved and + * put into the compressor again (may take longer). + */ + bool recompress; + + /** + * @brief Permissive mode + * + * In permissive mode, a warning is issued for certain cases rather than + * an error. For example paths/circles with odd diameter (rounded). + */ + bool permissive; + + /** + * @brief Implementation of FormatSpecificWriterOptions + */ + virtual db::FormatSpecificWriterOptions *clone () const + { + return new WriterOptions (*this); + } + + /** + * @brief Implementation of FormatSpecificWriterOptions + */ + virtual const std::string &format_name () const + { + static std::string n ("LStream"); + return n; + } +}; + +} + +#endif diff --git a/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc b/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc new file mode 100644 index 000000000..67e3f2105 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrPlugin.cc @@ -0,0 +1,121 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrReader.h" +#include "lstrWriter.h" +#include "lstrPlugin.h" +#include "lstrFormat.h" + +#include "dbStream.h" +#include "version.h" + +#include "tlClassRegistry.h" + +namespace lstr +{ + +// --------------------------------------------------------------- +// Signature string and generator + +const char *LStream_sig = "LStream_1.0"; + +const char *LStream_generator = "klayout " STRINGIFY(KLAYOUT_VERSION); + +// --------------------------------------------------------------- + +/** + * @brief The LStream plugin + * + * Providing a class a regiserting it will enable this file + * format inside KLayout. + * + * It implements the "db::StreamFormatDeclaration" interface + * and provides KLayout with the necessary information to + * implement the format. + */ +class LStreamFormatDeclaration + : public db::StreamFormatDeclaration +{ + virtual std::string format_name () const { return "LStream"; } + virtual std::string format_desc () const { return "LStream"; } + virtual std::string format_title () const { return "LStream"; } + virtual std::string file_format () const { return "LStream files (*.lstr *.lstr.gz)"; } + + /** + * @brief Returns a value indicating whether the given stream represents the particular format + * + * KLayout will use this method to identify a file by content, rather than + * suffix. In the LStream case, the format is detected by the magic bytes + * at the front of the stream. + */ + virtual bool detect (tl::InputStream &stream) const + { + const char *hdr = stream.get (strlen (LStream_sig) + 1); + return (hdr && strcmp (hdr, LStream_sig) == 0); + } + + /** + * @brief Creates a reader object that does the actual reading + */ + virtual db::ReaderBase *create_reader (tl::InputStream &s) const + { + return new Reader (s); + } + + /** + * @brief Creates a writer object that does the actual reading + */ + virtual db::WriterBase *create_writer () const + { + return new Writer (); + } + + /** + * @brief Returns a value indicating whether reading is supported + */ + virtual bool can_read () const + { + return true; + } + + /** + * @brief Returns a value indicating whether writing is supported + */ + virtual bool can_write () const + { + return true; + } + + virtual tl::XMLElementBase *xml_writer_options_element () const + { + return new db::WriterOptionsXMLElement ("lstream", + tl::make_member (&lstr::WriterOptions::compression_level, "compression-level") + + tl::make_member (&lstr::WriterOptions::recompress, "recompress") + + tl::make_member (&lstr::WriterOptions::permissive, "permissive") + ); + } +}; + +static tl::RegisteredClass format_decl (new LStreamFormatDeclaration (), 2050, "LStream"); + +} + diff --git a/src/plugins/streamers/lstream/db_plugin/lstrPlugin.h b/src/plugins/streamers/lstream/db_plugin/lstrPlugin.h new file mode 100644 index 000000000..5c8c6a0ab --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrPlugin.h @@ -0,0 +1,41 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef HDR_lstrPlugin +#define HDR_lstrPlugin + +namespace lstr +{ + +/** + * @brief The magic bytes at the beginning of a LStream file + */ +extern const char *LStream_sig; + +/** + * @brief The generator name for writing Header::generator + */ +extern const char *LStream_generator; + +} + +#endif diff --git a/src/plugins/streamers/lstream/db_plugin/lstrReader.cc b/src/plugins/streamers/lstream/db_plugin/lstrReader.cc new file mode 100644 index 000000000..272462790 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrReader.cc @@ -0,0 +1,1918 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrReader.h" +#include "lstrPlugin.h" +#include "lstrFormat.h" + +#include "dbArray.h" + +#include "tlException.h" +#include "tlString.h" +#include "tlInternational.h" +#include "tlClassRegistry.h" + +#include "header.capnp.h" +#include "library.capnp.h" +#include "cell.capnp.h" +#include "layoutView.capnp.h" +#include "metaDataView.capnp.h" + +#include + +namespace lstr +{ + +// --------------------------------------------------------------- +// Some utility functions for the reader + +class CoordinateOverflowException + : public tl::Exception +{ +public: + CoordinateOverflowException (int64_t c) + : tl::Exception (tl::to_string (tr ("Coordinate overflow for value: ")) + tl::to_string (c)) + { + // .. nothing yet .. + } +}; + +inline db::Coord cast_to_coord (int64_t c) +{ + if (c > std::numeric_limits::max () || c < std::numeric_limits::min ()) { + throw CoordinateOverflowException (c); + } + return db::Coord (c); +} + +/** + * @brief Converts a stream::geometry::Vector object to a db::Vector + */ +static db::Vector +make_vector (stream::geometry::Vector::Reader reader) +{ + return db::Vector (cast_to_coord (reader.getDx ()), cast_to_coord (reader.getDy ())); +} + +/** + * @brief Adds a vector to a point in a overflow-safe way + */ +static db::Point +add_vector (const db::Point &p, stream::geometry::Vector::Reader reader) +{ + return db::Point (cast_to_coord (p.x () + reader.getDx ()), cast_to_coord (p.x () + reader.getDy ())); +} + +/** + * @brief Converts a stream::geometry::Point object to a db::Point + */ +static db::Point +make_point (stream::geometry::Point::Reader reader) +{ + return db::Point (cast_to_coord (reader.getX ()), cast_to_coord (reader.getY ())); +} + +/** + * @brief Converts a stream::geometry::FixPointTransformation enum into a KLayout fixpoint transformation constant + */ +static unsigned int +make_fixpoint_trans (stream::geometry::FixPointTransformation fp) +{ + switch (fp) { + case stream::geometry::FixPointTransformation::R0: + return db::FTrans::r0; + case stream::geometry::FixPointTransformation::R90: + return db::FTrans::r90; + case stream::geometry::FixPointTransformation::R180: + return db::FTrans::r180; + case stream::geometry::FixPointTransformation::R270: + return db::FTrans::r270; + case stream::geometry::FixPointTransformation::M0: + return db::FTrans::m0; + case stream::geometry::FixPointTransformation::M45: + return db::FTrans::m45; + case stream::geometry::FixPointTransformation::M90: + return db::FTrans::m90; + case stream::geometry::FixPointTransformation::M135: + return db::FTrans::m135; + default: + return db::FTrans::r0; + } +} + +/** + * @brief Converts a stream::library::LayerEntry::Purpose enum value into a string + * + * This method is used to derive layer names. The default purpose is not + * converted to a string an left empty. + */ +static std::string +purpose_string (stream::library::LayerEntry::Purpose purpose, stream::library::LayerEntry::Purpose default_purpose = stream::library::LayerEntry::Purpose::DRAWING) +{ + std::string ps; + + if (purpose == default_purpose) { + return ps; + } + + switch (purpose) { + case stream::library::LayerEntry::Purpose::DRAWING: + ps = "DRAWING"; + break; + case stream::library::LayerEntry::Purpose::BLOCKAGE: + ps = "BLOCKAGE"; + break; + case stream::library::LayerEntry::Purpose::BOUNDARY: + ps = "BOUNDARY"; + break; + case stream::library::LayerEntry::Purpose::COMMENT: + ps = "COMMENT"; + break; + case stream::library::LayerEntry::Purpose::ERRORS: + ps = "ERRORS"; + break; + case stream::library::LayerEntry::Purpose::FILL: + ps = "FILL"; + break; + case stream::library::LayerEntry::Purpose::HANDLES: + ps = "HANDLES"; + break; + case stream::library::LayerEntry::Purpose::PIN: + ps = "PIN"; + break; + case stream::library::LayerEntry::Purpose::SLOT: + ps = "SLOT"; + break; + case stream::library::LayerEntry::Purpose::TEXT: + ps = "TEXT"; + break; + case stream::library::LayerEntry::Purpose::WIRE: + ps = "WIRE"; + break; + default: + break; + } + + return ps; +} + +/** + * @brief Turns a stream::geometry::Contour contour into a list of _PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC_2ARGS + * + * A contour is a list of points, representing a closed loop (for polygons) or + * a linear chain of line segments (for paths).get_regular_array + * + * This function will extract the list of points from the Contour object.get_regular_array + * + * @param contour The list of points (output) + * @param reader The stream::geometry::Contour object (input) + */ +static void +make_contour (std::vector &contour, stream::geometry::Contour::Reader reader) +{ + contour.clear (); + contour.reserve (reader.getDeltas ().size () + 1); + + db::Point pt = make_point (reader.getP1 ()); + auto deltas = reader.getDeltas (); + for (auto d = deltas.begin (); d != deltas.end (); ++d) { + contour.push_back (pt); + pt += make_vector (*d); + } + contour.push_back (pt); +} + +/** + * @brief Generates a ICplxTrans transformation from a stream::layoutView::CellTransformation object + * + * ICplxTrans is the generic (complex) transformation used inside KLayout to + * represent affine transformations. These including isotropic scaling, + * arbitrary angle rotations, mirroring and displacement. + */ +static db::ICplxTrans +make_transformation (stream::layoutView::CellTransformation::Reader transformation) +{ + db::Vector d = make_vector (transformation.getDisplacement ()); + + if (transformation.getTransformation ().isComplex ()) { + + auto complex = transformation.getTransformation ().getComplex (); + double angle = complex.getAngle (); + bool mirror = complex.getMirror (); + double mag = complex.getScale (); + + return db::ICplxTrans (mag, angle, mirror, d); + + } else if (transformation.getTransformation ().isSimple ()) { + + auto simple = transformation.getTransformation ().getSimple (); + return db::ICplxTrans (db::Trans (make_fixpoint_trans (simple.getOrientation ()), d)); + + } else { + return db::ICplxTrans (); + } +} + +/** + * @brief Extracts a list of displacements from a "ENUMERATED" type stream::repetition::Repetition + * + * @param repetition The Cap'n'Proto repetition type (input) + * @param vectors The displacements derived from the repetition (output) + * + * The repetition is expected to be of ENUMERATED type. + * The first element of the output list of displacements is a zero + * vector which is implicitly included in the enumerated repetition. + */ +static void +make_vectors (stream::repetition::Repetition::Reader repetition, std::vector &vectors) +{ + tl_assert (repetition.getTypes ().isEnumerated ()); + + auto deltas = repetition.getTypes ().getEnumerated ().getDeltas (); + + vectors.clear (); + vectors.reserve (deltas.size () + 1); + vectors.push_back (db::Vector ()); + + db::Vector dl; + for (auto d = deltas.begin (); d != deltas.end (); ++d) { + dl += make_vector (*d); + vectors.push_back (dl); + } +} + +/** + * @brief Turns a stream::repetition::Repetition into a db::iterated_array object + * + * The Repetition object is expected to be of ENUMERATED type. The list of + * displacements is turned into a irregular array for use in shape or instance + * arrays. + * + * Note that the output array will contain one element in addition. This + * is the first element which represents the original object without displacement. + * + * @param repetition The Repetition object delivered by Cap'n'Proto (input) + * @param array The KLayout irregular (enumerated) array object (output) + * + */ +static void +make_iterated_array (stream::repetition::Repetition::Reader repetition, db::iterated_array &array) +{ + tl_assert (repetition.getTypes ().isEnumerated ()); + + auto deltas = repetition.getTypes ().getEnumerated ().getDeltas (); + array.reserve (deltas.size () + 1); + array.insert (db::Vector ()); + db::Vector dl; + for (auto d = deltas.begin (); d != deltas.end (); ++d) { + dl += make_vector (*d); + array.insert (dl); + } + array.sort (); +} + +/** + * @brief Extracts the regular array parameters (a, b, na, nb) from stream::repetition::Repetition + * + * The Repetition object is expected to represent a REGULAR or REGULAR_ORTH + * repetition. The returned values are the array axes (a, b) and dimensions + * (na, nb). + * + * @param repetition The Repetition object delivered by Cap'n'Proto (input) + * @param a The a axis (output) + * @param b The b axis (output) + * @param na The a dimension (output) + * @param nb The b dimension (output) + */ +static void +get_regular_array (stream::repetition::Repetition::Reader repetition, db::Vector &a, db::Vector &b, unsigned long &na, unsigned long &nb) +{ + tl_assert (repetition.getTypes ().isRegularOrtho () || repetition.getTypes ().isRegular ()); + + if (repetition.getTypes ().which () == stream::repetition::Repetition::Types::REGULAR) { + + auto regular = repetition.getTypes ().getRegular (); + + a = make_vector (regular.getA ()); + b = make_vector (regular.getB ()); + na = regular.getNa (); + nb = regular.getNb (); + + } else { + + auto regular_ortho = repetition.getTypes ().getRegularOrtho (); + + a = db::Vector (regular_ortho.getDx (), 0); + b = db::Vector (0, regular_ortho.getDy ()); + na = regular_ortho.getNx (); + nb = regular_ortho.getNy (); + + } +} + +/** + * @brief Turns a stream::repetition::Repetition into a db::regular_arrayget_regular_array + * + * The latter is the basic object to represent a regular array in KLayout's + * shape and instance arrays. + * + * @param repetition The Repetition object delivered by Cap'n'Proto (input) + * @param array The KLayout regular array object (output) + */ +static void +make_regular_array (stream::repetition::Repetition::Reader repetition, db::regular_array &array) +{ + db::Vector a, b; + unsigned long na = 0, nb = 0; + get_regular_array (repetition, a, b, na, nb); + + array = db::regular_array (a, b, na, nb); +} + +// --------------------------------------------------------------- +// LStreamReader implementation + +Reader::Reader (tl::InputStream &s) + : m_stream (&s), m_source (s.source ()), + m_progress (tl::to_string (tr ("Reading LStream file"))), + m_library_index (0), mp_cell (0), mp_layout (0), m_layout_view_id (0) +{ + m_progress.set_format (tl::to_string (tr ("%.0f MB"))); + m_progress.set_unit (1024 * 1024); +} + +Reader::~Reader () noexcept +{ + // .. nothing yet .. +} + +void +Reader::init (const db::LoadLayoutOptions &options) +{ + db::CommonReader::init (options); + + lstr::ReaderOptions lstr_options = options.get_options (); + m_bbox_meta_data_key = lstr_options.bbox_meta_info_key; +} + +/** + * @brief Gets a string describing the position in the file + */ +std::string +Reader::position () +{ + if (m_stream.position () == m_stream.position_before ()) { + return tl::to_string (m_stream.position ()); + } else { + return tl::to_string (m_stream.position_before ()) + " .. " + tl::to_string (m_stream.position ()); + } +} + +void +Reader::error (const std::string &msg) +{ + throw LStreamReaderException (msg, cellname ().c_str (), m_source, position ()); +} + +void +Reader::warn (const std::string &msg, int wl) +{ + if (warn_level () < wl) { + return; + } + + if (first_warning ()) { + tl::warn << tl::sprintf (tl::to_string (tr ("In file %s:")), m_source); + } + + int ws = compress_warning (msg); + if (ws < 0) { + tl::warn << msg + << tl::to_string (tr (" (cell=")) << cellname ().c_str () + << ")"; + } else if (ws == 0) { + tl::warn << tl::to_string (tr ("... further warnings of this kind are not shown")); + } +} + +// See declaration +void +Reader::do_read (db::Layout &layout) +{ + try { + do_read_internal (layout); + } catch (lstr::CoordinateOverflowException &ex) { + // this adds source information + error (ex.msg ()); + } catch (kj::Exception &ex) { + // this adds source information + error (ex.getDescription ().cStr ()); + } +} + +// do_read delegate, unprotected +void +Reader::do_read_internal (db::Layout &layout) +{ + mp_layout = &layout; + m_cellname.clear (); + + // NOTE: we bypass buffering from the InputStream as KJ already buffers + + // TODO: this prevents using HTTP as of now (version 0.30.2). Maybe we can implement + // "reset" in the HTTP streams in KLayout later. + m_stream.reset (); + + size_t nhdr = strlen (LStream_sig) + 1; + std::unique_ptr hdr (new char [nhdr]); + size_t nhdr_read = m_stream.tryRead (hdr.get (), nhdr, nhdr); + if (nhdr_read != nhdr || memcmp (LStream_sig, hdr.get (), nhdr) != 0) { + error (tl::to_string (tr ("LStream format not recognized (missing magic bytes)"))); + } + + kj::BufferedInputStreamWrapper kj_stream (m_stream); + + // Reads the global header + read_header (kj_stream); + + // Skip libraries we're not interested in + while (m_library_index > 0) { + skip_library (kj_stream); + --m_library_index; + } + + read_library (kj_stream); + + // Read the cell messages after the library in the order the cells were defined in + // stream::library::CellSpecsTable. + for (auto c = m_cells.begin (); c != m_cells.end (); ++c) { + m_cellname = c->second; + read_cell (c->first, kj_stream); + m_cellname.clear (); + } +} + +/** + * @brief A helper class to join two datatype layer name map members + * TODO: should not be required with the proper extensions to the CommonReader base + */ +struct LNameJoinOp1 +{ + void operator() (std::string &a, const std::string &b) + { + db::join_layer_names (a, b); + } +}; + +/** + * @brief A helper class to join two layer map members + * This implementation basically merged the datatype maps. + * TODO: should not be required with the proper extensions to the CommonReader base + */ +struct LNameJoinOp2 +{ + void operator() (tl::interval_map &a, const tl::interval_map &b) + { + LNameJoinOp1 op1; + a.add (b.begin (), b.end (), op1); + } +}; + +void +Reader::read_layers (stream::library::ViewSpec::Reader view_specs) +{ + size_t index = 0; + auto layer_entries = view_specs.getLayerTable ().getLayerEntries (); + for (auto l = layer_entries.begin (); l != layer_entries.end (); ++l, ++index) { + + db::LayerProperties lp; + auto ln = l->getLayerNumbers (); + if (ln.size () == 1) { + lp = db::LayerProperties (ln[0], 0); + } else if (ln.size () >= 2) { + lp = db::LayerProperties (ln[0], ln[1]); + } + + lp.name = l->getName (); + + auto ps = purpose_string (l->getPurpose ()); + if (! ps.empty ()) { + // In case of a non-DRAWING Purpose, generate a named layer adding the purpose to + // the layer string + lp = db::LayerProperties (lp.to_string () + "." + ps); + } + + // TODO: Can't handle purely named layers in the current CommonReader implementation -> extend CommonReader to accept named layers + if (! lp.is_named ()) { + + if (! lp.name.empty ()) { + + // add name to the layer name map + // TODO: should be easier with a better API + tl::interval_map dt_map; + LNameJoinOp1 op1; + dt_map.add (lp.datatype, lp.datatype + 1, lp.name, op1); + LNameJoinOp2 op2; + layer_names ().add (lp.layer, lp.layer + 1, dt_map, op2); + + } + + auto li = open_dl (*mp_layout, db::LDPair (lp.layer, lp.datatype)); + if (li.first) { + m_layer_id_map.insert (std::make_pair (index, li.second)); + } + + } else { + warn (tl::sprintf (tl::to_string (tr ("Purely named layers (here: '%s') cannot be read currently")), lp.name)); + } + + } +} + +/** + * @brief Creates a KLayout variant from a stream::variant::Variant + * + * As a speciality, the "OBJECT" type allows using KLayout's + * string convention to represent KLayout objects. This allows serialization + * of certain types such as boxes or polygons, but basically bears the risk + * of incompatibilities. + */ +tl::Variant +Reader::make_variant (stream::variant::Variant::Value::Reader variant) +{ + switch (variant.which ()) { + case stream::variant::Variant::Value::NIL: + return tl::Variant (); + case stream::variant::Variant::Value::BOOL: + return tl::Variant (variant.getBool ()); + case stream::variant::Variant::Value::DOUBLE: + return tl::Variant (variant.getDouble ()); + case stream::variant::Variant::Value::UINT64: + return tl::Variant (variant.getUint64 ()); + case stream::variant::Variant::Value::INT64: + return tl::Variant (variant.getInt64 ()); + case stream::variant::Variant::Value::LIST: + { + tl::Variant var_list = tl::Variant::empty_list (); + auto list = variant.getList (); + for (auto l = list.begin (); l != list.end (); ++l) { + var_list.push (make_variant (l->getValue ())); + } + return var_list; + } + case stream::variant::Variant::Value::ARRAY: + { + tl::Variant var_array = tl::Variant::empty_array (); + auto array = variant.getArray (); + for (auto l = array.begin (); l != array.end (); ++l) { + var_array.insert (make_variant (l->getKey ().getValue ()), make_variant (l->getValue ().getValue ())); + } + return var_array; + } + case stream::variant::Variant::Value::OBJECT: + { + std::string str = variant.getObject (); + tl::Extractor ex (str.c_str ()); + tl::Variant var; + if (ex.test ("klayout") && ex.test (":")) { + try { + ex.read (var); + } catch (tl::Exception &ex) { + warn (tl::sprintf (tl::to_string (tr ("Error extracting object string from variant ('%s'): %s")), + str, ex.msg ())); + } + } + return var; + } + case stream::variant::Variant::Value::TEXT: + return tl::Variant (std::string (variant.getText ())); + default: + return tl::Variant (); + } +} + +/** + * @brief Reads meta information from the stream::propertySet::PropertySet + * + * This method will read the meta information from the given PropertySet object + * and attach it to the given cell (if cell != 0) or the layout (if cell == 0). + * + * Meta information is a mechanism to attach additional, rich key/value + * pairs to cells or the layout. Contrary to properties, meta information + * does not need to follow conventions. Also properties are available down + * to shape and instance level, while meta information isn't. + * + * Meta information can be used for example to attach blobs to the layout. + * Meta information is supposed to be generated, maintained and consumed + * by a particular system in it's own specific ways and to be considered + * opaque or optional by other systems. + * + * Properties on the other hand can be carried through other file formats + * such as GDS and OASIS, provided they follow some conventions (e.g. + * integer keys only for GDS). + */ +void +Reader::make_meta_data (const db::Cell *cell, stream::metaData::MetaData::Reader meta_data) +{ + auto entries = meta_data.getEntries (); + for (auto e = entries.begin (); e != entries.end (); ++e) { + + std::string name = e->getName (); + + db::MetaInfo meta_info; + meta_info.persisted = true; + meta_info.value = make_variant (e->getValue ().getValue ()); + meta_info.description = e->getDescription (); + + if (cell) { + mp_layout->add_meta_info (cell->cell_index (), name, meta_info); + } else { + mp_layout->add_meta_info (name, meta_info); + } + + } +} + +/** + * @brief Extract cell parameters from stream::library::CellParameters + * + * This method takes cell parameters and turns them into a map of + * parameter names vs. values. The values are variants. + */ +std::map +Reader::make_pcell_parameters (stream::library::CellParameters::Reader cell_parameters) +{ + std::map parameters; + + auto values = cell_parameters.getValues (); + for (auto v = values.begin (); v != values.end (); ++v) { + std::string name = db::property_name (get_property_name_id_by_id (v->getNameId ())).to_string (); + auto value = make_variant (v->getValue ().getValue ()); + parameters.insert (std::make_pair (name, value)); + } + + return parameters; +} + +/** + * @brief Creates the cells from the cell specification table + * + * This method is called inside "read_library". It will read + * every cell in the order defined by "library::CellSpecsTable" + * and create the corresponding KLayout cell. + * + * PCell and library cell resolution also happens here. + * Note that in order to properly restore a cell "alife", + * the corresponding libraries have to be installed. If + * a cell is not found in the libraries, a "cold proxy" + * (aka "defunct cell") is created. + */ +void +Reader::read_cells (stream::library::Library::Reader library) +{ + m_cells.clear (); + + size_t index = 0; + auto cell_specs = library.getCellSpecsTable ().getCellSpecs (); + for (auto l = cell_specs.begin (); l != cell_specs.end (); ++l, ++index) { + + std::string cell_name = l->getName (); + + // Let CommonReader handle the id to cell index translation + db::cell_index_type cell_index = make_cell (*mp_layout, index); + m_cells.push_back (std::make_pair (cell_index, cell_name)); + + rename_cell (*mp_layout, index, cell_name); + + db::Cell *cell = &mp_layout->cell (cell_index); + + std::string library_name = get_library_name_by_id (l->getLibraryRefId ()); + if (! library_name.empty ()) { + + std::string library_cell_name = l->getLibraryCellName (); + if (library_cell_name.empty ()) { + // Fallback to the actual cell name if no library cell name is given + library_cell_name = cell_name; + } + + db::LayoutOrCellContextInfo context_info; + + // NOTE: it is assumed that PCells define the "parameters" field and + // non-pcells don't. + if (l->hasParameters ()) { + auto pcell_param = make_pcell_parameters (l->getParameters ()); + context_info.pcell_name = library_cell_name; + context_info.pcell_parameters = pcell_param; + } else { + context_info.cell_name = library_cell_name; + } + + context_info.lib_name = library_name; + + db::CommonReaderLayerMapping layer_mapping (this, mp_layout); + mp_layout->recover_proxy_as (cell_index, context_info, &layer_mapping); + + cell = &mp_layout->cell (cell_index); + + } + + cell->prop_id (get_properties_id_by_id (l->getPropertySetId ())); + + } +} + +/** + * @brief Reads the "library::LibraryRefs" section + * + * This method will set up the library ID to name tables. + * Only after executing this method you can call "get_library_name_by_id" + * to get the library name for a library Id. + */ +void +Reader::read_library_refs (stream::library::Library::Reader library) +{ + auto libraries = library.getLibraryRefs ().getRefs (); + size_t index = 1; + for (auto l = libraries.begin (); l != libraries.end (); ++l, ++index) { + m_library_names_by_id.insert (std::make_pair (index, l->getLibraryName ())); + } +} + +/** + * @brief Reads the "library::PropertyNamesTable" and "library::PropertiesTable" sections + * + * This method will set up the property tables: one for translating a + * property name Id into a name and one for translating the property Id + * into a property set (basically an alias for a dictionary of property + * names to value). + * + * Only after executing this method you can call "get_property_name_id_by_id" + * to get the property name for a property name Id or "get_properties_id_by_id" + * to get the KLayout properties Id for a LStream property Id. + */ +void +Reader::read_properties (stream::library::Library::Reader library) +{ + auto property_names = library.getPropertyNamesTable ().getNames (); + + auto property_namespaces = library.getPropertyNamesTable ().getNamespaces (); + std::vector ns; + for (auto n = property_namespaces.begin (); n != property_namespaces.end (); ++n) { + ns.push_back (*n); + } + + for (auto n = property_names.begin (); n != property_names.end (); ++n) { + + size_t ns_id = n->getNamespaceId (); + + tl::Variant pn; + if (ns_id > 0) { + // Account for the namespace by building a prefixed string ("namespace:name"). In other words: namespaced + // names should be strings. + // TODO: introduce a namespace concept in KLayout's property name system + tl_assert (ns_id <= ns.size ()); + pn = ns [ns_id - 1] + ":" + make_variant (n->getName ().getValue ()).to_string (); + } else { + pn = make_variant (n->getName ().getValue ()); + } + + m_property_name_id_map.insert (std::make_pair (n - property_names.begin (), db::property_names_id (pn))); + + } + + auto properties = library.getPropertiesTable ().getPropertySets (); + for (auto p = properties.begin (); p != properties.end (); ++p) { + + auto property_set = p->getProperties (); + db::PropertiesSet ps; + for (auto pp = property_set.begin (); pp != property_set.end (); ++pp) { + auto name_id = get_property_name_id_by_id (pp->getNameId ()); + ps.insert (name_id, make_variant (pp->getValue ().getValue ())); + } + + m_properties_id_map.insert (std::make_pair (p - properties.begin () + 1, db::properties_id (ps))); + + } +} + +/** + * @brief Reads the text string table from library::TextStringsTable + * + * The text strings table associates Ids with strings. This method + * is called during reading the library. + * + * Only after executing this method you can use "get_string_by_id" + * to obtain the string reference for a text string Id. + */ +void +Reader::read_text_strings (stream::library::Library::Reader library) +{ + auto text_strings = library.getTextStringsTable ().getTextStrings (); + for (auto t = text_strings.begin (); t != text_strings.end (); ++t) { + + const db::StringRef *string_ref = db::StringRepository::instance ()->create_string_ref (); + db::StringRepository::instance ()->change_string_ref (string_ref, *t); + + m_text_strings_by_id.insert (std::make_pair (uint64_t (t - text_strings.begin ()), string_ref)); + + } +} + +/** + * @brief Reads the cell message for a given cell + * + * The reader will call this method to extract cell messages from + * the stream after the library was processed. + * + * This method will not only read the cell message, but also consume + * the following cell view messages. + */ +void +Reader::read_cell (db::cell_index_type cell_index, kj::BufferedInputStream &is) +{ + yield_progress (); + capnp::PackedMessageReader message (is); + stream::cell::Cell::Reader cell = message.getRoot (); + + bool has_layout_view = false; + + auto views = cell.getViewIds (); + for (auto v = views.begin (); v != views.end (); ++v) { + if (*v == m_layout_view_id) { + read_layout_view (cell_index, is); + has_layout_view = true; + } else if (*v == m_meta_data_view_id) { + read_meta_data_view (cell_index, is); + } else { + // skip other views + yield_progress (); + capnp::PackedMessageReader skipped_message (is); + } + } + + if (! has_layout_view) { + mp_layout->cell (cell_index).set_ghost_cell (true); + } +} + +/** + * @brief "make_object" overloads: make a db::Vector from a stream::geometry::Vector + */ +db::Vector +Reader::make_object (stream::geometry::Vector::Reader reader) +{ + return make_vector (reader); +} + +/** + * @brief "make_object" overloads: make a db::Point from a stream::geometry::Point + */ +db::Point +Reader::make_object (stream::geometry::Point::Reader reader) +{ + return make_point (reader); +} + +/** + * @brief "make_object" overloads: make a db::Box from a stream::geometry::Box + */ +db::Box +Reader::make_object (stream::geometry::Box::Reader reader) +{ + db::Point p1 = make_point (reader.getP1 ()); + db::Point p2 = p1 + make_vector (reader.getDelta ()); + if (p2.x () < p1.x ()) { + return db::Box (); + } else { + return db::Box (p1, p2); + } +} + +/** + * @brief "make_object" overloads: make a db::Edge from a stream::geometry::Edge + */ +db::Edge +Reader::make_object (stream::geometry::Edge::Reader reader) +{ + db::Point p1 = make_point (reader.getP1 ()); + db::Point p2 = p1 + make_vector (reader.getDelta ()); + return db::Edge (p1, p2); +} + +/** + * @brief "make_object" overloads: make a db::EdgePair from a stream::geometry::EdgePair + */ +db::EdgePair +Reader::make_object (stream::geometry::EdgePair::Reader reader) +{ + db::Edge e1 = make_object (reader.getE1 ()); + db::Edge e2 = make_object (reader.getE2 ()); + return db::EdgePair (e1, e2); +} + +/** + * @brief "make_object" overloads: make a db::SimplePolygonRef from a stream::geometry::SimplePolygon + * + * Note: db::SimplePolygonRef is choosen over db::SimplePolygon for compactness + * of the database. + */ +db::SimplePolygonRef +Reader::make_object (stream::geometry::SimplePolygon::Reader reader) +{ + std::vector contour; + make_contour (contour, reader.getHull ()); + + db::SimplePolygon polygon; + polygon.assign_hull (contour.begin (), contour.end (), false, false); + + return db::SimplePolygonRef (polygon, mp_layout->shape_repository ()); +} + +/** + * @brief "make_object" overloads: make a db::PolygonRef from a stream::geometry::Polygon + * + * Note: db::PolygonRef is choosen over db::Polygon for compactness + * of the database. + */ +db::PolygonRef +Reader::make_object (stream::geometry::Polygon::Reader reader) +{ + std::vector contour; + make_contour (contour, reader.getHull ()); + + db::Polygon polygon; + polygon.assign_hull (contour.begin (), contour.end (), false, false); + + auto holes = reader.getHoles (); + polygon.reserve_holes (holes.size ()); + for (auto h = holes.begin (); h != holes.end (); ++h) { + make_contour (contour, *h); + polygon.insert_hole (contour.begin (), contour.end (), false, false); + } + + return db::PolygonRef (polygon, mp_layout->shape_repository ()); +} + +/** + * @brief "make_object" overloads: make a db::PathRef from a stream::geometry::Path + * + * Note: db::PathRef is choosen over db::Path for compactness + * of the database. + */ +db::PathRef +Reader::make_object (stream::geometry::Path::Reader reader) +{ + std::vector contour; + make_contour (contour, reader.getSpine ()); + + db::Coord hw = cast_to_coord (reader.getHalfWidth ()); + db::Coord bgn_ext = 0, end_ext = 0; + bool round = false; + + if (reader.getExtensionType () == stream::geometry::Path::ExtensionType::FLUSH) { + // okay already + } else if (reader.getExtensionType () == stream::geometry::Path::ExtensionType::SQUARE) { + bgn_ext = end_ext = hw; + } else if (reader.getExtensionType () == stream::geometry::Path::ExtensionType::ROUND) { + bgn_ext = end_ext = hw; + round = true; + } else if (reader.getExtensionType () == stream::geometry::Path::ExtensionType::VARIABLE) { + bgn_ext = cast_to_coord (reader.getBeginExtension ()); + end_ext = cast_to_coord (reader.getEndExtension ()); + } + + return db::PathRef (db::Path (contour.begin (), contour.end (), 2 * hw, bgn_ext, end_ext, round), mp_layout->shape_repository ()); +} + +/** + * @brief "make_object" overloads: make a db::Text from a stream::geometry::Text + * + * Note: the texts use StringRef string references for compactness of the database. + */ +db::Text +Reader::make_object (stream::geometry::Label::Reader reader) +{ + unsigned int orientation = make_fixpoint_trans (reader.getOrientation ()); + db::Vector pos = make_point (reader.getPosition ()) - db::Point (); + db::Coord size = cast_to_coord (reader.getSize ()); + const db::StringRef *string = get_string_by_id (reader.getStringId ()); + + db::HAlign halign = db::HAlignLeft; + switch (reader.getHorizontalAlign ()) { + case stream::geometry::Label::HAlignment::CENTER: + halign = db::HAlignCenter; + break; + case stream::geometry::Label::HAlignment::LEFT: + halign = db::HAlignLeft; + break; + case stream::geometry::Label::HAlignment::RIGHT: + halign = db::HAlignRight; + break; + } + + db::VAlign valign = db::VAlignBottom; + switch (reader.getVerticalAlign ()) { + case stream::geometry::Label::VAlignment::CENTER: + valign = db::VAlignCenter; + break; + case stream::geometry::Label::VAlignment::BOTTOM: + valign = db::VAlignBottom; + break; + case stream::geometry::Label::VAlignment::TOP: + valign = db::VAlignTop; + break; + } + + return db::Text (string, db::Trans (orientation, pos), size, db::Font::DefaultFont, halign, valign); +} + +/** + * @brief Creates a single cell reference from the given cell index, property Id and transformation + * + * The new instance is inserted into the current cell. + * + * @param of_cell The cell to instantiate + * @param prop_id The (KLayout) property Id for the properties to attach to the cell instance + * @param ct The cell transformation + */ +void +Reader::make_single_cell_instance (db::cell_index_type of_cell, db::properties_id_type prop_id, const db::ICplxTrans &ct) +{ + db::CellInstArray ca; + + if (ct.is_complex ()) { + ca = db::CellInstArray (db::CellInst (of_cell), ct, mp_layout->array_repository ()); + } else { + ca = db::CellInstArray (db::CellInst (of_cell), db::Trans (ct)); + } + + if (prop_id == 0) { + mp_cell->insert (ca); + } else { + mp_cell->insert (db::CellInstArrayWithProperties (ca, prop_id)); + } +} + +/** + * @brief Creates an array cell reference from the given cell index, property Id, repetition and transformation + * + * The new instance is inserted into the current cell. + * + * Enumerated cell instances are resolved in non-editable mode and kept in editable mode. + * Regular arrays are always maintained. + * + * @param of_cell The cell to instantiate + * @param prop_id The (KLayout) property Id for the properties to attach to the cell instance + * @param repetition The LStream repetition of the cell + * @param ct The cell transformation + */ +void +Reader::make_cell_instance (db::cell_index_type of_cell, db::properties_id_type prop_id, stream::repetition::Repetition::Reader repetition, const db::ICplxTrans &ct) +{ + switch (repetition.getTypes ().which ()) { + case stream::repetition::Repetition::Types::ENUMERATED: + { + if (! mp_layout->is_editable ()) { + + db::CellInstArray ca; + + if (ct.is_complex ()) { + db::CellInstArray::iterated_complex_array_type array (ct.rcos (), ct.mag ()); + make_iterated_array (repetition, array); + ca = db::CellInstArray (db::CellInst (of_cell), db::Trans (ct), mp_layout->array_repository ().insert (array)); + } else { + db::CellInstArray::iterated_array_type array; + make_iterated_array (repetition, array); + ca = db::CellInstArray (db::CellInst (of_cell), db::Trans (ct), mp_layout->array_repository ().insert (array)); + } + + if (prop_id == 0) { + mp_cell->insert (ca); + } else { + mp_cell->insert (db::CellInstArrayWithProperties (ca, prop_id)); + } + + } else { + + // resolve iterated arrays in non-editable mode + + std::vector vectors; + make_vectors (repetition, vectors); + + for (auto v = vectors.begin (); v != vectors.end (); ++v) { + make_single_cell_instance (of_cell, prop_id, db::ICplxTrans (*v) * ct); + } + + } + } + break; + + case stream::repetition::Repetition::Types::REGULAR: + case stream::repetition::Repetition::Types::REGULAR_ORTHO: + { + db::CellInstArray ca; + + db::Vector a, b; + unsigned long na = 0, nb = 0; + get_regular_array (repetition, a, b, na, nb); + + if (ct.is_complex ()) { + ca = db::CellInstArray (db::CellInst (of_cell), ct, mp_layout->array_repository (), a, b, na, nb); + } else { + ca = db::CellInstArray (db::CellInst (of_cell), db::Trans (ct), mp_layout->array_repository (), a, b, na, nb); + } + + if (prop_id == 0) { + mp_cell->insert (ca); + } else { + mp_cell->insert (db::CellInstArrayWithProperties (ca, prop_id)); + } + } + break; + + case stream::repetition::Repetition::Types::SINGLE: + make_single_cell_instance (of_cell, prop_id, ct); + break; + + default: + break; + } +} + +/** + * @brief Creates array objects in "Ref" mode + * + * This method takes an object (e.g. Box etc.), a layer index and a + * KLayout property Id and a repetition specification. + * + * In editable mode, it will explode the repetition into a number of + * single shapes. + * + * In non-editable mode, it will create respective shape arrays. + * The shape arrays are of db::array type. + * These are the valid types for simple shapes such as edges and boxes. + * + * The objects are placed inside the current cell at the layer given + * by "li". + * + * @param li The layer index where the shapes are to be placed + * @param prop_id The (KLayout) property Id for the properties to attach to the shapes + * @param object The basic object to place (times the repetition) + * @param repetition The LStream repetition of the cell + */ +template +void +Reader::make_object_array_ref (unsigned int li, db::properties_id_type prop_id, const Object &object, stream::repetition::Repetition::Reader repetition) +{ + if (mp_layout->is_editable ()) { + make_object_array_explode (li, prop_id, object, repetition); + return; + } + + switch (repetition.getTypes ().which ()) { + case stream::repetition::Repetition::Types::ENUMERATED: + { + typedef db::array array_type; + typename array_type::iterated_array_type array; + make_iterated_array (repetition, array); + + if (prop_id == 0) { + mp_cell->shapes (li).insert (array_type (object, db::UnitTrans (), mp_layout->array_repository ().insert (array))); + } else { + mp_cell->shapes (li).insert (db::object_with_properties (array_type (object, db::UnitTrans (), mp_layout->array_repository ().insert (array)), prop_id)); + } + } + break; + + case stream::repetition::Repetition::Types::REGULAR: + case stream::repetition::Repetition::Types::REGULAR_ORTHO: + { + db::Vector a, b; + unsigned long na = 0, nb = 0; + get_regular_array (repetition, a, b, na, nb); + + db::array array (object, db::UnitTrans (), mp_layout->array_repository (), a, b, na, nb); + + if (prop_id == 0) { + mp_cell->shapes (li).insert (array); + } else { + mp_cell->shapes (li).insert (db::object_with_properties > (array, prop_id)); + } + } + break; + + case stream::repetition::Repetition::Types::SINGLE: + mp_cell->shapes (li).insert (object); + break; + + default: + break; + } +} + +/** + * @brief Creates array objects in "Ref to Ptr" mode + * + * This method takes an "ref" type object (e.g. PolygonRef etc.), a layer index and a + * KLayout property Id and a repetition specification. + * + * In editable mode, it will explode the repetition into a number of + * single shapes. + * + * In non-editable mode, it will create respective shape arrays. + * The shape arrays are of db::array type. + * The object will be converted to a "Ptr" type given by the "ObjectPtr" + * template argument. For example, the corresponding "Ptr" type for + * "PolygonRef" is "PolygonPtr". Eventually this is a pointer to a polygon + * without the displacement implied by "PolygonRef". This translation + * is implied by the array's "front" object. + * + * The objects are placed inside the current cell at the layer given + * by "li". + * + * @param li The layer index where the shapes are to be placed + * @param prop_id The (KLayout) property Id for the properties to attach to the shapes + * @param object The basic object to place (times the repetition) + * @param repetition The LStream repetition of the cell + */ +template +void +Reader::make_object_array_ptr (unsigned int li, db::properties_id_type prop_id, const Object &object, stream::repetition::Repetition::Reader repetition) +{ + if (mp_layout->is_editable ()) { + make_object_array_explode (li, prop_id, object, repetition); + return; + } + + switch (repetition.getTypes ().which ()) { + case stream::repetition::Repetition::Types::ENUMERATED: + { + typedef db::array array_type; + typename array_type::iterated_array_type array; + make_iterated_array (repetition, array); + + ObjectPtr ptr (object.ptr (), db::UnitTrans ()); + + if (prop_id == 0) { + mp_cell->shapes (li).insert (array_type (ptr, object.trans (), mp_layout->array_repository ().insert (array))); + } else { + mp_cell->shapes (li).insert (db::object_with_properties (array_type (ptr, object.trans (), mp_layout->array_repository ().insert (array)), prop_id)); + } + } + break; + + case stream::repetition::Repetition::Types::REGULAR: + case stream::repetition::Repetition::Types::REGULAR_ORTHO: + { + db::Vector a, b; + unsigned long na = 0, nb = 0; + get_regular_array (repetition, a, b, na, nb); + + ObjectPtr ptr (object.ptr (), db::UnitTrans ()); + db::array array (ptr, object.trans (), mp_layout->array_repository (), a, b, na, nb); + + if (prop_id == 0) { + mp_cell->shapes (li).insert (array); + } else { + mp_cell->shapes (li).insert (db::object_with_properties > (array, prop_id)); + } + } + break; + + case stream::repetition::Repetition::Types::SINGLE: + mp_cell->shapes (li).insert (object); + break; + + default: + break; + } +} + +/** + * @brief Creates array objects in "explode" mode + * + * This method takes an object (e.g. db::Box, db::Polygon), a layer index and a + * KLayout property Id and a repetition specification. + * + * It will explode the repetition into a number of single shapes and place + * them inside the current cell on the given layer. + * + * @param li The layer index where the shapes are to be placed + * @param prop_id The (KLayout) property Id for the properties to attach to the shapes + * @param object The basic object to place (times the repetition) + * @param repetition The LStream repetition of the cell + */ +template +void +Reader::make_object_array_explode (unsigned int li, db::properties_id_type prop_id, const Object &object, stream::repetition::Repetition::Reader repetition) +{ + switch (repetition.getTypes ().which ()) { + case stream::repetition::Repetition::Types::ENUMERATED: + { + std::vector vectors; + make_vectors (repetition, vectors); + + for (auto v = vectors.begin (); v != vectors.end (); ++v) { + + Object moved_object (object); + moved_object.transform (db::Disp (*v)); + + if (prop_id == 0) { + mp_cell->shapes (li).insert (moved_object); + } else { + mp_cell->shapes (li).insert (db::object_with_properties (moved_object, prop_id)); + } + + } + } + break; + + case stream::repetition::Repetition::Types::REGULAR: + case stream::repetition::Repetition::Types::REGULAR_ORTHO: + { + db::Vector a, b; + unsigned long na = 0, nb = 0; + get_regular_array (repetition, a, b, na, nb); + + na = std::max ((unsigned long) 1, na); + nb = std::max ((unsigned long) 1, nb); + + db::Vector da; + for (unsigned long ia = 0; ia < na; ++ia, da += a) { + + db::Vector db; + for (unsigned long ib = 0; ib < nb; ++ib, db += b) { + + Object moved_object (object); + moved_object.transform (db::Disp (da + db)); + + if (prop_id == 0) { + mp_cell->shapes (li).insert (moved_object); + } else { + mp_cell->shapes (li).insert (db::object_with_properties (moved_object, prop_id)); + } + + } + + } + + } + break; + + case stream::repetition::Repetition::Types::SINGLE: + if (prop_id == 0) { + mp_cell->shapes (li).insert (object); + } else { + mp_cell->shapes (li).insert (db::object_with_properties (object, prop_id)); + } + break; + + default: + break; + } +} + +/** + * @brief Overload: creates an object array for SimplePolygonRef objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::SimplePolygonRef &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_ptr (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for PolygonRef objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::PolygonRef &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_ptr (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for PathRef objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::PathRef &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_ptr (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for Box objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Box &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_ref (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for Edge objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Edge &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_explode (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for EdgePair objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::EdgePair &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_explode (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for Point objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Point &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_explode (li, prop_id, object, repetition); +} + +/** + * @brief Overload: creates an object array for Text objects + */ +void +Reader::make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Text &object, stream::repetition::Repetition::Reader repetition) +{ + make_object_array_explode (li, prop_id, object, repetition); +} + +/** + * @brief Reads the instances for a layout view + * + * This method will take the given layout view (stream::layoutView::LayoutView) + * and produce the instances contained therein in the current cell. + * + * This method is called while reading the layout view. + */ +void +Reader::read_instances (stream::layoutView::LayoutView::Reader layout_view) +{ + auto instance_repetitions = layout_view.getInstanceRepetitions (); + auto instances = layout_view.getInstances (); + + auto basic = instances.getBasic (); + auto with_properties = instances.getWithProperties (); + auto arrays = instances.getArrays (); + auto arrays_with_properties = instances.getArraysWithProperties (); + + for (auto i = basic.begin (); i != basic.end (); ++i) { + auto of_cell = cell_for_instance (*mp_layout, i->getBasic ().getCellId ()); + make_single_cell_instance (of_cell, 0, make_transformation (i->getBasic ().getTransformation ())); + } + + for (auto i = with_properties.begin (); i != with_properties.end (); ++i) { + auto of_cell = cell_for_instance (*mp_layout, i->getBasic ().getCellId ()); + auto prop_id = get_properties_id_by_id (i->getPropertySetId ()); + make_single_cell_instance (of_cell, prop_id, make_transformation (i->getBasic ().getTransformation ())); + } + + for (auto i = arrays.begin (); i != arrays.end (); ++i) { + auto of_cell = cell_for_instance (*mp_layout, i->getBasic ().getCellId ()); + auto rep = i->getRepetitionId (); + if (rep == 0) { + make_single_cell_instance (of_cell, 0, make_transformation (i->getBasic ().getTransformation ())); + } else { + --rep; + tl_assert (rep < instance_repetitions.size ()); + make_cell_instance (of_cell, 0, instance_repetitions [rep], make_transformation (i->getBasic ().getTransformation ())); + } + } + + for (auto i = arrays_with_properties.begin (); i != arrays_with_properties.end (); ++i) { + auto of_cell = cell_for_instance (*mp_layout, i->getBasic ().getBasic ().getCellId ()); + auto prop_id = get_properties_id_by_id (i->getPropertySetId ()); + auto rep = i->getBasic ().getRepetitionId (); + if (rep == 0) { + make_single_cell_instance (of_cell, prop_id, make_transformation (i->getBasic ().getBasic ().getTransformation ())); + } else { + --rep; + tl_assert (rep < instance_repetitions.size ()); + make_cell_instance (of_cell, prop_id, instance_repetitions [rep], make_transformation (i->getBasic ().getBasic ().getTransformation ())); + } + } +} + +/** + * @brief Reads the shapes of a given kindf for a layout view + * + * This method will take the given shape container (stream::layoutView::ObjectContainerForType) + * and produce the shapes of "CPObject" type contained therein. The shapes will + * be placed on the given layer (by "li") in the current cell. + * + * The KLayout shape type is given by the "Object" template parameter. + * + * This method is called while reading the layout view. + * + * @param li The layer index where to produce the shapes in the current cell + * @param reader The shape container + * @param repetitions The repetition repository. This list is used to identify the repetition per shape. + */ +template +void +Reader::read_shapes (unsigned int li, typename stream::layoutView::ObjectContainerForType::Reader reader, capnp::List::Reader repetitions) +{ + tl_assert (mp_cell != 0); + + auto basic = reader.getBasic (); + auto with_properties = reader.getWithProperties (); + auto arrays = reader.getArrays (); + auto arrays_with_properties = reader.getArraysWithProperties (); + + for (auto i = basic.begin (); i != basic.end (); ++i) { + mp_cell->shapes (li).insert (make_object (i->getBasic ())); + } + + for (auto i = with_properties.begin (); i != with_properties.end (); ++i) { + auto prop_id = get_properties_id_by_id (i->getPropertySetId ()); + mp_cell->shapes (li).insert (db::object_with_properties (make_object (i->getBasic ()), prop_id)); + } + + for (auto i = arrays.begin (); i != arrays.end (); ++i) { + auto object = make_object (i->getBasic ()); + auto rep = i->getRepetitionId (); + if (rep == 0) { + mp_cell->shapes (li).insert (object); + } else { + --rep; + tl_assert (rep < repetitions.size ()); + make_object_array (li, 0, object, repetitions [rep]); + } + } + + for (auto i = arrays_with_properties.begin (); i != arrays_with_properties.end (); ++i) { + auto object = make_object (i->getBasic ().getBasic ()); + auto prop_id = get_properties_id_by_id (i->getPropertySetId ()); + auto rep = i->getBasic ().getRepetitionId (); + if (rep == 0) { + mp_cell->shapes (li).insert (db::object_with_properties (object, prop_id)); + } else { + --rep; + tl_assert (rep < repetitions.size ()); + make_object_array (li, prop_id, object, repetitions [rep]); + } + } +} + +/** + * @brief Reads a layer from the given stream::layoutView::Layer + * + * The method is called while processing the layout view message. + * It is called per layer inside the layout view. It will extract + * the various shape types and place them in the specified layer. + */ +void +Reader::read_layer (stream::layoutView::Layer::Reader reader) +{ + auto li = get_layer_by_id (reader.getLayerId ()); + auto repetitions = reader.getRepetitions (); + + read_shapes (li, reader.getBoxes (), repetitions); + read_shapes (li, reader.getEdges (), repetitions); + read_shapes (li, reader.getEdgePairs (), repetitions); + read_shapes (li, reader.getSimplePolygons (), repetitions); + read_shapes (li, reader.getPolygons (), repetitions); + read_shapes (li, reader.getPoints (), repetitions); + read_shapes (li, reader.getLabels (), repetitions); + read_shapes (li, reader.getPaths (), repetitions); +} + +/** + * @brief Processes the layout view message + * + * This method reads the instances and shapes contained in this message + * into the cell given by "cell_index". + * + * While this method is executed the current cell is set. + */ +void +Reader::read_layout_view (db::cell_index_type cell_index, kj::BufferedInputStream &is) +{ + mp_cell = &mp_layout->cell (cell_index); + + // NOTE: maybe that is not wise, but these message can become really large ... + capnp::ReaderOptions options; + options.traversalLimitInWords = std::numeric_limits::max (); + + yield_progress (); + capnp::PackedMessageReader message (is, options); + stream::layoutView::LayoutView::Reader layout_view = message.getRoot (); + + if (mp_cell->is_proxy ()) { + // Do not read proxies (library cells, pcells) as they are restored already + // and are connected to some source. + // NOTE: this is a decision to "always update" which in actually should be + // configurable. To "use data from stream", we should not update the cell + // to proxy data and use the stream data instead. + return; + } + + // store the bounding box information if requested + if (! m_bbox_meta_data_key.empty ()) { + auto bbox = make_object (layout_view.getBoundingBox ()); + mp_layout->add_meta_info (cell_index, m_bbox_meta_data_key, db::MetaInfo (std::string (), bbox)); + } + + read_instances (layout_view); + + auto layers = layout_view.getLayers (); + for (auto l = layers.begin (); l != layers.end (); ++l) { + read_layer (*l); + } + + mp_cell = 0; +} + +/** + * @brief Processes the meta data view message + * + * This method reads the meta data information for a cell. + */ +void +Reader::read_meta_data_view (db::cell_index_type cell_index, kj::BufferedInputStream &is) +{ + mp_cell = &mp_layout->cell (cell_index); + + yield_progress (); + + capnp::PackedMessageReader message (is); + stream::metaDataView::MetaDataView::Reader meta_data = message.getRoot (); + + make_meta_data (&mp_layout->cell (cell_index), meta_data.getData ()); +} + +/** + * @brief This method is called "frequently" to yield the progress + */ +void +Reader::yield_progress () +{ + m_progress.set (m_stream.position ()); +} + +/** + * @brief Reader the global header + * + * This method will also decide which library to parse if + * multiple libraries are present. + * + * If a single layout-type library is present, it will read that + * one. Otherwise it will read the first unnamed one or the + * first one if there are no unnamed libraries. + * + * It will set "m_library_index" to the index of the library + * we want to read. + */ +void +Reader::read_header (kj::BufferedInputStream &is) +{ + yield_progress (); + capnp::PackedMessageReader message (is); + + stream::header::Header::Reader header = message.getRoot (); + + // fetch technology + + std::string technology_name = header.getTechnology (); + if (! technology_name.empty ()) { + // TODO: need more that this? + mp_layout->set_technology_name (technology_name); + } + + // decide for the library to read + + int library_index = -1; + m_libname.clear (); + + auto libraries = header.getLibraries (); + for (auto l = libraries.begin (); l != libraries.end () && library_index < 0; ++l) { + if (l->getType () == "layout" && l->getName () == "") { + library_index = (l - libraries.begin ()); + } + } + + for (auto l = libraries.begin (); l != libraries.end () && library_index < 0; ++l) { + if (l->getType () == "layout") { + library_index = (l - libraries.begin ()); + m_libname = l->getName (); + } + } + + if (library_index < 0) { + std::set types; + for (auto l = libraries.begin (); l != libraries.end (); ++l) { + if (l->getType ().size () > 0) { + types.insert (l->getType ()); + } + } + std::string types_str = tl::join (types.begin (), types.end (), ", "); + if (types_str.empty ()) { + error (tl::to_string (tr ("An LStream needs to have a library of type 'layout' to be loaded into KLayout - this stream does not have any"))); + } else { + error (tl::to_string (tr ("An LStream needs to have a library of type 'layout' to be loaded into KLayout - present types are: ")) + types_str); + } + } + + m_library_index = size_t (library_index); +} + +/** + * @brief Skips a library, including cells and cell views + */ +void +Reader::skip_library (kj::BufferedInputStream &is) +{ + yield_progress (); + capnp::PackedMessageReader message (is); + stream::library::Library::Reader library = message.getRoot (); + + size_t cells = library.getCellSpecsTable ().getCellSpecs ().size (); + + for (size_t i = 0; i < cells; ++i) { + + // fetch the cell message to extract the number of views + yield_progress (); + capnp::PackedMessageReader cell_message (is); + stream::cell::Cell::Reader cell = message.getRoot (); + size_t views = cell.getViewIds ().size (); + + for (size_t i = 0; i < views; ++i) { + // skip the views + yield_progress (); + capnp::PackedMessageReader consumed (is); + } + + } +} + +/** + * @brief Reads the library message + * + * Processes the various tables contained inside the library. + */ +void +Reader::read_library (kj::BufferedInputStream &is) +{ + yield_progress (); + capnp::PackedMessageReader message (is); + + stream::library::Library::Reader library = message.getRoot (); + + // Basic properties + + // Obtain the layout and (optional) meta data view Id + + m_layout_view_id = std::numeric_limits::max (); + m_meta_data_view_id = std::numeric_limits::max (); + + auto views = library.getViewSpecsTable ().getViewSpecs (); + for (auto v = views.begin (); v != views.end (); ++v) { + if (v->getName () == "layout" && v->getClass () == "LayoutView") { + if (m_layout_view_id == std::numeric_limits::max ()) { + m_layout_view_id = (v - views.begin ()); + } + } else if (v->getName () == "metaData" && v->getClass () == "MetaDataView") { + if (m_meta_data_view_id == std::numeric_limits::max ()) { + m_meta_data_view_id = (v - views.begin ()); + } + } + } + + if (m_layout_view_id == std::numeric_limits::max ()) { + std::set view_strings; + for (auto v = views.begin (); v != views.end (); ++v) { + view_strings.insert (v->getName ()); + } + std::string views_str = tl::join (view_strings.begin (), view_strings.end (), ", "); + error (tl::to_string (tr ("There is no view called 'layout' with 'LayoutView' class - present views are: ")) + views_str); + } + + auto layout_view = views[m_layout_view_id]; + + // Read the tables we're interested in + + // "Properties" and "Libraries" need to be first as we have to provide properties and library names + read_properties (library); + read_library_refs (library); + + read_layers (layout_view); + read_cells (library); + read_text_strings (library); + + // Now as we have read the properties tables, we can set the global properties + + mp_layout->prop_id (get_properties_id_by_id (layout_view.getPropertySetId ())); + make_meta_data (0, layout_view.getMetaData ()); + + double resolution = layout_view.getResolution (); + if (resolution < 1e-10) { + error (tl::to_string (tr ("The resolution is an invalid value: ")) + tl::to_string (resolution)); + } + mp_layout->dbu (1.0 / resolution); +} + +/** + * @brief Gets the KLayout layer Id from a LStream layer Id + * + * This method can only be called after the library has been processed. + * It will assert if the LStream Id is not valid. + */ +unsigned int +Reader::get_layer_by_id (uint64_t id) const +{ + auto m = m_layer_id_map.find (id); + tl_assert (m != m_layer_id_map.end ()); + return m->second; +} + +/** + * @brief Gets the name of the library for a given LStream library Id + * + * This method can only be called after the library has been processed. + * It will assert if the LStream Id is not valid. + */ +std::string +Reader::get_library_name_by_id (uint64_t id) const +{ + if (id == 0) { + return std::string (); + } else { + auto m = m_library_names_by_id.find (id); + tl_assert (m != m_library_names_by_id.end ()); + return m->second; + } +} + +/** + * @brief Gets the KLayout property name Id for a given LStream property name Id + * + * This method can only be called after the library has been processed. + * It will assert if the LStream Id is not valid. + */ +db::property_names_id_type +Reader::get_property_name_id_by_id (uint64_t id) const +{ + auto m = m_property_name_id_map.find (id); + tl_assert (m != m_property_name_id_map.end ()); + return m->second; +} + +/** + * @brief Gets the KLayout property set Id for a given LStream property set Id + * + * This method can only be called after the library has been processed. + * It will assert if the LStream Id is not valid. + */ +db::properties_id_type +Reader::get_properties_id_by_id (uint64_t id) const +{ + if (id == 0) { + return 0; + } else { + auto m = m_properties_id_map.find (id); + tl_assert (m != m_properties_id_map.end ()); + return m->second; + } +} + +/** + * @brief Gets the db::StringRef (a text string proxy) for a given LStream text Id + * + * This method can only be called after the library has been processed. + * It will assert if the LStream Id is not valid. + */ +const db::StringRef * +Reader::get_string_by_id (uint64_t id) const +{ + auto m = m_text_strings_by_id.find (id); + tl_assert (m != m_text_strings_by_id.end ()); + return m->second; +} + +} diff --git a/src/plugins/streamers/lstream/db_plugin/lstrReader.h b/src/plugins/streamers/lstream/db_plugin/lstrReader.h new file mode 100644 index 000000000..1d4b0a968 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrReader.h @@ -0,0 +1,268 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef HDR_lstrReader +#define HDR_lstrReader + +#include "dbPluginCommon.h" +#include "dbLayout.h" +#include "dbCommonReader.h" +#include "dbStreamLayers.h" + +#include "library.capnp.h" +#include "repetition.capnp.h" +#include "layoutView.capnp.h" + +#include "tlException.h" +#include "tlProgress.h" +#include "tlInternational.h" +#include "tlProgress.h" +#include "tlString.h" +#include "tlStream.h" + +#include + +namespace kj +{ + class BufferedInputStream; +} + +namespace lstr +{ + +/** + * @brief A reimplementation of the kj::InputStream interface to provide KLayout streams for Cap'n'Proto + * + * Note: this implementation is not based on the buffered streams of KLayout + * which are not compatible with kj::BufferedInputStreamWrapper as of now. + * Instead we use the unterlying basic stream of KLayout which is pretty + * much compatible with kj. + */ +class InputStream + : public kj::InputStream +{ +public: + InputStream (tl::InputStream *is) + : mp_is (is), m_pos (is->pos ()), m_pos_before (is->pos ()) + { + // .. nothing yet .. + } + + virtual size_t tryRead (void *buffer, size_t /*min_bytes*/, size_t max_bytes) + { + size_t n = mp_is->base ()->read ((char *) buffer, max_bytes); + m_pos_before = m_pos; + m_pos += n; + return n; + } + + /* TODO: we don't have "skip" on the delegate right now. + virtual void skip (size_t bytes) + { + mp_is->base ()->skip (bytes); + } + */ + + /** + * @brief Resets the basic stream, so we can restart + */ + void reset () + { + mp_is->base ()->reset (); + m_pos_before = m_pos = 0; + } + + /** + * @brief Gets the position in the stream after the current chunk + */ + size_t position () + { + return m_pos; + } + + /** + * @brief Gets the position in the stream before the current chunk + */ + size_t position_before () + { + return m_pos_before; + } + +private: + tl::InputStream *mp_is; + size_t m_pos, m_pos_before; +}; + +/** + * @brief Generic base class of LStream reader exceptions + */ +class DB_PLUGIN_PUBLIC LStreamReaderException + : public db::ReaderException +{ +public: + LStreamReaderException (const std::string &msg, const std::string &cell, const std::string &source, const std::string &pos) + : db::ReaderException ( + cell.empty () ? + tl::sprintf (tl::to_string (tr ("%s, in file: %s (position %s)")), msg, source, pos) : + tl::sprintf (tl::to_string (tr ("%s (cell=%s), in file: %s (position %s)")), msg, cell, source, pos) + ) + { } +}; + +/** + * @brief The LStream format stream reader + */ +class DB_PLUGIN_PUBLIC Reader + : public db::CommonReader +{ +public: + /** + * @brief Construct a stream reader object + * + * @param s The stream delegate from which to read stream data from + */ + Reader (tl::InputStream &s); + + /** + * @brief Destructor + */ + ~Reader () noexcept; + + /** + * @brief Format + */ + virtual const char *format () const { return "LStream"; } + +protected: + /** + * @brief Implementation of the db::CommonReader interface + * + * This method will read the information from the stream + * passed in the constructor. + */ + virtual void do_read (db::Layout &layout); + + /** + * @brief Implementation of db::CommonReader InputStream + * + * This method is called to initialize the reader + * from the given options. + */ + virtual void init (const db::LoadLayoutOptions &options); + + /** + * @brief Issues an errors + */ + void error (const std::string &msg); + + /** + * @brief Issues a warning + * + * The warning level indicates the severity. + * A higher value indicates lower severity. + */ + void warn (const std::string &msg, int warn_level = 1); + + /** + * @brief Accessor method to the current cellname + */ + const std::string &cellname () const { return m_cellname; } + +private: + lstr::InputStream m_stream; + std::string m_source; + std::string m_bbox_meta_data_key; + tl::AbsoluteProgress m_progress; + size_t m_library_index; + std::string m_cellname; + std::string m_libname; + db::Cell *mp_cell; + db::Layout *mp_layout; + std::map m_layer_id_map; + std::map m_library_names_by_id; + std::map m_property_name_id_map; + std::map m_properties_id_map; + std::map m_text_strings_by_id; + uint64_t m_layout_view_id; + uint64_t m_meta_data_view_id; + std::vector > m_cells; + + void yield_progress (); + std::string position (); + void do_read_internal (db::Layout &layout); + void read_header (kj::BufferedInputStream &is); + void read_library (kj::BufferedInputStream &is); + void skip_library (kj::BufferedInputStream &is); + void read_cell (db::cell_index_type cell_index, kj::BufferedInputStream &is); + void make_single_cell_instance (db::cell_index_type of_cell, db::properties_id_type prop_id, const db::ICplxTrans &ct); + void make_cell_instance (db::cell_index_type of_cell, db::properties_id_type prop_id, stream::repetition::Repetition::Reader repetition, const db::ICplxTrans &ct); + void read_instances (stream::layoutView::LayoutView::Reader layout_view); + template + void read_shapes (unsigned int li, typename stream::layoutView::ObjectContainerForType::Reader reader, capnp::List::Reader repetitions); + void read_layer (stream::layoutView::Layer::Reader reader); + void read_layout_view (db::cell_index_type cell_index, kj::BufferedInputStream &is); + void read_meta_data_view (db::cell_index_type cell_index, kj::BufferedInputStream &is); + void read_layers (stream::library::ViewSpec::Reader view_specs); + tl::Variant make_variant (stream::variant::Variant::Value::Reader variant); + void make_meta_data(const db::Cell *cell, stream::metaData::MetaData::Reader property_set); + std::map make_pcell_parameters (stream::library::CellParameters::Reader cell_parameters); + void read_cells(stream::library::Library::Reader header); + void read_library_refs (stream::library::Library::Reader header); + void read_properties (stream::library::Library::Reader header); + void read_text_strings (stream::library::Library::Reader header); + unsigned int get_layer_by_id (uint64_t id) const; + std::string get_library_name_by_id (uint64_t id) const; + db::property_names_id_type get_property_name_id_by_id (uint64_t id) const; + db::properties_id_type get_properties_id_by_id (uint64_t id) const; + const db::StringRef *get_string_by_id (uint64_t id) const; + db::Vector make_object (stream::geometry::Vector::Reader reader); + db::Point make_object (stream::geometry::Point::Reader reader); + db::Box make_object (stream::geometry::Box::Reader reader); + db::Edge make_object (stream::geometry::Edge::Reader reader); + db::EdgePair make_object (stream::geometry::EdgePair::Reader reader); + db::SimplePolygonRef make_object (stream::geometry::SimplePolygon::Reader reader); + db::PolygonRef make_object (stream::geometry::Polygon::Reader reader); + db::PathRef make_object (stream::geometry::Path::Reader reader); + db::Text make_object (stream::geometry::Label::Reader reader); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::PolygonRef &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::SimplePolygonRef &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::PathRef &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::EdgePair &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Edge &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Point &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Text &object, stream::repetition::Repetition::Reader repetition); + void make_object_array (unsigned int li, db::properties_id_type prop_id, const db::Box &object, stream::repetition::Repetition::Reader repetition); + template + void make_object_array_ref (unsigned int li, db::properties_id_type prop_id, const Object &object, stream::repetition::Repetition::Reader repetition); + template + void make_object_array_ptr (unsigned int li, db::properties_id_type prop_id, const Object &object, stream::repetition::Repetition::Reader repetition); + template + void make_object_array_explode (unsigned int li, db::properties_id_type prop_id, const Object &object, stream::repetition::Repetition::Reader repetition); + + virtual void common_reader_error (const std::string &msg) { error (msg); } + virtual void common_reader_warn (const std::string &msg, int warn_level = 1) { warn (msg, warn_level); } +}; + +} + +#endif + diff --git a/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc b/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc new file mode 100644 index 000000000..6ff965c42 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrWriter.cc @@ -0,0 +1,1404 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrWriter.h" +#include "lstrPlugin.h" +#include "lstrCompressor.h" +#include "lstrCompressed.h" +#include "lstrFormat.h" + +#include "dbLibraryManager.h" +#include "dbLibraryProxy.h" +#include "dbLibrary.h" +#include "tlStream.h" +#include "tlAssert.h" +#include "tlException.h" +#include "tlEnv.h" + +#include "metaDataView.capnp.h" + +#include +#include + +// Enable to replicate the messages into separate files for dumping +// and inspection with "capnp decode". +// Env var: $KLAYOUT_LSTREAM_REPLICATE_MESSAGES +static bool s_replicate_messages = tl::app_flag ("lstream-replicate-messages"); + +namespace lstr +{ + +class OutputStream + : public kj::OutputStream +{ +public: + OutputStream (tl::OutputStream *os) + : mp_os (os) + { + // .. nothing yet .. + } + + virtual void write (const void* buffer, size_t size) + { + mp_os->put ((const char *) buffer, size); + } + +private: + tl::OutputStream *mp_os; +}; + +// ------------------------------------------------------------------ +// LStreamWriter implementation + +Writer::Writer () + : mp_stream (0), m_progress (tl::to_string (tr ("Writing LStream file")), 1), mp_layout (0) +{ + m_progress.set_format (tl::to_string (tr ("%.0f MB"))); + m_progress.set_unit (1024 * 1024); + + m_recompress = true; + m_compression_level = 2; + m_permissive = true; +} + +void +Writer::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayoutOptions &options) +{ + // TODO: this seems to be needed to properly enumerate the properties in "collect_property_ids" + layout.update (); + + auto lstr_options = options.get_options (); + m_permissive = lstr_options.permissive; + m_compression_level = lstr_options.compression_level; + m_recompress = lstr_options.recompress; + + double dbu = (options.dbu () == 0.0) ? layout.dbu () : options.dbu (); + double sf = options.scale_factor () * (layout.dbu () / dbu); + if (fabs (sf - 1.0) < 1e-9) { + // to avoid rounding problems, set to 1.0 exactly if possible. + sf = 1.0; + } + + // TODO: implement + if (sf != 1.0) { + throw tl::Exception (tl::to_string (tr ("Scaling is not supported in LStream writer currently"))); + } + + mp_stream = &stream; + m_options = options; + mp_layout = &layout; + m_cellname.clear (); + m_layout_view_id = -1; + m_meta_data_view_id = -1; + + m_layers_to_write.clear (); + +#if KLAYOUT_MAJOR_VERSION == 0 && (KLAYOUT_MINOR_VERSION < 30 || (KLAYOUT_MINOR_VERSION == 30 && KLAYOUT_TINY_VERSION < 5)) + { + options.get_valid_layers (layout, m_layers_to_write, db::SaveLayoutOptions::LP_OnlyNumbered); + options.get_valid_layers (layout, m_layers_to_write, db::SaveLayoutOptions::LP_OnlyNamed); + + // clean up layer duplicates - see TODO above + auto lw = m_layers_to_write.begin (); + std::set lseen; + for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) { + if (lseen.find (l->first) == lseen.end ()) { + *lw++ = *l; + lseen.insert (l->first); + } + } + m_layers_to_write.erase (lw, m_layers_to_write.end ()); + } +#else + options.get_valid_layers (layout, m_layers_to_write, db::SaveLayoutOptions::LP_AsIs); +#endif + + m_cells_to_write.clear (); + options.get_cells (layout, m_cells_to_write, m_layers_to_write); + + lstr::OutputStream os_adaptor (&stream); + kj::BufferedOutputStreamWrapper kj_stream (os_adaptor); + + // prepare the stream by writing the signature + kj_stream.write (LStream_sig, strlen (LStream_sig) + 1); + + // creates the global header + write_header (kj_stream); + + // this stream contains a single library currently + write_library (kj_stream); + + for (auto c = mp_layout->begin_top_down (); c != mp_layout->end_top_down (); ++c) { + if (m_cells_to_write.find (*c) != m_cells_to_write.end ()) { + m_cellname = layout.cell_name (*c); + write_cell (*c, kj_stream); + m_cellname.clear (); + } + } +} + +/** + * @brief Replicates a single message to a separate file for debugging + * + * Decoding a message is easer when it is written to a separate file. + */ +void +Writer::replicate_message (const std::string &suffix, capnp::MessageBuilder &message) +{ + if (s_replicate_messages) { + tl::OutputStream os_msg (mp_stream->path () + suffix); + lstr::OutputStream ls_os_msg (&os_msg); + kj::BufferedOutputStreamWrapper kj_os_msg (ls_os_msg); + writePackedMessage (kj_os_msg, message); + } +} + +/** + * @brief Is called "frequently" to report the progress + */ +void +Writer::yield_progress () +{ + m_progress.set (mp_stream->pos ()); +} + +/** + * @brief Issues a warning on the writer + * + * With "m_permissive" set to false, every warning will become an error. + */ +void +Writer::warn (const std::string &msg) +{ + std::string msg_full = msg; + if (! m_cellname.empty ()) { + msg_full += tl::to_string (tr (", in cell: ")); + msg_full += m_cellname; + } + + if (m_permissive) { + tl::warn << msg_full; + } else { + throw tl::Exception (msg_full); + } +} + +/** + * @brief Writes the header message to the stream + * + * This is the main header provided by the LStream. + * It lists the libraries available inside this stream. + * For KLayout, this is only one library - of "layout" + * type. + */ +void +Writer::write_header (kj::BufferedOutputStream &os) +{ + capnp::MallocMessageBuilder message; + + stream::header::Header::Builder header = message.initRoot (); + header.setGenerator (LStream_generator); + header.setTechnology (mp_layout->technology_name ()); + + header.initLibraries (1); + auto lib = header.getLibraries () [0]; + + // TODO: use layout's lib name? + lib.setName (""); + lib.setType ("layout"); + + // NOTE: our layout's metadata is placed in the library + + // Write message to stream + + writePackedMessage (os, message); + yield_progress (); + replicate_message (".header", message); +} + +/** + * @brief Writes the library header message to the stream + * + * This involves build a number of tables before they are written. + * As these tables are the basis for LStream Id allocation, this + * method must be called before LStream Ids can be obtained. + */ +void +Writer::write_library (kj::BufferedOutputStream &os) +{ + capnp::MallocMessageBuilder message; + + stream::library::Library::Builder library = message.initRoot (); + + // Library references + + make_library_refs_table (library.getLibraryRefs ()); + + // Properties + + { + std::vector prop_ids; + std::vector prop_names; + collect_property_ids (prop_ids, prop_names); + make_property_names_tables (prop_names, library.getPropertyNamesTable ()); + make_properties_tables (prop_ids, library.getPropertiesTable ()); + } + + // Text strings + + { + std::vector text_strings; + collect_text_strings (text_strings); + make_text_strings_table (text_strings, library.getTextStringsTable ()); + } + + // View specs table + // NOTE: currently there are only "layout" views and optionally "metaData" views + + { + m_layout_view_id = 0; + m_meta_data_view_id = -1; + + bool needs_meta_data_view = false; + for (auto c = m_cells_to_write.begin (); c != m_cells_to_write.end () && !needs_meta_data_view; ++c) { + needs_meta_data_view = (mp_layout->begin_meta (*c) != mp_layout->end_meta (*c)); + } + + auto view_specs = library.getViewSpecsTable (); + + view_specs.initViewSpecs (needs_meta_data_view ? 2 : 1); + + auto layout_view = view_specs.getViewSpecs () [m_layout_view_id]; + + layout_view.setName ("layout"); + layout_view.setClass ("LayoutView"); + layout_view.setPropertySetId (get_property_id (mp_layout->prop_id ())); + + // Computes the resolution: + // Rounds to integer if "close to one". This achieves a + // kind of normalization and prevents propagation of rounding + // errors. + double resolution = 1.0 / mp_layout->dbu (); + double integer_resolution = floor (resolution + 0.5); + if (std::abs (resolution - integer_resolution) < 1e-10) { + resolution = integer_resolution; + } + + layout_view.setResolution (integer_resolution); + + make_meta_data (0, layout_view.getMetaData ()); + + // adds a meta data view if needed + if (needs_meta_data_view) { + m_meta_data_view_id = 1; + auto meta_data_view = view_specs.getViewSpecs () [m_meta_data_view_id]; + meta_data_view.setName ("metaData"); + meta_data_view.setClass ("MetaDataView"); + } + } + + // Layer table + + { + auto view_specs = library.getViewSpecsTable (); + auto layout_view = view_specs.getViewSpecs () [m_layout_view_id]; + make_layer_table (layout_view.getLayerTable ()); + } + + // Cell specs table + + make_cell_specs (library.getCellSpecsTable ()); + + // Cell hierachy tree + + make_cell_hierarchy_tree (library.getCellHierarchyTree ()); + + // Write message to stream + + writePackedMessage (os, message); + yield_progress (); + replicate_message (".library", message); +} + +/** + * @brief Produces a variant value to a stream::variant::Variant struct + */ +void +Writer::make_variant_value (const tl::Variant &value, stream::variant::Variant::Builder builder) +{ + if (value.is_nil ()) { + builder.getValue ().setNil (); + } else if (value.is_bool ()) { + builder.getValue ().setBool (value.to_bool ()); + } else if (value.is_a_string ()) { + builder.getValue ().setText (value.to_string ()); + } else if (value.can_convert_to_ulonglong ()) { + builder.getValue ().setUint64 (uint64_t (value.to_ulonglong ())); + } else if (value.can_convert_to_longlong ()) { + builder.getValue ().setInt64 (int64_t (value.to_longlong ())); + } else if (value.can_convert_to_double ()) { + builder.getValue ().setDouble (value.to_double ()); + } else if (value.is_user ()) { + // NOTE: the "klayout:" prefix indicates the object is in KLayout's + // object serialization notation. + builder.getValue ().setObject (std::string ("klayout:") + value.to_parsable_string ()); + } else if (value.is_list ()) { + builder.getValue ().initList (value.size ()); + size_t index = 0; + for (auto i = value.begin (); i != value.end (); ++i, ++index) { + make_variant_value (*i, builder.getValue ().getList ()[index]); + } + } else if (value.is_array ()) { + builder.getValue ().initArray (value.array_size ()); + size_t index = 0; + for (auto i = value.begin_array (); i != value.end_array (); ++i, ++index) { + make_variant_value (i->first, builder.getValue ().getArray ()[index].getKey ()); + make_variant_value (i->second, builder.getValue ().getArray ()[index].getValue ()); + } + } +} + +/** + * @brief Produces the library names table + * + * This method collects the library references from all cells to write and + * produces a table with all these references. It will also assign + * library name Ids in that step. + */ +void +Writer::make_library_refs_table (stream::library::LibraryRefs::Builder library_refs) +{ + m_ls_lib_ids.clear (); + std::vector lib_names; + + for (auto c = m_cells_to_write.begin (); c != m_cells_to_write.end (); ++c) { + + const db::Cell &cell = mp_layout->cell (*c); + const db::LibraryProxy *lib_proxy = dynamic_cast (&cell); + if (lib_proxy) { + + auto lib_id = lib_proxy->lib_id (); + if (m_ls_lib_ids.find (lib_id) == m_ls_lib_ids.end ()) { + const db::Library *lib = db::LibraryManager::instance ().lib (lib_id); + lib_names.push_back (lib->get_name ()); + m_ls_lib_ids.insert (std::make_pair (lib_id, lib_names.size ())); + } + + } + + } + + library_refs.initRefs (lib_names.size ()); + for (auto n = lib_names.begin (); n != lib_names.end (); ++n) { + auto ref = library_refs.getRefs ()[n - lib_names.begin ()]; + ref.setLibraryName (*n); + } +} + +/** + * @brief Gets the library name Id from a given library Id + * + * Note that "make_library_names_table" must have been called before + * this method can be used. + */ +uint64_t +Writer::get_library_ref_id (db::lib_id_type lib_id) +{ + auto i = m_ls_lib_ids.find (lib_id); + tl_assert (i != m_ls_lib_ids.end ()); + return i->second; +} + +/** + * @brief Collect all KLayout property name Ids and properties Ids used in the context of this writer + * + * This method scans layout, cells, meta info, instances and shapes for used properties + * and registers properties Ids and names. + * + * @param prop_ids Where the properties Ids are collected + * @param prop_names Where the property names are collected + */ +void +Writer::collect_property_ids (std::vector &prop_ids, std::vector &prop_names) +{ + make_property_id (mp_layout->prop_id (), prop_ids, prop_names); + + for (auto c = m_cells_to_write.begin (); c != m_cells_to_write.end (); ++c) { + + const db::Cell &cell = mp_layout->cell (*c); + + // PCell parameters only employ the name ID space + auto param_dict = mp_layout->get_named_pcell_parameters (*c); + for (auto p = param_dict.begin (); p != param_dict.end (); ++p) { + make_property_name_id_from_variant (tl::Variant (p->first), prop_names); + } + + make_property_id (cell.prop_id (), prop_ids, prop_names); + + for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) { + for (auto s = db::ShapeIterator (cell.shapes (l->first), db::ShapeIterator::AllWithProperties); ! s.at_end (); s.finish_array ()) { + make_property_id (s->prop_id (), prop_ids, prop_names); + } + } + + for (auto i = cell.begin (); ! i.at_end (); ++i) { + make_property_id (i->prop_id (), prop_ids, prop_names); + } + + } +} + +namespace +{ + +struct ComparePropertyNameIdByValue +{ + bool operator() (db::property_names_id_type a, db::property_names_id_type b) const + { + const tl::Variant &na = db::property_name (a); + const tl::Variant &nb = db::property_name (b); + return na.less (nb); + } +}; + +} + +/** + * @brief Gets the LStream property set Id from a KLayout properties Id + * + * If the properties Id is not registered yet, a new LStream Id will be generated. + * + * @param id The KLayout properties Id + * @param prop_id New KLayout properties Ids will be added here + * @param prop_names New property names go here (happens when a new property set is registered) + */ +uint64_t +Writer::make_property_id (db::properties_id_type id, std::vector &prop_ids, std::vector &prop_names) +{ + if (id != 0) { + + auto i = m_ls_prop_ids.find (id); + if (i != m_ls_prop_ids.end ()) { + + return i->second; + + } else { + + uint64_t ls_id = uint64_t (prop_ids.size () + 1); + m_ls_prop_ids.insert (std::make_pair (id, ls_id)); + prop_ids.push_back (id); + + auto ps = db::properties (id); + std::set ps_sorted; + for (auto i = ps.begin (); i != ps.end (); ++i) { + ps_sorted.insert (i->first); + } + + for (auto i = ps_sorted.begin (); i != ps_sorted.end (); ++i) { + make_property_name_id_from_id (*i, prop_names); + } + + return ls_id; + + } + + } else { + return 0; + } +} + +/** + * @brief Gets the LStream property name Id for a given name (by variant) + * + * @param name The name to register + * @param prop_names New names will be added here + */ +uint64_t +Writer::make_property_name_id_from_variant (const tl::Variant &name, std::vector &prop_names) +{ + return make_property_name_id_from_id (db::property_names_id (name), prop_names); +} + +/** + * @brief Gets the LStream property name Id for a given name (by KLayout property name Id) + * + * @param name_id The name Id to register + * @param prop_names New names will be added here + */ +uint64_t +Writer::make_property_name_id_from_id (db::property_names_id_type name_id, std::vector &prop_names) +{ + auto i = m_ls_prop_name_ids.find (name_id); + if (i != m_ls_prop_name_ids.end ()) { + return i->second; + } else { + uint64_t ls_name_id = prop_names.size (); + prop_names.push_back (name_id); + m_ls_prop_name_ids.insert (std::make_pair (name_id, ls_name_id)); + return ls_name_id; + } +} + +/** + * @brief Gets the LStream property set Id from a KLayout properties Id + * + * If the properties Id is not valid, this method will assert. + * Note, that "make_property_id" must have been called before to register + * the property set. + */ +uint64_t +Writer::get_property_id (db::properties_id_type id) +{ + if (id == 0) { + return 0; + } else { + auto i = m_ls_prop_ids.find (id); + tl_assert (i != m_ls_prop_ids.end ()); + return i->second; + } +} + +/** + * @brief Obtain the LStream property name Id from KLayout property name Id + * + * If the KLayout property name Id is not valid, this method asserts. + * Note that "make_property_name_id_from_id" must have been called before to + * register the name. + */ +uint64_t +Writer::get_property_name_id_from_id (db::property_names_id_type name_id) +{ + auto i = m_ls_prop_name_ids.find (name_id); + tl_assert (i != m_ls_prop_name_ids.end ()); + return i->second; +} + +/** + * @brief Obtain the LStream property name Id from a name variant + * + * If the name variant is not a valid name, this method asserts. + */ +uint64_t +Writer::get_property_name_id_from_variant (const tl::Variant &name) +{ + return get_property_name_id_from_id (db::property_names_id (name)); +} + +/** + * @brief Produces the property names table from a given set of KLayout property name Ids + */ +void +Writer::make_property_names_tables (const std::vector &prop_names, stream::library::PropertyNamesTable::Builder property_names) +{ + property_names.initNames (prop_names.size ()); + + for (auto i = prop_names.begin (); i != prop_names.end (); ++i) { + stream::propertySet::PropertyName::Builder property_name = property_names.getNames ()[i - prop_names.begin ()]; + // No namespace yet: property_name.setNamespaceId (0); + make_variant_value (db::property_name (*i), property_name.getName ()); + } +} + +/** + * @brief Produces the property sets table from a given set of KLayout properties Ids + * + * Note that the property names must have been collected already before this + * method can be used ("make_property_name_id_from_id"). + */ +void +Writer::make_properties_tables (const std::vector &prop_ids, stream::library::PropertiesTable::Builder properties) +{ + properties.initPropertySets (prop_ids.size ()); + + for (auto p = prop_ids.begin (); p != prop_ids.end (); ++p) { + + auto set = properties.getPropertySets ()[p - prop_ids.begin ()]; + + // NOTE: we go through the map to become independent from the name order + auto map = db::properties (*p).to_map (); + set.initProperties (map.size ()); + + size_t index = 0; + for (auto m = map.begin (); m != map.end (); ++m, ++index) { + auto ni = m_ls_prop_name_ids.find (db::property_names_id (m->first)); + tl_assert (ni != m_ls_prop_name_ids.end ()); + auto prop = set.getProperties ()[index]; + prop.setNameId (ni->second); + make_variant_value (m->second, prop.getValue ()); + } + + } +} + +/** + * @brief Collects all used text strings + */ +void +Writer::collect_text_strings (std::vector &text_strings) +{ + for (auto c = m_cells_to_write.begin (); c != m_cells_to_write.end (); ++c) { + + const db::Cell &cell = mp_layout->cell (*c); + + for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) { + for (auto s = db::ShapeIterator (cell.shapes (l->first), db::ShapeIterator::Texts); ! s.at_end (); s.finish_array ()) { + make_text_string_id (std::string (s->text_string ()), text_strings); + } + } + + } +} + +/** + * @brief Gets the LStream text string Id for a given text + * + * This method will create a new entry if the string had not been + * registered before. + * + * @param string The new text string + * @param text_strings New strings are added here + */ +uint64_t +Writer::make_text_string_id (const std::string &string, std::vector &text_strings) +{ + auto i = m_text_strings.find (string); + if (i == m_text_strings.end ()) { + uint64_t id = text_strings.size (); + text_strings.push_back (string); + m_text_strings.insert (std::make_pair (string, id)); + return id; + } else { + return i->second; + } +} + +/** + * @brief Gets the LStream text string Id for a given text + * + * Note that make_text_string_id had to be called before. + * This method will assert if the string does not have an associated + * text string Id. + */ +uint64_t +Writer::get_text_string_id (const std::string &string) +{ + auto i = m_text_strings.find (string); + tl_assert (i != m_text_strings.end ()); + return i->second; +} + +/** + * @brief Produces the text strings table on stream::library::TextStringsTable + * + * @param text_strings The list of text strings, where the LStream text string Id in an index in that table + * @param table The Builder for the table + */ +void +Writer::make_text_strings_table (const std::vector &text_strings, stream::library::TextStringsTable::Builder table) +{ + table.initTextStrings (text_strings.size ()); + + for (auto i = text_strings.begin (); i != text_strings.end (); ++i) { + table.getTextStrings ().set (i - text_strings.begin (), i->c_str ()); + } +} + +/** + * @brief Produces the layer table on stream::library::LayerTable + * + * Only selected layers will be produced. + */ +void +Writer::make_layer_table (stream::library::LayerTable::Builder layers) +{ + layers.initLayerEntries (m_layers_to_write.size ()); + + for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) { + + auto lp = l->second; + + // NOTE: currently, the purpose is always DRAWING + auto le = layers.getLayerEntries ()[l - m_layers_to_write.begin ()]; + if (lp.layer >= 0 && lp.datatype >= 0) { + le.initLayerNumbers (2); + le.getLayerNumbers ().set (0, lp.layer); + le.getLayerNumbers ().set (1, lp.datatype); + } + le.setName (lp.name); + le.setPurpose (stream::library::LayerEntry::Purpose::DRAWING); + + } +} + +/** + * @brief Produces the cell specifications on stream::library::CellSpecsTable + * + * Only selected cells will be produced. The cell specs are generated top-down. + */ +void +Writer::make_cell_specs (stream::library::CellSpecsTable::Builder cell_specs) +{ + cell_specs.initCellSpecs (m_cells_to_write.size ()); + + size_t index = 0; + + m_ls_cell_ids.clear (); + for (auto c = mp_layout->begin_top_down (); c != mp_layout->end_top_down (); ++c) { + + if (m_cells_to_write.find (*c) == m_cells_to_write.end ()) { + continue; + } + + m_ls_cell_ids.insert (std::make_pair (*c, index)); + + auto cs = cell_specs.getCellSpecs ()[index]; + const db::Cell &cell = mp_layout->cell (*c); + + cs.setName (mp_layout->cell_name (*c)); + + const db::LibraryProxy *lib_proxy = dynamic_cast (&cell); + if (lib_proxy) { + cs.setLibraryCellName (cell.get_basic_name ()); + cs.setLibraryRefId (get_library_ref_id (lib_proxy->lib_id ())); + } + + if (mp_layout->is_pcell_instance (*c).first) { + + // Only PCells have a "parameters" object. Others won't initialize "parameters" + auto param_dict = mp_layout->get_named_pcell_parameters (*c); + auto pcell_parameters = cs.getParameters ().initValues (param_dict.size ()); + + size_t pindex = 0; + for (auto p = param_dict.begin (); p != param_dict.end (); ++p, ++pindex) { + auto pn = pcell_parameters[pindex]; + pn.setNameId (get_property_name_id_from_variant (tl::Variant (p->first))); + make_variant_value (p->second, pn.getValue ()); + } + + } + + cs.setPropertySetId (get_property_id (cell.prop_id ())); + + ++index; + + } +} + +/** + * @brief Gets the LStream Id for a given KLayout cell Id + * + * Note that the "make_cell_specs" must have been executed, before this method + * can be used. + */ +uint64_t +Writer::get_cell_id (db::cell_index_type ci) +{ + auto i = m_ls_cell_ids.find (ci); + tl_assert (i != m_ls_cell_ids.end ()); + return i->second; +} + +/** + * @brief Produces the cell hierarchy tree on stream::library::CellHierarchyTree + * + * This method will consider the selected cells and produce a cell hierarchy + * tree in top-down mode. + */ +void +Writer::make_cell_hierarchy_tree (stream::library::CellHierarchyTree::Builder cell_tree) +{ + size_t top_cell_count = 0; + for (auto c = mp_layout->begin_top_down (); c != mp_layout->end_top_cells (); ++c) { + if (m_cells_to_write.find (*c) != m_cells_to_write.end ()) { + ++top_cell_count; + } + } + + cell_tree.setNumberOfTopCells (top_cell_count); + cell_tree.initNodes (m_cells_to_write.size ()); + + size_t index = 0; + for (auto c = mp_layout->begin_top_down (); c != mp_layout->end_top_down (); ++c) { + + if (m_cells_to_write.find (*c) == m_cells_to_write.end ()) { + continue; + } + + auto cn = cell_tree.getNodes ()[index]; + cn.setCellId (get_cell_id (*c)); + + std::set children; + const db::Cell &cell = mp_layout->cell (*c); + for (auto cc = cell.begin_child_cells (); ! cc.at_end (); ++cc) { + if (m_cells_to_write.find (*cc) != m_cells_to_write.end ()) { + children.insert (get_cell_id (*cc)); + } + } + + cn.initChildCellIds (children.size ()); + size_t cindex = 0; + for (auto cc = children.begin (); cc != children.end (); ++cc, ++cindex) { + cn.getChildCellIds ().set (cindex, *cc); + } + + ++index; + + } + + // all cells have been written + tl_assert (index == m_cells_to_write.size ()); +} + +/** + * @brief Generates meta info for the given cell or layout in the stream::propertySet::PropertySet struct + * + * If cell is 0, the layout meta info will be generated. Otherwise the + * cell specific meta info will be produced. In both cases the meta info + * is written to the given PropertySet builder. + */ +void +Writer::make_meta_data (const db::Cell *cell, stream::metaData::MetaData::Builder meta_data) +{ + auto mfrom = cell ? mp_layout->begin_meta (cell->cell_index ()) : mp_layout->begin_meta (); + auto mto = cell ? mp_layout->end_meta (cell->cell_index ()) : mp_layout->end_meta (); + + size_t count = 0; + for (auto m = mfrom; m != mto; ++m) { + if (m->second.persisted) { + ++count; + } + } + meta_data.initEntries (count); + + size_t index = 0; + for (auto m = mfrom; m != mto; ++m) { + if (m->second.persisted) { + auto p = meta_data.getEntries ()[index]; + auto name = mp_layout->meta_info_name (m->first); + p.setName (name); + p.setDescription (m->second.description); + make_variant_value (m->second.value, p.getValue ()); + ++index; + } + } +} + +/** + * @brief Writes the cell message for the given cell, followed by the layout view message + * + * @param ci The cell for which to generate the message + * @param os The stream where to write the message + * + * This method generates a single-view cell message (the view is only a layout view). + */ +void +Writer::write_cell (db::cell_index_type ci, kj::BufferedOutputStream &os) +{ + bool needs_layout_view = ! mp_layout->cell (ci).is_ghost_cell (); + bool needs_meta_data_view = mp_layout->begin_meta (ci) != mp_layout->end_meta (ci); + + capnp::MallocMessageBuilder message; + + stream::cell::Cell::Builder cell = message.initRoot (); + + cell.initViewIds ((needs_layout_view ? 1 : 0) + (needs_meta_data_view ? 1 : 0)); + + int view_index = 0; + if (needs_layout_view) { + tl_assert (m_layout_view_id >= 0); + cell.getViewIds ().set (view_index++, (unsigned int) m_layout_view_id); + } + if (needs_meta_data_view) { + tl_assert (m_meta_data_view_id >= 0); + cell.getViewIds ().set (view_index++, (unsigned int) m_meta_data_view_id); + } + + writePackedMessage (os, message); + yield_progress (); + replicate_message (std::string (".cell_") + mp_layout->cell_name (ci), message); + + if (needs_layout_view) { + write_layout_view (ci, os); + } + if (needs_meta_data_view) { + write_meta_data_view (ci, os); + } +} + +/** + * @brief generates and writes a layout view message for the given cell + * + * @param ci The cell for which to generate the message + * @param os The stream where to write the message + * + * Generating the message involves compressing and producing the + * instances and shapes for various kinds on each layer. + */ +void +Writer::write_layout_view (db::cell_index_type ci, kj::BufferedOutputStream &os) +{ + capnp::MallocMessageBuilder message; + + auto layout_view = message.initRoot (); + const db::Cell &cell = mp_layout->cell (ci); + + std::vector > layers_for_cell; + layers_for_cell.reserve (m_layers_to_write.size ()); + for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) { + if (! cell.shapes (l->first).empty ()) { + layers_for_cell.push_back (std::make_pair (l->first, l - m_layers_to_write.begin ())); + } + } + + layout_view.initLayers (layers_for_cell.size ()); + + for (auto l = layers_for_cell.begin (); l != layers_for_cell.end (); ++l) { + + auto layer = layout_view.getLayers () [l - layers_for_cell.begin ()]; + layer.setLayerId (l->second); + + Compressed compressed; + compressed.compress_shapes (cell.shapes (l->first), m_compression_level, m_recompress); + + layer.initRepetitions (compressed.num_arrays ()); + for (auto r = compressed.begin_regular_arrays (); r != compressed.end_regular_arrays (); ++r) { + tl_assert (r->second > 0); + make_repetition (r->first, layer.getRepetitions ()[r->second - 1]); + } + for (auto r = compressed.begin_irregular_arrays (); r != compressed.end_irregular_arrays (); ++r) { + tl_assert (r->second > 0); + make_repetition (r->first, layer.getRepetitions ()[r->second - 1]); + } + + make_objects (compressed.get_container (), layer.getPoints ()); + make_objects (compressed.get_container (), layer.getBoxes ()); + make_objects (compressed.get_container (), layer.getEdges ()); + make_objects (compressed.get_container (), layer.getEdgePairs ()); + make_objects (compressed.get_container (), layer.getLabels ()); + make_objects (compressed.get_container (), layer.getPolygons ()); + make_objects (compressed.get_container (), layer.getSimplePolygons ()); + make_objects (compressed.get_container (), layer.getPaths ()); + + } + + // collects and writes the bounding box from the layers we want to write + db::Box bbox; + for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) { + bbox += cell.bbox (l->first); + } + make_object (bbox, layout_view.getBoundingBox ()); + + // instances + { + Compressed compressed; + compressed.compress_instances (cell.begin (), m_cells_to_write, m_compression_level); + + layout_view.initInstanceRepetitions (compressed.num_arrays ()); + for (auto r = compressed.begin_regular_arrays (); r != compressed.end_regular_arrays (); ++r) { + tl_assert (r->second > 0); + make_repetition (r->first, layout_view.getInstanceRepetitions ()[r->second - 1]); + } + for (auto r = compressed.begin_irregular_arrays (); r != compressed.end_irregular_arrays (); ++r) { + tl_assert (r->second > 0); + make_repetition (r->first, layout_view.getInstanceRepetitions ()[r->second - 1]); + } + + make_objects (compressed.get_container (), layout_view.getInstances ()); + } + + writePackedMessage (os, message); + yield_progress (); + replicate_message (std::string (".lv_") + mp_layout->cell_name (ci), message); +} + +/** + * @brief generates and writes a meta data view message for the given cell + * + * @param ci The cell for which to generate the message + * @param os The stream where to write the message + */ +void +Writer::write_meta_data_view (db::cell_index_type ci, kj::BufferedOutputStream &os) +{ + capnp::MallocMessageBuilder message; + + auto meta_data_view = message.initRoot (); + + make_meta_data (&mp_layout->cell (ci), meta_data_view.getData ()); + + writePackedMessage (os, message); + yield_progress (); + replicate_message (std::string (".lv_") + mp_layout->cell_name (ci), message); +} + +/** + * @brief Creates a regular repetition from the RegularArray object + * + * The regular array should not be a null array. + */ +void +Writer::make_repetition (const RegularArray &array, stream::repetition::Repetition::Builder builder) +{ + if (array.a ().y () == 0 && array.b ().x () == 0) { + + auto regular = builder.getTypes ().initRegularOrtho (); + regular.setDx (array.a ().x ()); + regular.setDy (array.b ().y ()); + regular.setNx (array.na ()); + regular.setNy (array.nb ()); + + } else if (array.a ().x () == 0 && array.b ().y () == 0) { + + auto regular = builder.getTypes ().initRegularOrtho (); + regular.setDx (array.b ().x ()); + regular.setDy (array.a ().y ()); + regular.setNx (array.nb ()); + regular.setNy (array.na ()); + + } else { + + auto regular = builder.getTypes ().initRegular (); + auto a = regular.getA (); + a.setDx (array.a ().x ()); + a.setDy (array.a ().y ()); + auto b = regular.getB (); + b.setDx (array.b ().x ()); + b.setDy (array.b ().y ()); + regular.setNa (array.na ()); + regular.setNb (array.nb ()); + + } +} + +/** + * @brief Creates an enumerated stream::repetition::Repetition object from a sequence of displacements + * + * The list of displacements is directly converted into the repetition object. + * The implied zero-displacement element at the beginning must not be added at the front. + */ +void +Writer::make_repetition (const std::vector &disp_array, stream::repetition::Repetition::Builder builder) +{ + auto enumerated = builder.getTypes ().initEnumerated (); + + enumerated.initDeltas (disp_array.size ()); + + size_t index = 0; + db::Vector dl; + for (auto d = disp_array.begin (); d != disp_array.end (); ++d, ++index) { + auto delta = enumerated.getDeltas ()[index]; + db::Vector dd = *d - dl; + dl = *d; + delta.setDx (dd.x ()); + delta.setDy (dd.y ()); + } +} + +/** + * @brief Creates a stream::geometry::Contour struct from a sequence of points + * + * @param begin The begin iterator for the point sequence + * @param end The end iterator for the point sequence + * @param n The number of points + * @param builder The stream::geometry::Contour builder + */ +template +static void +make_contour (Iter begin, Iter end, size_t n, stream::geometry::Contour::Builder builder) +{ + auto p = begin; + tl_assert (n > 0); + + db::Point pl = *p; + builder.getP1 ().setX (pl.x ()); + builder.getP1 ().setY (pl.y ()); + ++p; + + builder.initDeltas (n - 1); + size_t index = 0; + for ( ; p != end; ++p, ++index) { + auto d = builder.getDeltas ()[index]; + auto pd = *p - pl; + d.setDx (pd.x ()); + d.setDy (pd.y ()); + pl = *p; + } +} + +/** + * @brief "make_object" overload for db::SimplePolygon and stream::layoutView::SimplePolygon + */ +void +Writer::make_object (const db::SimplePolygon &obj, stream::geometry::SimplePolygon::Builder cpnp_obj) +{ + make_contour (obj.hull ().begin (), obj.hull ().end (), obj.hull ().size (), cpnp_obj.getHull ()); +} + +/** + * @brief "make_object" overload for db::Polygon and stream::layoutView::Polygon + */ +void +Writer::make_object (const db::Polygon &obj, stream::geometry::Polygon::Builder cpnp_obj) +{ + make_contour (obj.hull ().begin (), obj.hull ().end (), obj.hull ().size (), cpnp_obj.getHull ()); + + cpnp_obj.initHoles (obj.holes ()); + for (unsigned int h = 0; h < obj.holes (); ++h) { + make_contour (obj.hole (h).begin (), obj.hole (h).end (), obj.hole (h).size (), cpnp_obj.getHoles ()[h]); + } +} + +/** + * @brief "make_object" overload for db::Edge and stream::layoutView::Edge + */ +void +Writer::make_object (const db::Edge &obj, stream::geometry::Edge::Builder cpnp_obj) +{ + auto p1 = cpnp_obj.getP1 (); + p1.setX (obj.p1 ().x ()); + p1.setY (obj.p1 ().y ()); + + auto delta = cpnp_obj.getDelta (); + delta.setDx (obj.d ().x ()); + delta.setDy (obj.d ().y ()); +} + +/** + * @brief "make_object" overload for db::EdgePair and stream::layoutView::EdgePair + */ +void +Writer::make_object (const db::EdgePair &obj, stream::geometry::EdgePair::Builder cpnp_obj) +{ + make_object (obj.first (), cpnp_obj.getE1 ()); + make_object (obj.second (), cpnp_obj.getE2 ()); +} + +/** + * @brief "make_object" overload for db::Box and stream::layoutView::Box + */ +void +Writer::make_object (const db::Box &obj, stream::geometry::Box::Builder cpnp_obj) +{ + auto p1 = cpnp_obj.getP1 (); + p1.setX (obj.p1 ().x ()); + p1.setY (obj.p1 ().y ()); + + auto delta = cpnp_obj.getDelta (); + auto d = obj.p2 () - obj.p1 (); + delta.setDx (d.x ()); + delta.setDy (d.y ()); +} + +/** + * @brief Converts KLayout's fixpoint transformation code into a stream::geometry::FixPointTransformation enum + */ +stream::geometry::FixPointTransformation +Writer::make_fixpoint_transformation (const db::Trans &trans) +{ + switch (trans.fp_trans ().rot ()) { + case db::FTrans::r0: + default: + return stream::geometry::FixPointTransformation::R0; + case db::FTrans::r90: + return stream::geometry::FixPointTransformation::R90; + case db::FTrans::r180: + return stream::geometry::FixPointTransformation::R180; + case db::FTrans::r270: + return stream::geometry::FixPointTransformation::R270; + case db::FTrans::m0: + return stream::geometry::FixPointTransformation::M0; + case db::FTrans::m45: + return stream::geometry::FixPointTransformation::M45; + case db::FTrans::m90: + return stream::geometry::FixPointTransformation::M90; + case db::FTrans::m135: + return stream::geometry::FixPointTransformation::M135; + } +} + +/** + * @brief "make_object" overload for db::Text and stream::layoutView::Text + */ +void +Writer::make_object (const db::Text &obj, stream::geometry::Label::Builder cpnp_obj) +{ + db::Point pos = db::Point () + obj.trans ().disp (); + cpnp_obj.getPosition ().setX (pos.x ()); + cpnp_obj.getPosition ().setY (pos.y ()); + cpnp_obj.setOrientation (make_fixpoint_transformation (obj.trans ())); + + cpnp_obj.setStringId (get_text_string_id (obj.string ())); + + cpnp_obj.setSize (obj.size ()); + + switch (obj.halign ()) { + case db::HAlignCenter: + cpnp_obj.setHorizontalAlign (stream::geometry::Label::HAlignment::CENTER); + break; + case db::HAlignRight: + cpnp_obj.setHorizontalAlign (stream::geometry::Label::HAlignment::RIGHT); + break; + case db::HAlignLeft: + default: + cpnp_obj.setHorizontalAlign (stream::geometry::Label::HAlignment::LEFT); + } + + switch (obj.valign ()) { + case db::VAlignCenter: + cpnp_obj.setVerticalAlign (stream::geometry::Label::VAlignment::CENTER); + break; + case db::VAlignTop: + cpnp_obj.setVerticalAlign (stream::geometry::Label::VAlignment::TOP); + break; + case db::VAlignBottom: + default: + cpnp_obj.setVerticalAlign (stream::geometry::Label::VAlignment::BOTTOM); + } +} + +/** + * @brief "make_object" overload for db::Point and stream::layoutView::Point + */ +void +Writer::make_object (const db::Point &obj, stream::geometry::Point::Builder cpnp_obj) +{ + cpnp_obj.setX (obj.x ()); + cpnp_obj.setY (obj.y ()); +} + +/** + * @brief "make_object" overload for db::Path and stream::layoutView::Path + */ +void +Writer::make_object (const db::Path &obj, stream::geometry::Path::Builder cpnp_obj) +{ + make_contour (obj.begin (), obj.end (), obj.points (), cpnp_obj.getSpine ()); + if ((obj.width () / 2) * 2 != obj.width ()) { + warn (tl::to_string (tr ("Rounding width to even DBU value in path: ")) + obj.to_string ()); + } + cpnp_obj.setHalfWidth (obj.width () / 2); + + if (obj.round ()) { + if (obj.bgn_ext () != obj.end_ext () || obj.bgn_ext () * 2 != obj.width ()) { + warn (tl::to_string (tr ("Changing elliptic-end path to circular ends: ")) + obj.to_string ()); + } + cpnp_obj.setExtensionType (stream::geometry::Path::ExtensionType::ROUND); + } else if (obj.bgn_ext () * 2 == obj.width () && obj.bgn_ext () == obj.end_ext ()) { + cpnp_obj.setExtensionType (stream::geometry::Path::ExtensionType::SQUARE); + } else if (obj.bgn_ext () == 0 && obj.end_ext () == 0) { + cpnp_obj.setExtensionType (stream::geometry::Path::ExtensionType::FLUSH); + } else { + cpnp_obj.setExtensionType (stream::geometry::Path::ExtensionType::VARIABLE); + cpnp_obj.setBeginExtension (obj.bgn_ext ()); + cpnp_obj.setEndExtension (obj.end_ext ()); + } +} + +/** + * @brief "make_object" overload for db::CellInstArray and stream::layoutView::CellInstance + */ +void +Writer::make_object (const db::CellInstArray &obj, stream::layoutView::CellInstance::Builder cpnp_obj) +{ + // NOTE: the "CellInstArray" will actually be a single instance always + tl_assert (obj.size () == 1); + + cpnp_obj.setCellId (get_cell_id (obj.object ().cell_index ())); + + auto transformation = cpnp_obj.getTransformation (); + + db::Point pos = db::Point () + obj.front ().disp (); + transformation.getDisplacement ().setDx (pos.x ()); + transformation.getDisplacement ().setDy (pos.y ()); + + if (! obj.is_complex ()) { + auto simple = transformation.getTransformation ().initSimple (); + simple.setOrientation (make_fixpoint_transformation (obj.front ())); + } else { + db::ICplxTrans trans = obj.complex_trans (); + auto complex = transformation.getTransformation ().initComplex (); + complex.setScale (trans.mag ()); + complex.setAngle (trans.angle ()); + complex.setMirror (trans.is_mirror ()); + } +} + +/** + * @brief Writes the given compressed container to the container builder + * + * "Object" is an object that is supported by the compression scheme + * (those are db::CellInstArray and the geometrical primitives such as db::Box etc.). + * + * "Builder" is the Builder object of a "ObjectContainerForType" generic struct. + * + * This method will use the "make_object" overloads to actually create the objects. + * The "compressed_container" will contain various variants involved plain and + * arrayed objects, optionally combined with properties. + * + * These schemes are placed in the corresponding slots of the "ObjectContainerForType" + * struct. + * + * This method is called after the compressed objects have been computed. + * This also involves generating repetition Ids which are already available when + * this method is called. + */ +template +void +Writer::make_objects (const Compressed::compressed_container &container, Builder builder) +{ + size_t i; + + builder.initBasic (container.plain.size ()); + i = 0; + for (auto s = container.plain.begin (); s != container.plain.end (); ++s, ++i) { + make_object (*s, builder.getBasic ()[i].getBasic ()); + } + + builder.initArrays (container.array.size ()); + i = 0; + for (auto s = container.array.begin (); s != container.array.end (); ++s, ++i) { + auto a = builder.getArrays ()[i]; + make_object (s->first, a.getBasic ()); + a.setRepetitionId (s->second); + } + + builder.initWithProperties (container.with_properties.size ()); + i = 0; + for (auto s = container.with_properties.begin (); s != container.with_properties.end (); ++s, ++i) { + auto a = builder.getWithProperties ()[i]; + make_object (s->first, a.getBasic ()); + a.setPropertySetId (get_property_id (s->second)); + } + + builder.initArraysWithProperties (container.array_with_properties.size ()); + i = 0; + for (auto s = container.array_with_properties.begin (); s != container.array_with_properties.end (); ++s, ++i) { + auto a = builder.getArraysWithProperties ()[i]; + auto ab = a.getBasic (); + make_object (s->first.first, ab.getBasic ()); + ab.setRepetitionId (s->second); + a.setPropertySetId (get_property_id (s->first.second)); + } +} + +} // namespace db + diff --git a/src/plugins/streamers/lstream/db_plugin/lstrWriter.h b/src/plugins/streamers/lstream/db_plugin/lstrWriter.h new file mode 100644 index 000000000..f771380c1 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/lstrWriter.h @@ -0,0 +1,142 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef HDR_lstrWriter +#define HDR_lstrWriter + +#include "lstrCompressed.h" + +#include "dbPluginCommon.h" +#include "dbWriterTools.h" +#include "dbWriter.h" + +#include "tlProgress.h" + +#include "header.capnp.h" +#include "library.capnp.h" +#include "variant.capnp.h" +#include "geometry.capnp.h" +#include "cell.capnp.h" +#include "layoutView.capnp.h" + +#include + +namespace kj +{ + class BufferedOutputStream; +} + +namespace lstr +{ + +/** + * @brief The LStream format stream writer + */ +class DB_PLUGIN_PUBLIC Writer + : public db::WriterBase +{ +public: + /** + * @brief Instantiate the writer + */ + Writer (); + + /** + * @brief Writes the layout object + * + * @param layout The layout object to write + * @param stream The stream to write to + * @param options The writer options to use + */ + void write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayoutOptions &options); + +private: + tl::OutputStream *mp_stream; + tl::AbsoluteProgress m_progress; + db::SaveLayoutOptions m_options; + bool m_recompress; + int m_compression_level; + bool m_permissive; + db::Layout *mp_layout; + std::string m_cellname; + int m_layout_view_id; + int m_meta_data_view_id; + std::map m_ls_lib_ids; + std::vector > m_layers_to_write; + std::set m_cells_to_write; + std::map m_ls_prop_name_ids; + std::map m_ls_prop_ids; + std::map m_text_strings; + std::map m_ls_cell_ids; + + void yield_progress (); + void warn (const std::string &msg); + void write_header (kj::BufferedOutputStream &os); + void write_library (kj::BufferedOutputStream &os); + void make_library_refs_table (stream::library::LibraryRefs::Builder library_names); + uint64_t get_library_ref_id (db::lib_id_type lib_id); + void collect_property_ids (std::vector &prop_ids, std::vector &prop_names); + uint64_t make_property_id (db::properties_id_type id, std::vector &prop_ids, std::vector &prop_names); + uint64_t make_property_name_id_from_id (db::property_names_id_type name_id, std::vector &prop_names); + uint64_t make_property_name_id_from_variant (const tl::Variant &name, std::vector &prop_names); + uint64_t get_property_id (db::properties_id_type id); + uint64_t get_property_name_id_from_id (db::property_names_id_type name_id); + uint64_t get_property_name_id_from_variant (const tl::Variant &name); + void make_property_names_tables (const std::vector &prop_names, stream::library::PropertyNamesTable::Builder property_names); + void make_properties_tables (const std::vector &prop_ids, stream::library::PropertiesTable::Builder properties); + void make_variant_value (const tl::Variant &value, stream::variant::Variant::Builder builder); + void collect_text_strings (std::vector &text_strings); + uint64_t make_text_string_id (const std::string &string, std::vector &text_strings); + uint64_t get_text_string_id (const std::string &string); + void make_text_strings_table (const std::vector &text_strings, stream::library::TextStringsTable::Builder table); + void make_layer_table (stream::library::LayerTable::Builder layers); + void make_cell_specs (stream::library::CellSpecsTable::Builder cell_specs); + uint64_t get_cell_id (db::cell_index_type ci); + void make_cell_hierarchy_tree (stream::library::CellHierarchyTree::Builder cell_tree); + void make_meta_data (const db::Cell *cell, stream::metaData::MetaData::Builder meta_data); + + void write_cell (db::cell_index_type ci, kj::BufferedOutputStream &os); + void write_layout_view (db::cell_index_type ci, kj::BufferedOutputStream &os); + void write_meta_data_view (db::cell_index_type ci, kj::BufferedOutputStream &os); + void make_repetition (const RegularArray &array, stream::repetition::Repetition::Builder builder); + void make_repetition (const std::vector &disp_array, stream::repetition::Repetition::Builder builder); + void make_object (const db::SimplePolygon &obj, stream::geometry::SimplePolygon::Builder cpnp_obj); + void make_object (const db::Polygon &obj, stream::geometry::Polygon::Builder cpnp_obj); + void make_object (const db::Edge &obj, stream::geometry::Edge::Builder cpnp_obj); + void make_object (const db::EdgePair &obj, stream::geometry::EdgePair::Builder cpnp_obj); + void make_object (const db::Point &obj, stream::geometry::Point::Builder cpnp_obj); + void make_object (const db::Box &obj, stream::geometry::Box::Builder cpnp_obj); + void make_object (const db::Text &obj, stream::geometry::Label::Builder cpnp_obj); + void make_object (const db::Path &obj, stream::geometry::Path::Builder cpnp_obj); + void make_object (const db::CellInstArray &obj, stream::layoutView::CellInstance::Builder cpnp_obj); + template + void make_objects (const Compressed::compressed_container &container, Builder builder); + stream::geometry::FixPointTransformation make_fixpoint_transformation (const db::Trans &trans); + + // for debugging + void replicate_message (const std::string &suffix, capnp::MessageBuilder &builder); +}; + +} // namespace db + +#endif + diff --git a/src/plugins/streamers/lstream/db_plugin/pysetup.toml b/src/plugins/streamers/lstream/db_plugin/pysetup.toml new file mode 100644 index 000000000..fe1fc2543 --- /dev/null +++ b/src/plugins/streamers/lstream/db_plugin/pysetup.toml @@ -0,0 +1,10 @@ + +[library] + name = "_lstream_dbpi" + defines = [["MAKE_DB_PLUGIN_LIBRARY", 1], ["CAPNP_LITE", 1]] + depends = ["_tl", "_db", "_gsi"] + includes = ["/src/plugins/common", "/src/version", "capnp", "../runtime/capnp", "../runtime/kj"] + submodules = ["db_plugins"] + sources = ["capnp", "../runtime/capnp/capnp", "../runtime/kj/kj"] + cxxflags-gcc = ["-std=c++14"] + diff --git a/src/plugins/streamers/lstream/lay_plugin/LStreamWriterOptionPage.ui b/src/plugins/streamers/lstream/lay_plugin/LStreamWriterOptionPage.ui new file mode 100644 index 000000000..8b66e7aa8 --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/LStreamWriterOptionPage.ui @@ -0,0 +1,283 @@ + + + LStreamWriterOptionPage + + + + 0 + 0 + 633 + 338 + + + + Form + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + LStream Writer Options + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + Compaction level +(repetition detection) + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + 0 (low) + + + + + + + Permissive mode + + + + + + + + 0 + 0 + + + + 10 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + Don't fail on paths with odd width and other odd shapes + + + + + + + + 0 + 0 + + + + (high) 10 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Qt::Vertical + + + + 524 + 51 + + + + + + + + compression_slider + + + + diff --git a/src/plugins/streamers/lstream/lay_plugin/layLStreamReaderPlugin.cc b/src/plugins/streamers/lstream/lay_plugin/layLStreamReaderPlugin.cc new file mode 100644 index 000000000..bf7aaee8d --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/layLStreamReaderPlugin.cc @@ -0,0 +1,59 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "lstrReader.h" +#include "lstrFormat.h" +#include "dbLoadLayoutOptions.h" +#include "layLStreamReaderPlugin.h" +#include "gsiDecl.h" + +namespace lay +{ + +// --------------------------------------------------------------- +// LStreamReaderPluginDeclaration definition and implementation + +class LStreamReaderPluginDeclaration + : public StreamReaderPluginDeclaration +{ +public: + LStreamReaderPluginDeclaration () + : StreamReaderPluginDeclaration (lstr::ReaderOptions ().format_name ()) + { + // .. nothing yet .. + } + + StreamReaderOptionsPage *format_specific_options_page (QWidget *parent) const + { + return 0; + } + + db::FormatSpecificReaderOptions *create_specific_options () const + { + return new lstr::ReaderOptions (); + } +}; + +static tl::RegisteredClass plugin_decl (new lay::LStreamReaderPluginDeclaration (), 10000, "LStreamReader"); + +} + diff --git a/src/plugins/streamers/lstream/lay_plugin/layLStreamReaderPlugin.h b/src/plugins/streamers/lstream/lay_plugin/layLStreamReaderPlugin.h new file mode 100644 index 000000000..09347526e --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/layLStreamReaderPlugin.h @@ -0,0 +1,38 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_layLStreamReaderPlugin_h +#define HDR_layLStreamReaderPlugin_h + +#include "layStream.h" + +namespace lay +{ + +// .. nothing yet .. + +} + +#endif + + diff --git a/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.cc b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.cc new file mode 100644 index 000000000..504391031 --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.cc @@ -0,0 +1,99 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "dbSaveLayoutOptions.h" +#include "lstrWriter.h" +#include "lstrFormat.h" +#include "layLStreamWriterPlugin.h" + +#include + +namespace lay +{ + +// --------------------------------------------------------------- +// LStreamWriterOptionPage definition and implementation + +LStreamWriterOptionPage::LStreamWriterOptionPage (QWidget *parent) + : StreamWriterOptionsPage (parent) +{ + mp_ui = new Ui::LStreamWriterOptionPage (); + mp_ui->setupUi (this); +} + +LStreamWriterOptionPage::~LStreamWriterOptionPage () +{ + delete mp_ui; +} + +void +LStreamWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/) +{ + const lstr::WriterOptions *options = dynamic_cast (o); + if (options) { + mp_ui->compression_slider->setValue (options->compression_level); + mp_ui->permissive->setChecked (options->permissive); + } +} + +void +LStreamWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Technology * /*tech*/, bool gzip) +{ + lstr::WriterOptions *options = dynamic_cast (o); + if (options) { + options->compression_level = mp_ui->compression_slider->value (); + options->permissive = mp_ui->permissive->isChecked (); + } +} + +// --------------------------------------------------------------- +// LStreamWriterPluginDeclaration definition and implementation + +class LStreamWriterPluginDeclaration + : public StreamWriterPluginDeclaration +{ +public: + LStreamWriterPluginDeclaration () + : StreamWriterPluginDeclaration (lstr::WriterOptions ().format_name ()) + { + // .. nothing yet .. + } + + StreamWriterOptionsPage *format_specific_options_page (QWidget *parent) const + { + return new LStreamWriterOptionPage (parent); + } + + db::FormatSpecificWriterOptions *create_specific_options () const + { + return new lstr::WriterOptions (); + } +}; + +static tl::RegisteredClass plugin_decl (new lay::LStreamWriterPluginDeclaration (), 10002, "LStreamWriter"); + +} + + + + diff --git a/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.h b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.h new file mode 100644 index 000000000..3b7510e5c --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/layLStreamWriterPlugin.h @@ -0,0 +1,52 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2025 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_layLStreamWriterPlugin_h +#define HDR_layLStreamWriterPlugin_h + +#include "layStream.h" +#include "ui_LStreamWriterOptionPage.h" + +namespace lay +{ + +class LStreamWriterOptionPage + : public StreamWriterOptionsPage +{ +Q_OBJECT + +public: + LStreamWriterOptionPage (QWidget *parent); + ~LStreamWriterOptionPage (); + + void setup (const db::FormatSpecificWriterOptions *options, const db::Technology *tech); + void commit (db::FormatSpecificWriterOptions *options, const db::Technology *tech, bool gzip); + +private: + Ui::LStreamWriterOptionPage *mp_ui; +}; + +} + +#endif + diff --git a/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro b/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro new file mode 100644 index 000000000..bac0bd3f6 --- /dev/null +++ b/src/plugins/streamers/lstream/lay_plugin/lay_plugin.pro @@ -0,0 +1,25 @@ + +DESTDIR = $$OUT_PWD/../../../../lay_plugins + +include($$PWD/../../../lay_plugin.pri) +include($$PWD/../lstream.pri) + +INCLUDEPATH += $$PWD/../db_plugin $$PWD/../db_plugin/capnp +DEPENDPATH += $$PWD/../db_plugin +LIBS += -L$$DESTDIR/../db_plugins -llstream + +!isEmpty(RPATH) { + QMAKE_RPATHDIR += $$RPATH/db_plugins +} + +HEADERS = \ + layLStreamReaderPlugin.h \ + layLStreamWriterPlugin.h \ + +SOURCES = \ + layLStreamReaderPlugin.cc \ + layLStreamWriterPlugin.cc \ + +FORMS = \ + LStreamWriterOptionPage.ui \ + diff --git a/src/plugins/streamers/lstream/lstream.pri b/src/plugins/streamers/lstream/lstream.pri new file mode 100644 index 000000000..05b84310e --- /dev/null +++ b/src/plugins/streamers/lstream/lstream.pri @@ -0,0 +1,15 @@ + +!msvc { + + # capnp needs C++ 14 in version 1.0.1 + # Qt6 comes with C++ 17 requirement. + equals(HAVE_QT, "0") || lessThan(QT_MAJOR_VERSION, 6) { + QMAKE_CXXFLAGS += -std=c++14 + } + + # capnp runtimes have some unused arguments + QMAKE_CXXFLAGS += \ + -Wno-unused-parameter +} + + INCLUDEPATH += $$PWD/runtime/capnp $$PWD/runtime/kj diff --git a/src/plugins/streamers/lstream/lstream.pro b/src/plugins/streamers/lstream/lstream.pro new file mode 100644 index 000000000..c0a135563 --- /dev/null +++ b/src/plugins/streamers/lstream/lstream.pro @@ -0,0 +1,16 @@ + +TEMPLATE = subdirs + +!equals(HAVE_LSTREAM, "0") { + + SUBDIRS = runtime db_plugin unit_tests + db_plugin.depends += runtime + unit_tests.depends += db_plugin + + !equals(HAVE_QT, "0") { + SUBDIRS += lay_plugin + lay_plugin.depends += db_plugin + } + +} + diff --git a/src/plugins/streamers/lstream/runtime/README.md b/src/plugins/streamers/lstream/runtime/README.md new file mode 100644 index 000000000..7157df3af --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/README.md @@ -0,0 +1,13 @@ + +# Cap'n'Proto runtime libraries + +This code reflects version 1.0.1 of the kj and capnp library. + +The "fetch.sh" script is used to populate this folder and to +adapt the original project to qmake. + +The original license files are found here: + + capnp/LICENSE + kj/LICENSE + diff --git a/src/plugins/streamers/lstream/runtime/capnp.pro b/src/plugins/streamers/lstream/runtime/capnp.pro new file mode 100644 index 000000000..60e6923c9 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp.pro @@ -0,0 +1,17 @@ + +TEMPLATE = lib +DESTDIR = $$OUT_PWD/../../../../.. +INCLUDEPATH = + +include($$PWD/../../lstream.pri) +include($$PWD/capnp.pri) + +TARGET = xcapnp +CONFIG += staticlib +SOURCES = $$CAPNP_SOURCES +HEADERS = $$CAPNP_HEADERS + +DEFINES += CAPNP_LITE +LIBS = +QT = + diff --git a/src/plugins/streamers/lstream/runtime/capnp/CONTRIBUTORS b/src/plugins/streamers/lstream/runtime/capnp/CONTRIBUTORS new file mode 100644 index 000000000..24902a940 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/CONTRIBUTORS @@ -0,0 +1,23 @@ +The following people have made large code contributions to this repository. +Those contributions are copyright the respective authors and licensed by them +under the same MIT license terms as the rest of the library. + +Kenton Varda : Primary Author +Jason Choy : kj/threadlocal.h and other iOS tweaks, `name` annotation in C++ code generator +Remy Blank (contributions copyright Google Inc.): KJ Timers +Joshua Warner : cmake build, AnyStruct/AnyList, other stuff +Scott Purdy : kj/std iostream interface +Bryan Borham : Initial MSVC support +Philip Quinn : cmake build and other assorted bits +Brian Taylor : emacs syntax highlighting +Ben Laurie : discovered and responsibly disclosed security bugs +Kamal Marhubi : JSON parser +Oliver Kuckertz : FdObserver POLLPRI support +Harris Hancock : MSVC support +Branislav Katreniak : JSON decode +Matthew Maurer : Canonicalization Support +David Renshaw : bugfixes and miscellaneous maintenance +Ingvar Stepanyan : Custom handlers for JSON decode + +This file does not list people who maintain their own Cap'n Proto +implementations as separate projects. Those people are awesome too! :) diff --git a/src/plugins/streamers/lstream/runtime/capnp/LICENSE b/src/plugins/streamers/lstream/runtime/capnp/LICENSE new file mode 100644 index 000000000..1eabc941f --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013-2017 Sandstorm Development Group, Inc.; Cloudflare, Inc.; +and other contributors. Each commit is copyright by its respective author or +author's employer. + +Licensed under the MIT License: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp.pri b/src/plugins/streamers/lstream/runtime/capnp/capnp.pri new file mode 100644 index 000000000..6fc715985 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp.pri @@ -0,0 +1,43 @@ + +CAPNP_SOURCES=\ + capnp/c++.capnp.cc \ + capnp/blob.cc \ + capnp/arena.cc \ + capnp/layout.cc \ + capnp/list.cc \ + capnp/any.cc \ + capnp/message.cc \ + capnp/schema.capnp.cc \ + capnp/stream.capnp.cc \ + capnp/serialize.cc \ + capnp/serialize-packed.cc \ + +CAPNP_HEADERS=\ + capnp/arena.h \ + capnp/c++.capnp.h \ + capnp/common.h \ + capnp/blob.h \ + capnp/endian.h \ + capnp/layout.h \ + capnp/orphan.h \ + capnp/list.h \ + capnp/any.h \ + capnp/message.h \ + capnp/capability.h \ + capnp/membrane.h \ + capnp/dynamic.h \ + capnp/schema.h \ + capnp/schema.capnp.h \ + capnp/stream.capnp.h \ + capnp/schema-lite.h \ + capnp/schema-loader.h \ + capnp/schema-parser.h \ + capnp/pretty-print.h \ + capnp/serialize.h \ + capnp/serialize-async.h \ + capnp/serialize-packed.h \ + capnp/serialize-text.h \ + capnp/pointer-helpers.h \ + capnp/generated-header-support.h \ + capnp/raw-schema.h \ + capnp/compat/std-iterator.h \ diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp.pro b/src/plugins/streamers/lstream/runtime/capnp/capnp.pro new file mode 100644 index 000000000..6241259d7 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp.pro @@ -0,0 +1,20 @@ +# DO NOT EDIT! +# (SEE ../capnp.pro) + + +TEMPLATE = lib +DESTDIR = $$OUT_PWD/../../../../.. +INCLUDEPATH = + +include($$PWD/../../lstream.pri) +include($$PWD/capnp.pri) + +TARGET = xcapnp +CONFIG += staticlib +SOURCES = $$CAPNP_SOURCES +HEADERS = $$CAPNP_HEADERS + +DEFINES += CAPNP_LITE +LIBS = +QT = + diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/any.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/any.cc new file mode 100644 index 000000000..5439bf545 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/any.cc @@ -0,0 +1,269 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "any.h" + +#include + +#if !CAPNP_LITE +#include "capability.h" +#endif // !CAPNP_LITE + +namespace capnp { + +#if !CAPNP_LITE + +kj::Own PipelineHook::getPipelinedCap(kj::Array&& ops) { + return getPipelinedCap(ops.asPtr()); +} + +kj::Own AnyPointer::Reader::getPipelinedCap( + kj::ArrayPtr ops) const { + _::PointerReader pointer = reader; + + for (auto& op: ops) { + switch (op.type) { + case PipelineOp::Type::NOOP: + break; + + case PipelineOp::Type::GET_POINTER_FIELD: + pointer = pointer.getStruct(nullptr).getPointerField(bounded(op.pointerIndex) * POINTERS); + break; + } + } + + return pointer.getCapability(); +} + +AnyPointer::Pipeline AnyPointer::Pipeline::noop() { + auto newOps = kj::heapArray(ops.size()); + for (auto i: kj::indices(ops)) { + newOps[i] = ops[i]; + } + return Pipeline(hook->addRef(), kj::mv(newOps)); +} + +AnyPointer::Pipeline AnyPointer::Pipeline::getPointerField(uint16_t pointerIndex) { + auto newOps = kj::heapArray(ops.size() + 1); + for (auto i: kj::indices(ops)) { + newOps[i] = ops[i]; + } + auto& newOp = newOps[ops.size()]; + newOp.type = PipelineOp::GET_POINTER_FIELD; + newOp.pointerIndex = pointerIndex; + + return Pipeline(hook->addRef(), kj::mv(newOps)); +} + +kj::Own AnyPointer::Pipeline::asCap() { + return hook->getPipelinedCap(ops); +} + +#endif // !CAPNP_LITE + +Equality AnyStruct::Reader::equals(AnyStruct::Reader right) const { + auto dataL = getDataSection(); + size_t dataSizeL = dataL.size(); + while(dataSizeL > 0 && dataL[dataSizeL - 1] == 0) { + -- dataSizeL; + } + + auto dataR = right.getDataSection(); + size_t dataSizeR = dataR.size(); + while(dataSizeR > 0 && dataR[dataSizeR - 1] == 0) { + -- dataSizeR; + } + + if(dataSizeL != dataSizeR) { + return Equality::NOT_EQUAL; + } + + if(0 != memcmp(dataL.begin(), dataR.begin(), dataSizeL)) { + return Equality::NOT_EQUAL; + } + + auto ptrsL = getPointerSection(); + size_t ptrsSizeL = ptrsL.size(); + while (ptrsSizeL > 0 && ptrsL[ptrsSizeL - 1].isNull()) { + -- ptrsSizeL; + } + + auto ptrsR = right.getPointerSection(); + size_t ptrsSizeR = ptrsR.size(); + while (ptrsSizeR > 0 && ptrsR[ptrsSizeR - 1].isNull()) { + -- ptrsSizeR; + } + + if(ptrsSizeL != ptrsSizeR) { + return Equality::NOT_EQUAL; + } + + size_t i = 0; + + auto eqResult = Equality::EQUAL; + for (; i < ptrsSizeL; i++) { + auto l = ptrsL[i]; + auto r = ptrsR[i]; + switch(l.equals(r)) { + case Equality::EQUAL: + break; + case Equality::NOT_EQUAL: + return Equality::NOT_EQUAL; + case Equality::UNKNOWN_CONTAINS_CAPS: + eqResult = Equality::UNKNOWN_CONTAINS_CAPS; + break; + default: + KJ_UNREACHABLE; + } + } + + return eqResult; +} + +kj::StringPtr KJ_STRINGIFY(Equality res) { + switch(res) { + case Equality::NOT_EQUAL: + return "NOT_EQUAL"; + case Equality::EQUAL: + return "EQUAL"; + case Equality::UNKNOWN_CONTAINS_CAPS: + return "UNKNOWN_CONTAINS_CAPS"; + } + KJ_UNREACHABLE; +} + +Equality AnyList::Reader::equals(AnyList::Reader right) const { + if(size() != right.size()) { + return Equality::NOT_EQUAL; + } + + if (getElementSize() != right.getElementSize()) { + return Equality::NOT_EQUAL; + } + + auto eqResult = Equality::EQUAL; + switch(getElementSize()) { + case ElementSize::VOID: + case ElementSize::BIT: + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: { + size_t cmpSize = getRawBytes().size(); + + if (getElementSize() == ElementSize::BIT && size() % 8 != 0) { + // The list does not end on a byte boundary. We need special handling for the final + // byte because we only care about the bits that are actually elements of the list. + + uint8_t mask = (1 << (size() % 8)) - 1; // lowest size() bits set + if ((getRawBytes()[cmpSize - 1] & mask) != (right.getRawBytes()[cmpSize - 1] & mask)) { + return Equality::NOT_EQUAL; + } + cmpSize -= 1; + } + + if (memcmp(getRawBytes().begin(), right.getRawBytes().begin(), cmpSize) == 0) { + return Equality::EQUAL; + } else { + return Equality::NOT_EQUAL; + } + } + case ElementSize::POINTER: + case ElementSize::INLINE_COMPOSITE: { + auto llist = as>(); + auto rlist = right.as>(); + for(size_t i = 0; i < size(); i++) { + switch(llist[i].equals(rlist[i])) { + case Equality::EQUAL: + break; + case Equality::NOT_EQUAL: + return Equality::NOT_EQUAL; + case Equality::UNKNOWN_CONTAINS_CAPS: + eqResult = Equality::UNKNOWN_CONTAINS_CAPS; + break; + default: + KJ_UNREACHABLE; + } + } + return eqResult; + } + } + KJ_UNREACHABLE; +} + +Equality AnyPointer::Reader::equals(AnyPointer::Reader right) const { + if(getPointerType() != right.getPointerType()) { + return Equality::NOT_EQUAL; + } + switch(getPointerType()) { + case PointerType::NULL_: + return Equality::EQUAL; + case PointerType::STRUCT: + return getAs().equals(right.getAs()); + case PointerType::LIST: + return getAs().equals(right.getAs()); + case PointerType::CAPABILITY: + return Equality::UNKNOWN_CONTAINS_CAPS; + } + // There aren't currently any other types of pointers + KJ_UNREACHABLE; +} + +bool AnyPointer::Reader::operator==(AnyPointer::Reader right) const { + switch(equals(right)) { + case Equality::EQUAL: + return true; + case Equality::NOT_EQUAL: + return false; + case Equality::UNKNOWN_CONTAINS_CAPS: + KJ_FAIL_REQUIRE( + "operator== cannot determine equality of capabilities; use equals() instead if you need to handle this case"); + } + KJ_UNREACHABLE; +} + +bool AnyStruct::Reader::operator==(AnyStruct::Reader right) const { + switch(equals(right)) { + case Equality::EQUAL: + return true; + case Equality::NOT_EQUAL: + return false; + case Equality::UNKNOWN_CONTAINS_CAPS: + KJ_FAIL_REQUIRE( + "operator== cannot determine equality of capabilities; use equals() instead if you need to handle this case"); + } + KJ_UNREACHABLE; +} + +bool AnyList::Reader::operator==(AnyList::Reader right) const { + switch(equals(right)) { + case Equality::EQUAL: + return true; + case Equality::NOT_EQUAL: + return false; + case Equality::UNKNOWN_CONTAINS_CAPS: + KJ_FAIL_REQUIRE( + "operator== cannot determine equality of capabilities; use equals() instead if you need to handle this case"); + } + KJ_UNREACHABLE; +} + +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/any.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/any.h new file mode 100644 index 000000000..94b527dc3 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/any.h @@ -0,0 +1,1131 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "layout.h" +#include "pointer-helpers.h" +#include "orphan.h" +#include "list.h" +#include // work-around macro conflict with `VOID` +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class StructSchema; +class ListSchema; +class InterfaceSchema; +class Orphanage; +class ClientHook; +class PipelineHook; +struct PipelineOp; +struct AnyPointer; + +struct AnyList { + AnyList() = delete; + + class Reader; + class Builder; +}; + +struct AnyStruct { + AnyStruct() = delete; + + class Reader; + class Builder; + class Pipeline; +}; + +template<> +struct List { + List() = delete; + + class Reader; + class Builder; +}; + +namespace _ { // private +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +} // namespace _ (private) + +// ======================================================================================= +// AnyPointer! + +enum class Equality { + NOT_EQUAL, + EQUAL, + UNKNOWN_CONTAINS_CAPS +}; + +kj::StringPtr KJ_STRINGIFY(Equality res); + +struct AnyPointer { + // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary + // object. + + AnyPointer() = delete; + + class Reader { + public: + typedef AnyPointer Reads; + + Reader() = default; + inline Reader(_::PointerReader reader): reader(reader) {} + + inline MessageSize targetSize() const; + // Get the total size of the target object and all its children. + + inline PointerType getPointerType() const; + + inline bool isNull() const { return getPointerType() == PointerType::NULL_; } + inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; } + inline bool isList() const { return getPointerType() == PointerType::LIST; } + inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; } + + Equality equals(AnyPointer::Reader right) const; + bool operator==(AnyPointer::Reader right) const; + inline bool operator!=(AnyPointer::Reader right) const { + return !(*this == right); + } + + template + inline ReaderFor getAs() const; + // Valid for T = any generated struct type, interface type, List, Text, or Data. + + template + inline ReaderFor getAs(StructSchema schema) const; + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline ReaderFor getAs(ListSchema schema) const; + // Only valid for T = DynamicList. Requires `#include `. + + template + inline ReaderFor getAs(InterfaceSchema schema) const; + // Only valid for T = DynamicCapability. Requires `#include `. + +#if !CAPNP_LITE + kj::Own getPipelinedCap(kj::ArrayPtr ops) const; + // Used by RPC system to implement pipelining. Applications generally shouldn't use this + // directly. +#endif // !CAPNP_LITE + + private: + _::PointerReader reader; + friend struct AnyPointer; + friend class Orphanage; + friend class CapReaderContext; + friend struct _::PointerHelpers; + }; + + class Builder { + public: + typedef AnyPointer Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)) {} + inline Builder(_::PointerBuilder builder): builder(builder) {} + + inline MessageSize targetSize() const; + // Get the total size of the target object and all its children. + + inline PointerType getPointerType(); + + inline bool isNull() { return getPointerType() == PointerType::NULL_; } + inline bool isStruct() { return getPointerType() == PointerType::STRUCT; } + inline bool isList() { return getPointerType() == PointerType::LIST; } + inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; } + + inline Equality equals(AnyPointer::Reader right) const { + return asReader().equals(right); + } + inline bool operator==(AnyPointer::Reader right) const { + return asReader() == right; + } + inline bool operator!=(AnyPointer::Reader right) const { + return !(*this == right); + } + + inline void clear(); + // Set to null. + + template + inline BuilderFor getAs(); + // Valid for T = any generated struct type, List, Text, or Data. + + template + inline BuilderFor getAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline BuilderFor getAs(ListSchema schema); + // Only valid for T = DynamicList. Requires `#include `. + + template + inline BuilderFor getAs(InterfaceSchema schema); + // Only valid for T = DynamicCapability. Requires `#include `. + + template + inline BuilderFor initAs(); + // Valid for T = any generated struct type. + + template + inline BuilderFor initAs(uint elementCount); + // Valid for T = List, Text, or Data. + + template + inline BuilderFor initAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline BuilderFor initAs(ListSchema schema, uint elementCount); + // Only valid for T = DynamicList. Requires `#include `. + + inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount); + // Note: Does not accept INLINE_COMPOSITE for elementSize. + + inline List::Builder initAsListOfAnyStruct( + uint16_t dataWordCount, uint16_t pointerCount, uint elementCount); + + inline AnyStruct::Builder initAsAnyStruct(uint16_t dataWordCount, uint16_t pointerCount); + + template + inline void setAs(ReaderFor value); + // Valid for ReaderType = T::Reader for T = any generated struct type, List, Text, Data, + // DynamicStruct, or DynamicList (the dynamic types require `#include `). + + template + inline void setAs(std::initializer_list>> list); + // Valid for T = List. + + template + inline void setCanonicalAs(ReaderFor value); + + inline void set(Reader value) { builder.copyFrom(value.reader); } + // Set to a copy of another AnyPointer. + + inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); } + + template + inline void adopt(Orphan&& orphan); + // Valid for T = any generated struct type, List, Text, Data, DynamicList, DynamicStruct, + // or DynamicValue (the dynamic types require `#include `). + + template + inline Orphan disownAs(); + // Valid for T = any generated struct type, List, Text, Data. + + template + inline Orphan disownAs(StructSchema schema); + // Only valid for T = DynamicStruct. Requires `#include `. + + template + inline Orphan disownAs(ListSchema schema); + // Only valid for T = DynamicList. Requires `#include `. + + template + inline Orphan disownAs(InterfaceSchema schema); + // Only valid for T = DynamicCapability. Requires `#include `. + + inline Orphan disown(); + // Disown without a type. + + inline Reader asReader() const { return Reader(builder.asReader()); } + inline operator Reader() const { return Reader(builder.asReader()); } + + private: + _::PointerBuilder builder; + friend class Orphanage; + friend class CapBuilderContext; + friend struct _::PointerHelpers; + }; + +#if !CAPNP_LITE + class Pipeline { + public: + typedef AnyPointer Pipelines; + + inline Pipeline(decltype(nullptr)) {} + inline explicit Pipeline(kj::Own&& hook): hook(kj::mv(hook)) {} + + Pipeline noop(); + // Just make a copy. + + Pipeline getPointerField(uint16_t pointerIndex); + // Deprecated. In the future, we should use .asAnyStruct.getPointerField. + + inline AnyStruct::Pipeline asAnyStruct(); + + kj::Own asCap(); + // Expect that the result is a capability and construct a pipelined version of it now. + + inline kj::Own releasePipelineHook() { return kj::mv(hook); } + // For use by RPC implementations. + + template ) == Kind::INTERFACE>> + inline operator T() { return T(asCap()); } + + private: + kj::Own hook; + kj::Array ops; + + inline Pipeline(kj::Own&& hook, kj::Array&& ops) + : hook(kj::mv(hook)), ops(kj::mv(ops)) {} + + friend class LocalClient; + friend class PipelineHook; + friend class AnyStruct::Pipeline; + }; +#endif // !CAPNP_LITE +}; + +template <> +class Orphan { + // An orphaned object of unknown type. + +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + inline Orphan(_::OrphanBuilder&& builder) + : builder(kj::mv(builder)) {} + + Orphan& operator=(Orphan&&) = default; + + template + inline Orphan(Orphan&& other): builder(kj::mv(other.builder)) {} + template + inline Orphan& operator=(Orphan&& other) { builder = kj::mv(other.builder); return *this; } + // Cast from typed orphan. + + // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no + // underlying pointer (the pointer would normally live in the parent, but this object is + // orphaned). It is possible, however, to request typed readers/builders. + + template + inline BuilderFor getAs(); + template + inline BuilderFor getAs(StructSchema schema); + template + inline BuilderFor getAs(ListSchema schema); + template + inline typename T::Client getAs(InterfaceSchema schema); + template + inline ReaderFor getAsReader() const; + template + inline ReaderFor getAsReader(StructSchema schema) const; + template + inline ReaderFor getAsReader(ListSchema schema) const; + template + inline typename T::Client getAsReader(InterfaceSchema schema) const; + + template + inline Orphan releaseAs(); + template + inline Orphan releaseAs(StructSchema schema); + template + inline Orphan releaseAs(ListSchema schema); + template + inline Orphan releaseAs(InterfaceSchema schema); + // Down-cast the orphan to a specific type. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + _::OrphanBuilder builder; + + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend class Orphan; + friend class AnyPointer::Builder; +}; + +template struct AnyTypeFor_; +template <> struct AnyTypeFor_ { typedef AnyStruct Type; }; +template <> struct AnyTypeFor_ { typedef AnyList Type; }; + +template +using AnyTypeFor = typename AnyTypeFor_::Type; + +template +inline ReaderFor>> toAny(T&& value) { + return ReaderFor>>( + _::PointerHelpers>::getInternalReader(value)); +} +template +inline BuilderFor>> toAny(T&& value) { + return BuilderFor>>( + _::PointerHelpers>::getInternalBuilder(kj::mv(value))); +} + +template <> +struct List { + // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer + // lists! Use List. + + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline AnyPointer::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return AnyPointer::Reader(reader.getPointerElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline AnyPointer::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return AnyPointer::Builder(builder.getPointerElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; +}; + +class AnyStruct::Reader { +public: + typedef AnyStruct Reads; + + Reader() = default; + inline Reader(_::StructReader reader): _reader(reader) {} + + template ) == Kind::STRUCT>> + inline Reader(T&& value) + : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} + + inline MessageSize totalSize() const { return _reader.totalSize().asPublic(); } + + kj::ArrayPtr getDataSection() const { + return _reader.getDataSectionAsBlob(); + } + List::Reader getPointerSection() const { + return List::Reader(_reader.getPointerSectionAsList()); + } + + kj::Array canonicalize() { + return _reader.canonicalize(); + } + + Equality equals(AnyStruct::Reader right) const; + bool operator==(AnyStruct::Reader right) const; + inline bool operator!=(AnyStruct::Reader right) const { + return !(*this == right); + } + + template + ReaderFor as() const { + // T must be a struct type. + return typename T::Reader(_reader); + } + + template + ReaderFor as(StructSchema schema) const; + // T must be DynamicStruct. Defined in dynamic.h. + +private: + _::StructReader _reader; + + template + friend struct _::PointerHelpers; + friend class Orphanage; +}; + +class AnyStruct::Builder { +public: + typedef AnyStruct Builds; + + inline Builder(decltype(nullptr)) {} + inline Builder(_::StructBuilder builder): _builder(builder) {} + +#if !_MSC_VER || defined(__clang__) // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template ) == Kind::STRUCT>> + inline Builder(T&& value) + : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} +#endif + + inline kj::ArrayPtr getDataSection() { + return _builder.getDataSectionAsBlob(); + } + List::Builder getPointerSection() { + return List::Builder(_builder.getPointerSectionAsList()); + } + + inline Equality equals(AnyStruct::Reader right) const { + return asReader().equals(right); + } + inline bool operator==(AnyStruct::Reader right) const { + return asReader() == right; + } + inline bool operator!=(AnyStruct::Reader right) const { + return !(*this == right); + } + + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return Reader(_builder.asReader()); } + + template + BuilderFor as() { + // T must be a struct type. + return typename T::Builder(_builder); + } + + template + BuilderFor as(StructSchema schema); + // T must be DynamicStruct. Defined in dynamic.h. + +private: + _::StructBuilder _builder; + friend class Orphanage; + friend class CapBuilderContext; +}; + +#if !CAPNP_LITE +class AnyStruct::Pipeline { +public: + inline Pipeline(decltype(nullptr)): typeless(nullptr) {} + inline explicit Pipeline(AnyPointer::Pipeline&& typeless) + : typeless(kj::mv(typeless)) {} + + inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) { + // Return a new Promise representing a sub-object of the result. `pointerIndex` is the index + // of the sub-object within the pointer section of the result (the result must be a struct). + // + // TODO(perf): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies. + // Also make `ops` into a Vector to optimize this. + return typeless.getPointerField(pointerIndex); + } + +private: + AnyPointer::Pipeline typeless; +}; +#endif // !CAPNP_LITE + +class List::Reader { +public: + typedef List Reads; + + inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline AnyStruct::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return AnyStruct::Reader(reader.getStructElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + +private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; +}; + +class List::Builder { +public: + typedef List Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline AnyStruct::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return AnyStruct::Builder(builder.getStructElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + +private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; +}; + +class AnyList::Reader { +public: + typedef AnyList Reads; + + inline Reader(): _reader(ElementSize::VOID) {} + inline Reader(_::ListReader reader): _reader(reader) {} + +#if !_MSC_VER || defined(__clang__) // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template ) == Kind::LIST>> + inline Reader(T&& value) + : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} +#endif + + inline ElementSize getElementSize() const { return _reader.getElementSize(); } + inline uint size() const { return unbound(_reader.size() / ELEMENTS); } + + inline kj::ArrayPtr getRawBytes() const { return _reader.asRawBytes(); } + + Equality equals(AnyList::Reader right) const; + bool operator==(AnyList::Reader right) const; + inline bool operator!=(AnyList::Reader right) const { + return !(*this == right); + } + + inline MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + + template ReaderFor as() const { + // T must be List. + return ReaderFor(_reader); + } +private: + _::ListReader _reader; + + template + friend struct _::PointerHelpers; + friend class Orphanage; +}; + +class AnyList::Builder { +public: + typedef AnyList Builds; + + inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {} + inline Builder(_::ListBuilder builder): _builder(builder) {} + +#if !_MSC_VER || defined(__clang__) // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. + template ) == Kind::LIST>> + inline Builder(T&& value) + : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} +#endif + + inline ElementSize getElementSize() { return _builder.getElementSize(); } + inline uint size() { return unbound(_builder.size() / ELEMENTS); } + + Equality equals(AnyList::Reader right) const; + inline bool operator==(AnyList::Reader right) const{ + return asReader() == right; + } + inline bool operator!=(AnyList::Reader right) const{ + return !(*this == right); + } + + template BuilderFor as() { + // T must be List. + return BuilderFor(_builder); + } + + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return Reader(_builder.asReader()); } + +private: + _::ListBuilder _builder; + + friend class Orphanage; +}; + +// ======================================================================================= +// Pipeline helpers +// +// These relate to capabilities, but we don't declare them in capability.h because generated code +// for structs needs to know about these, even in files that contain no interfaces. + +#if !CAPNP_LITE + +struct PipelineOp { + // Corresponds to rpc.capnp's PromisedAnswer.Op. + + enum Type { + NOOP, // for convenience + + GET_POINTER_FIELD + + // There may be other types in the future... + }; + + Type type; + union { + uint16_t pointerIndex; // for GET_POINTER_FIELD + }; +}; + +inline uint KJ_HASHCODE(const PipelineOp& op) { + switch (op.type) { + case PipelineOp::NOOP: return kj::hashCode(op.type); + case PipelineOp::GET_POINTER_FIELD: return kj::hashCode(op.type, op.pointerIndex); + } + KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT +} + +inline bool operator==(const PipelineOp& a, const PipelineOp& b) { + if (a.type != b.type) return false; + switch (a.type) { + case PipelineOp::NOOP: return true; + case PipelineOp::GET_POINTER_FIELD: return a.pointerIndex == b.pointerIndex; + } + KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT +} + +inline bool operator!=(const PipelineOp& a, const PipelineOp& b) { + return !(a == b); +} + +class PipelineHook { + // Represents a currently-running call, and implements pipelined requests on its result. + +public: + virtual kj::Own addRef() = 0; + // Increment this object's reference count. + + virtual kj::Own getPipelinedCap(kj::ArrayPtr ops) = 0; + // Extract a promised Capability from the results. + + virtual kj::Own getPipelinedCap(kj::Array&& ops); + // Version of getPipelinedCap() passing the array by move. May avoid a copy in some cases. + // Default implementation just calls the other version. + + template > + static inline kj::Own from(Pipeline&& pipeline); + + template > + static inline PipelineHook& from(Pipeline& pipeline); + +private: + template struct FromImpl; +}; + +#endif // !CAPNP_LITE + +// ======================================================================================= +// Inline implementation details + +inline MessageSize AnyPointer::Reader::targetSize() const { + return reader.targetSize().asPublic(); +} + +inline PointerType AnyPointer::Reader::getPointerType() const { + return reader.getPointerType(); +} + +template +inline ReaderFor AnyPointer::Reader::getAs() const { + return _::PointerHelpers::get(reader); +} + +inline MessageSize AnyPointer::Builder::targetSize() const { + return asReader().targetSize(); +} + +inline PointerType AnyPointer::Builder::getPointerType() { + return builder.getPointerType(); +} + +inline void AnyPointer::Builder::clear() { + return builder.clear(); +} + +template +inline BuilderFor AnyPointer::Builder::getAs() { + return _::PointerHelpers::get(builder); +} + +template +inline BuilderFor AnyPointer::Builder::initAs() { + return _::PointerHelpers::init(builder); +} + +template +inline BuilderFor AnyPointer::Builder::initAs(uint elementCount) { + return _::PointerHelpers::init(builder, elementCount); +} + +inline AnyList::Builder AnyPointer::Builder::initAsAnyList( + ElementSize elementSize, uint elementCount) { + return AnyList::Builder(builder.initList(elementSize, bounded(elementCount) * ELEMENTS)); +} + +inline List::Builder AnyPointer::Builder::initAsListOfAnyStruct( + uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) { + return List::Builder(builder.initStructList(bounded(elementCount) * ELEMENTS, + _::StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); +} + +inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct( + uint16_t dataWordCount, uint16_t pointerCount) { + return AnyStruct::Builder(builder.initStruct( + _::StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); +} + +template +inline void AnyPointer::Builder::setAs(ReaderFor value) { + return _::PointerHelpers::set(builder, value); +} + +template +inline void AnyPointer::Builder::setCanonicalAs(ReaderFor value) { + return _::PointerHelpers::setCanonical(builder, value); +} + +template +inline void AnyPointer::Builder::setAs( + std::initializer_list>> list) { + return _::PointerHelpers::set(builder, list); +} + +template +inline void AnyPointer::Builder::adopt(Orphan&& orphan) { + _::PointerHelpers::adopt(builder, kj::mv(orphan)); +} + +template +inline Orphan AnyPointer::Builder::disownAs() { + return _::PointerHelpers::disown(builder); +} + +inline Orphan AnyPointer::Builder::disown() { + return Orphan(builder.disown()); +} + +template <> struct ReaderFor_ { typedef AnyPointer::Reader Type; }; +template <> struct BuilderFor_ { typedef AnyPointer::Builder Type; }; +template <> struct ReaderFor_ { typedef AnyStruct::Reader Type; }; +template <> struct BuilderFor_ { typedef AnyStruct::Builder Type; }; + +template <> +struct Orphanage::GetInnerReader { + static inline _::PointerReader apply(const AnyPointer::Reader& t) { + return t.reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::PointerBuilder apply(AnyPointer::Builder& t) { + return t.builder; + } +}; + +template <> +struct Orphanage::GetInnerReader { + static inline _::StructReader apply(const AnyStruct::Reader& t) { + return t._reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::StructBuilder apply(AnyStruct::Builder& t) { + return t._builder; + } +}; + +template <> +struct Orphanage::GetInnerReader { + static inline _::ListReader apply(const AnyList::Reader& t) { + return t._reader; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::ListBuilder apply(AnyList::Builder& t) { + return t._builder; + } +}; + +template +inline BuilderFor Orphan::getAs() { + return _::OrphanGetImpl::apply(builder); +} +template +inline ReaderFor Orphan::getAsReader() const { + return _::OrphanGetImpl::applyReader(builder); +} +template +inline Orphan Orphan::releaseAs() { + return Orphan(kj::mv(builder)); +} + +// Using AnyPointer as the template type should work... + +template <> +inline typename AnyPointer::Reader AnyPointer::Reader::getAs() const { + return *this; +} +template <> +inline typename AnyPointer::Builder AnyPointer::Builder::getAs() { + return *this; +} +template <> +inline typename AnyPointer::Builder AnyPointer::Builder::initAs() { + clear(); + return *this; +} +template <> +inline void AnyPointer::Builder::setAs(AnyPointer::Reader value) { + return builder.copyFrom(value.reader); +} +template <> +inline void AnyPointer::Builder::adopt(Orphan&& orphan) { + builder.adopt(kj::mv(orphan.builder)); +} +template <> +inline Orphan AnyPointer::Builder::disownAs() { + return Orphan(builder.disown()); +} +template <> +inline Orphan Orphan::releaseAs() { + return kj::mv(*this); +} + +namespace _ { // private + +// Specialize PointerHelpers for AnyPointer. + +template <> +struct PointerHelpers { + static inline AnyPointer::Reader get(PointerReader reader, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return AnyPointer::Reader(reader); + } + static inline AnyPointer::Builder get(PointerBuilder builder, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return AnyPointer::Builder(builder); + } + static inline void set(PointerBuilder builder, AnyPointer::Reader value) { + AnyPointer::Builder(builder).set(value); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } + static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) { + return reader.reader; + } + static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) { + return builder.builder; + } +}; + +template <> +struct PointerHelpers { + static inline AnyStruct::Reader get( + PointerReader reader, const word* defaultValue = nullptr) { + return AnyStruct::Reader(reader.getStruct(defaultValue)); + } + static inline AnyStruct::Builder get( + PointerBuilder builder, const word* defaultValue = nullptr) { + // TODO(someday): Allow specifying the size somehow? + return AnyStruct::Builder(builder.getStruct( + _::StructSize(ZERO * WORDS, ZERO * POINTERS), defaultValue)); + } + static inline void set(PointerBuilder builder, AnyStruct::Reader value) { + builder.setStruct(value._reader); + } + static inline AnyStruct::Builder init( + PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount) { + return AnyStruct::Builder(builder.initStruct( + StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); + } + + static void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +template <> +struct PointerHelpers { + static inline AnyList::Reader get( + PointerReader reader, const word* defaultValue = nullptr) { + return AnyList::Reader(reader.getListAnySize(defaultValue)); + } + static inline AnyList::Builder get( + PointerBuilder builder, const word* defaultValue = nullptr) { + return AnyList::Builder(builder.getListAnySize(defaultValue)); + } + static inline void set(PointerBuilder builder, AnyList::Reader value) { + builder.setList(value._reader); + } + static inline AnyList::Builder init( + PointerBuilder builder, ElementSize elementSize, uint elementCount) { + return AnyList::Builder(builder.initList( + elementSize, bounded(elementCount) * ELEMENTS)); + } + static inline AnyList::Builder init( + PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) { + return AnyList::Builder(builder.initStructList( + bounded(elementCount) * ELEMENTS, + StructSize(bounded(dataWordCount) * WORDS, + bounded(pointerCount) * POINTERS))); + } + + static void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +template <> +struct OrphanGetImpl { + static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) { + return AnyStruct::Builder(builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); + } + static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) { + return AnyStruct::Reader(builder.asStructReader(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::StructSize(ZERO * WORDS, ZERO * POINTERS)); + } +}; + +template <> +struct OrphanGetImpl { + static inline AnyList::Builder apply(_::OrphanBuilder& builder) { + return AnyList::Builder(builder.asListAnySize()); + } + static inline AnyList::Reader applyReader(const _::OrphanBuilder& builder) { + return AnyList::Reader(builder.asListReaderAnySize()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +} // namespace _ (private) + +#if !CAPNP_LITE + +template +struct PipelineHook::FromImpl { + static inline kj::Own apply(typename T::Pipeline&& pipeline) { + return from(kj::mv(pipeline._typeless)); + } + static inline PipelineHook& apply(typename T::Pipeline& pipeline) { + return from(pipeline._typeless); + } +}; + +template <> +struct PipelineHook::FromImpl { + static inline kj::Own apply(AnyPointer::Pipeline&& pipeline) { + return kj::mv(pipeline.hook); + } + static inline PipelineHook& apply(AnyPointer::Pipeline& pipeline) { + return *pipeline.hook; + } +}; + +template +inline kj::Own PipelineHook::from(Pipeline&& pipeline) { + return FromImpl::apply(kj::fwd(pipeline)); +} + +template +inline PipelineHook& PipelineHook::from(Pipeline& pipeline) { + return FromImpl::apply(pipeline); +} + +#endif // !CAPNP_LITE + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/arena.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/arena.cc new file mode 100644 index 000000000..77061db1d --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/arena.cc @@ -0,0 +1,392 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#define CAPNP_PRIVATE +#include "arena.h" +#include "message.h" +#include +#include +#include +#include +#include +#include + +#if !CAPNP_LITE +#include "capability.h" +#endif // !CAPNP_LITE + +namespace capnp { +namespace _ { // private + +Arena::~Arena() noexcept(false) {} + +void ReadLimiter::unread(WordCount64 amount) { + // Be careful not to overflow here. Since ReadLimiter has no thread-safety, it's possible that + // the limit value was not updated correctly for one or more reads, and therefore unread() could + // overflow it even if it is only unreading bytes that were actually read. + uint64_t oldValue = readLimit(); + uint64_t newValue = oldValue + unbound(amount / WORDS); + if (newValue > oldValue) { + setLimit(newValue); + } +} + +void SegmentReader::abortCheckObjectFault() { + KJ_LOG(FATAL, "checkObject()'s parameter is not in-range; this would segfault in opt mode", + "this is a serious bug in Cap'n Proto; please notify security@sandstorm.io"); + abort(); +} + +void SegmentBuilder::throwNotWritable() { + KJ_FAIL_REQUIRE( + "Tried to form a Builder to an external data segment referenced by the MessageBuilder. " + "When you use Orphanage::reference*(), you are not allowed to obtain Builders to the " + "referenced data, only Readers, because that data is const."); +} + +// ======================================================================================= + +static SegmentWordCount verifySegmentSize(size_t size) { + auto gsize = bounded(size) * WORDS; + return assertMaxBits(gsize, [&]() { + KJ_FAIL_REQUIRE("segment is too large", size); + }); +} + +static SegmentWordCount verifySegment(kj::ArrayPtr segment) { +#if !CAPNP_ALLOW_UNALIGNED + KJ_REQUIRE(reinterpret_cast(segment.begin()) % sizeof(void*) == 0, + "Detected unaligned data in Cap'n Proto message. Messages must be aligned to the " + "architecture's word size. Yes, even on x86: Unaligned access is undefined behavior " + "under the C/C++ language standard, and compilers can and do assume alignment for the " + "purpose of optimizations. Unaligned access may lead to crashes or subtle corruption. " + "For example, GCC will use SIMD instructions in optimizations, and those instrsuctions " + "require alignment. If you really insist on taking your changes with unaligned data, " + "compile the Cap'n Proto library with -DCAPNP_ALLOW_UNALIGNED to remove this check.") { + break; + } +#endif + return verifySegmentSize(segment.size()); +} + +inline ReaderArena::ReaderArena(MessageReader* message, const word* firstSegment, + SegmentWordCount firstSegmentSize) + : message(message), + readLimiter(bounded(message->getOptions().traversalLimitInWords) * WORDS), + segment0(this, SegmentId(0), firstSegment, firstSegmentSize, &readLimiter) {} + +inline ReaderArena::ReaderArena(MessageReader* message, kj::ArrayPtr firstSegment) + : ReaderArena(message, firstSegment.begin(), verifySegment(firstSegment)) {} + +ReaderArena::ReaderArena(MessageReader* message) + : ReaderArena(message, message->getSegment(0)) {} + +ReaderArena::~ReaderArena() noexcept(false) {} + +size_t ReaderArena::sizeInWords() { + size_t total = segment0.getArray().size(); + + for (uint i = 1; ; i++) { + SegmentReader* segment = tryGetSegment(SegmentId(i)); + if (segment == nullptr) return total; + total += unboundAs(segment->getSize() / WORDS); + } +} + +SegmentReader* ReaderArena::tryGetSegment(SegmentId id) { + if (id == SegmentId(0)) { + if (segment0.getArray() == nullptr) { + return nullptr; + } else { + return &segment0; + } + } + + auto lock = moreSegments.lockExclusive(); + + SegmentMap* segments = nullptr; + KJ_IF_MAYBE(s, *lock) { + KJ_IF_MAYBE(segment, s->find(id.value)) { + return *segment; + } + segments = s; + } + + kj::ArrayPtr newSegment = message->getSegment(id.value); + if (newSegment == nullptr) { + return nullptr; + } + + SegmentWordCount newSegmentSize = verifySegment(newSegment); + + if (*lock == nullptr) { + // OK, the segment exists, so allocate the map. + segments = &lock->emplace(); + } + + auto segment = kj::heap( + this, id, newSegment.begin(), newSegmentSize, &readLimiter); + SegmentReader* result = segment; + segments->insert(id.value, kj::mv(segment)); + return result; +} + +void ReaderArena::reportReadLimitReached() { + KJ_FAIL_REQUIRE("Exceeded message traversal limit. See capnp::ReaderOptions.") { + return; + } +} + +// ======================================================================================= + +BuilderArena::BuilderArena(MessageBuilder* message) + : message(message), segment0(nullptr, SegmentId(0), nullptr, nullptr) {} + +BuilderArena::BuilderArena(MessageBuilder* message, + kj::ArrayPtr segments) + : message(message), + segment0(this, SegmentId(0), segments[0].space.begin(), + verifySegment(segments[0].space), + &this->dummyLimiter, verifySegmentSize(segments[0].wordsUsed)) { + if (segments.size() > 1) { + kj::Vector> builders(segments.size() - 1); + + uint i = 1; + for (auto& segment: segments.slice(1, segments.size())) { + builders.add(kj::heap( + this, SegmentId(i++), segment.space.begin(), verifySegment(segment.space), + &this->dummyLimiter, verifySegmentSize(segment.wordsUsed))); + } + + kj::Vector> forOutput; + forOutput.resize(segments.size()); + + segmentWithSpace = builders.back(); + + this->moreSegments = kj::heap( + MultiSegmentState { kj::mv(builders), kj::mv(forOutput) }); + + } else { + segmentWithSpace = &segment0; + } +} + +BuilderArena::~BuilderArena() noexcept(false) {} + +size_t BuilderArena::sizeInWords() { + KJ_IF_MAYBE(segmentState, moreSegments) { + size_t total = segment0.currentlyAllocated().size(); + for (auto& builder: segmentState->get()->builders) { + total += builder->currentlyAllocated().size(); + } + return total; + } else { + if (segment0.getArena() == nullptr) { + // We haven't actually allocated any segments yet. + return 0; + } else { + // We have only one segment so far. + return segment0.currentlyAllocated().size(); + } + } +} + +SegmentBuilder* BuilderArena::getSegment(SegmentId id) { + // This method is allowed to fail if the segment ID is not valid. + if (id == SegmentId(0)) { + return &segment0; + } else { + KJ_IF_MAYBE(s, moreSegments) { + KJ_REQUIRE(id.value - 1 < s->get()->builders.size(), "invalid segment id", id.value); + return const_cast(s->get()->builders[id.value - 1].get()); + } else { + KJ_FAIL_REQUIRE("invalid segment id", id.value); + } + } +} + +BuilderArena::AllocateResult BuilderArena::allocate(SegmentWordCount amount) { + if (segment0.getArena() == nullptr) { + // We're allocating the first segment. + kj::ArrayPtr ptr = message->allocateSegment(unbound(amount / WORDS)); + auto actualSize = verifySegment(ptr); + + // Re-allocate segment0 in-place. This is a bit of a hack, but we have not returned any + // pointers to this segment yet, so it should be fine. + kj::dtor(segment0); + kj::ctor(segment0, this, SegmentId(0), ptr.begin(), actualSize, &this->dummyLimiter); + + segmentWithSpace = &segment0; + return AllocateResult { &segment0, segment0.allocate(amount) }; + } else { + if (segmentWithSpace != nullptr) { + // Check if there is space in an existing segment. + // TODO(perf): Check for available space in more than just the last segment. We don't + // want this to be O(n), though, so we'll need to maintain some sort of table. Complicating + // matters, we want SegmentBuilders::allocate() to be fast, so we can't update any such + // table when allocation actually happens. Instead, we could have a priority queue based + // on the last-known available size, and then re-check the size when we pop segments off it + // and shove them to the back of the queue if they have become too small. + word* attempt = segmentWithSpace->allocate(amount); + if (attempt != nullptr) { + return AllocateResult { segmentWithSpace, attempt }; + } + } + + // Need to allocate a new segment. + SegmentBuilder* result = addSegmentInternal(message->allocateSegment(unbound(amount / WORDS))); + + // Check this new segment first the next time we need to allocate. + segmentWithSpace = result; + + // Allocating from the new segment is guaranteed to succeed since we made it big enough. + return AllocateResult { result, result->allocate(amount) }; + } +} + +SegmentBuilder* BuilderArena::addExternalSegment(kj::ArrayPtr content) { + return addSegmentInternal(content); +} + +template +SegmentBuilder* BuilderArena::addSegmentInternal(kj::ArrayPtr content) { + // This check should never fail in practice, since you can't get an Orphanage without allocating + // the root segment. + KJ_REQUIRE(segment0.getArena() != nullptr, + "Can't allocate external segments before allocating the root segment."); + + auto contentSize = verifySegmentSize(content.size()); + + MultiSegmentState* segmentState; + KJ_IF_MAYBE(s, moreSegments) { + segmentState = *s; + } else { + auto newSegmentState = kj::heap(); + segmentState = newSegmentState; + moreSegments = kj::mv(newSegmentState); + } + + kj::Own newBuilder = kj::heap( + this, SegmentId(segmentState->builders.size() + 1), + content.begin(), contentSize, &this->dummyLimiter); + SegmentBuilder* result = newBuilder.get(); + segmentState->builders.add(kj::mv(newBuilder)); + + // Keep forOutput the right size so that we don't have to re-allocate during + // getSegmentsForOutput(), which callers might reasonably expect is a thread-safe method. + segmentState->forOutput.resize(segmentState->builders.size() + 1); + + return result; +} + +kj::ArrayPtr> BuilderArena::getSegmentsForOutput() { + // Although this is a read-only method, we shouldn't need to lock a mutex here because if this + // is called multiple times simultaneously, we should only be overwriting the array with the + // exact same data. If the number or size of segments is actually changing due to an activity + // in another thread, then the caller has a problem regardless of locking here. + + KJ_IF_MAYBE(segmentState, moreSegments) { + KJ_DASSERT(segmentState->get()->forOutput.size() == segmentState->get()->builders.size() + 1, + "segmentState->forOutput wasn't resized correctly when the last builder was added.", + segmentState->get()->forOutput.size(), segmentState->get()->builders.size()); + + kj::ArrayPtr> result( + &segmentState->get()->forOutput[0], segmentState->get()->forOutput.size()); + uint i = 0; + result[i++] = segment0.currentlyAllocated(); + for (auto& builder: segmentState->get()->builders) { + result[i++] = builder->currentlyAllocated(); + } + return result; + } else { + if (segment0.getArena() == nullptr) { + // We haven't actually allocated any segments yet. + return nullptr; + } else { + // We have only one segment so far. + segment0ForOutput = segment0.currentlyAllocated(); + return kj::arrayPtr(&segment0ForOutput, 1); + } + } +} + +SegmentReader* BuilderArena::tryGetSegment(SegmentId id) { + if (id == SegmentId(0)) { + if (segment0.getArena() == nullptr) { + // We haven't allocated any segments yet. + return nullptr; + } else { + return &segment0; + } + } else { + KJ_IF_MAYBE(segmentState, moreSegments) { + if (id.value <= segmentState->get()->builders.size()) { + // TODO(cleanup): Return a const SegmentReader and tediously constify all SegmentBuilder + // pointers throughout the codebase. + return const_cast(kj::implicitCast( + segmentState->get()->builders[id.value - 1].get())); + } + } + return nullptr; + } +} + +void BuilderArena::reportReadLimitReached() { + KJ_FAIL_ASSERT("Read limit reached for BuilderArena, but it should have been unlimited.") { + return; + } +} + +kj::Maybe> BuilderArena::LocalCapTable::extractCap(uint index) { +#if CAPNP_LITE + KJ_UNIMPLEMENTED("no cap tables in lite mode"); +#else + if (index < capTable.size()) { + return capTable[index].map([](kj::Own& cap) { return cap->addRef(); }); + } else { + return nullptr; + } +#endif +} + +uint BuilderArena::LocalCapTable::injectCap(kj::Own&& cap) { +#if CAPNP_LITE + KJ_UNIMPLEMENTED("no cap tables in lite mode"); +#else + uint result = capTable.size(); + capTable.add(kj::mv(cap)); + return result; +#endif +} + +void BuilderArena::LocalCapTable::dropCap(uint index) { +#if CAPNP_LITE + KJ_UNIMPLEMENTED("no cap tables in lite mode"); +#else + KJ_ASSERT(index < capTable.size(), "Invalid capability descriptor in message.") { + return; + } + capTable[index] = nullptr; +#endif +} + +} // namespace _ (private) +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/arena.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/arena.h new file mode 100644 index 000000000..aeaff8448 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/arena.h @@ -0,0 +1,523 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#ifndef CAPNP_PRIVATE +#error "This header is only meant to be included by Cap'n Proto's own source code." +#endif + +#include +#include +#include +#include +#include +#include "common.h" +#include "message.h" +#include "layout.h" +#include + +#if !CAPNP_LITE +#include "capability.h" +#endif // !CAPNP_LITE + +CAPNP_BEGIN_HEADER + +namespace capnp { + +#if !CAPNP_LITE +class ClientHook; +#endif // !CAPNP_LITE + +namespace _ { // private + +class SegmentReader; +class SegmentBuilder; +class Arena; +class BuilderArena; +class ReadLimiter; + +class Segment; +typedef kj::Id SegmentId; + +class ReadLimiter { + // Used to keep track of how much data has been processed from a message, and cut off further + // processing if and when a particular limit is reached. This is primarily intended to guard + // against maliciously-crafted messages which contain cycles or overlapping structures. Cycles + // and overlapping are not permitted by the Cap'n Proto format because in many cases they could + // be used to craft a deceptively small message which could consume excessive server resources to + // process, perhaps even sending it into an infinite loop. Actually detecting overlaps would be + // time-consuming, so instead we just keep track of how many words worth of data structures the + // receiver has actually dereferenced and error out if this gets too high. + // + // This counting takes place as you call getters (for non-primitive values) on the message + // readers. If you call the same getter twice, the data it returns may be double-counted. This + // should not be a big deal in most cases -- just set the read limit high enough that it will + // only trigger in unreasonable cases. + // + // This class is "safe" to use from multiple threads for its intended use case. Threads may + // overwrite each others' changes to the counter, but this is OK because it only means that the + // limit is enforced a bit less strictly -- it will still kick in eventually. + +public: + inline explicit ReadLimiter(); // No limit. + inline explicit ReadLimiter(WordCount64 limit); // Limit to the given number of words. + + inline void reset(WordCount64 limit); + + KJ_ALWAYS_INLINE(bool canRead(WordCount64 amount, Arena* arena)); + + void unread(WordCount64 amount); + // Adds back some words to the limit. Useful when the caller knows they are double-reading + // some data. + +private: + alignas(8) volatile uint64_t limit; + // Current limit, decremented each time catRead() is called. We modify this variable using atomics + // with "relaxed" thread safety to make TSAN happy (on ARM & x86 this is no different from a + // regular read/write of the variable). See the class comment for why this is OK (previously we + // used a regular volatile variable - this is just to make ASAN happy). + // + // alignas(8) is the default on 64-bit systems, but needed on 32-bit to avoid an expensive + // unaligned atomic operation. + + KJ_DISALLOW_COPY_AND_MOVE(ReadLimiter); + + KJ_ALWAYS_INLINE(void setLimit(uint64_t newLimit)) { +#if defined(__GNUC__) || defined(__clang__) + __atomic_store_n(&limit, newLimit, __ATOMIC_RELAXED); +#else + limit = newLimit; +#endif + } + + KJ_ALWAYS_INLINE(uint64_t readLimit() const) { +#if defined(__GNUC__) || defined(__clang__) + return __atomic_load_n(&limit, __ATOMIC_RELAXED); +#else + return limit; +#endif + } +}; + +#if !CAPNP_LITE +class BrokenCapFactory { + // Callback for constructing broken caps. We use this so that we can avoid arena.c++ having a + // link-time dependency on capability code that lives in libcapnp-rpc. + +public: + virtual kj::Own newBrokenCap(kj::StringPtr description) = 0; + virtual kj::Own newNullCap() = 0; +}; +#endif // !CAPNP_LITE + +class SegmentReader { +public: + inline SegmentReader(Arena* arena, SegmentId id, const word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter); + + KJ_ALWAYS_INLINE(const word* checkOffset(const word* from, ptrdiff_t offset)); + // Adds the given offset to the given pointer, checks that it is still within the bounds of the + // segment, then returns it. Note that the "end" pointer of the segment (which technically points + // to the word after the last in the segment) is considered in-bounds for this purpose, so you + // can't necessarily dereference it. You must call checkObject() next to check that the object + // you want to read is entirely in-bounds. + // + // If `from + offset` is out-of-range, this returns a pointer to the end of the segment. Thus, + // any non-zero-sized object will fail `checkObject()`. We do this instead of throwing to save + // some code footprint. + + KJ_ALWAYS_INLINE(bool checkObject(const word* start, WordCountN<31> size)); + // Assuming that `start` is in-bounds for this segment (probably checked using `checkOffset()`), + // check that `start + size` is also in-bounds, and hence the whole area in-between is valid. + + KJ_ALWAYS_INLINE(bool amplifiedRead(WordCount virtualAmount)); + // Indicates that the reader should pretend that `virtualAmount` additional data was read even + // though no actual pointer was traversed. This is used e.g. when reading a struct list pointer + // where the element sizes are zero -- the sender could set the list size arbitrarily high and + // cause the receiver to iterate over this list even though the message itself is small, so we + // need to defend against DoS attacks based on this. + + inline Arena* getArena(); + inline SegmentId getSegmentId(); + + inline const word* getStartPtr(); + inline SegmentWordCount getOffsetTo(const word* ptr); + inline SegmentWordCount getSize(); + + inline kj::ArrayPtr getArray(); + + inline void unread(WordCount64 amount); + // Add back some words to the ReadLimiter. + +private: + Arena* arena; + SegmentId id; + kj::ArrayPtr ptr; // size guaranteed to fit in SEGMENT_WORD_COUNT_BITS bits + ReadLimiter* readLimiter; + + KJ_DISALLOW_COPY_AND_MOVE(SegmentReader); + + friend class SegmentBuilder; + + [[noreturn]] static void abortCheckObjectFault(); + // Called in debug mode in cases that would segfault in opt mode. (Should be impossible!) +}; + +class SegmentBuilder: public SegmentReader { +public: + inline SegmentBuilder(BuilderArena* arena, SegmentId id, word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter, SegmentWordCount wordsUsed = ZERO * WORDS); + inline SegmentBuilder(BuilderArena* arena, SegmentId id, const word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter); + inline SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), + ReadLimiter* readLimiter); + + KJ_ALWAYS_INLINE(word* allocate(SegmentWordCount amount)); + + KJ_ALWAYS_INLINE(void checkWritable()); + // Throw an exception if the segment is read-only (meaning it is a reference to external data). + + KJ_ALWAYS_INLINE(word* getPtrUnchecked(SegmentWordCount offset)); + // Get a writable pointer into the segment. Throws an exception if the segment is read-only (i.e. + // a reference to external immutable data). + + inline BuilderArena* getArena(); + + inline kj::ArrayPtr currentlyAllocated(); + + inline void reset(); + + inline bool isWritable() { return !readOnly; } + + inline void tryTruncate(word* from, word* to); + // If `from` points just past the current end of the segment, then move the end back to `to`. + // Otherwise, do nothing. + + inline bool tryExtend(word* from, word* to); + // If `from` points just past the current end of the segment, and `to` is within the segment + // boundaries, then move the end up to `to` and return true. Otherwise, do nothing and return + // false. + +private: + word* pos; + // Pointer to a pointer to the current end point of the segment, i.e. the location where the + // next object should be allocated. + + bool readOnly; + + [[noreturn]] void throwNotWritable(); + + KJ_DISALLOW_COPY_AND_MOVE(SegmentBuilder); +}; + +class Arena { +public: + virtual ~Arena() noexcept(false); + + virtual SegmentReader* tryGetSegment(SegmentId id) = 0; + // Gets the segment with the given ID, or return nullptr if no such segment exists. + + virtual void reportReadLimitReached() = 0; + // Called to report that the read limit has been reached. See ReadLimiter, below. This invokes + // the VALIDATE_INPUT() macro which may throw an exception; if it returns normally, the caller + // will need to continue with default values. +}; + +class ReaderArena final: public Arena { +public: + explicit ReaderArena(MessageReader* message); + ~ReaderArena() noexcept(false); + KJ_DISALLOW_COPY_AND_MOVE(ReaderArena); + + size_t sizeInWords(); + + // implements Arena ------------------------------------------------ + SegmentReader* tryGetSegment(SegmentId id) override; + void reportReadLimitReached() override; + +private: + MessageReader* message; + ReadLimiter readLimiter; + + // Optimize for single-segment messages so that small messages are handled quickly. + SegmentReader segment0; + + typedef kj::HashMap> SegmentMap; + kj::MutexGuarded> moreSegments; + // We need to mutex-guard the segment map because we lazily initialize segments when they are + // first requested, but a Reader is allowed to be used concurrently in multiple threads. Luckily + // this only applies to large messages. + // + // TODO(perf): Thread-local thing instead? Some kind of lockless map? Or do sharing of data + // in a different way, where you have to construct a new MessageReader in each thread (but + // possibly backed by the same data)? + + ReaderArena(MessageReader* message, kj::ArrayPtr firstSegment); + ReaderArena(MessageReader* message, const word* firstSegment, SegmentWordCount firstSegmentSize); +}; + +class BuilderArena final: public Arena { + // A BuilderArena that does not allow the injection of capabilities. + +public: + explicit BuilderArena(MessageBuilder* message); + BuilderArena(MessageBuilder* message, kj::ArrayPtr segments); + ~BuilderArena() noexcept(false); + KJ_DISALLOW_COPY_AND_MOVE(BuilderArena); + + size_t sizeInWords(); + + inline SegmentBuilder* getRootSegment() { return &segment0; } + + kj::ArrayPtr> getSegmentsForOutput(); + // Get an array of all the segments, suitable for writing out. This only returns the allocated + // portion of each segment, whereas tryGetSegment() returns something that includes + // not-yet-allocated space. + + inline CapTableBuilder* getLocalCapTable() { + // Return a CapTableBuilder that merely implements local loopback. That is, you can set + // capabilities, then read the same capabilities back, but there is no intent ever to transmit + // these capabilities. A MessageBuilder that isn't imbued with some other CapTable uses this + // by default. + // + // TODO(cleanup): It's sort of a hack that this exists. In theory, perhaps, unimbued + // MessageBuilders should throw exceptions on any attempt to access capability fields, like + // unimbued MessageReaders do. However, lots of code exists which uses MallocMessageBuilder + // as a temporary holder for data to be copied in and out (without being serialized), and it + // is expected that such data can include capabilities, which is admittedly reasonable. + // Therefore, all MessageBuilders must have a cap table by default. Arguably we should + // deprecate this usage and instead define a new helper type for this exact purpose. + + return &localCapTable; + } + + kj::Own<_::CapTableBuilder> releaseLocalCapTable() { + return kj::heap(kj::mv(localCapTable)); + } + + SegmentBuilder* getSegment(SegmentId id); + // Get the segment with the given id. Crashes or throws an exception if no such segment exists. + + struct AllocateResult { + SegmentBuilder* segment; + word* words; + }; + + AllocateResult allocate(SegmentWordCount amount); + // Find a segment with at least the given amount of space available and allocate the space. + // Note that allocating directly from a particular segment is much faster, but allocating from + // the arena is guaranteed to succeed. Therefore callers should try to allocate from a specific + // segment first if there is one, then fall back to the arena. + + SegmentBuilder* addExternalSegment(kj::ArrayPtr content); + // Add a new segment to the arena which points to some existing memory region. The segment is + // assumed to be completley full; the arena will never allocate from it. In fact, the segment + // is considered read-only. Any attempt to get a Builder pointing into this segment will throw + // an exception. Readers are allowed, however. + // + // This can be used to inject some external data into a message without a copy, e.g. embedding a + // large mmap'd file into a message as `Data` without forcing that data to actually be read in + // from disk (until the message itself is written out). `Orphanage` provides the public API for + // this feature. + + // implements Arena ------------------------------------------------ + SegmentReader* tryGetSegment(SegmentId id) override; + void reportReadLimitReached() override; + +private: + MessageBuilder* message; + ReadLimiter dummyLimiter; + + class LocalCapTable final: public CapTableBuilder { + public: + kj::Maybe> extractCap(uint index) override; + uint injectCap(kj::Own&& cap) override; + void dropCap(uint index) override; + +#if !CAPNP_LITE + private: + kj::Vector>> capTable; +#endif // ! CAPNP_LITE + }; + + LocalCapTable localCapTable; + + SegmentBuilder segment0; + kj::ArrayPtr segment0ForOutput; + + struct MultiSegmentState { + kj::Vector> builders; + kj::Vector> forOutput; + }; + kj::Maybe> moreSegments; + + SegmentBuilder* segmentWithSpace = nullptr; + // When allocating, look for space in this segment first before resorting to allocating a new + // segment. This is not necessarily the last segment because addExternalSegment() may add a + // segment that is already-full, in which case we don't update this pointer. + + template // Can be `word` or `const word`. + SegmentBuilder* addSegmentInternal(kj::ArrayPtr content); +}; + +// ======================================================================================= + +inline ReadLimiter::ReadLimiter() + : limit(kj::maxValue) {} + +inline ReadLimiter::ReadLimiter(WordCount64 limit): limit(unbound(limit / WORDS)) {} + +inline void ReadLimiter::reset(WordCount64 limit) { + setLimit(unbound(limit / WORDS)); +} + +inline bool ReadLimiter::canRead(WordCount64 amount, Arena* arena) { + // Be careful not to store an underflowed value into `limit`, even if multiple threads are + // decrementing it. + uint64_t current = readLimit(); + if (KJ_UNLIKELY(unbound(amount / WORDS) > current)) { + arena->reportReadLimitReached(); + return false; + } else { + setLimit(current - unbound(amount / WORDS)); + return true; + } +} + +// ------------------------------------------------------------------- + +inline SegmentReader::SegmentReader(Arena* arena, SegmentId id, const word* ptr, + SegmentWordCount size, ReadLimiter* readLimiter) + : arena(arena), id(id), ptr(kj::arrayPtr(ptr, unbound(size / WORDS))), + readLimiter(readLimiter) {} + +inline const word* SegmentReader::checkOffset(const word* from, ptrdiff_t offset) { + ptrdiff_t min = ptr.begin() - from; + ptrdiff_t max = ptr.end() - from; + if (offset >= min && offset <= max) { + return from + offset; + } else { + return ptr.end(); + } +} + +inline bool SegmentReader::checkObject(const word* start, WordCountN<31> size) { + auto startOffset = intervalLength(ptr.begin(), start, MAX_SEGMENT_WORDS); +#ifdef KJ_DEBUG + if (startOffset > bounded(ptr.size()) * WORDS) { + abortCheckObjectFault(); + } +#endif + return startOffset + size <= bounded(ptr.size()) * WORDS && + readLimiter->canRead(size, arena); +} + +inline bool SegmentReader::amplifiedRead(WordCount virtualAmount) { + return readLimiter->canRead(virtualAmount, arena); +} + +inline Arena* SegmentReader::getArena() { return arena; } +inline SegmentId SegmentReader::getSegmentId() { return id; } +inline const word* SegmentReader::getStartPtr() { return ptr.begin(); } +inline SegmentWordCount SegmentReader::getOffsetTo(const word* ptr) { + KJ_IREQUIRE(this->ptr.begin() <= ptr && ptr <= this->ptr.end()); + return intervalLength(this->ptr.begin(), ptr, MAX_SEGMENT_WORDS); +} +inline SegmentWordCount SegmentReader::getSize() { + return assumeBits(ptr.size()) * WORDS; +} +inline kj::ArrayPtr SegmentReader::getArray() { return ptr; } +inline void SegmentReader::unread(WordCount64 amount) { readLimiter->unread(amount); } + +// ------------------------------------------------------------------- + +inline SegmentBuilder::SegmentBuilder( + BuilderArena* arena, SegmentId id, word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter, SegmentWordCount wordsUsed) + : SegmentReader(arena, id, ptr, size, readLimiter), + pos(ptr + wordsUsed), readOnly(false) {} +inline SegmentBuilder::SegmentBuilder( + BuilderArena* arena, SegmentId id, const word* ptr, SegmentWordCount size, + ReadLimiter* readLimiter) + : SegmentReader(arena, id, ptr, size, readLimiter), + // const_cast is safe here because the member won't ever be dereferenced because it appears + // to point to the end of the segment anyway. + pos(const_cast(ptr + size)), readOnly(true) {} +inline SegmentBuilder::SegmentBuilder(BuilderArena* arena, SegmentId id, decltype(nullptr), + ReadLimiter* readLimiter) + : SegmentReader(arena, id, nullptr, ZERO * WORDS, readLimiter), + pos(nullptr), readOnly(false) {} + +inline word* SegmentBuilder::allocate(SegmentWordCount amount) { + if (intervalLength(pos, ptr.end(), MAX_SEGMENT_WORDS) < amount) { + // Not enough space in the segment for this allocation. + return nullptr; + } else { + // Success. + word* result = pos; + pos = pos + amount; + return result; + } +} + +inline void SegmentBuilder::checkWritable() { + if (KJ_UNLIKELY(readOnly)) throwNotWritable(); +} + +inline word* SegmentBuilder::getPtrUnchecked(SegmentWordCount offset) { + return const_cast(ptr.begin() + offset); +} + +inline BuilderArena* SegmentBuilder::getArena() { + // Down-cast safe because SegmentBuilder's constructor always initializes its SegmentReader base + // class with an Arena pointer that actually points to a BuilderArena. + return static_cast(arena); +} + +inline kj::ArrayPtr SegmentBuilder::currentlyAllocated() { + return kj::arrayPtr(ptr.begin(), pos - ptr.begin()); +} + +inline void SegmentBuilder::reset() { + word* start = getPtrUnchecked(ZERO * WORDS); + memset(start, 0, (pos - start) * sizeof(word)); + pos = start; +} + +inline void SegmentBuilder::tryTruncate(word* from, word* to) { + if (pos == from) pos = to; +} + +inline bool SegmentBuilder::tryExtend(word* from, word* to) { + // Careful about overflow. + if (pos == from && to <= ptr.end() && to >= from) { + pos = to; + return true; + } else { + return false; + } +} + +} // namespace _ (private) +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/blob.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/blob.cc new file mode 100644 index 000000000..d31aaa3a0 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/blob.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "blob.h" + +namespace capnp { + +char Text::Builder::nulstr[1] = ""; + +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/blob.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/blob.h new file mode 100644 index 000000000..451e443dc --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/blob.h @@ -0,0 +1,219 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include +#include "common.h" +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +struct Data { + Data() = delete; + class Reader; + class Builder; + class Pipeline {}; +}; + +struct Text { + Text() = delete; + class Reader; + class Builder; + class Pipeline {}; +}; + +class Data::Reader: public kj::ArrayPtr { + // Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple + // pointer which does not own its target, can be passed by value, etc. + +public: + typedef Data Reads; + + Reader() = default; + inline Reader(decltype(nullptr)): ArrayPtr(nullptr) {} + inline Reader(const byte* value, size_t size): ArrayPtr(value, size) {} + inline Reader(const kj::Array& value): ArrayPtr(value) {} + inline Reader(const ArrayPtr& value): ArrayPtr(value) {} + inline Reader(const kj::Array& value): ArrayPtr(value) {} + inline Reader(const ArrayPtr& value): ArrayPtr(value) {} +}; + +class Text::Reader: public kj::StringPtr { + // Like Data::Reader, but points at NUL-terminated UTF-8 text. The NUL terminator is not counted + // in the size but must be present immediately after the last byte. + // + // Text::Reader's interface contract is that its data MUST be NUL-terminated. The producer of + // the Text::Reader must guarantee this, so that the consumer need not check. The data SHOULD + // also be valid UTF-8, but this is NOT guaranteed -- the consumer must verify if it cares. + +public: + typedef Text Reads; + + Reader() = default; + inline Reader(decltype(nullptr)): StringPtr(nullptr) {} + inline Reader(const char* value): StringPtr(value) {} + inline Reader(const char* value, size_t size): StringPtr(value, size) {} + inline Reader(const kj::String& value): StringPtr(value) {} + inline Reader(const StringPtr& value): StringPtr(value) {} + +#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP + template ().c_str())> + inline Reader(const T& t): StringPtr(t) {} + // Allow implicit conversion from any class that has a c_str() method (namely, std::string). + // We use a template trick to detect std::string in order to avoid including the header for + // those who don't want it. +#endif +}; + +class Data::Builder: public kj::ArrayPtr { + // Like Data::Reader except the pointers aren't const. + +public: + typedef Data Builds; + + Builder() = default; + inline Builder(decltype(nullptr)): ArrayPtr(nullptr) {} + inline Builder(byte* value, size_t size): ArrayPtr(value, size) {} + inline Builder(kj::Array& value): ArrayPtr(value) {} + inline Builder(ArrayPtr value): ArrayPtr(value) {} + + inline Data::Reader asReader() const { + return Data::Reader(kj::implicitCast&>(*this)); + } + inline operator Reader() const { return asReader(); } +}; + +class Text::Builder: public kj::DisallowConstCopy { + // Basically identical to kj::StringPtr, except that the contents are non-const. + +public: + inline Builder(): content(nulstr, 1) {} + inline Builder(decltype(nullptr)): content(nulstr, 1) {} + inline Builder(char* value): content(value, strlen(value) + 1) {} + inline Builder(char* value, size_t size): content(value, size + 1) { + KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); + } + + inline Reader asReader() const { return Reader(content.begin(), content.size() - 1); } + inline operator Reader() const { return asReader(); } + + inline operator kj::ArrayPtr(); + inline kj::ArrayPtr asArray(); + inline operator kj::ArrayPtr() const; + inline kj::ArrayPtr asArray() const; + inline kj::ArrayPtr asBytes() { return asArray().asBytes(); } + inline kj::ArrayPtr asBytes() const { return asArray().asBytes(); } + // Result does not include NUL terminator. + + inline operator kj::StringPtr() const; + inline kj::StringPtr asString() const; + + inline const char* cStr() const { return content.begin(); } + // Returns NUL-terminated string. + + inline size_t size() const { return content.size() - 1; } + // Result does not include NUL terminator. + + inline char operator[](size_t index) const { return content[index]; } + inline char& operator[](size_t index) { return content[index]; } + + inline char* begin() { return content.begin(); } + inline char* end() { return content.end() - 1; } + inline const char* begin() const { return content.begin(); } + inline const char* end() const { return content.end() - 1; } + + inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } + inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } + + inline bool operator==(Builder other) const { return asString() == other.asString(); } + inline bool operator!=(Builder other) const { return asString() != other.asString(); } + inline bool operator< (Builder other) const { return asString() < other.asString(); } + inline bool operator> (Builder other) const { return asString() > other.asString(); } + inline bool operator<=(Builder other) const { return asString() <= other.asString(); } + inline bool operator>=(Builder other) const { return asString() >= other.asString(); } + + inline kj::StringPtr slice(size_t start) const; + inline kj::ArrayPtr slice(size_t start, size_t end) const; + inline Builder slice(size_t start); + inline kj::ArrayPtr slice(size_t start, size_t end); + // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter + // version that assumes end = size(). + +private: + inline explicit Builder(kj::ArrayPtr content): content(content) {} + + kj::ArrayPtr content; + + static char nulstr[1]; +}; + +inline kj::StringPtr KJ_STRINGIFY(Text::Builder builder) { + return builder.asString(); +} + +inline bool operator==(const char* a, const Text::Builder& b) { return b.asString() == a; } +inline bool operator!=(const char* a, const Text::Builder& b) { return b.asString() != a; } + +inline Text::Builder::operator kj::StringPtr() const { + return kj::StringPtr(content.begin(), content.size() - 1); +} + +inline kj::StringPtr Text::Builder::asString() const { + return kj::StringPtr(content.begin(), content.size() - 1); +} + +inline Text::Builder::operator kj::ArrayPtr() { + return content.slice(0, content.size() - 1); +} + +inline kj::ArrayPtr Text::Builder::asArray() { + return content.slice(0, content.size() - 1); +} + +inline Text::Builder::operator kj::ArrayPtr() const { + return content.slice(0, content.size() - 1); +} + +inline kj::ArrayPtr Text::Builder::asArray() const { + return content.slice(0, content.size() - 1); +} + +inline kj::StringPtr Text::Builder::slice(size_t start) const { + return asReader().slice(start); +} +inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) const { + return content.slice(start, end); +} + +inline Text::Builder Text::Builder::slice(size_t start) { + return Text::Builder(content.slice(start, content.size())); +} +inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) { + return content.slice(start, end); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/c++.capnp.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/c++.capnp.cc new file mode 100644 index 000000000..02378a9c8 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/c++.capnp.cc @@ -0,0 +1,99 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: c++.capnp + +#include "c++.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<21> b_b9c6f99ebf805f2c = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 44, 95, 128, 191, 158, 249, 198, 185, + 16, 0, 0, 0, 5, 0, 1, 0, + 129, 78, 48, 184, 123, 125, 248, 189, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 210, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 99, 43, + 43, 46, 99, 97, 112, 110, 112, 58, + 110, 97, 109, 101, 115, 112, 97, 99, + 101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b9c6f99ebf805f2c = b_b9c6f99ebf805f2c.words; +#if !CAPNP_LITE +const ::capnp::_::RawSchema s_b9c6f99ebf805f2c = { + 0xb9c6f99ebf805f2c, b_b9c6f99ebf805f2c.words, 21, nullptr, nullptr, + 0, 0, nullptr, nullptr, nullptr, { &s_b9c6f99ebf805f2c, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<20> b_f264a779fef191ce = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 206, 145, 241, 254, 121, 167, 100, 242, + 16, 0, 0, 0, 5, 0, 252, 7, + 129, 78, 48, 184, 123, 125, 248, 189, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 170, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 24, 0, 0, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 99, 43, + 43, 46, 99, 97, 112, 110, 112, 58, + 110, 97, 109, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_f264a779fef191ce = b_f264a779fef191ce.words; +#if !CAPNP_LITE +const ::capnp::_::RawSchema s_f264a779fef191ce = { + 0xf264a779fef191ce, b_f264a779fef191ce.words, 20, nullptr, nullptr, + 0, 0, nullptr, nullptr, nullptr, { &s_f264a779fef191ce, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<22> b_ac7096ff8cfc9dce = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 206, 157, 252, 140, 255, 150, 112, 172, + 16, 0, 0, 0, 5, 0, 1, 3, + 129, 78, 48, 184, 123, 125, 248, 189, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 18, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 3, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 99, 43, + 43, 46, 99, 97, 112, 110, 112, 58, + 97, 108, 108, 111, 119, 67, 97, 110, + 99, 101, 108, 108, 97, 116, 105, 111, + 110, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ac7096ff8cfc9dce = b_ac7096ff8cfc9dce.words; +#if !CAPNP_LITE +const ::capnp::_::RawSchema s_ac7096ff8cfc9dce = { + 0xac7096ff8cfc9dce, b_ac7096ff8cfc9dce.words, 22, nullptr, nullptr, + 0, 0, nullptr, nullptr, nullptr, { &s_ac7096ff8cfc9dce, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/c++.capnp.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/c++.capnp.h new file mode 100644 index 000000000..234ed4b0c --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/c++.capnp.h @@ -0,0 +1,39 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: c++.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(b9c6f99ebf805f2c); +CAPNP_DECLARE_SCHEMA(f264a779fef191ce); +CAPNP_DECLARE_SCHEMA(ac7096ff8cfc9dce); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace annotations { + +// ======================================================================================= + +// ======================================================================================= + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/capability.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/capability.h new file mode 100644 index 000000000..1e71840ac --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/capability.h @@ -0,0 +1,1295 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#if CAPNP_LITE +#error "RPC APIs, including this header, are not available in lite mode." +#endif + +#include +#include +#include "raw-schema.h" +#include "any.h" +#include "pointer-helpers.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +template +class Response; + +template +class RemotePromise: public kj::Promise>, public T::Pipeline { + // A Promise which supports pipelined calls. T is typically a struct type. T must declare + // an inner "mix-in" type "Pipeline" which implements pipelining; RemotePromise simply + // multiply-inherits that type along with Promise>. T::Pipeline must be movable, + // but does not need to be copyable (i.e. just like Promise). + // + // The promise is for an owned pointer so that the RPC system can allocate the MessageReader + // itself. + +public: + inline RemotePromise(kj::Promise>&& promise, typename T::Pipeline&& pipeline) + : kj::Promise>(kj::mv(promise)), + T::Pipeline(kj::mv(pipeline)) {} + inline RemotePromise(decltype(nullptr)) + : kj::Promise>(nullptr), + T::Pipeline(nullptr) {} + KJ_DISALLOW_COPY(RemotePromise); + RemotePromise(RemotePromise&& other) = default; + RemotePromise& operator=(RemotePromise&& other) = default; + + kj::Promise> dropPipeline() { + // Convenience method to convert this into a plain promise. + return kj::mv(*this); + } + + static RemotePromise reducePromise(kj::Promise&& promise); + // Hook for KJ so that Promise> automatically reduces to RemotePromise. +}; + +class LocalClient; +namespace _ { // private +extern const RawSchema NULL_INTERFACE_SCHEMA; // defined in schema.c++ +class CapabilityServerSetBase; +struct PipelineBuilderPair; +} // namespace _ (private) + +struct Capability { + // A capability without type-safe methods. Typed capability clients wrap `Client` and typed + // capability servers subclass `Server` to dispatch to the regular, typed methods. + + class Client; + class Server; + + struct _capnpPrivate { + struct IsInterface; + static constexpr uint64_t typeId = 0x3; + static constexpr Kind kind = Kind::INTERFACE; + static constexpr _::RawSchema const* schema = &_::NULL_INTERFACE_SCHEMA; + + static const _::RawBrandedSchema* brand() { + return &_::NULL_INTERFACE_SCHEMA.defaultBrand; + } + }; +}; + +// ======================================================================================= +// Capability clients + +class RequestHook; +class ResponseHook; +class PipelineHook; +class ClientHook; +template +class RevocableServer; + +template +class Request: public Params::Builder { + // A call that hasn't been sent yet. This class extends a Builder for the call's "Params" + // structure with a method send() that actually sends it. + // + // Given a Cap'n Proto method `foo(a :A, b :B): C`, the generated client interface will have + // a method `Request fooRequest()` (as well as a convenience method + // `RemotePromise foo(A::Reader a, B::Reader b)`). + +public: + inline Request(typename Params::Builder builder, kj::Own&& hook) + : Params::Builder(builder), hook(kj::mv(hook)) {} + inline Request(decltype(nullptr)): Params::Builder(nullptr) {} + + RemotePromise send() KJ_WARN_UNUSED_RESULT; + // Send the call and return a promise for the results. + + typename Results::Pipeline sendForPipeline(); + // Send the call in pipeline-only mode. The returned object can be used to make pipelined calls, + // but there is no way to wait for the completion of the original call. This allows some + // bookkeeping to be skipped under the hood, saving some time. + // + // Generally, this method should only be used when the caller will immediately make one or more + // pipelined calls on the result, and then throw away the pipeline and all pipelined + // capabilities. Other uses may run into caveats, such as: + // - Normally, calling `whenResolved()` on a pipelined capability would wait for the original RPC + // to complete (and possibly other things, if that RPC itself returned a promise capability), + // but when using `sendPipelineOnly()`, `whenResolved()` may complete immediately, or never, or + // at an arbitrary time. Do not rely on it. + // - Normal path shortening may not work with these capabilities. For exmaple, if the caller + // forwards a pipelined capability back to the callee's vat, calls made by the callee to that + // capability may continue to proxy through the caller. Conversely, if the callee ends up + // returning a capability that points back to the caller's vat, calls on the pipelined + // capability may continue to proxy through the callee. + +private: + kj::Own hook; + + friend class Capability::Client; + friend struct DynamicCapability; + template + friend class CallContext; + friend class RequestHook; +}; + +template +class StreamingRequest: public Params::Builder { + // Like `Request` but for streaming requests. + +public: + inline StreamingRequest(typename Params::Builder builder, kj::Own&& hook) + : Params::Builder(builder), hook(kj::mv(hook)) {} + inline StreamingRequest(decltype(nullptr)): Params::Builder(nullptr) {} + + kj::Promise send() KJ_WARN_UNUSED_RESULT; + +private: + kj::Own hook; + + friend class Capability::Client; + friend struct DynamicCapability; + template + friend class CallContext; + friend class RequestHook; +}; + +template +class Response: public Results::Reader { + // A completed call. This class extends a Reader for the call's answer structure. The Response + // is move-only -- once it goes out-of-scope, the underlying message will be freed. + +public: + inline Response(typename Results::Reader reader, kj::Own&& hook) + : Results::Reader(reader), hook(kj::mv(hook)) {} + +private: + kj::Own hook; + + template + friend class Request; + friend class ResponseHook; +}; + +class Capability::Client { + // Base type for capability clients. + +public: + typedef Capability Reads; + typedef Capability Calls; + + Client(decltype(nullptr)); + // If you need to declare a Client before you have anything to assign to it (perhaps because + // the assignment is going to occur in an if/else scope), you can start by initializing it to + // `nullptr`. The resulting client is not meant to be called and throws exceptions from all + // methods. + + template ()>> + Client(kj::Own&& server); + // Make a client capability that wraps the given server capability. The server's methods will + // only be executed in the given EventLoop, regardless of what thread calls the client's methods. + + template ()>> + Client(kj::Promise&& promise); + // Make a client from a promise for a future client. The resulting client queues calls until the + // promise resolves. + + Client(kj::Exception&& exception); + // Make a broken client that throws the given exception from all calls. + + Client(Client& other); + Client& operator=(Client& other); + // Copies by reference counting. Warning: This refcounting is not thread-safe. All copies of + // the client must remain in one thread. + + Client(Client&&) = default; + Client& operator=(Client&&) = default; + // Move constructor avoids reference counting. + + explicit Client(kj::Own&& hook); + // For use by the RPC implementation: Wrap a ClientHook. + + template + typename T::Client castAs(); + // Reinterpret the capability as implementing the given interface. Note that no error will occur + // here if the capability does not actually implement this interface, but later method calls will + // fail. It's up to the application to decide how indicate that additional interfaces are + // supported. + // + // TODO(perf): GCC 4.8 / Clang 3.3: rvalue-qualified version for better performance. + + template + typename T::Client castAs(InterfaceSchema schema); + // Dynamic version. `T` must be `DynamicCapability`, and you must `#include `. + + kj::Promise whenResolved(); + // If the capability is actually only a promise, the returned promise resolves once the + // capability itself has resolved to its final destination (or propagates the exception if + // the capability promise is rejected). This is mainly useful for error-checking in the case + // where no calls are being made. There is no reason to wait for this before making calls; if + // the capability does not resolve, the call results will propagate the error. + + struct CallHints { + bool noPromisePipelining = false; + // Hints that the pipeline part of the VoidPromiseAndPipeline won't be used, so it can be + // a bogus object. + + bool onlyPromisePipeline = false; + // Hints that the promise part of the VoidPromiseAndPipeline won't be used, so it can be a + // bogus promise. + // + // This hint is primarily intended to be passed to `ClientHook::call()`. When using + // `ClientHook::newCall()`, you would instead indicate the hint by calling the `ResponseHook`'s + // `sendForPipeline()` method. The effect of setting `onlyPromisePipeline = true` when invoking + // `ClientHook::newCall()` is unspecified; it might cause the returned `Request` to support + // only pipelining even when `send()` is called, or it might not. + }; + + Request typelessRequest( + uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint, CallHints hints); + // Make a request without knowing the types of the params or results. You specify the type ID + // and method number manually. + + kj::Promise> getFd(); + // If the capability's server implemented Capability::Server::getFd() returning non-null, and all + // RPC links between the client and server support FD passing, returns a file descriptor pointing + // to the same underlying file description as the server did. Returns null if the server provided + // no FD or if FD passing was unavailable at some intervening link. + // + // This returns a Promise to handle the case of an unresolved promise capability, e.g. a + // pipelined capability. The promise resolves no later than when the capability settles, i.e. + // the same time `whenResolved()` would complete. + // + // The file descriptor will remain open at least as long as the Capability::Client remains alive. + // If you need it to last longer, you will need to `dup()` it. + + // TODO(someday): method(s) for Join + +protected: + Client() = default; + + template + Request newCall(uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint, CallHints hints); + template + StreamingRequest newStreamingCall(uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint, CallHints hints); + +private: + kj::Own hook; + + static kj::Own makeLocalClient(kj::Own&& server); + static kj::Own makeRevocableLocalClient(Capability::Server& server); + static void revokeLocalClient(ClientHook& hook); + static void revokeLocalClient(ClientHook& hook, kj::Exception&& reason); + + template + friend struct _::PointerHelpers; + friend struct DynamicCapability; + friend class Orphanage; + friend struct DynamicStruct; + friend struct DynamicList; + template + friend struct List; + friend class _::CapabilityServerSetBase; + friend class ClientHook; + template + friend class RevocableServer; +}; + +// ======================================================================================= +// Capability servers + +class CallContextHook; + +template +class CallContext: public kj::DisallowConstCopy { + // Wrapper around CallContextHook with a specific return type. + // + // Methods of this class may only be called from within the server's event loop, not from other + // threads. + // + // The CallContext becomes invalid as soon as the call reports completion. + +public: + explicit CallContext(CallContextHook& hook); + + typename Params::Reader getParams(); + // Get the params payload. + + void releaseParams(); + // Release the params payload. getParams() will throw an exception after this is called. + // Releasing the params may allow the RPC system to free up buffer space to handle other + // requests. Long-running asynchronous methods should try to call this as early as is + // convenient. + + typename Results::Builder getResults(kj::Maybe sizeHint = nullptr); + typename Results::Builder initResults(kj::Maybe sizeHint = nullptr); + void setResults(typename Results::Reader value); + void adoptResults(Orphan&& value); + Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); + // Manipulate the results payload. The "Return" message (part of the RPC protocol) will + // typically be allocated the first time one of these is called. Some RPC systems may + // allocate these messages in a limited space (such as a shared memory segment), therefore the + // application should delay calling these as long as is convenient to do so (but don't delay + // if doing so would require extra copies later). + // + // `sizeHint` indicates a guess at the message size. This will usually be used to decide how + // much space to allocate for the first message segment (don't worry: only space that is actually + // used will be sent on the wire). If omitted, the system decides. The message root pointer + // should not be included in the size. So, if you are simply going to copy some existing message + // directly into the results, just call `.totalSize()` and pass that in. + + void setPipeline(typename Results::Pipeline&& pipeline); + void setPipeline(typename Results::Pipeline& pipeline); + // Tells the system where the capabilities in the response will eventually resolve to. This + // allows requests that are promise-pipelined on this call's results to continue their journey + // to the final destination before this call itself has completed. + // + // This is particularly useful when forwarding RPC calls to other remote servers, but where a + // tail call can't be used. For example, imagine Alice calls `foo()` on Bob. In `foo()`'s + // implementation, Bob calls `bar()` on Charlie. `bar()` returns a capability to Bob, and then + // `foo()` returns the same capability on to Alice. Now imagine Alice is actually using promise + // pipelining in a chain like `foo().getCap().baz()`. The `baz()` call will travel to Bob as a + // pipelined call without waiting for `foo()` to return first. But once it gets to Bob, the + // message has to patiently wait until `foo()` has completed there, before it can then be + // forwarded on to Charlie. It would be better if immediately upon Bob calling `bar()` on + // Charlie, then Alice's call to `baz()` could be forwarded to Charlie as a pipelined call, + // without waiting for `bar()` to return. This would avoid a network round trip of latency + // between Bob and Charlie. + // + // To solve this problem, Bob takes the pipeline object from the `bar()` call, transforms it into + // an appropriate pipeline for a `foo()` call, and passes that to `setPipeline()`. This allows + // Alice's pipelined `baz()` call to flow through immediately. The code looks like: + // + // kj::Promise foo(FooContext context) { + // auto barPromise = charlie.barRequest().send(); + // + // // Set up the final pipeline using pipelined capabilities from `barPromise`. + // capnp::PipelineBuilder pipeline; + // pipeline.setResultCap(barPromise.getSomeCap()); + // context.setPipeline(pipeline.build()); + // + // // Now actually wait for the results and process them. + // return barPromise + // .then([context](capnp::Response response) mutable { + // auto results = context.initResults(); + // + // // Make sure to set up the capabilities exactly as we did in the pipeline. + // results.setResultCap(response.getSomeCap()); + // + // // ... do other stuff with the real response ... + // }); + // } + // + // Of course, if `foo()` and `bar()` return exactly the same type, and Bob doesn't intend + // to do anything with `bar()`'s response except pass it through, then `tailCall()` is a better + // choice here. `setPipeline()` is useful when some transformation is needed on the response, + // or the middleman needs to inspect the response for some reason. + // + // Note: This method has an overload that takes an lvalue reference for convenience. This + // overload increments the refcount on the underlying PipelineHook -- it does not keep the + // reference. + // + // Note: Capabilities returned by the replacement pipeline MUST either be exactly the same + // capabilities as in the final response, or eventually resolve to exactly the same + // capabilities, where "exactly the same" means the underlying `ClientHook` object is exactly + // the same object by identity. Resolving to some "equivalent" capability is not good enough. + + template + kj::Promise tailCall(Request&& tailRequest); + // Resolve the call by making a tail call. `tailRequest` is a request that has been filled in + // but not yet sent. The context will send the call, then fill in the results with the result + // of the call. If tailCall() is used, {get,init,set,adopt}Results (above) *must not* be called. + // + // The RPC implementation may be able to optimize a tail call to another machine such that the + // results never actually pass through this machine. Even if no such optimization is possible, + // `tailCall()` may allow pipelined calls to be forwarded optimistically to the new call site. + // + // In general, this should be the last thing a method implementation calls, and the promise + // returned from `tailCall()` should then be returned by the method implementation. + + void allowCancellation() + KJ_UNAVAILABLE( + "As of Cap'n Proto 1.0, allowCancellation must be applied statically using an " + "annotation in the schema. See annotations defined in /capnp/c++.capnp. For " + "DynamicCapability::Server, use the constructor option (the annotation does not apply " + "to DynamicCapability). This change was made to gain a significant performance boost -- " + "dynamically allowing cancellation required excessive bookkeeping."); + +private: + CallContextHook* hook; + + friend class Capability::Server; + friend struct DynamicCapability; + friend class CallContextHook; +}; + +template +class StreamingCallContext: public kj::DisallowConstCopy { + // Like CallContext but for streaming calls. + +public: + explicit StreamingCallContext(CallContextHook& hook); + + typename Params::Reader getParams(); + void releaseParams(); + + // Note: tailCall() is not supported because: + // - It would significantly complicate the implementation of streaming. + // - It wouldn't be particularly useful since streaming calls don't return anything, and they + // already compensate for latency. + + void allowCancellation() + KJ_UNAVAILABLE( + "As of Cap'n Proto 1.0, allowCancellation must be applied statically using an " + "annotation in the schema. See annotations defined in /capnp/c++.capnp. For " + "DynamicCapability::Server, use the constructor option (the annotation does not apply " + "to DynamicCapability). This change was made to gain a significant performance boost -- " + "dynamically allowing cancellation required excessive bookkeeping."); + +private: + CallContextHook* hook; + + friend class Capability::Server; + friend struct DynamicCapability; + friend class CallContextHook; +}; + +class Capability::Server { + // Objects implementing a Cap'n Proto interface must subclass this. Typically, such objects + // will instead subclass a typed Server interface which will take care of implementing + // dispatchCall(). + +public: + typedef Capability Serves; + + struct DispatchCallResult { + kj::Promise promise; + // Promise for completion of the call. + + bool isStreaming; + // If true, this method was declared as `-> stream;`. No other calls should be permitted until + // this call finishes, and if this call throws an exception, all future calls will throw the + // same exception. + + bool allowCancellation = false; + // If true, the call can be canceled normally. If false, the immediate caller is responsible + // for ensuring that cancellation is prevented and that `context` remains valid until the + // call completes normally. + // + // See the `allowCancellation` annotation defined in `c++.capnp`. + }; + + virtual DispatchCallResult dispatchCall(uint64_t interfaceId, uint16_t methodId, + CallContext context) = 0; + // Call the given method. `params` is the input struct, and should be released as soon as it + // is no longer needed. `context` may be used to allocate the output struct and other call + // logistics. + + virtual kj::Maybe getFd() { return nullptr; } + // If this capability is backed by a file descriptor that is safe to directly expose to clients, + // returns that FD. When FD passing has been enabled in the RPC layer, this FD may be sent to + // other processes along with the capability. + + virtual kj::Maybe> shortenPath(); + // If this returns non-null, then it is a promise which, when resolved, points to a new + // capability to which future calls can be sent. Use this in cases where an object implementation + // might discover a more-optimized path some time after it starts. + // + // Implementing this (and returning non-null) will cause the capability to be advertised as a + // promise at the RPC protocol level. Once the promise returned by shortenPath() resolves, the + // remote client will receive a `Resolve` message updating it to point at the new destination. + // + // `shortenPath()` can also be used as a hack to shut up the client. If shortenPath() returns + // a promise that resolves to an exception, then the client will be notified that the capability + // is now broken. Assuming the client is using a correct RPC implemnetation, this should cause + // all further calls initiated by the client to this capability to immediately fail client-side, + // sparing the server's bandwidth. + // + // The default implementation always returns nullptr. + + // TODO(someday): Method which can optionally be overridden to implement Join when the object is + // a proxy. + +protected: + inline Capability::Client thisCap(); + // Get a capability pointing to this object, much like the `this` keyword. + // + // The effect of this method is undefined if: + // - No capability client has been created pointing to this object. (This is always the case in + // the server's constructor.) + // - The capability client pointing at this object has been destroyed. (This is always the case + // in the server's destructor.) + // - The capability client pointing at this object has been revoked using RevocableServer. + // - Multiple capability clients have been created around the same server (possible if the server + // is refcounted, which is not recommended since the client itself provides refcounting). + + template + CallContext internalGetTypedContext( + CallContext typeless); + template + StreamingCallContext internalGetTypedStreamingContext( + CallContext typeless); + DispatchCallResult internalUnimplemented(const char* actualInterfaceName, + uint64_t requestedTypeId); + DispatchCallResult internalUnimplemented(const char* interfaceName, + uint64_t typeId, uint16_t methodId); + kj::Promise internalUnimplemented(const char* interfaceName, const char* methodName, + uint64_t typeId, uint16_t methodId); + +private: + ClientHook* thisHook = nullptr; + friend class LocalClient; +}; + +template +class RevocableServer { + // Allows you to create a capability client pointing to a capability server without taking + // ownership of the server. When `RevocableServer` is destroyed, all clients created through it + // will become broken. All outstanding RPCs via those clients will be canceled and all future + // RPCs will immediately throw. Hence, once the `RevocableServer` is destroyed, it is safe + // to destroy the server object it referenced. + // + // This is particularly useful when you want to create a capability server that points to an + // object that you do not own, and thus cannot keep alive beyond some defined lifetime. Since + // you cannot force the client to respect lifetime rules, you should use a RevocableServer to + // revoke access before the lifetime ends. + // + // The RevocableServer object can be moved (as long as the server outlives it). + +public: + RevocableServer(typename T::Server& server); + RevocableServer(RevocableServer&&) = default; + RevocableServer& operator=(RevocableServer&&) = default; + ~RevocableServer() noexcept(false); + KJ_DISALLOW_COPY(RevocableServer); + + typename T::Client getClient(); + + void revoke(); + void revoke(kj::Exception&& reason); + // Revokes the capability immediately, rather than waiting for the destructor. This can also + // be used to specify a custom exception to use when revoking. + +private: + kj::Own hook; +}; + +// ======================================================================================= + +template +class PipelineBuilder: public T::Builder { + // Convenience class to build a Pipeline object for use with CallContext::setPipeline(). + // + // Building a pipeline object is like building an RPC result message, except that you only need + // to fill in the capabilities, since the purpose is only to allow pipelined RPC requests to + // flow through. + // + // See the docs for `CallContext::setPipeline()` for an example. + +public: + PipelineBuilder(uint firstSegmentWords = 64); + // Construct a builder, allocating the given number of words for the first segment of the backing + // message. Since `PipelineBuilder` is typically used with small RPC messages, the default size + // here is considerably smaller than with MallocMessageBuilder. + + typename T::Pipeline build(); + // Constructs a `Pipeline` object backed by the current content of this builder. Calling this + // consumes the `PipelineBuilder`; no further methods can be invoked. + +private: + kj::Own hook; + + PipelineBuilder(_::PipelineBuilderPair pair); +}; + +// ======================================================================================= + +class ReaderCapabilityTable: private _::CapTableReader { + // Class which imbues Readers with the ability to read capabilities. + // + // In Cap'n Proto format, the encoding of a capability pointer is simply an integer index into + // an external table. Since these pointers fundamentally point outside the message, a + // MessageReader by default has no idea what they point at, and therefore reading capabilities + // from such a reader will throw exceptions. + // + // In order to be able to read capabilities, you must first attach a capability table, using + // this class. By "imbuing" a Reader, you get a new Reader which will interpret capability + // pointers by treating them as indexes into the ReaderCapabilityTable. + // + // Note that when using Cap'n Proto's RPC system, this is handled automatically. + +public: + explicit ReaderCapabilityTable(kj::Array>> table); + KJ_DISALLOW_COPY_AND_MOVE(ReaderCapabilityTable); + + template + T imbue(T reader); + // Return a reader equivalent to `reader` except that when reading capability-valued fields, + // the capabilities are looked up in this table. + +private: + kj::Array>> table; + + kj::Maybe> extractCap(uint index) override; +}; + +class BuilderCapabilityTable: private _::CapTableBuilder { + // Class which imbues Builders with the ability to read and write capabilities. + // + // This is much like ReaderCapabilityTable, except for builders. The table starts out empty, + // but capabilities can be added to it over time. + +public: + BuilderCapabilityTable(); + KJ_DISALLOW_COPY_AND_MOVE(BuilderCapabilityTable); + + inline kj::ArrayPtr>> getTable() { return table; } + + template + T imbue(T builder); + // Return a builder equivalent to `builder` except that when reading capability-valued fields, + // the capabilities are looked up in this table. + +private: + kj::Vector>> table; + + kj::Maybe> extractCap(uint index) override; + uint injectCap(kj::Own&& cap) override; + void dropCap(uint index) override; +}; + +// ======================================================================================= + +namespace _ { // private + +class CapabilityServerSetBase { +public: + Capability::Client addInternal(kj::Own&& server, void* ptr); + kj::Promise getLocalServerInternal(Capability::Client& client); +}; + +} // namespace _ (private) + +template +class CapabilityServerSet: private _::CapabilityServerSetBase { + // Allows a server to recognize its own capabilities when passed back to it, and obtain the + // underlying Server objects associated with them. + // + // All objects in the set must have the same interface type T. The objects may implement various + // interfaces derived from T (and in fact T can be `capnp::Capability` to accept all objects), + // but note that if you compile with RTTI disabled then you will not be able to down-cast through + // virtual inheritance, and all inheritance between server interfaces is virtual. So, with RTTI + // disabled, you will likely need to set T to be the most-derived Cap'n Proto interface type, + // and you server class will need to be directly derived from that, so that you can use + // static_cast (or kj::downcast) to cast to it after calling getLocalServer(). (If you compile + // with RTTI, then you can freely dynamic_cast and ignore this issue!) + +public: + CapabilityServerSet() = default; + KJ_DISALLOW_COPY_AND_MOVE(CapabilityServerSet); + + typename T::Client add(kj::Own&& server); + // Create a new capability Client for the given Server and also add this server to the set. + + kj::Promise> getLocalServer(typename T::Client& client); + // Given a Client pointing to a server previously passed to add(), return the corresponding + // Server. This returns a promise because if the input client is itself a promise, this must + // wait for it to resolve. Keep in mind that the server will be deleted when all clients are + // gone, so the caller should make sure to keep the client alive (hence why this method only + // accepts an lvalue input). +}; + +// ======================================================================================= +// Hook interfaces which must be implemented by the RPC system. Applications never call these +// directly; the RPC system implements them and the types defined earlier in this file wrap them. + +class RequestHook { + // Hook interface implemented by RPC system representing a request being built. + +public: + virtual RemotePromise send() = 0; + // Send the call and return a promise for the result. + + virtual kj::Promise sendStreaming() = 0; + // Send a streaming call. + + virtual AnyPointer::Pipeline sendForPipeline() = 0; + // Send a call for pipelining purposes only. + + virtual const void* getBrand() = 0; + // Returns a void* that identifies who made this request. This can be used by an RPC adapter to + // discover when tail call is going to be sent over its own connection and therefore can be + // optimized into a remote tail call. + + template + inline static kj::Own from(Request&& request) { + return kj::mv(request.hook); + } +}; + +class ResponseHook { + // Hook interface implemented by RPC system representing a response. + // + // At present this class has no methods. It exists only for garbage collection -- when the + // ResponseHook is destroyed, the results can be freed. + +public: + virtual ~ResponseHook() noexcept(false); + // Just here to make sure the type is dynamic. + + template + inline static kj::Own from(Response&& response) { + return kj::mv(response.hook); + } +}; + +// class PipelineHook is declared in any.h because it is needed there. + +class ClientHook { +public: + ClientHook(); + + using CallHints = Capability::Client::CallHints; + + virtual Request newCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint, + CallHints hints) = 0; + // Start a new call, allowing the client to allocate request/response objects as it sees fit. + // This version is used when calls are made from application code in the local process. + + struct VoidPromiseAndPipeline { + kj::Promise promise; + kj::Own pipeline; + }; + + virtual VoidPromiseAndPipeline call(uint64_t interfaceId, uint16_t methodId, + kj::Own&& context, CallHints hints) = 0; + // Call the object, but the caller controls allocation of the request/response objects. If the + // callee insists on allocating these objects itself, it must make a copy. This version is used + // when calls come in over the network via an RPC system. Note that even if the returned + // `Promise` is discarded, the call may continue executing if any pipelined calls are + // waiting for it. + // + // The call must not begin synchronously; the callee must arrange for the call to begin in a + // later turn of the event loop. Otherwise, application code may call back and affect the + // callee's state in an unexpected way. + + virtual kj::Maybe getResolved() = 0; + // If this ClientHook is a promise that has already resolved, returns the inner, resolved version + // of the capability. The caller may permanently replace this client with the resolved one if + // desired. Returns null if the client isn't a promise or hasn't resolved yet -- use + // `whenMoreResolved()` to distinguish between them. + // + // Once a particular ClientHook's `getResolved()` returns non-null, it must permanently return + // exactly the same resolution. This is why `getResolved()` returns a reference -- it is assumed + // this object must have a strong reference to the resolution which it intends to keep + // permanently, therefore the returned reference will live at least as long as this `ClientHook`. + // This "only one resolution" policy is necessary for the RPC system to implement embargoes + // properly. + + virtual kj::Maybe>> whenMoreResolved() = 0; + // If this client is a settled reference (not a promise), return nullptr. Otherwise, return a + // promise that eventually resolves to a new client that is closer to being the final, settled + // client (i.e. the value eventually returned by `getResolved()`). Calling this repeatedly + // should eventually produce a settled client. + // + // Once the promise resolves, `getResolved()` must return exactly the same `ClientHook` as the + // one this Promise resolved to. + + kj::Promise whenResolved(); + // Repeatedly calls whenMoreResolved() until it returns nullptr. + + virtual kj::Own addRef() = 0; + // Return a new reference to the same capability. + + virtual const void* getBrand() = 0; + // Returns a void* that identifies who made this client. This can be used by an RPC adapter to + // discover when a capability it needs to marshal is one that it created in the first place, and + // therefore it can transfer the capability without proxying. + + static const uint NULL_CAPABILITY_BRAND; + static const uint BROKEN_CAPABILITY_BRAND; + // Values are irrelevant; used for pointers. + + inline bool isNull() { return getBrand() == &NULL_CAPABILITY_BRAND; } + // Returns true if the capability was created as a result of assigning a Client to null or by + // reading a null pointer out of a Cap'n Proto message. + + inline bool isError() { return getBrand() == &BROKEN_CAPABILITY_BRAND; } + // Returns true if the capability was created by newBrokenCap(). + + virtual kj::Maybe getFd() = 0; + // Implements Capability::Client::getFd(). If this returns null but whenMoreResolved() returns + // non-null, then Capability::Client::getFd() waits for resolution and tries again. + + static kj::Own from(Capability::Client client) { return kj::mv(client.hook); } +}; + +class RevocableClientHook: public ClientHook { +public: + virtual void revoke() = 0; + virtual void revoke(kj::Exception&& reason) = 0; +}; + +class CallContextHook { + // Hook interface implemented by RPC system to manage a call on the server side. See + // CallContext. + +public: + virtual AnyPointer::Reader getParams() = 0; + virtual void releaseParams() = 0; + virtual AnyPointer::Builder getResults(kj::Maybe sizeHint) = 0; + virtual kj::Promise tailCall(kj::Own&& request) = 0; + + virtual void setPipeline(kj::Own&& pipeline) = 0; + + virtual kj::Promise onTailCall() = 0; + // If `tailCall()` is called, resolves to the PipelineHook from the tail call. An + // implementation of `ClientHook::call()` is allowed to call this at most once. + + virtual ClientHook::VoidPromiseAndPipeline directTailCall(kj::Own&& request) = 0; + // Call this when you would otherwise call onTailCall() immediately followed by tailCall(). + // Implementations of tailCall() should typically call directTailCall() and then fulfill the + // promise fulfiller for onTailCall() with the returned pipeline. + + virtual kj::Own addRef() = 0; + + template + static CallContextHook& from(CallContext& context) { return *context.hook; } + template + static CallContextHook& from(StreamingCallContext& context) { return *context.hook; } +}; + +kj::Own newLocalPromiseClient(kj::Promise>&& promise); +// Returns a ClientHook that queues up calls until `promise` resolves, then forwards them to +// the new client. This hook's `getResolved()` and `whenMoreResolved()` methods will reflect the +// redirection to the eventual replacement client. + +kj::Own newLocalPromisePipeline(kj::Promise>&& promise); +// Returns a PipelineHook that queues up calls until `promise` resolves, then forwards them to +// the new pipeline. + +kj::Own newBrokenCap(kj::StringPtr reason); +kj::Own newBrokenCap(kj::Exception&& reason); +// Helper function that creates a capability which simply throws exceptions when called. + +kj::Own newBrokenPipeline(kj::Exception&& reason); +// Helper function that creates a pipeline which simply throws exceptions when called. + +Request newBrokenRequest( + kj::Exception&& reason, kj::Maybe sizeHint); +// Helper function that creates a Request object that simply throws exceptions when sent. + +kj::Own getDisabledPipeline(); +// Gets a PipelineHook appropriate to use when CallHints::noPromisePipelining is true. This will +// throw from all calls. This does not actually allocate the object; a static global object is +// returned with a null disposer. + +// ======================================================================================= +// Extend PointerHelpers for interfaces + +namespace _ { // private + +template +struct PointerHelpers { + static inline typename T::Client get(PointerReader reader) { + return typename T::Client(reader.getCapability()); + } + static inline typename T::Client get(PointerBuilder builder) { + return typename T::Client(builder.getCapability()); + } + static inline void set(PointerBuilder builder, typename T::Client&& value) { + builder.setCapability(kj::mv(value.Capability::Client::hook)); + } + static inline void set(PointerBuilder builder, typename T::Client& value) { + builder.setCapability(value.Capability::Client::hook->addRef()); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +} // namespace _ (private) + +// ======================================================================================= +// Extend List for interfaces + +template +struct List { + List() = delete; + + class Reader { + public: + typedef List Reads; + + Reader() = default; + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename T::Client operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename T::Client(reader.getPointerElement( + bounded(index) * ELEMENTS).getCapability()); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + Builder() = delete; + inline Builder(decltype(nullptr)) {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename T::Client operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename T::Client(builder.getPointerElement( + bounded(index) * ELEMENTS).getCapability()); + } + inline void set(uint index, typename T::Client value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).setCapability(kj::mv(value.hook)); + } + inline void adopt(uint index, Orphan&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value)); + } + inline Orphan disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +// ======================================================================================= +// Inline implementation details + +template +RemotePromise RemotePromise::reducePromise(kj::Promise&& promise) { + kj::Tuple>, kj::Promise>> splitPromise = + promise.then([](RemotePromise&& inner) { + // `inner` is multiply-inherited, and we want to move away each superclass separately. + // Let's create two references to make clear what we're doing (though this is not strictly + // necessary). + kj::Promise>& innerPromise = inner; + typename T::Pipeline& innerPipeline = inner; + return kj::tuple(kj::mv(innerPromise), PipelineHook::from(kj::mv(innerPipeline))); + }).split(); + + return RemotePromise(kj::mv(kj::get<0>(splitPromise)), + typename T::Pipeline(AnyPointer::Pipeline( + newLocalPromisePipeline(kj::mv(kj::get<1>(splitPromise)))))); +} + +template +RemotePromise Request::send() { + auto typelessPromise = hook->send(); + hook = nullptr; // prevent reuse + + // Convert the Promise to return the correct response type. + // Explicitly upcast to kj::Promise to make clear that calling .then() doesn't invalidate the + // Pipeline part of the RemotePromise. + auto typedPromise = kj::implicitCast>&>(typelessPromise) + .then([](Response&& response) -> Response { + return Response(response.getAs(), kj::mv(response.hook)); + }); + + // Wrap the typeless pipeline in a typed wrapper. + typename Results::Pipeline typedPipeline( + kj::mv(kj::implicitCast(typelessPromise))); + + return RemotePromise(kj::mv(typedPromise), kj::mv(typedPipeline)); +} + +template +typename Results::Pipeline Request::sendForPipeline() { + auto typelessPipeline = hook->sendForPipeline(); + hook = nullptr; // prevent reuse + return typename Results::Pipeline(kj::mv(typelessPipeline)); +} + +template +kj::Promise StreamingRequest::send() { + auto promise = hook->sendStreaming(); + hook = nullptr; // prevent reuse + return promise; +} + +inline Capability::Client::Client(kj::Own&& hook): hook(kj::mv(hook)) {} +template +inline Capability::Client::Client(kj::Own&& server) + : hook(makeLocalClient(kj::mv(server))) {} +template +inline Capability::Client::Client(kj::Promise&& promise) + : hook(newLocalPromiseClient(promise.then([](T&& t) { return kj::mv(t.hook); }))) {} +inline Capability::Client::Client(Client& other): hook(other.hook->addRef()) {} +inline Capability::Client& Capability::Client::operator=(Client& other) { + hook = other.hook->addRef(); + return *this; +} +template +inline typename T::Client Capability::Client::castAs() { + return typename T::Client(hook->addRef()); +} +inline Request Capability::Client::typelessRequest( + uint64_t interfaceId, uint16_t methodId, + kj::Maybe sizeHint, CallHints hints) { + return newCall(interfaceId, methodId, sizeHint, hints); +} +template +inline Request Capability::Client::newCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint, CallHints hints) { + auto typeless = hook->newCall(interfaceId, methodId, sizeHint, hints); + return Request(typeless.template getAs(), kj::mv(typeless.hook)); +} +template +inline StreamingRequest Capability::Client::newStreamingCall( + uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint, CallHints hints) { + auto typeless = hook->newCall(interfaceId, methodId, sizeHint, hints); + return StreamingRequest(typeless.template getAs(), kj::mv(typeless.hook)); +} + +template +inline CallContext::CallContext(CallContextHook& hook): hook(&hook) {} +template +inline StreamingCallContext::StreamingCallContext(CallContextHook& hook): hook(&hook) {} +template +inline typename Params::Reader CallContext::getParams() { + return hook->getParams().template getAs(); +} +template +inline typename Params::Reader StreamingCallContext::getParams() { + return hook->getParams().template getAs(); +} +template +inline void CallContext::releaseParams() { + hook->releaseParams(); +} +template +inline void StreamingCallContext::releaseParams() { + hook->releaseParams(); +} +template +inline typename Results::Builder CallContext::getResults( + kj::Maybe sizeHint) { + // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 + return hook->getResults(sizeHint).template getAs(); +} +template +inline typename Results::Builder CallContext::initResults( + kj::Maybe sizeHint) { + // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 + return hook->getResults(sizeHint).template initAs(); +} +template +inline void CallContext::setResults(typename Results::Reader value) { + hook->getResults(value.totalSize()).template setAs(value); +} +template +inline void CallContext::adoptResults(Orphan&& value) { + hook->getResults(nullptr).adopt(kj::mv(value)); +} +template +inline Orphanage CallContext::getResultsOrphanage( + kj::Maybe sizeHint) { + return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); +} +template +void CallContext::setPipeline(typename Results::Pipeline&& pipeline) { + hook->setPipeline(PipelineHook::from(kj::mv(pipeline))); +} +template +void CallContext::setPipeline(typename Results::Pipeline& pipeline) { + hook->setPipeline(PipelineHook::from(pipeline).addRef()); +} +template +template +inline kj::Promise CallContext::tailCall( + Request&& tailRequest) { + return hook->tailCall(kj::mv(tailRequest.hook)); +} + +template +CallContext Capability::Server::internalGetTypedContext( + CallContext typeless) { + return CallContext(*typeless.hook); +} + +template +StreamingCallContext Capability::Server::internalGetTypedStreamingContext( + CallContext typeless) { + return StreamingCallContext(*typeless.hook); +} + +Capability::Client Capability::Server::thisCap() { + return Client(thisHook->addRef()); +} + +template +RevocableServer::RevocableServer(typename T::Server& server) + : hook(Capability::Client::makeRevocableLocalClient(server)) {} +template +RevocableServer::~RevocableServer() noexcept(false) { + // Check if moved away. + if (hook.get() != nullptr) { + Capability::Client::revokeLocalClient(*hook); + } +} + +template +typename T::Client RevocableServer::getClient() { + return typename T::Client(hook->addRef()); +} + +template +void RevocableServer::revoke() { + Capability::Client::revokeLocalClient(*hook); +} +template +void RevocableServer::revoke(kj::Exception&& exception) { + Capability::Client::revokeLocalClient(*hook, kj::mv(exception)); +} + +namespace _ { // private + +struct PipelineBuilderPair { + AnyPointer::Builder root; + kj::Own hook; +}; + +PipelineBuilderPair newPipelineBuilder(uint firstSegmentWords); + +} // namespace _ (private) + +template +PipelineBuilder::PipelineBuilder(uint firstSegmentWords) + : PipelineBuilder(_::newPipelineBuilder(firstSegmentWords)) {} + +template +PipelineBuilder::PipelineBuilder(_::PipelineBuilderPair pair) + : T::Builder(pair.root.initAs()), + hook(kj::mv(pair.hook)) {} + +template +typename T::Pipeline PipelineBuilder::build() { + // Prevent subsequent accidental modification. A good compiler should be able to optimize this + // assignment away assuming the PipelineBuilder is not accessed again after this point. + static_cast(*this) = nullptr; + + return typename T::Pipeline(AnyPointer::Pipeline(kj::mv(hook))); +} + +template +T ReaderCapabilityTable::imbue(T reader) { + return T(_::PointerHelpers>::getInternalReader(reader).imbue(this)); +} + +template +T BuilderCapabilityTable::imbue(T builder) { + return T(_::PointerHelpers>::getInternalBuilder(kj::mv(builder)).imbue(this)); +} + +template +typename T::Client CapabilityServerSet::add(kj::Own&& server) { + void* ptr = reinterpret_cast(server.get()); + // Clang insists that `castAs` is a template-dependent member and therefore we need the + // `template` keyword here, but AFAICT this is wrong: addImpl() is not a template. + return addInternal(kj::mv(server), ptr).template castAs(); +} + +template +kj::Promise> CapabilityServerSet::getLocalServer( + typename T::Client& client) { + return getLocalServerInternal(client) + .then([](void* server) -> kj::Maybe { + if (server == nullptr) { + return nullptr; + } else { + return *reinterpret_cast(server); + } + }); +} + +template +struct Orphanage::GetInnerReader { + static inline kj::Own apply(typename T::Client t) { + return ClientHook::from(kj::mv(t)); + } +}; + +#define CAPNP_CAPABILITY_H_INCLUDED // for testing includes in unit test + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/common.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/common.h new file mode 100644 index 000000000..28c90cd9f --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/common.h @@ -0,0 +1,751 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file contains types which are intended to help detect incorrect usage at compile +// time, but should then be optimized down to basic primitives (usually, integers) by the +// compiler. + +#pragma once + +#include +#include +#include +#include // work-around macro conflict with `VOID` + +#if CAPNP_DEBUG_TYPES +#include +#endif + +#if !defined(CAPNP_HEADER_WARNINGS) || !CAPNP_HEADER_WARNINGS +#define CAPNP_BEGIN_HEADER KJ_BEGIN_SYSTEM_HEADER +#define CAPNP_END_HEADER KJ_END_SYSTEM_HEADER +#else +#define CAPNP_BEGIN_HEADER +#define CAPNP_END_HEADER +#endif + +CAPNP_BEGIN_HEADER + +namespace capnp { + +#define CAPNP_VERSION_MAJOR 1 +#define CAPNP_VERSION_MINOR 0 +#define CAPNP_VERSION_MICRO 1 + +#define CAPNP_VERSION \ + (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO) + +#ifndef CAPNP_LITE +#define CAPNP_LITE 0 +#endif + +#if CAPNP_TESTING_CAPNP // defined in Cap'n Proto's own unit tests; others should not define this +#define CAPNP_DEPRECATED(reason) +#else +#define CAPNP_DEPRECATED KJ_DEPRECATED +#endif + +typedef unsigned int uint; + +struct Void { + // Type used for Void fields. Using C++'s "void" type creates a bunch of issues since it behaves + // differently from other types. + + inline constexpr bool operator==(Void other) const { return true; } + inline constexpr bool operator!=(Void other) const { return false; } +}; + +static constexpr Void VOID = Void(); +// Constant value for `Void`, which is an empty struct. + +inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; } + +struct Text; +struct Data; + +enum class Kind: uint8_t { + PRIMITIVE, + BLOB, + ENUM, + STRUCT, + UNION, + INTERFACE, + LIST, + + OTHER + // Some other type which is often a type parameter to Cap'n Proto templates, but which needs + // special handling. This includes types like AnyPointer, Dynamic*, etc. +}; + +enum class Style: uint8_t { + PRIMITIVE, + POINTER, // other than struct + STRUCT, + CAPABILITY +}; + +enum class ElementSize: uint8_t { + // Size of a list element. + + VOID = 0, + BIT = 1, + BYTE = 2, + TWO_BYTES = 3, + FOUR_BYTES = 4, + EIGHT_BYTES = 5, + + POINTER = 6, + + INLINE_COMPOSITE = 7 +}; + +enum class PointerType { + // Various wire types a pointer field can take + + NULL_, + // Should be NULL, but that's #defined in stddef.h + + STRUCT, + LIST, + CAPABILITY +}; + +namespace schemas { + +template +struct EnumInfo; + +} // namespace schemas + +namespace _ { // private + +template struct Kind_; + +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; + +template struct Kind_> { + static constexpr Kind kind = Kind::STRUCT; +}; +template struct Kind_> { + static constexpr Kind kind = Kind::INTERFACE; +}; +template struct Kind_::IsEnum>> { + static constexpr Kind kind = Kind::ENUM; +}; + +} // namespace _ (private) + +template ::kind> +inline constexpr Kind kind() { + // This overload of kind() matches types which have a Kind_ specialization. + + return k; +} + +#if _MSC_VER && !defined(__clang__) + +#define CAPNP_KIND(T) ::capnp::_::Kind_::kind +// Avoid constexpr methods in MSVC (it remains buggy in many situations). + +#else // _MSC_VER + +#define CAPNP_KIND(T) ::capnp::kind() +// Use this macro rather than kind() in any code which must work in MSVC. + +#endif // _MSC_VER, else + +#if !CAPNP_LITE + +template ()> +inline constexpr Style style() { + return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE + : k == Kind::STRUCT ? Style::STRUCT + : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER; +} + +#endif // !CAPNP_LITE + +template +struct List; + +#if _MSC_VER && !defined(__clang__) + +template +struct List {}; +// For some reason, without this declaration, MSVC will error out on some uses of List +// claiming that "T" -- as used in the default initializer for the second template param, "k" -- +// is not defined. I do not understand this error, but adding this empty default declaration fixes +// it. + +#endif + +template struct ListElementType_; +template struct ListElementType_> { typedef T Type; }; +template using ListElementType = typename ListElementType_::Type; + +namespace _ { // private +template struct Kind_> { + static constexpr Kind kind = Kind::LIST; +}; +} // namespace _ (private) + +template struct ReaderFor_ { typedef typename T::Reader Type; }; +template struct ReaderFor_ { typedef T Type; }; +template struct ReaderFor_ { typedef T Type; }; +template struct ReaderFor_ { typedef typename T::Client Type; }; +template using ReaderFor = typename ReaderFor_::Type; +// The type returned by List::Reader::operator[]. + +template struct BuilderFor_ { typedef typename T::Builder Type; }; +template struct BuilderFor_ { typedef T Type; }; +template struct BuilderFor_ { typedef T Type; }; +template struct BuilderFor_ { typedef typename T::Client Type; }; +template using BuilderFor = typename BuilderFor_::Type; +// The type returned by List::Builder::operator[]. + +template struct PipelineFor_ { typedef typename T::Pipeline Type;}; +template struct PipelineFor_ { typedef typename T::Client Type; }; +template using PipelineFor = typename PipelineFor_::Type; + +template struct TypeIfEnum_; +template struct TypeIfEnum_ { typedef T Type; }; + +template +using TypeIfEnum = typename TypeIfEnum_>::Type; + +template +using FromReader = typename kj::Decay::Reads; +// FromReader = MyType (for any Cap'n Proto type). + +template +using FromBuilder = typename kj::Decay::Builds; +// FromBuilder = MyType (for any Cap'n Proto type). + +template +using FromPipeline = typename kj::Decay::Pipelines; +// FromBuilder = MyType (for any Cap'n Proto type). + +template +using FromClient = typename kj::Decay::Calls; +// FromReader = MyType (for any Cap'n Proto interface type). + +template +using FromServer = typename kj::Decay::Serves; +// FromBuilder = MyType (for any Cap'n Proto interface type). + +template +struct FromAny_; + +template +struct FromAny_>> { + using Type = FromReader; +}; + +template +struct FromAny_>> { + using Type = FromBuilder; +}; + +template +struct FromAny_>> { + using Type = FromPipeline; +}; + +// Note that T::Client is covered by FromReader + +template +struct FromAny_, kj::VoidSfinae>> { + using Type = FromServer; +}; + +template +struct FromAny_::kind == Kind::PRIMITIVE || _::Kind_::kind == Kind::ENUM>> { + // TODO(msvc): Ideally the EnableIf condition would be `style() == Style::PRIMITIVE`, but MSVC + // cannot yet use style() in this constexpr context. + + using Type = kj::Decay; +}; + +template +using FromAny = typename FromAny_::Type; +// Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is: +// +// Foo::Reader -> Foo +// Foo::Builder -> Foo +// Foo::Pipeline -> Foo +// Foo::Client -> Foo +// Own -> Foo +// uint32_t -> uint32_t + +namespace _ { // private + +template +struct PointerHelpers; + +#if _MSC_VER && !defined(__clang__) + +template +struct PointerHelpers {}; +// For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers +// claiming that "T" -- as used in the default initializer for the second template param, "k" -- +// is not defined. I do not understand this error, but adding this empty default declaration fixes +// it. + +#endif + +} // namespace _ (private) + +struct MessageSize { + // Size of a message. Every struct and list type has a method `.totalSize()` that returns this. + uint64_t wordCount; + uint capCount; + + inline constexpr MessageSize operator+(const MessageSize& other) const { + return { wordCount + other.wordCount, capCount + other.capCount }; + } +}; + +// ======================================================================================= +// Raw memory types and measures + +using kj::byte; + +class word { + // word is an opaque type with size of 64 bits. This type is useful only to make pointer + // arithmetic clearer. Since the contents are private, the only way to access them is to first + // reinterpret_cast to some other pointer type. + // + // Copying is disallowed because you should always use memcpy(). Otherwise, you may run afoul of + // aliasing rules. + // + // A pointer of type word* should always be word-aligned even if won't actually be dereferenced + // as that type. +public: + word() = default; +private: + uint64_t content KJ_UNUSED_MEMBER; +#if __GNUC__ < 8 || __clang__ + // GCC 8's -Wclass-memaccess complains whenever we try to memcpy() a `word` if we've disallowed + // the copy constructor. We don't want to disable the warning because it's a useful warning and + // we'd have to disable it for all applications that include this header. Instead we allow `word` + // to be copyable on GCC. + KJ_DISALLOW_COPY_AND_MOVE(word); +#endif +}; + +static_assert(sizeof(byte) == 1, "uint8_t is not one byte?"); +static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?"); + +#if CAPNP_DEBUG_TYPES +// Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types. Otherwise, plain integers are +// used. All the code should still operate exactly the same, we just lose compile-time checking. +// Note that this will also change symbol names, so it's important that the library and any clients +// be compiled with the same setting here. +// +// We disable this by default to reduce symbol name size and avoid any possibility of the compiler +// failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this +// during development and testing. + +namespace _ { class BitLabel; class ElementLabel; struct WirePointer; } + +template +using BitCountN = kj::Quantity(), T>, _::BitLabel>; +template +using ByteCountN = kj::Quantity(), T>, byte>; +template +using WordCountN = kj::Quantity(), T>, word>; +template +using ElementCountN = kj::Quantity(), T>, _::ElementLabel>; +template +using WirePointerCountN = kj::Quantity(), T>, _::WirePointer>; + +typedef BitCountN<8, uint8_t> BitCount8; +typedef BitCountN<16, uint16_t> BitCount16; +typedef BitCountN<32, uint32_t> BitCount32; +typedef BitCountN<64, uint64_t> BitCount64; +typedef BitCountN BitCount; + +typedef ByteCountN<8, uint8_t> ByteCount8; +typedef ByteCountN<16, uint16_t> ByteCount16; +typedef ByteCountN<32, uint32_t> ByteCount32; +typedef ByteCountN<64, uint64_t> ByteCount64; +typedef ByteCountN ByteCount; + +typedef WordCountN<8, uint8_t> WordCount8; +typedef WordCountN<16, uint16_t> WordCount16; +typedef WordCountN<32, uint32_t> WordCount32; +typedef WordCountN<64, uint64_t> WordCount64; +typedef WordCountN WordCount; + +typedef ElementCountN<8, uint8_t> ElementCount8; +typedef ElementCountN<16, uint16_t> ElementCount16; +typedef ElementCountN<32, uint32_t> ElementCount32; +typedef ElementCountN<64, uint64_t> ElementCount64; +typedef ElementCountN ElementCount; + +typedef WirePointerCountN<8, uint8_t> WirePointerCount8; +typedef WirePointerCountN<16, uint16_t> WirePointerCount16; +typedef WirePointerCountN<32, uint32_t> WirePointerCount32; +typedef WirePointerCountN<64, uint64_t> WirePointerCount64; +typedef WirePointerCountN WirePointerCount; + +template +using BitsPerElementN = decltype(BitCountN() / ElementCountN()); +template +using BytesPerElementN = decltype(ByteCountN() / ElementCountN()); +template +using WordsPerElementN = decltype(WordCountN() / ElementCountN()); +template +using PointersPerElementN = decltype(WirePointerCountN() / ElementCountN()); + +using kj::bounded; +using kj::unbound; +using kj::unboundAs; +using kj::unboundMax; +using kj::unboundMaxBits; +using kj::assertMax; +using kj::assertMaxBits; +using kj::upgradeBound; +using kj::ThrowOverflow; +using kj::assumeBits; +using kj::assumeMax; +using kj::subtractChecked; +using kj::trySubtract; + +template +inline constexpr U* operator+(U* ptr, kj::Quantity offset) { + return ptr + unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator+(const U* ptr, kj::Quantity offset) { + return ptr + unbound(offset / kj::unit>()); +} +template +inline constexpr U* operator+=(U*& ptr, kj::Quantity offset) { + return ptr = ptr + unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator+=(const U*& ptr, kj::Quantity offset) { + return ptr = ptr + unbound(offset / kj::unit>()); +} + +template +inline constexpr U* operator-(U* ptr, kj::Quantity offset) { + return ptr - unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator-(const U* ptr, kj::Quantity offset) { + return ptr - unbound(offset / kj::unit>()); +} +template +inline constexpr U* operator-=(U*& ptr, kj::Quantity offset) { + return ptr = ptr - unbound(offset / kj::unit>()); +} +template +inline constexpr const U* operator-=(const U*& ptr, kj::Quantity offset) { + return ptr = ptr - unbound(offset / kj::unit>()); +} + +constexpr auto BITS = kj::unit>(); +constexpr auto BYTES = kj::unit>(); +constexpr auto WORDS = kj::unit>(); +constexpr auto ELEMENTS = kj::unit>(); +constexpr auto POINTERS = kj::unit>(); + +constexpr auto ZERO = kj::bounded<0>(); +constexpr auto ONE = kj::bounded<1>(); + +// GCC 4.7 actually gives unused warnings on these constants in opt mode... +constexpr auto BITS_PER_BYTE KJ_UNUSED = bounded<8>() * BITS / BYTES; +constexpr auto BITS_PER_WORD KJ_UNUSED = bounded<64>() * BITS / WORDS; +constexpr auto BYTES_PER_WORD KJ_UNUSED = bounded<8>() * BYTES / WORDS; + +constexpr auto BITS_PER_POINTER KJ_UNUSED = bounded<64>() * BITS / POINTERS; +constexpr auto BYTES_PER_POINTER KJ_UNUSED = bounded<8>() * BYTES / POINTERS; +constexpr auto WORDS_PER_POINTER KJ_UNUSED = ONE * WORDS / POINTERS; + +constexpr auto POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER; + +constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment. +constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list. +constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section. +constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section. +constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob. + +typedef WordCountN SegmentWordCount; +typedef ElementCountN ListElementCount; +typedef WordCountN StructDataWordCount; +typedef WirePointerCountN StructPointerCount; +typedef ByteCountN BlobSize; + +constexpr auto MAX_SEGMENT_WORDS = + bounded()>() * WORDS; +constexpr auto MAX_LIST_ELEMENTS = + bounded()>() * ELEMENTS; +constexpr auto MAX_STUCT_DATA_WORDS = + bounded()>() * WORDS; +constexpr auto MAX_STRUCT_POINTER_COUNT = + bounded()>() * POINTERS; + +using StructDataBitCount = decltype(WordCountN() * BITS_PER_WORD); +// Number of bits in a Struct data segment (should come out to BitCountN<22>). + +using StructDataOffset = decltype(StructDataBitCount() * (ONE * ELEMENTS / BITS)); +using StructPointerOffset = StructPointerCount; +// Type of a field offset. + +inline StructDataOffset assumeDataOffset(uint32_t offset) { + return assumeMax(MAX_STUCT_DATA_WORDS * BITS_PER_WORD * (ONE * ELEMENTS / BITS), + bounded(offset) * ELEMENTS); +} + +inline StructPointerOffset assumePointerOffset(uint32_t offset) { + return assumeMax(MAX_STRUCT_POINTER_COUNT, bounded(offset) * POINTERS); +} + +constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits() - 1; +typedef kj::Quantity, byte> TextSize; +// Not including NUL terminator. + +template +inline KJ_CONSTEXPR() decltype(bounded() * BYTES / ELEMENTS) bytesPerElement() { + return bounded() * BYTES / ELEMENTS; +} + +template +inline KJ_CONSTEXPR() decltype(bounded() * BITS / ELEMENTS) bitsPerElement() { + return bounded() * BITS / ELEMENTS; +} + +template +inline constexpr kj::Quantity, T> +intervalLength(const T* a, const T* b, kj::Quantity, T>) { + return kj::assumeMax(b - a) * kj::unit, T>>(); +} + +template +inline constexpr kj::ArrayPtr arrayPtr(const U* ptr, kj::Quantity size) { + return kj::ArrayPtr(ptr, unbound(size / kj::unit>())); +} +template +inline constexpr kj::ArrayPtr arrayPtr(U* ptr, kj::Quantity size) { + return kj::ArrayPtr(ptr, unbound(size / kj::unit>())); +} + +#else + +template +using BitCountN = T; +template +using ByteCountN = T; +template +using WordCountN = T; +template +using ElementCountN = T; +template +using WirePointerCountN = T; + + +// XXX +typedef BitCountN<8, uint8_t> BitCount8; +typedef BitCountN<16, uint16_t> BitCount16; +typedef BitCountN<32, uint32_t> BitCount32; +typedef BitCountN<64, uint64_t> BitCount64; +typedef BitCountN BitCount; + +typedef ByteCountN<8, uint8_t> ByteCount8; +typedef ByteCountN<16, uint16_t> ByteCount16; +typedef ByteCountN<32, uint32_t> ByteCount32; +typedef ByteCountN<64, uint64_t> ByteCount64; +typedef ByteCountN ByteCount; + +typedef WordCountN<8, uint8_t> WordCount8; +typedef WordCountN<16, uint16_t> WordCount16; +typedef WordCountN<32, uint32_t> WordCount32; +typedef WordCountN<64, uint64_t> WordCount64; +typedef WordCountN WordCount; + +typedef ElementCountN<8, uint8_t> ElementCount8; +typedef ElementCountN<16, uint16_t> ElementCount16; +typedef ElementCountN<32, uint32_t> ElementCount32; +typedef ElementCountN<64, uint64_t> ElementCount64; +typedef ElementCountN ElementCount; + +typedef WirePointerCountN<8, uint8_t> WirePointerCount8; +typedef WirePointerCountN<16, uint16_t> WirePointerCount16; +typedef WirePointerCountN<32, uint32_t> WirePointerCount32; +typedef WirePointerCountN<64, uint64_t> WirePointerCount64; +typedef WirePointerCountN WirePointerCount; + +template +using BitsPerElementN = decltype(BitCountN() / ElementCountN()); +template +using BytesPerElementN = decltype(ByteCountN() / ElementCountN()); +template +using WordsPerElementN = decltype(WordCountN() / ElementCountN()); +template +using PointersPerElementN = decltype(WirePointerCountN() / ElementCountN()); + +using kj::ThrowOverflow; +// YYY + +template inline constexpr uint bounded() { return i; } +template inline constexpr T bounded(T i) { return i; } +template inline constexpr T unbound(T i) { return i; } + +template inline constexpr T unboundAs(U i) { return i; } + +template inline constexpr uint unboundMax(T i) { return i; } +template inline constexpr uint unboundMaxBits(T i) { return i; } + +template +inline T assertMax(T value, ErrorFunc&& func) { + if (KJ_UNLIKELY(value > newMax)) func(); + return value; +} + +template +inline T assertMax(uint newMax, T value, ErrorFunc&& func) { + if (KJ_UNLIKELY(value > newMax)) func(); + return value; +} + +template +inline T assertMaxBits(T value, ErrorFunc&& func = ErrorFunc()) { + if (KJ_UNLIKELY(value > kj::maxValueForBits())) func(); + return value; +} + +template +inline T assertMaxBits(uint bits, T value, ErrorFunc&& func = ErrorFunc()) { + if (KJ_UNLIKELY(value > (1ull << bits) - 1)) func(); + return value; +} + +template inline constexpr T upgradeBound(U i) { return i; } + +template inline constexpr T assumeBits(T i) { return i; } +template inline constexpr T assumeMax(T i) { return i; } + +template +inline auto subtractChecked(T a, U b, ErrorFunc&& errorFunc = ErrorFunc()) + -> decltype(a - b) { + if (b > a) errorFunc(); + return a - b; +} + +template +inline auto trySubtract(T a, U b) -> kj::Maybe { + if (b > a) { + return nullptr; + } else { + return a - b; + } +} + +constexpr uint BITS = 1; +constexpr uint BYTES = 1; +constexpr uint WORDS = 1; +constexpr uint ELEMENTS = 1; +constexpr uint POINTERS = 1; + +constexpr uint ZERO = 0; +constexpr uint ONE = 1; + +// GCC 4.7 actually gives unused warnings on these constants in opt mode... +constexpr uint BITS_PER_BYTE KJ_UNUSED = 8; +constexpr uint BITS_PER_WORD KJ_UNUSED = 64; +constexpr uint BYTES_PER_WORD KJ_UNUSED = 8; + +constexpr uint BITS_PER_POINTER KJ_UNUSED = 64; +constexpr uint BYTES_PER_POINTER KJ_UNUSED = 8; +constexpr uint WORDS_PER_POINTER KJ_UNUSED = 1; + +// XXX +constexpr uint POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER; + +constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment. +constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list. +constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section. +constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section. +constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob. + +typedef WordCountN SegmentWordCount; +typedef ElementCountN ListElementCount; +typedef WordCountN StructDataWordCount; +typedef WirePointerCountN StructPointerCount; +typedef ByteCountN BlobSize; +// YYY + +constexpr auto MAX_SEGMENT_WORDS = kj::maxValueForBits(); +constexpr auto MAX_LIST_ELEMENTS = kj::maxValueForBits(); +constexpr auto MAX_STUCT_DATA_WORDS = kj::maxValueForBits(); +constexpr auto MAX_STRUCT_POINTER_COUNT = kj::maxValueForBits(); + +typedef uint StructDataBitCount; +typedef uint StructDataOffset; +typedef uint StructPointerOffset; + +inline StructDataOffset assumeDataOffset(uint32_t offset) { return offset; } +inline StructPointerOffset assumePointerOffset(uint32_t offset) { return offset; } + +constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits() - 1; +typedef uint TextSize; + +template +inline KJ_CONSTEXPR() size_t bytesPerElement() { return sizeof(T); } + +template +inline KJ_CONSTEXPR() size_t bitsPerElement() { return sizeof(T) * 8; } + +template +inline constexpr ptrdiff_t intervalLength(const T* a, const T* b, uint) { + return b - a; +} + +template +inline constexpr kj::ArrayPtr arrayPtr(const U* ptr, T size) { + return kj::arrayPtr(ptr, size); +} +template +inline constexpr kj::ArrayPtr arrayPtr(U* ptr, T size) { + return kj::arrayPtr(ptr, size); +} + +#endif + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/compat/std-iterator.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/compat/std-iterator.h new file mode 100644 index 000000000..039d5371f --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/compat/std-iterator.h @@ -0,0 +1,47 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +// This exposes IndexingIterator as something compatible with std::iterator so that things like +// std::copy work with List::begin/List::end. + +// Make sure that if this header is before list.h by the user it includes it to make +// IndexingIterator visible to avoid brittle header problems. +#include "../list.h" +#include + +CAPNP_BEGIN_HEADER + +namespace std { + +template +struct iterator_traits> { + using iterator_category = std::random_access_iterator_tag; + using value_type = Element; + using difference_type = int; + using pointer = Element*; + using reference = Element&; +}; + +} // namespace std + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/dynamic.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/dynamic.h new file mode 100644 index 000000000..8aab1f7ad --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/dynamic.h @@ -0,0 +1,1694 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file defines classes that can be used to manipulate messages based on schemas that are not +// known until runtime. This is also useful for writing generic code that uses schemas to handle +// arbitrary types in a generic way. +// +// Each of the classes defined here has a to() template method which converts an instance back to a +// native type. This method will throw an exception if the requested type does not match the +// schema. To convert native types to dynamic, use DynamicFactory. +// +// As always, underlying data is validated lazily, so you have to actually traverse the whole +// message if you want to validate all content. + +#pragma once + +#include "schema.h" +#include "layout.h" +#include "message.h" +#include "any.h" +#include "capability.h" +#include // work-around macro conflict with `VOID` + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class MessageReader; +class MessageBuilder; + +struct DynamicValue { + DynamicValue() = delete; + + enum Type { + UNKNOWN, + // Means that the value has unknown type and content because it comes from a newer version of + // the schema, or from a newer version of Cap'n Proto that has new features that this version + // doesn't understand. + + VOID, + BOOL, + INT, + UINT, + FLOAT, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + CAPABILITY, + ANY_POINTER + }; + + class Reader; + class Builder; + class Pipeline; +}; +class DynamicEnum; +struct DynamicStruct { + DynamicStruct() = delete; + class Reader; + class Builder; + class Pipeline; +}; +struct DynamicList { + DynamicList() = delete; + class Reader; + class Builder; +}; +struct DynamicCapability { + DynamicCapability() = delete; + class Client; + class Server; +}; +template <> class Orphan; + +template struct DynamicTypeFor_; +template <> struct DynamicTypeFor_ { typedef DynamicEnum Type; }; +template <> struct DynamicTypeFor_ { typedef DynamicStruct Type; }; +template <> struct DynamicTypeFor_ { typedef DynamicList Type; }; +template <> struct DynamicTypeFor_ { typedef DynamicCapability Type; }; + +template +using DynamicTypeFor = typename DynamicTypeFor_()>::Type; + +template +ReaderFor>> toDynamic(T&& value); +template +BuilderFor>> toDynamic(T&& value); +template +DynamicTypeFor> toDynamic(T&& value); +template +typename DynamicTypeFor>::Client toDynamic(kj::Own&& value); + +namespace _ { // private + +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; + +} // namespace _ (private) + +template <> inline constexpr Style style() { return Style::POINTER; } +template <> inline constexpr Style style() { return Style::PRIMITIVE; } +template <> inline constexpr Style style() { return Style::STRUCT; } +template <> inline constexpr Style style() { return Style::POINTER; } +template <> inline constexpr Style style() { return Style::CAPABILITY; } + +// ------------------------------------------------------------------- + +class DynamicEnum { +public: + DynamicEnum() = default; + inline DynamicEnum(EnumSchema::Enumerant enumerant) + : schema(enumerant.getContainingEnum()), value(enumerant.getOrdinal()) {} + inline DynamicEnum(EnumSchema schema, uint16_t value) + : schema(schema), value(value) {} + + template () == Kind::ENUM>> + inline DynamicEnum(T&& value): DynamicEnum(toDynamic(value)) {} + + template + inline T as() const { return static_cast(asImpl(typeId())); } + // Cast to a native enum type. + + inline EnumSchema getSchema() const { return schema; } + + kj::Maybe getEnumerant() const; + // Get which enumerant this enum value represents. Returns nullptr if the numeric value does not + // correspond to any enumerant in the schema -- this can happen if the data was built using a + // newer schema that has more values defined. + + inline uint16_t getRaw() const { return value; } + // Returns the raw underlying enum value. + +private: + EnumSchema schema; + uint16_t value; + + uint16_t asImpl(uint64_t requestedTypeId) const; + + friend struct DynamicStruct; + friend struct DynamicList; + friend struct DynamicValue; + template + friend DynamicTypeFor> toDynamic(T&& value); +}; + +// ------------------------------------------------------------------- + +enum class HasMode: uint8_t { + // Specifies the meaning of "has(field)". + + NON_NULL, + // "has(field)" only returns false if the field is a pointer and the pointer is null. This is the + // default behavior. + + NON_DEFAULT + // "has(field)" returns false if the field is set to its default value. This differs from + // NON_NULL only in the handling of primitive values. + // + // "Equal to default value" is technically defined as the field value being encoded as all-zero + // on the wire (since primitive values are XORed by their defined default value when encoded). +}; + +class DynamicStruct::Reader { +public: + typedef DynamicStruct Reads; + + Reader() = default; + + template >() == Kind::STRUCT>> + inline Reader(T&& value): Reader(toDynamic(value)) {} + + inline operator AnyStruct::Reader() const { return AnyStruct::Reader(reader); } + + inline MessageSize totalSize() const { return reader.totalSize().asPublic(); } + + template + typename T::Reader as() const; + // Convert the dynamic struct to its compiled-in type. + + inline StructSchema getSchema() const { return schema; } + + DynamicValue::Reader get(StructSchema::Field field) const; + // Read the given field value. + + bool has(StructSchema::Field field, HasMode mode = HasMode::NON_NULL) const; + // Tests whether the given field is "present". If the field is a union member and is not the + // active member, this always returns false. Otherwise, the field's value is interpreted + // according to `mode`. + + kj::Maybe which() const; + // If the struct contains an (unnamed) union, and the currently-active field within that union + // is known, this returns that field. Otherwise, it returns null. In other words, this returns + // null if there is no union present _or_ if the union's discriminant is set to an unrecognized + // value. This could happen in particular when receiving a message from a sender who has a + // newer version of the protocol and is using a field of the union that you don't know about yet. + + DynamicValue::Reader get(kj::StringPtr name) const; + bool has(kj::StringPtr name, HasMode mode = HasMode::NON_NULL) const; + // Shortcuts to access fields by name. These throw exceptions if no such field exists. + +private: + StructSchema schema; + _::StructReader reader; + + inline Reader(StructSchema schema, _::StructReader reader) + : schema(schema), reader(reader) {} + Reader(StructSchema schema, const _::OrphanBuilder& orphan); + + bool isSetInUnion(StructSchema::Field field) const; + void verifySetInUnion(StructSchema::Field field) const; + static DynamicValue::Reader getImpl(_::StructReader reader, StructSchema::Field field); + + template + friend struct _::PointerHelpers; + friend class DynamicStruct::Builder; + friend struct DynamicList; + friend class MessageReader; + friend class MessageBuilder; + template + friend struct ::capnp::ToDynamic_; + friend kj::StringTree _::structString( + _::StructReader reader, const _::RawBrandedSchema& schema); + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class Orphan; + friend class AnyStruct::Reader; +}; + +class DynamicStruct::Builder { +public: + typedef DynamicStruct Builds; + + Builder() = default; + inline Builder(decltype(nullptr)) {} + + template >() == Kind::STRUCT>> + inline Builder(T&& value): Builder(toDynamic(value)) {} + + inline operator AnyStruct::Builder() { return AnyStruct::Builder(builder); } + + inline MessageSize totalSize() const { return asReader().totalSize(); } + + template + typename T::Builder as(); + // Cast to a particular struct type. + + inline StructSchema getSchema() const { return schema; } + + DynamicValue::Builder get(StructSchema::Field field); + // Read the given field value. + + inline bool has(StructSchema::Field field, HasMode mode = HasMode::NON_NULL) + { return asReader().has(field, mode); } + // Tests whether the given field is "present". If the field is a union member and is not the + // active member, this always returns false. Otherwise, the field's value is interpreted + // according to `mode`. + + kj::Maybe which(); + // If the struct contains an (unnamed) union, and the currently-active field within that union + // is known, this returns that field. Otherwise, it returns null. In other words, this returns + // null if there is no union present _or_ if the union's discriminant is set to an unrecognized + // value. This could happen in particular when receiving a message from a sender who has a + // newer version of the protocol and is using a field of the union that you don't know about yet. + + void set(StructSchema::Field field, const DynamicValue::Reader& value); + // Set the given field value. + + DynamicValue::Builder init(StructSchema::Field field); + DynamicValue::Builder init(StructSchema::Field field, uint size); + // Init a struct, list, or blob field. + + void adopt(StructSchema::Field field, Orphan&& orphan); + Orphan disown(StructSchema::Field field); + // Adopt/disown. This works even for non-pointer fields: adopt() becomes equivalent to set() + // and disown() becomes like get() followed by clear(). + + void clear(StructSchema::Field field); + // Clear a field, setting it to its default value. For pointer fields, this actually makes the + // field null. + + DynamicValue::Builder get(kj::StringPtr name); + bool has(kj::StringPtr name, HasMode mode = HasMode::NON_NULL); + void set(kj::StringPtr name, const DynamicValue::Reader& value); + void set(kj::StringPtr name, std::initializer_list value); + DynamicValue::Builder init(kj::StringPtr name); + DynamicValue::Builder init(kj::StringPtr name, uint size); + void adopt(kj::StringPtr name, Orphan&& orphan); + Orphan disown(kj::StringPtr name); + void clear(kj::StringPtr name); + // Shortcuts to access fields by name. These throw exceptions if no such field exists. + + Reader asReader() const; + +private: + StructSchema schema; + _::StructBuilder builder; + + inline Builder(StructSchema schema, _::StructBuilder builder) + : schema(schema), builder(builder) {} + Builder(StructSchema schema, _::OrphanBuilder& orphan); + + bool isSetInUnion(StructSchema::Field field); + void verifySetInUnion(StructSchema::Field field); + void setInUnion(StructSchema::Field field); + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class MessageReader; + friend class MessageBuilder; + template + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class Orphan; + friend class AnyStruct::Builder; +}; + +class DynamicStruct::Pipeline { +public: + typedef DynamicStruct Pipelines; + + inline Pipeline(decltype(nullptr)): typeless(nullptr) {} + + template + typename T::Pipeline releaseAs(); + // Convert the dynamic pipeline to its compiled-in type. + + inline StructSchema getSchema() { return schema; } + + DynamicValue::Pipeline get(StructSchema::Field field); + // Read the given field value. + + DynamicValue::Pipeline get(kj::StringPtr name); + // Get by string name. + +private: + StructSchema schema; + AnyPointer::Pipeline typeless; + + inline explicit Pipeline(StructSchema schema, AnyPointer::Pipeline&& typeless) + : schema(schema), typeless(kj::mv(typeless)) {} + + friend class Request; +}; + +// ------------------------------------------------------------------- + +class DynamicList::Reader { +public: + typedef DynamicList Reads; + + inline Reader(): reader(ElementSize::VOID) {} + + template >() == Kind::LIST>> + inline Reader(T&& value): Reader(toDynamic(value)) {} + + inline operator AnyList::Reader() const { return AnyList::Reader(reader); } + + template + typename T::Reader as() const; + // Try to convert to any List, Data, or Text. Throws an exception if the underlying data + // can't possibly represent the requested type. + + inline ListSchema getSchema() const { return schema; } + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + DynamicValue::Reader operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + ListSchema schema; + _::ListReader reader; + + Reader(ListSchema schema, _::ListReader reader): schema(schema), reader(reader) {} + Reader(ListSchema schema, const _::OrphanBuilder& orphan); + + template + friend struct _::PointerHelpers; + friend struct DynamicStruct; + friend class DynamicList::Builder; + template + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class Orphan; +}; + +class DynamicList::Builder { +public: + typedef DynamicList Builds; + + inline Builder(): builder(ElementSize::VOID) {} + inline Builder(decltype(nullptr)): builder(ElementSize::VOID) {} + + template >() == Kind::LIST>> + inline Builder(T&& value): Builder(toDynamic(value)) {} + + inline operator AnyList::Builder() { return AnyList::Builder(builder); } + + template + typename T::Builder as(); + // Try to convert to any List, Data, or Text. Throws an exception if the underlying data + // can't possibly represent the requested type. + + inline ListSchema getSchema() const { return schema; } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + DynamicValue::Builder operator[](uint index); + void set(uint index, const DynamicValue::Reader& value); + DynamicValue::Builder init(uint index, uint size); + void adopt(uint index, Orphan&& orphan); + Orphan disown(uint index); + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + void copyFrom(std::initializer_list value); + + Reader asReader() const; + +private: + ListSchema schema; + _::ListBuilder builder; + + Builder(ListSchema schema, _::ListBuilder builder): schema(schema), builder(builder) {} + Builder(ListSchema schema, _::OrphanBuilder& orphan); + + template + friend struct _::PointerHelpers; + friend struct DynamicStruct; + template + friend struct ::capnp::ToDynamic_; + friend class Orphanage; + template + friend struct _::OrphanGetImpl; + friend class Orphan; + friend class Orphan; + friend class Orphan; +}; + +// ------------------------------------------------------------------- + +class DynamicCapability::Client: public Capability::Client { +public: + typedef DynamicCapability Calls; + typedef DynamicCapability Reads; + + Client() = default; + + template >() == Kind::INTERFACE>> + inline Client(T&& client); + + template ()>> + inline Client(kj::Own&& server); + + template () == Kind::INTERFACE>> + typename T::Client as(); + template () == Kind::INTERFACE>> + typename T::Client releaseAs(); + // Convert to any client type. + + Client upcast(InterfaceSchema requestedSchema); + // Upcast to a superclass. Throws an exception if `schema` is not a superclass. + + inline InterfaceSchema getSchema() { return schema; } + + Request newRequest( + InterfaceSchema::Method method, kj::Maybe sizeHint = nullptr); + Request newRequest( + kj::StringPtr methodName, kj::Maybe sizeHint = nullptr); + +private: + InterfaceSchema schema; + + Client(InterfaceSchema schema, kj::Own&& hook) + : Capability::Client(kj::mv(hook)), schema(schema) {} + + template + inline Client(InterfaceSchema schema, kj::Own&& server); + + friend struct Capability; + friend struct DynamicStruct; + friend struct DynamicList; + friend struct DynamicValue; + friend class Orphan; + friend class Orphan; + friend class Orphan; + template + friend struct _::PointerHelpers; +}; + +class DynamicCapability::Server: public Capability::Server { +public: + typedef DynamicCapability Serves; + + struct Options { + bool allowCancellation = false; + // See the `allowCancellation` annotation defined in `c++.capnp`. + // + // This option applies to all calls made to this server object. The annotation in the schema + // is NOT used for dynamic servers. + }; + + Server(InterfaceSchema schema): schema(schema) {} + Server(InterfaceSchema schema, Options options): schema(schema), options(options) {} + + virtual kj::Promise call(InterfaceSchema::Method method, + CallContext context) = 0; + + DispatchCallResult dispatchCall(uint64_t interfaceId, uint16_t methodId, + CallContext context) override final; + + inline InterfaceSchema getSchema() const { return schema; } + +private: + InterfaceSchema schema; + Options options; +}; + +template <> +class Request: public DynamicStruct::Builder { + // Specialization of `Request` for DynamicStruct. + +public: + inline Request(DynamicStruct::Builder builder, kj::Own&& hook, + StructSchema resultSchema) + : DynamicStruct::Builder(builder), hook(kj::mv(hook)), resultSchema(resultSchema) {} + + RemotePromise send(); + // Send the call and return a promise for the results. + + kj::Promise sendStreaming(); + // Use when the caller is aware that the response type is StreamResult and wants to invoke + // streaming behavior. It is an error to call this if the response type is not StreamResult. + +private: + kj::Own hook; + StructSchema resultSchema; + + friend class Capability::Client; + friend struct DynamicCapability; + template + friend class CallContext; + friend class RequestHook; +}; + +template <> +class CallContext: public kj::DisallowConstCopy { + // Wrapper around CallContextHook with a specific return type. + // + // Methods of this class may only be called from within the server's event loop, not from other + // threads. + +public: + explicit CallContext(CallContextHook& hook, StructSchema paramType, StructSchema resultType); + + DynamicStruct::Reader getParams(); + void releaseParams(); + DynamicStruct::Builder getResults(kj::Maybe sizeHint = nullptr); + DynamicStruct::Builder initResults(kj::Maybe sizeHint = nullptr); + void setResults(DynamicStruct::Reader value); + void adoptResults(Orphan&& value); + Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); + template + kj::Promise tailCall(Request&& tailRequest); + + StructSchema getParamsType() const { return paramType; } + StructSchema getResultsType() const { return resultType; } + +private: + CallContextHook* hook; + StructSchema paramType; + StructSchema resultType; + + friend class DynamicCapability::Server; +}; + +// ------------------------------------------------------------------- + +// Make sure ReaderFor and BuilderFor work for DynamicEnum, DynamicStruct, and +// DynamicList, so that we can define DynamicValue::as(). + +template <> struct ReaderFor_ { typedef DynamicEnum Type; }; +template <> struct BuilderFor_ { typedef DynamicEnum Type; }; +template <> struct ReaderFor_ { typedef DynamicStruct::Reader Type; }; +template <> struct BuilderFor_ { typedef DynamicStruct::Builder Type; }; +template <> struct ReaderFor_ { typedef DynamicList::Reader Type; }; +template <> struct BuilderFor_ { typedef DynamicList::Builder Type; }; +template <> struct ReaderFor_ { typedef DynamicCapability::Client Type; }; +template <> struct BuilderFor_ { typedef DynamicCapability::Client Type; }; +template <> struct PipelineFor_ { typedef DynamicCapability::Client Type; }; + +class DynamicValue::Reader { +public: + typedef DynamicValue Reads; + + inline Reader(decltype(nullptr) n = nullptr); // UNKNOWN + inline Reader(Void value); + inline Reader(bool value); + inline Reader(char value); + inline Reader(signed char value); + inline Reader(short value); + inline Reader(int value); + inline Reader(long value); + inline Reader(long long value); + inline Reader(unsigned char value); + inline Reader(unsigned short value); + inline Reader(unsigned int value); + inline Reader(unsigned long value); + inline Reader(unsigned long long value); + inline Reader(float value); + inline Reader(double value); + inline Reader(const char* value); // Text + inline Reader(const Text::Reader& value); + inline Reader(const Data::Reader& value); + inline Reader(const DynamicList::Reader& value); + inline Reader(DynamicEnum value); + inline Reader(const DynamicStruct::Reader& value); + inline Reader(const AnyPointer::Reader& value); + inline Reader(DynamicCapability::Client& value); + inline Reader(DynamicCapability::Client&& value); + template ()>> + inline Reader(kj::Own&& value); + Reader(ConstSchema constant); + + template ()))> + inline Reader(T&& value): Reader(toDynamic(kj::mv(value))) {} + + Reader(const Reader& other); + Reader(Reader&& other) noexcept; + ~Reader() noexcept(false); + Reader& operator=(const Reader& other); + Reader& operator=(Reader&& other); + // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not + // trivially copyable. + + template + inline ReaderFor as() const { return AsImpl::apply(*this); } + // Use to interpret the value as some Cap'n Proto type. Allowed types are: + // - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value. + // - Text, Data, AnyPointer, any struct type: Returns the corresponding Reader. + // - List for any T listed above: Returns List::Reader. + // - DynamicEnum: Returns the corresponding type. + // - DynamicStruct, DynamicList: Returns the corresponding Reader. + // - Any capability type, including DynamicCapability: Returns the corresponding Client. + // - DynamicValue: Returns an identical Reader. Useful to avoid special-casing in generic code. + // (TODO(perf): On GCC 4.8 / Clang 3.3, provide rvalue-qualified version that avoids + // refcounting.) + // + // DynamicValue allows various implicit conversions, mostly just to make the interface friendlier. + // - Any integer can be converted to any other integer type so long as the actual value is within + // the new type's range. + // - Floating-point types can be converted to integers as long as no information would be lost + // in the conversion. + // - Integers can be converted to floating points. This may lose information, but won't throw. + // - Float32/Float64 can be converted between each other. Converting Float64 -> Float32 may lose + // information, but won't throw. + // - Text can be converted to an enum, if the Text matches one of the enumerant names (but not + // vice-versa). + // - Capabilities can be upcast (cast to a supertype), but not downcast. + // + // Any other conversion attempt will throw an exception. + + inline Type getType() const { return type; } + // Get the type of this value. + +private: + Type type; + + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + Text::Reader textValue; + Data::Reader dataValue; + DynamicList::Reader listValue; + DynamicEnum enumValue; + DynamicStruct::Reader structValue; + AnyPointer::Reader anyPointerValue; + + mutable DynamicCapability::Client capabilityValue; + // Declared mutable because `Client`s normally cannot be const. + + // Warning: Copy/move constructors assume all these types are trivially copyable except + // Capability. + }; + + template ()> struct AsImpl; + // Implementation backing the as() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. + + friend class Orphanage; // to speed up newOrphanCopy(DynamicValue::Reader) +}; + +class DynamicValue::Builder { +public: + typedef DynamicValue Builds; + + inline Builder(decltype(nullptr) n = nullptr); // UNKNOWN + inline Builder(Void value); + inline Builder(bool value); + inline Builder(char value); + inline Builder(signed char value); + inline Builder(short value); + inline Builder(int value); + inline Builder(long value); + inline Builder(long long value); + inline Builder(unsigned char value); + inline Builder(unsigned short value); + inline Builder(unsigned int value); + inline Builder(unsigned long value); + inline Builder(unsigned long long value); + inline Builder(float value); + inline Builder(double value); + inline Builder(Text::Builder value); + inline Builder(Data::Builder value); + inline Builder(DynamicList::Builder value); + inline Builder(DynamicEnum value); + inline Builder(DynamicStruct::Builder value); + inline Builder(AnyPointer::Builder value); + inline Builder(DynamicCapability::Client& value); + inline Builder(DynamicCapability::Client&& value); + + template ()))> + inline Builder(T value): Builder(toDynamic(value)) {} + + Builder(Builder& other); + Builder(Builder&& other) noexcept; + ~Builder() noexcept(false); + Builder& operator=(Builder& other); + Builder& operator=(Builder&& other); + // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not + // trivially copyable. + + template + inline BuilderFor as() { return AsImpl::apply(*this); } + // See DynamicValue::Reader::as(). + + inline Type getType() { return type; } + // Get the type of this value. + + Reader asReader() const; + +private: + Type type; + + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + Text::Builder textValue; + Data::Builder dataValue; + DynamicList::Builder listValue; + DynamicEnum enumValue; + DynamicStruct::Builder structValue; + AnyPointer::Builder anyPointerValue; + + mutable DynamicCapability::Client capabilityValue; + // Declared mutable because `Client`s normally cannot be const. + }; + + template ()> struct AsImpl; + // Implementation backing the as() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. + + friend class Orphan; +}; + +class DynamicValue::Pipeline { +public: + typedef DynamicValue Pipelines; + + inline Pipeline(decltype(nullptr) n = nullptr); + inline Pipeline(DynamicStruct::Pipeline&& value); + inline Pipeline(DynamicCapability::Client&& value); + + Pipeline(Pipeline&& other) noexcept; + Pipeline& operator=(Pipeline&& other); + ~Pipeline() noexcept(false); + + template + inline PipelineFor releaseAs() { return AsImpl::apply(*this); } + + inline Type getType() { return type; } + // Get the type of this value. + +private: + Type type; + union { + DynamicStruct::Pipeline structValue; + DynamicCapability::Client capabilityValue; + }; + + template ()> struct AsImpl; + // Implementation backing the releaseAs() method. Needs to be a struct to allow partial + // specialization. Has a method apply() which does the work. +}; + +kj::StringTree KJ_STRINGIFY(const DynamicValue::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicValue::Builder& value); +kj::StringTree KJ_STRINGIFY(DynamicEnum value); +kj::StringTree KJ_STRINGIFY(const DynamicStruct::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicStruct::Builder& value); +kj::StringTree KJ_STRINGIFY(const DynamicList::Reader& value); +kj::StringTree KJ_STRINGIFY(const DynamicList::Builder& value); + +// ------------------------------------------------------------------- +// Orphan <-> Dynamic glue + +template <> +class Orphan { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template () == Kind::STRUCT>> + inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} + + DynamicStruct::Builder get(); + DynamicStruct::Reader getReader() const; + + template + Orphan releaseAs(); + // Like DynamicStruct::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + StructSchema schema; + _::OrphanBuilder builder; + + inline Orphan(StructSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan; + friend class Orphan; + friend class MessageBuilder; +}; + +template <> +class Orphan { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template () == Kind::LIST>> + inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} + + DynamicList::Builder get(); + DynamicList::Reader getReader() const; + + template + Orphan releaseAs(); + // Like DynamicList::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + + // TODO(someday): Support truncate(). + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + ListSchema schema; + _::OrphanBuilder builder; + + inline Orphan(ListSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan; + friend class Orphan; +}; + +template <> +class Orphan { +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + + template () == Kind::INTERFACE>> + inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} + + DynamicCapability::Client get(); + DynamicCapability::Client getReader() const; + + template + Orphan releaseAs(); + // Like DynamicCapability::Client::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + +private: + InterfaceSchema schema; + _::OrphanBuilder builder; + + inline Orphan(InterfaceSchema schema, _::OrphanBuilder&& builder) + : schema(schema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicList; + friend class Orphanage; + friend class Orphan; + friend class Orphan; +}; + +template <> +class Orphan { +public: + inline Orphan(decltype(nullptr) n = nullptr): type(DynamicValue::UNKNOWN) {} + inline Orphan(Void value); + inline Orphan(bool value); + inline Orphan(char value); + inline Orphan(signed char value); + inline Orphan(short value); + inline Orphan(int value); + inline Orphan(long value); + inline Orphan(long long value); + inline Orphan(unsigned char value); + inline Orphan(unsigned short value); + inline Orphan(unsigned int value); + inline Orphan(unsigned long value); + inline Orphan(unsigned long long value); + inline Orphan(float value); + inline Orphan(double value); + inline Orphan(DynamicEnum value); + Orphan(Orphan&&) = default; + template + Orphan(Orphan&&); + Orphan(Orphan&&); + Orphan(void*) = delete; // So Orphan(bool) doesn't accept pointers. + KJ_DISALLOW_COPY(Orphan); + + Orphan& operator=(Orphan&&) = default; + + inline DynamicValue::Type getType() { return type; } + + DynamicValue::Builder get(); + DynamicValue::Reader getReader() const; + + template + Orphan releaseAs(); + // Like DynamicValue::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, + // the original Orphan is no longer valid after this call; ownership is + // transferred to the returned Orphan. + +private: + DynamicValue::Type type; + union { + Void voidValue; + bool boolValue; + int64_t intValue; + uint64_t uintValue; + double floatValue; + DynamicEnum enumValue; + StructSchema structSchema; + ListSchema listSchema; + InterfaceSchema interfaceSchema; + }; + + _::OrphanBuilder builder; + // Only used if `type` is a pointer type. + + Orphan(DynamicValue::Builder value, _::OrphanBuilder&& builder); + Orphan(DynamicValue::Type type, _::OrphanBuilder&& builder) + : type(type), builder(kj::mv(builder)) {} + Orphan(StructSchema structSchema, _::OrphanBuilder&& builder) + : type(DynamicValue::STRUCT), structSchema(structSchema), builder(kj::mv(builder)) {} + Orphan(ListSchema listSchema, _::OrphanBuilder&& builder) + : type(DynamicValue::LIST), listSchema(listSchema), builder(kj::mv(builder)) {} + + template + friend struct _::PointerHelpers; + friend struct DynamicStruct; + friend struct DynamicList; + friend struct AnyPointer; + friend class Orphanage; +}; + +template +inline Orphan::Orphan(Orphan&& other) + : Orphan(other.get(), kj::mv(other.builder)) {} + +inline Orphan::Orphan(Orphan&& other) + : type(DynamicValue::ANY_POINTER), builder(kj::mv(other.builder)) {} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + return Orphan(kj::mv(builder)); +} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + return Orphan(kj::mv(builder)); +} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + return Orphan(kj::mv(builder)); +} + +template +Orphan Orphan::releaseAs() { + get().as(); // type check + type = DynamicValue::UNKNOWN; + return Orphan(kj::mv(builder)); +} + +template <> +Orphan Orphan::releaseAs(); +template <> +Orphan Orphan::releaseAs(); +template <> +Orphan Orphan::releaseAs(); +template <> +Orphan Orphan::releaseAs(); + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::StructBuilder apply(DynamicStruct::Builder& t) { + return t.builder; + } +}; + +template <> +struct Orphanage::GetInnerBuilder { + static inline _::ListBuilder apply(DynamicList::Builder& t) { + return t.builder; + } +}; + +template <> +inline Orphan Orphanage::newOrphanCopy( + DynamicStruct::Reader copyFrom) const { + return Orphan( + copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); +} + +template <> +inline Orphan Orphanage::newOrphanCopy( + DynamicList::Reader copyFrom) const { + return Orphan(copyFrom.getSchema(), + _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); +} + +template <> +inline Orphan Orphanage::newOrphanCopy( + DynamicCapability::Client copyFrom) const { + return Orphan( + copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.hook->addRef())); +} + +template <> +Orphan Orphanage::newOrphanCopy( + DynamicValue::Reader copyFrom) const; + +namespace _ { // private + +template <> +struct PointerHelpers { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicStruct::Reader getDynamic(PointerReader reader, StructSchema schema); + static DynamicStruct::Builder getDynamic(PointerBuilder builder, StructSchema schema); + static void set(PointerBuilder builder, const DynamicStruct::Reader& value); + static DynamicStruct::Builder init(PointerBuilder builder, StructSchema schema); + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder, StructSchema schema) { + return Orphan(schema, builder.disown()); + } +}; + +template <> +struct PointerHelpers { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicList::Reader getDynamic(PointerReader reader, ListSchema schema); + static DynamicList::Builder getDynamic(PointerBuilder builder, ListSchema schema); + static void set(PointerBuilder builder, const DynamicList::Reader& value); + static DynamicList::Builder init(PointerBuilder builder, ListSchema schema, uint size); + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder, ListSchema schema) { + return Orphan(schema, builder.disown()); + } +}; + +template <> +struct PointerHelpers { + // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for + // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we + // don't want people to accidentally be able to provide their own default value. + static DynamicCapability::Client getDynamic(PointerReader reader, InterfaceSchema schema); + static DynamicCapability::Client getDynamic(PointerBuilder builder, InterfaceSchema schema); + static void set(PointerBuilder builder, DynamicCapability::Client& value); + static void set(PointerBuilder builder, DynamicCapability::Client&& value); + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder, InterfaceSchema schema) { + return Orphan(schema, builder.disown()); + } +}; + +} // namespace _ (private) + +template +inline ReaderFor AnyPointer::Reader::getAs(StructSchema schema) const { + return _::PointerHelpers::getDynamic(reader, schema); +} +template +inline ReaderFor AnyPointer::Reader::getAs(ListSchema schema) const { + return _::PointerHelpers::getDynamic(reader, schema); +} +template +inline ReaderFor AnyPointer::Reader::getAs(InterfaceSchema schema) const { + return _::PointerHelpers::getDynamic(reader, schema); +} +template +inline BuilderFor AnyPointer::Builder::getAs(StructSchema schema) { + return _::PointerHelpers::getDynamic(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::getAs(ListSchema schema) { + return _::PointerHelpers::getDynamic(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::getAs(InterfaceSchema schema) { + return _::PointerHelpers::getDynamic(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::initAs(StructSchema schema) { + return _::PointerHelpers::init(builder, schema); +} +template +inline BuilderFor AnyPointer::Builder::initAs(ListSchema schema, uint elementCount) { + return _::PointerHelpers::init(builder, schema, elementCount); +} +template <> +inline void AnyPointer::Builder::setAs(DynamicStruct::Reader value) { + return _::PointerHelpers::set(builder, value); +} +template <> +inline void AnyPointer::Builder::setAs(DynamicList::Reader value) { + return _::PointerHelpers::set(builder, value); +} +template <> +inline void AnyPointer::Builder::setAs(DynamicCapability::Client value) { + return _::PointerHelpers::set(builder, kj::mv(value)); +} +template <> +void AnyPointer::Builder::adopt(Orphan&& orphan); +template +inline Orphan AnyPointer::Builder::disownAs(StructSchema schema) { + return _::PointerHelpers::disown(builder, schema); +} +template +inline Orphan AnyPointer::Builder::disownAs(ListSchema schema) { + return _::PointerHelpers::disown(builder, schema); +} +template +inline Orphan AnyPointer::Builder::disownAs(InterfaceSchema schema) { + return _::PointerHelpers::disown(builder, schema); +} + +// We have to declare the methods below inline because Clang and GCC disagree about how to mangle +// their symbol names. +template <> +inline DynamicStruct::Builder Orphan::getAs(StructSchema schema) { + return DynamicStruct::Builder(schema, builder); +} +template <> +inline DynamicStruct::Reader Orphan::getAsReader( + StructSchema schema) const { + return DynamicStruct::Reader(schema, builder); +} +template <> +inline Orphan Orphan::releaseAs(StructSchema schema) { + return Orphan(schema, kj::mv(builder)); +} +template <> +inline DynamicList::Builder Orphan::getAs(ListSchema schema) { + return DynamicList::Builder(schema, builder); +} +template <> +inline DynamicList::Reader Orphan::getAsReader(ListSchema schema) const { + return DynamicList::Reader(schema, builder); +} +template <> +inline Orphan Orphan::releaseAs(ListSchema schema) { + return Orphan(schema, kj::mv(builder)); +} +template <> +inline DynamicCapability::Client Orphan::getAs( + InterfaceSchema schema) { + return DynamicCapability::Client(schema, builder.asCapability()); +} +template <> +inline DynamicCapability::Client Orphan::getAsReader( + InterfaceSchema schema) const { + return DynamicCapability::Client(schema, builder.asCapability()); +} +template <> +inline Orphan Orphan::releaseAs( + InterfaceSchema schema) { + return Orphan(schema, kj::mv(builder)); +} + +// ======================================================================================= +// Inline implementation details. + +template +struct ToDynamic_ { + static inline DynamicStruct::Reader apply(const typename T::Reader& value) { + return DynamicStruct::Reader(Schema::from(), value._reader); + } + static inline DynamicStruct::Builder apply(typename T::Builder& value) { + return DynamicStruct::Builder(Schema::from(), value._builder); + } +}; + +template +struct ToDynamic_ { + static inline DynamicList::Reader apply(const typename T::Reader& value) { + return DynamicList::Reader(Schema::from(), value.reader); + } + static inline DynamicList::Builder apply(typename T::Builder& value) { + return DynamicList::Builder(Schema::from(), value.builder); + } +}; + +template +struct ToDynamic_ { + static inline DynamicCapability::Client apply(typename T::Client value) { + return DynamicCapability::Client(kj::mv(value)); + } + static inline DynamicCapability::Client apply(typename T::Client&& value) { + return DynamicCapability::Client(kj::mv(value)); + } +}; + +template +ReaderFor>> toDynamic(T&& value) { + return ToDynamic_>::apply(value); +} +template +BuilderFor>> toDynamic(T&& value) { + return ToDynamic_>::apply(value); +} +template +DynamicTypeFor> toDynamic(T&& value) { + return DynamicEnum(Schema::from>(), static_cast(value)); +} +template +typename DynamicTypeFor>::Client toDynamic(kj::Own&& value) { + return typename FromServer::Client(kj::mv(value)); +} + +inline DynamicValue::Reader::Reader(std::nullptr_t n): type(UNKNOWN) {} +inline DynamicValue::Builder::Builder(std::nullptr_t n): type(UNKNOWN) {} + +#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ +inline DynamicValue::Reader::Reader(cppType value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline DynamicValue::Builder::Builder(cppType value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline Orphan::Orphan(cppType value) \ + : type(DynamicValue::typeTag), fieldName##Value(value) {} + +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Void, VOID, void); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(bool, BOOL, bool); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(char, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(signed char, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(short, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(int, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long long, INT, int); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned char, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned short, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned int, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long long, UINT, uint); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(float, FLOAT, float); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(double, FLOAT, float); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicEnum, ENUM, enum); +#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR + +#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ +inline DynamicValue::Reader::Reader(const cppType::Reader& value) \ + : type(typeTag), fieldName##Value(value) {} \ +inline DynamicValue::Builder::Builder(cppType::Builder value) \ + : type(typeTag), fieldName##Value(value) {} + +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Text, TEXT, text); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Data, DATA, data); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicList, LIST, list); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicStruct, STRUCT, struct); +CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(AnyPointer, ANY_POINTER, anyPointer); + +#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR + +inline DynamicValue::Reader::Reader(DynamicCapability::Client& value) + : type(CAPABILITY), capabilityValue(value) {} +inline DynamicValue::Reader::Reader(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} +template +inline DynamicValue::Reader::Reader(kj::Own&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} +inline DynamicValue::Builder::Builder(DynamicCapability::Client& value) + : type(CAPABILITY), capabilityValue(value) {} +inline DynamicValue::Builder::Builder(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} + +inline DynamicValue::Reader::Reader(const char* value): Reader(Text::Reader(value)) {} + +#define CAPNP_DECLARE_TYPE(discrim, typeName) \ +template <> \ +struct DynamicValue::Reader::AsImpl { \ + static ReaderFor apply(const Reader& reader); \ +}; \ +template <> \ +struct DynamicValue::Builder::AsImpl { \ + static BuilderFor apply(Builder& builder); \ +}; + +//CAPNP_DECLARE_TYPE(VOID, Void) +CAPNP_DECLARE_TYPE(BOOL, bool) +CAPNP_DECLARE_TYPE(INT8, int8_t) +CAPNP_DECLARE_TYPE(INT16, int16_t) +CAPNP_DECLARE_TYPE(INT32, int32_t) +CAPNP_DECLARE_TYPE(INT64, int64_t) +CAPNP_DECLARE_TYPE(UINT8, uint8_t) +CAPNP_DECLARE_TYPE(UINT16, uint16_t) +CAPNP_DECLARE_TYPE(UINT32, uint32_t) +CAPNP_DECLARE_TYPE(UINT64, uint64_t) +CAPNP_DECLARE_TYPE(FLOAT32, float) +CAPNP_DECLARE_TYPE(FLOAT64, double) + +CAPNP_DECLARE_TYPE(TEXT, Text) +CAPNP_DECLARE_TYPE(DATA, Data) +CAPNP_DECLARE_TYPE(LIST, DynamicList) +CAPNP_DECLARE_TYPE(STRUCT, DynamicStruct) +CAPNP_DECLARE_TYPE(INTERFACE, DynamicCapability) +CAPNP_DECLARE_TYPE(ENUM, DynamicEnum) +CAPNP_DECLARE_TYPE(ANY_POINTER, AnyPointer) +#undef CAPNP_DECLARE_TYPE + +// CAPNP_DECLARE_TYPE(Void) causes gcc 4.7 to segfault. If I do it manually and remove the +// ReaderFor<> and BuilderFor<> wrappers, it works. +template <> +struct DynamicValue::Reader::AsImpl { + static Void apply(const Reader& reader); +}; +template <> +struct DynamicValue::Builder::AsImpl { + static Void apply(Builder& builder); +}; + +template +struct DynamicValue::Reader::AsImpl { + static T apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static T apply(Builder& builder) { + return builder.as().as(); + } +}; + +template +struct DynamicValue::Reader::AsImpl { + static typename T::Reader apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static typename T::Builder apply(Builder& builder) { + return builder.as().as(); + } +}; + +template +struct DynamicValue::Reader::AsImpl { + static typename T::Reader apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static typename T::Builder apply(Builder& builder) { + return builder.as().as(); + } +}; + +template +struct DynamicValue::Reader::AsImpl { + static typename T::Client apply(const Reader& reader) { + return reader.as().as(); + } +}; +template +struct DynamicValue::Builder::AsImpl { + static typename T::Client apply(Builder& builder) { + return builder.as().as(); + } +}; + +template <> +struct DynamicValue::Reader::AsImpl { + static DynamicValue::Reader apply(const Reader& reader) { + return reader; + } +}; +template <> +struct DynamicValue::Builder::AsImpl { + static DynamicValue::Builder apply(Builder& builder) { + return builder; + } +}; + +inline DynamicValue::Pipeline::Pipeline(std::nullptr_t n): type(UNKNOWN) {} +inline DynamicValue::Pipeline::Pipeline(DynamicStruct::Pipeline&& value) + : type(STRUCT), structValue(kj::mv(value)) {} +inline DynamicValue::Pipeline::Pipeline(DynamicCapability::Client&& value) + : type(CAPABILITY), capabilityValue(kj::mv(value)) {} + +template +struct DynamicValue::Pipeline::AsImpl { + static typename T::Pipeline apply(Pipeline& pipeline) { + return pipeline.releaseAs().releaseAs(); + } +}; +template +struct DynamicValue::Pipeline::AsImpl { + static typename T::Client apply(Pipeline& pipeline) { + return pipeline.releaseAs().releaseAs(); + } +}; +template <> +struct DynamicValue::Pipeline::AsImpl { + static PipelineFor apply(Pipeline& pipeline); +}; +template <> +struct DynamicValue::Pipeline::AsImpl { + static PipelineFor apply(Pipeline& pipeline); +}; + +// ------------------------------------------------------------------- + +template +typename T::Reader DynamicStruct::Reader::as() const { + static_assert(kind() == Kind::STRUCT, + "DynamicStruct::Reader::as() can only convert to struct types."); + schema.requireUsableAs(); + return typename T::Reader(reader); +} + +template +typename T::Builder DynamicStruct::Builder::as() { + static_assert(kind() == Kind::STRUCT, + "DynamicStruct::Builder::as() can only convert to struct types."); + schema.requireUsableAs(); + return typename T::Builder(builder); +} + +template <> +inline DynamicStruct::Reader DynamicStruct::Reader::as() const { + return *this; +} +template <> +inline DynamicStruct::Builder DynamicStruct::Builder::as() { + return *this; +} + +inline DynamicStruct::Reader DynamicStruct::Builder::asReader() const { + return DynamicStruct::Reader(schema, builder.asReader()); +} + +template <> +inline AnyStruct::Reader DynamicStruct::Reader::as() const { + return AnyStruct::Reader(reader); +} + +template <> +inline AnyStruct::Builder DynamicStruct::Builder::as() { + return AnyStruct::Builder(builder); +} + +template <> +inline DynamicStruct::Reader AnyStruct::Reader::as(StructSchema schema) const { + return DynamicStruct::Reader(schema, _reader); +} + +template <> +inline DynamicStruct::Builder AnyStruct::Builder::as(StructSchema schema) { + return DynamicStruct::Builder(schema, _builder); +} + +template +typename T::Pipeline DynamicStruct::Pipeline::releaseAs() { + static_assert(kind() == Kind::STRUCT, + "DynamicStruct::Pipeline::releaseAs() can only convert to struct types."); + schema.requireUsableAs(); + return typename T::Pipeline(kj::mv(typeless)); +} + +// ------------------------------------------------------------------- + +template +typename T::Reader DynamicList::Reader::as() const { + static_assert(kind() == Kind::LIST, + "DynamicStruct::Reader::as() can only convert to list types."); + schema.requireUsableAs(); + return typename T::Reader(reader); +} +template +typename T::Builder DynamicList::Builder::as() { + static_assert(kind() == Kind::LIST, + "DynamicStruct::Builder::as() can only convert to list types."); + schema.requireUsableAs(); + return typename T::Builder(builder); +} + +template <> +inline DynamicList::Reader DynamicList::Reader::as() const { + return *this; +} +template <> +inline DynamicList::Builder DynamicList::Builder::as() { + return *this; +} + +template <> +inline AnyList::Reader DynamicList::Reader::as() const { + return AnyList::Reader(reader); +} + +template <> +inline AnyList::Builder DynamicList::Builder::as() { + return AnyList::Builder(builder); +} + +// ------------------------------------------------------------------- + +template +inline DynamicCapability::Client::Client(T&& client) + : Capability::Client(kj::mv(client)), schema(Schema::from>()) {} + +template +inline DynamicCapability::Client::Client(kj::Own&& server) + : Client(server->getSchema(), kj::mv(server)) {} +template +inline DynamicCapability::Client::Client(InterfaceSchema schema, kj::Own&& server) + : Capability::Client(kj::mv(server)), schema(schema) {} + +template +typename T::Client DynamicCapability::Client::as() { + static_assert(kind() == Kind::INTERFACE, + "DynamicCapability::Client::as() can only convert to interface types."); + schema.requireUsableAs(); + return typename T::Client(hook->addRef()); +} + +template +typename T::Client DynamicCapability::Client::releaseAs() { + static_assert(kind() == Kind::INTERFACE, + "DynamicCapability::Client::as() can only convert to interface types."); + schema.requireUsableAs(); + return typename T::Client(kj::mv(hook)); +} + +inline CallContext::CallContext( + CallContextHook& hook, StructSchema paramType, StructSchema resultType) + : hook(&hook), paramType(paramType), resultType(resultType) {} +inline DynamicStruct::Reader CallContext::getParams() { + return hook->getParams().getAs(paramType); +} +inline void CallContext::releaseParams() { + hook->releaseParams(); +} +inline DynamicStruct::Builder CallContext::getResults( + kj::Maybe sizeHint) { + return hook->getResults(sizeHint).getAs(resultType); +} +inline DynamicStruct::Builder CallContext::initResults( + kj::Maybe sizeHint) { + return hook->getResults(sizeHint).initAs(resultType); +} +inline void CallContext::setResults(DynamicStruct::Reader value) { + hook->getResults(value.totalSize()).setAs(value); +} +inline void CallContext::adoptResults(Orphan&& value) { + hook->getResults(MessageSize { 0, 0 }).adopt(kj::mv(value)); +} +inline Orphanage CallContext::getResultsOrphanage( + kj::Maybe sizeHint) { + return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); +} +template +inline kj::Promise CallContext::tailCall( + Request&& tailRequest) { + return hook->tailCall(kj::mv(tailRequest.hook)); +} + +template <> +inline DynamicCapability::Client Capability::Client::castAs( + InterfaceSchema schema) { + return DynamicCapability::Client(schema, hook->addRef()); +} + +template <> +inline DynamicCapability::Client CapabilityServerSet::add( + kj::Own&& server) { + void* ptr = reinterpret_cast(server.get()); + auto schema = server->getSchema(); + return addInternal(kj::mv(server), ptr).castAs(schema); +} + +// ------------------------------------------------------------------- + +template +ReaderFor ConstSchema::as() const { + return DynamicValue::Reader(*this).as(); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/endian.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/endian.h new file mode 100644 index 000000000..c0e3d7584 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/endian.h @@ -0,0 +1,306 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "common.h" +#include +#include // memcpy + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace _ { // private + +// WireValue +// +// Wraps a primitive value as it appears on the wire. Namely, values are little-endian on the +// wire, because little-endian is the most common endianness in modern CPUs. +// +// Note: In general, code that depends cares about byte ordering is bad. See: +// http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +// Cap'n Proto is special because it is essentially doing compiler-like things, fussing over +// allocation and layout of memory, in order to squeeze out every last drop of performance. + +#if _MSC_VER +// Assume Windows is little-endian. +// +// TODO(msvc): This is ugly. Maybe refactor later checks to be based on CAPNP_BYTE_ORDER or +// CAPNP_SWAP_BYTES or something, and define that in turn based on _MSC_VER or the GCC +// intrinsics. + +#ifndef __ORDER_BIG_ENDIAN__ +#define __ORDER_BIG_ENDIAN__ 4321 +#endif +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ 1234 +#endif +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif +#endif + +#if CAPNP_REVERSE_ENDIAN +#define CAPNP_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ +#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ +#else +#define CAPNP_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ +#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ +#endif + +#if defined(__BYTE_ORDER__) && \ + __BYTE_ORDER__ == CAPNP_WIRE_BYTE_ORDER && \ + !CAPNP_DISABLE_ENDIAN_DETECTION +// CPU is little-endian. We can just read/write the memory directly. + +template +class DirectWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template +using WireValue = DirectWireValue; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#elif defined(__BYTE_ORDER__) && \ + __BYTE_ORDER__ == CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER && \ + defined(__GNUC__) && !CAPNP_DISABLE_ENDIAN_DETECTION +// Big-endian, but GCC's __builtin_bswap() is available. + +// TODO(perf): Use dedicated instructions to read little-endian data on big-endian CPUs that have +// them. + +// TODO(perf): Verify that this code optimizes reasonably. In particular, ensure that the +// compiler optimizes away the memcpy()s and keeps everything in registers. + +template +class SwappingWireValue; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing + // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). + uint16_t swapped = (value << 8) | (value >> 8); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint16_t raw; + memcpy(&raw, &newValue, sizeof(T)); + // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing + // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). + value = (raw << 8) | (raw >> 8); + } + +private: + uint16_t value; +}; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint32_t swapped = __builtin_bswap32(value); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint32_t raw; + memcpy(&raw, &newValue, sizeof(T)); + value = __builtin_bswap32(raw); + } + +private: + uint32_t value; +}; + +template +class SwappingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint64_t swapped = __builtin_bswap64(value); + T result; + memcpy(&result, &swapped, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint64_t raw; + memcpy(&raw, &newValue, sizeof(T)); + value = __builtin_bswap64(raw); + } + +private: + uint64_t value; +}; + +template +using WireValue = SwappingWireValue; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#else +// Unknown endianness. Fall back to bit shifts. + +#if !CAPNP_DISABLE_ENDIAN_DETECTION +#if _MSC_VER +#pragma message("Couldn't detect endianness of your platform. Using unoptimized fallback implementation.") +#pragma message("Consider changing this code to detect your platform and send us a patch!") +#else +#warning "Couldn't detect endianness of your platform. Using unoptimized fallback implementation." +#warning "Consider changing this code to detect your platform and send us a patch!" +#endif +#endif // !CAPNP_DISABLE_ENDIAN_DETECTION + +template +class ShiftingWireValue; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { return value; } + KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } + +private: + T value; +}; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint16_t raw = (static_cast(bytes[0]) ) | + (static_cast(bytes[1]) << 8); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint16_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + } + +private: + union { + byte bytes[2]; + uint16_t align; + }; +}; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint32_t raw = (static_cast(bytes[0]) ) | + (static_cast(bytes[1]) << 8) | + (static_cast(bytes[2]) << 16) | + (static_cast(bytes[3]) << 24); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint32_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + bytes[2] = raw >> 16; + bytes[3] = raw >> 24; + } + +private: + union { + byte bytes[4]; + uint32_t align; + }; +}; + +template +class ShiftingWireValue { +public: + KJ_ALWAYS_INLINE(T get() const) { + uint64_t raw = (static_cast(bytes[0]) ) | + (static_cast(bytes[1]) << 8) | + (static_cast(bytes[2]) << 16) | + (static_cast(bytes[3]) << 24) | + (static_cast(bytes[4]) << 32) | + (static_cast(bytes[5]) << 40) | + (static_cast(bytes[6]) << 48) | + (static_cast(bytes[7]) << 56); + T result; + memcpy(&result, &raw, sizeof(T)); + return result; + } + KJ_ALWAYS_INLINE(void set(T newValue)) { + uint64_t raw; + memcpy(&raw, &newValue, sizeof(T)); + bytes[0] = raw; + bytes[1] = raw >> 8; + bytes[2] = raw >> 16; + bytes[3] = raw >> 24; + bytes[4] = raw >> 32; + bytes[5] = raw >> 40; + bytes[6] = raw >> 48; + bytes[7] = raw >> 56; + } + +private: + union { + byte bytes[8]; + uint64_t align; + }; +}; + +template +using WireValue = ShiftingWireValue; +// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are +// linked together, we define each implementation with a different name and define an alias to the +// one we want to use. + +#endif + +} // namespace _ (private) +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/generated-header-support.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/generated-header-support.h new file mode 100644 index 000000000..b103d4bc8 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/generated-header-support.h @@ -0,0 +1,424 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file is included from all generated headers. + +#pragma once + +#include "raw-schema.h" +#include "layout.h" +#include "list.h" +#include "orphan.h" +#include "pointer-helpers.h" +#include "any.h" +#include +#include +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class MessageBuilder; // So that it can be declared a friend. + +template +struct ToDynamic_; // Defined in dynamic.h, needs to be declared as everyone's friend. + +struct DynamicStruct; // So that it can be declared a friend. + +struct Capability; // To declare brandBindingFor() + +namespace _ { // private + +#if !CAPNP_LITE + +template +inline const RawSchema& rawSchema() { + return *CapnpPrivate::schema; +} +template ::typeId> +inline const RawSchema& rawSchema() { + return *schemas::EnumInfo::schema; +} + +template +inline const RawBrandedSchema& rawBrandedSchema() { + return *CapnpPrivate::brand(); +} +template ::typeId> +inline const RawBrandedSchema& rawBrandedSchema() { + return schemas::EnumInfo::schema->defaultBrand; +} + +template +struct ChooseBrand; +// If all of `Params` are `AnyPointer`, return the type's default brand. Otherwise, return a +// specific brand instance. TypeTag is the _capnpPrivate struct for the type in question. + +template +struct ChooseBrand { + // All params were AnyPointer. No specific brand needed. + static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::schema->defaultBrand; } +}; + +template +struct ChooseBrand: public ChooseBrand {}; +// The first parameter is AnyPointer, so recurse to check the rest. + +template +struct ChooseBrand { + // At least one parameter is not AnyPointer, so use the specificBrand constant. + static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::specificBrand; } +}; + +template ()> +struct BrandBindingFor_; + +#define HANDLE_TYPE(Type, which) \ + template <> \ + struct BrandBindingFor_ { \ + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { \ + return { which, listDepth, nullptr }; \ + } \ + } +HANDLE_TYPE(Void, 0); +HANDLE_TYPE(bool, 1); +HANDLE_TYPE(int8_t, 2); +HANDLE_TYPE(int16_t, 3); +HANDLE_TYPE(int32_t, 4); +HANDLE_TYPE(int64_t, 5); +HANDLE_TYPE(uint8_t, 6); +HANDLE_TYPE(uint16_t, 7); +HANDLE_TYPE(uint32_t, 8); +HANDLE_TYPE(uint64_t, 9); +HANDLE_TYPE(float, 10); +HANDLE_TYPE(double, 11); +#undef HANDLE_TYPE + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 12, listDepth, nullptr }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 13, listDepth, nullptr }; + } +}; + +template +struct BrandBindingFor_, Kind::LIST> { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return BrandBindingFor_::get(listDepth + 1); + } +}; + +template +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 15, listDepth, &rawSchema().defaultBrand }; + } +}; + +template +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 16, listDepth, T::_capnpPrivate::brand() }; + } +}; + +template +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 17, listDepth, T::_capnpPrivate::brand() }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 0 }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 1 }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 2 }; + } +}; + +template <> +struct BrandBindingFor_ { + static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { + return { 18, listDepth, 0, 3 }; + } +}; + +template +constexpr RawBrandedSchema::Binding brandBindingFor() { + return BrandBindingFor_::get(0); +} + +kj::StringTree structString(StructReader reader, const RawBrandedSchema& schema); +kj::String enumString(uint16_t value, const RawBrandedSchema& schema); +// Declared here so that we can declare inline stringify methods on generated types. +// Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in. + +template +inline kj::StringTree structString(StructReader reader) { + return structString(reader, rawBrandedSchema()); +} +template +inline kj::String enumString(T value) { + return enumString(static_cast(value), rawBrandedSchema()); +} + +#endif // !CAPNP_LITE + +// TODO(cleanup): Unify ConstStruct and ConstList. +template +class ConstStruct { +public: + ConstStruct() = delete; + KJ_DISALLOW_COPY_AND_MOVE(ConstStruct); + inline explicit constexpr ConstStruct(const word* ptr): ptr(ptr) {} + + inline typename T::Reader get() const { + return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs(); + } + + inline operator typename T::Reader() const { return get(); } + inline typename T::Reader operator*() const { return get(); } + inline TemporaryPointer operator->() const { return get(); } + +private: + const word* ptr; +}; + +template +class ConstList { +public: + ConstList() = delete; + KJ_DISALLOW_COPY_AND_MOVE(ConstList); + inline explicit constexpr ConstList(const word* ptr): ptr(ptr) {} + + inline typename List::Reader get() const { + return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs>(); + } + + inline operator typename List::Reader() const { return get(); } + inline typename List::Reader operator*() const { return get(); } + inline TemporaryPointer::Reader> operator->() const { return get(); } + +private: + const word* ptr; +}; + +template +class ConstText { +public: + ConstText() = delete; + KJ_DISALLOW_COPY_AND_MOVE(ConstText); + inline explicit constexpr ConstText(const word* ptr): ptr(ptr) {} + + inline Text::Reader get() const { + return Text::Reader(reinterpret_cast(ptr), size); + } + + inline operator Text::Reader() const { return get(); } + inline Text::Reader operator*() const { return get(); } + inline TemporaryPointer operator->() const { return get(); } + + inline kj::StringPtr toString() const { + return get(); + } + +private: + const word* ptr; +}; + +template +inline kj::StringPtr KJ_STRINGIFY(const ConstText& s) { + return s.get(); +} + +template +class ConstData { +public: + ConstData() = delete; + KJ_DISALLOW_COPY_AND_MOVE(ConstData); + inline explicit constexpr ConstData(const word* ptr): ptr(ptr) {} + + inline Data::Reader get() const { + return Data::Reader(reinterpret_cast(ptr), size); + } + + inline operator Data::Reader() const { return get(); } + inline Data::Reader operator*() const { return get(); } + inline TemporaryPointer operator->() const { return get(); } + +private: + const word* ptr; +}; + +template +inline auto KJ_STRINGIFY(const ConstData& s) -> decltype(kj::toCharSequence(s.get())) { + return kj::toCharSequence(s.get()); +} + +} // namespace _ (private) + +template +inline constexpr uint64_t typeId() { return CapnpPrivate::typeId; } +template ::typeId> +inline constexpr uint64_t typeId() { return id; } +// typeId() returns the type ID as defined in the schema. Works with structs, enums, and +// interfaces. + +template +inline constexpr uint sizeInWords() { + // Return the size, in words, of a Struct type, if allocated free-standing (not in a list). + // May be useful for pre-computing space needed in order to precisely allocate messages. + + return unbound((upgradeBound(_::structSize().data) + + _::structSize().pointers * WORDS_PER_POINTER) / WORDS); +} + +} // namespace capnp + +#if _MSC_VER && !defined(__clang__) +// MSVC doesn't understand floating-point constexpr yet. +// +// TODO(msvc): Remove this hack when MSVC is fixed. +#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) +#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) = value +#else +#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) = value +#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) +#endif + +#if _MSC_VER && !defined(__clang__) +// TODO(msvc): A little hack to allow MSVC to use C++14 return type deduction in cases where the +// explicit type exposes bugs in the compiler. +#define CAPNP_AUTO_IF_MSVC(...) auto +#else +#define CAPNP_AUTO_IF_MSVC(...) __VA_ARGS__ +#endif + +// TODO(msvc): MSVC does not even expect constexprs to have definitions below C++17. +#if (__cplusplus < 201703L) && !(defined(_MSC_VER) && !defined(__clang__)) +#define CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL 1 +#else +#define CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL 0 +#endif + +#if CAPNP_LITE + +#define CAPNP_DECLARE_SCHEMA(id) \ + extern ::capnp::word const* const bp_##id + +#define CAPNP_DECLARE_ENUM(type, id) \ + inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ + return ::kj::str(static_cast(value)); \ + } \ + template <> struct EnumInfo { \ + struct IsEnum; \ + static constexpr uint64_t typeId = 0x##id; \ + static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ + } + +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#define CAPNP_DEFINE_ENUM(type, id) \ + constexpr uint64_t EnumInfo::typeId +#else +#define CAPNP_DEFINE_ENUM(type, id) +#endif + +#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ + struct IsStruct; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr uint16_t dataWordSize = dataWordSize_; \ + static constexpr uint16_t pointerCount = pointerCount_; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } + +#else // CAPNP_LITE + +#define CAPNP_DECLARE_SCHEMA(id) \ + extern ::capnp::word const* const bp_##id; \ + extern const ::capnp::_::RawSchema s_##id + +#define CAPNP_DECLARE_ENUM(type, id) \ + inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ + return ::capnp::_::enumString(value); \ + } \ + template <> struct EnumInfo { \ + struct IsEnum; \ + static constexpr uint64_t typeId = 0x##id; \ + static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \ + } + +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#define CAPNP_DEFINE_ENUM(type, id) \ + constexpr uint64_t EnumInfo::typeId; \ + constexpr ::capnp::_::RawSchema const* EnumInfo::schema +#else +#define CAPNP_DEFINE_ENUM(type, id) +#endif + +#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ + struct IsStruct; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \ + static constexpr uint16_t dataWordSize = dataWordSize_; \ + static constexpr uint16_t pointerCount = pointerCount_; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; + +#define CAPNP_DECLARE_INTERFACE_HEADER(id) \ + struct IsInterface; \ + static constexpr uint64_t typeId = 0x##id; \ + static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \ + static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ + static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; + +#endif // CAPNP_LITE, else + +namespace capnp { +namespace schemas { +CAPNP_DECLARE_SCHEMA(995f9a3377c0b16e); +// HACK: Forward-declare the RawSchema for StreamResult, from stream.capnp. This allows capnp +// files which declare streaming methods to avoid including stream.capnp.h. +} +} + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/layout.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/layout.cc new file mode 100644 index 000000000..e2fa84df6 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/layout.cc @@ -0,0 +1,3893 @@ +// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#define CAPNP_PRIVATE +#include "layout.h" +#include +#include "arena.h" +#include +#include + +#if !CAPNP_LITE +#include "capability.h" +#endif // !CAPNP_LITE + +namespace capnp { +namespace _ { // private + +#if !CAPNP_LITE +static BrokenCapFactory* globalBrokenCapFactory = nullptr; +// Horrible hack: We need to be able to construct broken caps without any capability context, +// but we can't have a link-time dependency on libcapnp-rpc. + +void setGlobalBrokenCapFactoryForLayoutCpp(BrokenCapFactory& factory) { + // Called from capability.c++ when the capability API is used, to make sure that layout.c++ + // is ready for it. May be called multiple times but always with the same value. +#if __GNUC__ || defined(__clang__) + __atomic_store_n(&globalBrokenCapFactory, &factory, __ATOMIC_RELAXED); +#elif _MSC_VER + *static_cast(&globalBrokenCapFactory) = &factory; +#else +#error "Platform not supported" +#endif +} + +static BrokenCapFactory* readGlobalBrokenCapFactoryForLayoutCpp() { +#if __GNUC__ || defined(__clang__) + // Thread-sanitizer doesn't have the right information to know this is safe without doing an + // atomic read. https://groups.google.com/g/capnproto/c/634juhn5ap0/m/pyRiwWl1AAAJ + return __atomic_load_n(&globalBrokenCapFactory, __ATOMIC_RELAXED); +#else + return globalBrokenCapFactory; +#endif +} + +} // namespace _ (private) + +const uint ClientHook::NULL_CAPABILITY_BRAND = 0; +const uint ClientHook::BROKEN_CAPABILITY_BRAND = 0; +// Defined here rather than capability.c++ so that we can safely call isNull() in this file. + +namespace _ { // private + +#endif // !CAPNP_LITE + +#if CAPNP_DEBUG_TYPES +#define G(n) bounded() +#else +#define G(n) n +#endif + +// ======================================================================================= + +#if __GNUC__ >= 8 && !__clang__ +// GCC 8 introduced a warning which complains whenever we try to memset() or memcpy() a +// WirePointer, because we deleted the regular copy constructor / assignment operator. Weirdly, if +// I remove those deletions, GCC *still* complains that WirePointer is non-trivial. I don't +// understand why -- maybe because WireValue has private members? We don't want to make WireValue's +// member public, but memset() and memcpy() on it are certainly valid and desirable, so we'll just +// have to disable the warning I guess. +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + +struct WirePointer { + // A pointer, in exactly the format in which it appears on the wire. + + // Copying and moving is not allowed because the offset would become wrong. + WirePointer(const WirePointer& other) = delete; + WirePointer(WirePointer&& other) = delete; + WirePointer& operator=(const WirePointer& other) = delete; + WirePointer& operator=(WirePointer&& other) = delete; + + // ----------------------------------------------------------------- + // Common part of all pointers: kind + offset + // + // Actually this is not terribly common. The "offset" could actually be different things + // depending on the context: + // - For a regular (e.g. struct/list) pointer, a signed word offset from the word immediately + // following the pointer pointer. (The off-by-one means the offset is more often zero, saving + // bytes on the wire when packed.) + // - For an inline composite list tag (not really a pointer, but structured similarly), an + // element count. + // - For a FAR pointer, an unsigned offset into the target segment. + // - For a FAR landing pad, zero indicates that the target value immediately follows the pad while + // 1 indicates that the pad is followed by another FAR pointer that actually points at the + // value. + + enum Kind { + STRUCT = 0, + // Reference points at / describes a struct. + + LIST = 1, + // Reference points at / describes a list. + + FAR = 2, + // Reference is a "far pointer", which points at data located in a different segment. The + // eventual target is one of the other kinds. + + OTHER = 3 + // Reference has type "other". If the next 30 bits are all zero (i.e. the lower 32 bits contain + // only the kind OTHER) then the pointer is a capability. All other values are reserved. + }; + + WireValue offsetAndKind; + + KJ_ALWAYS_INLINE(Kind kind() const) { + return static_cast(offsetAndKind.get() & 3); + } + KJ_ALWAYS_INLINE(bool isPositional() const) { + return (offsetAndKind.get() & 2) == 0; // match STRUCT and LIST but not FAR or OTHER + } + KJ_ALWAYS_INLINE(bool isCapability() const) { + return offsetAndKind.get() == OTHER; + } + + KJ_ALWAYS_INLINE(word* target()) { + return reinterpret_cast(this) + 1 + (static_cast(offsetAndKind.get()) >> 2); + } + KJ_ALWAYS_INLINE(const word* target(SegmentReader* segment) const) { + if (segment == nullptr) { + return reinterpret_cast(this + 1) + + (static_cast(offsetAndKind.get()) >> 2); + } else { + return segment->checkOffset(reinterpret_cast(this + 1), + static_cast(offsetAndKind.get()) >> 2); + } + } + KJ_ALWAYS_INLINE(void setKindAndTarget(Kind kind, word* target, SegmentBuilder* segment)) { + // Check that the target is really in the same segment, otherwise subtracting pointers is + // undefined behavior. As it turns out, it's undefined behavior that actually produces + // unexpected results in a real-world situation that actually happened: At one time, + // OrphanBuilder's "tag" (a WirePointer) was allowed to be initialized as if it lived in + // a particular segment when in fact it does not. On 32-bit systems, where words might + // only be 32-bit aligned, it's possible that the difference between `this` and `target` is + // not a whole number of words. But clang optimizes: + // (target - (word*)this - 1) << 2 + // to: + // (((ptrdiff_t)target - (ptrdiff_t)this - 8) >> 1) + // So now when the pointers are not aligned the same, we can end up corrupting the bottom + // two bits, where `kind` is stored. For example, this turns a struct into a far pointer. + // Ouch! + KJ_DREQUIRE(reinterpret_cast(this) >= + reinterpret_cast(segment->getStartPtr())); + KJ_DREQUIRE(reinterpret_cast(this) < + reinterpret_cast(segment->getStartPtr() + segment->getSize())); + KJ_DREQUIRE(reinterpret_cast(target) >= + reinterpret_cast(segment->getStartPtr())); + KJ_DREQUIRE(reinterpret_cast(target) <= + reinterpret_cast(segment->getStartPtr() + segment->getSize())); + offsetAndKind.set((static_cast(target - reinterpret_cast(this) - 1) << 2) | kind); + } + KJ_ALWAYS_INLINE(void setKindWithZeroOffset(Kind kind)) { + offsetAndKind.set(kind); + } + KJ_ALWAYS_INLINE(void setKindAndTargetForEmptyStruct()) { + // This pointer points at an empty struct. Assuming the WirePointer itself is in-bounds, we + // can set the target to point either at the WirePointer itself or immediately after it. The + // latter would cause the WirePointer to be "null" (since for an empty struct the upper 32 + // bits are going to be zero). So we set an offset of -1, as if the struct were allocated + // immediately before this pointer, to distinguish it from null. + offsetAndKind.set(0xfffffffc); + } + KJ_ALWAYS_INLINE(void setKindForOrphan(Kind kind)) { + // OrphanBuilder contains a WirePointer, but since it isn't located in a segment, it should + // not have a valid offset (unless it is a FAR or OTHER pointer). We set its offset to -1 + // because setting it to zero would mean a pointer to an empty struct would appear to be a null + // pointer. + KJ_DREQUIRE(isPositional()); + offsetAndKind.set(kind | 0xfffffffc); + } + + KJ_ALWAYS_INLINE(ListElementCount inlineCompositeListElementCount() const) { + return ((bounded(offsetAndKind.get()) >> G(2)) + & G(kj::maxValueForBits())) * ELEMENTS; + } + KJ_ALWAYS_INLINE(void setKindAndInlineCompositeListElementCount( + Kind kind, ListElementCount elementCount)) { + offsetAndKind.set(unboundAs((elementCount / ELEMENTS) << G(2)) | kind); + } + + KJ_ALWAYS_INLINE(const word* farTarget(SegmentReader* segment) const) { + KJ_DREQUIRE(kind() == FAR, + "farTarget() should only be called on FAR pointers."); + return segment->checkOffset(segment->getStartPtr(), offsetAndKind.get() >> 3); + } + KJ_ALWAYS_INLINE(word* farTarget(SegmentBuilder* segment) const) { + KJ_DREQUIRE(kind() == FAR, + "farTarget() should only be called on FAR pointers."); + return segment->getPtrUnchecked((bounded(offsetAndKind.get()) >> G(3)) * WORDS); + } + KJ_ALWAYS_INLINE(bool isDoubleFar() const) { + KJ_DREQUIRE(kind() == FAR, + "isDoubleFar() should only be called on FAR pointers."); + return (offsetAndKind.get() >> 2) & 1; + } + KJ_ALWAYS_INLINE(void setFar(bool isDoubleFar, WordCountN<29> pos)) { + offsetAndKind.set(unboundAs((pos / WORDS) << G(3)) | + (static_cast(isDoubleFar) << 2) | + static_cast(Kind::FAR)); + } + KJ_ALWAYS_INLINE(void setCap(uint index)) { + offsetAndKind.set(static_cast(Kind::OTHER)); + capRef.index.set(index); + } + + // ----------------------------------------------------------------- + // Part of pointer that depends on the kind. + + // Note: Originally StructRef, ListRef, and FarRef were unnamed types, but this somehow + // tickled a bug in GCC: + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58192 + struct StructRef { + WireValue dataSize; + WireValue ptrCount; + + inline WordCountN<17> wordSize() const { + return upgradeBound(dataSize.get()) + ptrCount.get() * WORDS_PER_POINTER; + } + + KJ_ALWAYS_INLINE(void set(WordCount16 ds, WirePointerCount16 rc)) { + dataSize.set(ds); + ptrCount.set(rc); + } + KJ_ALWAYS_INLINE(void set(StructSize size)) { + dataSize.set(size.data); + ptrCount.set(size.pointers); + } + }; + + struct ListRef { + WireValue elementSizeAndCount; + + KJ_ALWAYS_INLINE(ElementSize elementSize() const) { + return static_cast(elementSizeAndCount.get() & 7); + } + KJ_ALWAYS_INLINE(ElementCountN<29> elementCount() const) { + return (bounded(elementSizeAndCount.get()) >> G(3)) * ELEMENTS; + } + KJ_ALWAYS_INLINE(WordCountN<29> inlineCompositeWordCount() const) { + return elementCount() * (ONE * WORDS / ELEMENTS); + } + + KJ_ALWAYS_INLINE(void set(ElementSize es, ElementCountN<29> ec)) { + elementSizeAndCount.set(unboundAs((ec / ELEMENTS) << G(3)) | + static_cast(es)); + } + + KJ_ALWAYS_INLINE(void setInlineComposite(WordCountN<29> wc)) { + elementSizeAndCount.set(unboundAs((wc / WORDS) << G(3)) | + static_cast(ElementSize::INLINE_COMPOSITE)); + } + }; + + struct FarRef { + WireValue segmentId; + + KJ_ALWAYS_INLINE(void set(SegmentId si)) { + segmentId.set(si); + } + }; + + struct CapRef { + WireValue index; + // Index into the message's capability table. + }; + + union { + uint32_t upper32Bits; + + StructRef structRef; + + ListRef listRef; + + FarRef farRef; + + CapRef capRef; + }; + + KJ_ALWAYS_INLINE(bool isNull() const) { + // If the upper 32 bits are zero, this is a pointer to an empty struct. We consider that to be + // our "null" value. + return (offsetAndKind.get() == 0) & (upper32Bits == 0); + } + +}; +static_assert(sizeof(WirePointer) == sizeof(word), + "capnp::WirePointer is not exactly one word. This will probably break everything."); +static_assert(unboundAs(POINTERS * WORDS_PER_POINTER * BYTES_PER_WORD / BYTES) == + sizeof(WirePointer), + "WORDS_PER_POINTER is wrong."); +static_assert(unboundAs(POINTERS * BYTES_PER_POINTER / BYTES) == sizeof(WirePointer), + "BYTES_PER_POINTER is wrong."); +static_assert(unboundAs(POINTERS * BITS_PER_POINTER / BITS_PER_BYTE / BYTES) == + sizeof(WirePointer), + "BITS_PER_POINTER is wrong."); + +#define OUT_OF_BOUNDS_ERROR_DETAIL \ + "This usually indicates that " \ + "the input data was corrupted, used a different encoding than specified (e.g. " \ + "packed vs. non-packed), or was not a Cap'n Proto message to begin with. Note " \ + "that this error is NOT due to a schema mismatch; the input is invalid " \ + "regardless of schema." + +namespace { + +static const union { + AlignedData word; + WirePointer pointer; +} zero = {{{0}}}; + +} // namespace + +// ======================================================================================= + +namespace { + +template +struct SegmentAnd { + SegmentBuilder* segment; + T value; +}; + +} // namespace + +struct WireHelpers { +#if CAPNP_DEBUG_TYPES + template + static KJ_ALWAYS_INLINE( + kj::Quantity, word> roundBytesUpToWords( + kj::Quantity, byte> bytes)) { + static_assert(sizeof(word) == 8, "This code assumes 64-bit words."); + return (bytes + G(7) * BYTES) / BYTES_PER_WORD; + } + + template + static KJ_ALWAYS_INLINE( + kj::Quantity, byte> roundBitsUpToBytes( + kj::Quantity, BitLabel> bits)) { + return (bits + G(7) * BITS) / BITS_PER_BYTE; + } + + template + static KJ_ALWAYS_INLINE( + kj::Quantity, word> roundBitsUpToWords( + kj::Quantity, BitLabel> bits)) { + static_assert(sizeof(word) == 8, "This code assumes 64-bit words."); + return (bits + G(63) * BITS) / BITS_PER_WORD; + } +#else + static KJ_ALWAYS_INLINE(WordCount roundBytesUpToWords(ByteCount bytes)) { + static_assert(sizeof(word) == 8, "This code assumes 64-bit words."); + return (bytes + G(7) * BYTES) / BYTES_PER_WORD; + } + + static KJ_ALWAYS_INLINE(ByteCount roundBitsUpToBytes(BitCount bits)) { + return (bits + G(7) * BITS) / BITS_PER_BYTE; + } + + static KJ_ALWAYS_INLINE(WordCount64 roundBitsUpToWords(BitCount64 bits)) { + static_assert(sizeof(word) == 8, "This code assumes 64-bit words."); + return (bits + G(63) * BITS) / BITS_PER_WORD; + } + + static KJ_ALWAYS_INLINE(ByteCount64 roundBitsUpToBytes(BitCount64 bits)) { + return (bits + G(7) * BITS) / BITS_PER_BYTE; + } +#endif + + static KJ_ALWAYS_INLINE(void zeroMemory(byte* ptr, ByteCount32 count)) { + if (count != ZERO * BYTES) memset(ptr, 0, unbound(count / BYTES)); + } + + static KJ_ALWAYS_INLINE(void zeroMemory(word* ptr, WordCountN<29> count)) { + if (count != ZERO * WORDS) memset(ptr, 0, unbound(count * BYTES_PER_WORD / BYTES)); + } + + static KJ_ALWAYS_INLINE(void zeroMemory(WirePointer* ptr, WirePointerCountN<29> count)) { + if (count != ZERO * POINTERS) memset(ptr, 0, unbound(count * BYTES_PER_POINTER / BYTES)); + } + + static KJ_ALWAYS_INLINE(void zeroMemory(WirePointer* ptr)) { + memset(ptr, 0, sizeof(*ptr)); + } + + template + static inline void zeroMemory(kj::ArrayPtr array) { + if (array.size() != 0u) memset(array.begin(), 0, array.size() * sizeof(array[0])); + } + + static KJ_ALWAYS_INLINE(void copyMemory(byte* to, const byte* from, ByteCount32 count)) { + if (count != ZERO * BYTES) memcpy(to, from, unbound(count / BYTES)); + } + + static KJ_ALWAYS_INLINE(void copyMemory(word* to, const word* from, WordCountN<29> count)) { + if (count != ZERO * WORDS) memcpy(to, from, unbound(count * BYTES_PER_WORD / BYTES)); + } + + static KJ_ALWAYS_INLINE(void copyMemory(WirePointer* to, const WirePointer* from, + WirePointerCountN<29> count)) { + if (count != ZERO * POINTERS) memcpy(to, from, unbound(count * BYTES_PER_POINTER / BYTES)); + } + + template + static inline void copyMemory(T* to, const T* from) { + memcpy(to, from, sizeof(*from)); + } + + // TODO(cleanup): Turn these into a .copyTo() method of ArrayPtr? + template + static inline void copyMemory(T* to, kj::ArrayPtr from) { + if (from.size() != 0u) memcpy(to, from.begin(), from.size() * sizeof(from[0])); + } + template + static inline void copyMemory(T* to, kj::ArrayPtr from) { + if (from.size() != 0u) memcpy(to, from.begin(), from.size() * sizeof(from[0])); + } + static KJ_ALWAYS_INLINE(void copyMemory(char* to, kj::StringPtr from)) { + if (from.size() != 0u) memcpy(to, from.begin(), from.size() * sizeof(from[0])); + } + + static KJ_ALWAYS_INLINE(bool boundsCheck( + SegmentReader* segment, const word* start, WordCountN<31> size)) { + // If segment is null, this is an unchecked message, so we don't do bounds checks. + return segment == nullptr || segment->checkObject(start, size); + } + + static KJ_ALWAYS_INLINE(bool amplifiedRead(SegmentReader* segment, WordCount virtualAmount)) { + // If segment is null, this is an unchecked message, so we don't do read limiter checks. + return segment == nullptr || segment->amplifiedRead(virtualAmount); + } + + static KJ_ALWAYS_INLINE(word* allocate( + WirePointer*& ref, SegmentBuilder*& segment, CapTableBuilder* capTable, + SegmentWordCount amount, WirePointer::Kind kind, BuilderArena* orphanArena)) { + // Allocate space in the message for a new object, creating far pointers if necessary. The + // space is guaranteed to be zero'd (because MessageBuilder implementations are required to + // return zero'd memory). + // + // * `ref` starts out being a reference to the pointer which shall be assigned to point at the + // new object. On return, `ref` points to a pointer which needs to be initialized with + // the object's type information. Normally this is the same pointer, but it can change if + // a far pointer was allocated -- in this case, `ref` will end up pointing to the far + // pointer's tag. Either way, `allocate()` takes care of making sure that the original + // pointer ends up leading to the new object. On return, only the upper 32 bit of `*ref` + // need to be filled in by the caller. + // * `segment` starts out pointing to the segment containing `ref`. On return, it points to + // the segment containing the allocated object, which is usually the same segment but could + // be a different one if the original segment was out of space. + // * `amount` is the number of words to allocate. + // * `kind` is the kind of object to allocate. It is used to initialize the pointer. It + // cannot be `FAR` -- far pointers are allocated automatically as needed. + // * `orphanArena` is usually null. If it is non-null, then we're allocating an orphan object. + // In this case, `segment` starts out null; the allocation takes place in an arbitrary + // segment belonging to the arena. `ref` will be initialized as a non-far pointer, but its + // target offset will be set to zero. + + if (orphanArena == nullptr) { + if (!ref->isNull()) zeroObject(segment, capTable, ref); + + if (amount == ZERO * WORDS && kind == WirePointer::STRUCT) { + // Note that the check for kind == WirePointer::STRUCT will hopefully cause this whole + // branch to be optimized away from all the call sites that are allocating non-structs. + ref->setKindAndTargetForEmptyStruct(); + return reinterpret_cast(ref); + } + + KJ_ASSUME(segment != nullptr); + word* ptr = segment->allocate(amount); + + if (ptr == nullptr) { + + // Need to allocate in a new segment. We'll need to allocate an extra pointer worth of + // space to act as the landing pad for a far pointer. + + WordCount amountPlusRef = amount + POINTER_SIZE_IN_WORDS; + auto allocation = segment->getArena()->allocate( + assertMaxBits(amountPlusRef, []() { + KJ_FAIL_REQUIRE("requested object size exceeds maximum segment size"); + })); + segment = allocation.segment; + ptr = allocation.words; + + // Set up the original pointer to be a far pointer to the new segment. + ref->setFar(false, segment->getOffsetTo(ptr)); + ref->farRef.set(segment->getSegmentId()); + + // Initialize the landing pad to indicate that the data immediately follows the pad. + ref = reinterpret_cast(ptr); + ref->setKindAndTarget(kind, ptr + POINTER_SIZE_IN_WORDS, segment); + + // Allocated space follows new pointer. + return ptr + POINTER_SIZE_IN_WORDS; + } else { + ref->setKindAndTarget(kind, ptr, segment); + return ptr; + } + } else { + // orphanArena is non-null. Allocate an orphan. + KJ_DASSERT(ref->isNull()); + auto allocation = orphanArena->allocate(amount); + segment = allocation.segment; + ref->setKindForOrphan(kind); + return allocation.words; + } + } + + static KJ_ALWAYS_INLINE(word* followFarsNoWritableCheck( + WirePointer*& ref, word* refTarget, SegmentBuilder*& segment)) { + // If `ref` is a far pointer, follow it. On return, `ref` will have been updated to point at + // a WirePointer that contains the type information about the target object, and a pointer to + // the object contents is returned. The caller must NOT use `ref->target()` as this may or may + // not actually return a valid pointer. `segment` is also updated to point at the segment which + // actually contains the object. + // + // If `ref` is not a far pointer, this simply returns `refTarget`. Usually, `refTarget` should + // be the same as `ref->target()`, but may not be in cases where `ref` is only a tag. + + if (ref->kind() == WirePointer::FAR) { + segment = segment->getArena()->getSegment(ref->farRef.segmentId.get()); + WirePointer* pad = reinterpret_cast(ref->farTarget(segment)); + if (!ref->isDoubleFar()) { + ref = pad; + return pad->target(); + } + + // Landing pad is another far pointer. It is followed by a tag describing the pointed-to + // object. + ref = pad + 1; + + segment = segment->getArena()->getSegment(pad->farRef.segmentId.get()); + return pad->farTarget(segment); + } else { + return refTarget; + } + } + + static KJ_ALWAYS_INLINE(word* followFars( + WirePointer*& ref, word* refTarget, SegmentBuilder*& segment)) { + auto result = followFarsNoWritableCheck(ref, refTarget, segment); + segment->checkWritable(); + return result; + } + + static KJ_ALWAYS_INLINE(kj::Maybe followFars( + const WirePointer*& ref, const word* refTarget, SegmentReader*& segment)) + KJ_WARN_UNUSED_RESULT { + // Like the other followFars() but operates on readers. + + // If the segment is null, this is an unchecked message, so there are no FAR pointers. + if (segment != nullptr && ref->kind() == WirePointer::FAR) { + // Look up the segment containing the landing pad. + segment = segment->getArena()->tryGetSegment(ref->farRef.segmentId.get()); + KJ_REQUIRE(segment != nullptr, "Message contains far pointer to unknown segment.") { + return nullptr; + } + + // Find the landing pad and check that it is within bounds. + const word* ptr = ref->farTarget(segment); + auto padWords = (ONE + bounded(ref->isDoubleFar())) * POINTER_SIZE_IN_WORDS; + KJ_REQUIRE(boundsCheck(segment, ptr, padWords), + "Message contains out-of-bounds far pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + return nullptr; + } + + const WirePointer* pad = reinterpret_cast(ptr); + + // If this is not a double-far then the landing pad is our final pointer. + if (!ref->isDoubleFar()) { + ref = pad; + return pad->target(segment); + } + + // Landing pad is another far pointer. It is followed by a tag describing the pointed-to + // object. + ref = pad + 1; + + SegmentReader* newSegment = segment->getArena()->tryGetSegment(pad->farRef.segmentId.get()); + KJ_REQUIRE(newSegment != nullptr, + "Message contains double-far pointer to unknown segment.") { + return nullptr; + } + KJ_REQUIRE(pad->kind() == WirePointer::FAR, + "Second word of double-far pad must be far pointer.") { + return nullptr; + } + + segment = newSegment; + return pad->farTarget(segment); + } else { + KJ_DASSERT(refTarget != nullptr); + return refTarget; + } + } + + // ----------------------------------------------------------------- + + static void zeroObject(SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* ref) { + // Zero out the pointed-to object. Use when the pointer is about to be overwritten making the + // target object no longer reachable. + + // We shouldn't zero out external data linked into the message. + if (!segment->isWritable()) return; + + switch (ref->kind()) { + case WirePointer::STRUCT: + case WirePointer::LIST: + zeroObject(segment, capTable, ref, ref->target()); + break; + case WirePointer::FAR: { + segment = segment->getArena()->getSegment(ref->farRef.segmentId.get()); + if (segment->isWritable()) { // Don't zero external data. + WirePointer* pad = reinterpret_cast(ref->farTarget(segment)); + + if (ref->isDoubleFar()) { + segment = segment->getArena()->getSegment(pad->farRef.segmentId.get()); + if (segment->isWritable()) { + zeroObject(segment, capTable, pad + 1, pad->farTarget(segment)); + } + zeroMemory(pad, G(2) * POINTERS); + } else { + zeroObject(segment, capTable, pad); + zeroMemory(pad); + } + } + break; + } + case WirePointer::OTHER: + if (ref->isCapability()) { +#if CAPNP_LITE + KJ_FAIL_ASSERT("Capability encountered in builder in lite mode?") { break; } +#else // CAPNP_LINE + capTable->dropCap(ref->capRef.index.get()); +#endif // CAPNP_LITE, else + } else { + KJ_FAIL_REQUIRE("Unknown pointer type.") { break; } + } + break; + } + } + + static void zeroObject(SegmentBuilder* segment, CapTableBuilder* capTable, + WirePointer* tag, word* ptr) { + // We shouldn't zero out external data linked into the message. + if (!segment->isWritable()) return; + + switch (tag->kind()) { + case WirePointer::STRUCT: { + WirePointer* pointerSection = + reinterpret_cast(ptr + tag->structRef.dataSize.get()); + for (auto i: kj::zeroTo(tag->structRef.ptrCount.get())) { + zeroObject(segment, capTable, pointerSection + i); + } + zeroMemory(ptr, tag->structRef.wordSize()); + break; + } + case WirePointer::LIST: { + switch (tag->listRef.elementSize()) { + case ElementSize::VOID: + // Nothing. + break; + case ElementSize::BIT: + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: { + zeroMemory(ptr, roundBitsUpToWords( + upgradeBound(tag->listRef.elementCount()) * + dataBitsPerElement(tag->listRef.elementSize()))); + break; + } + case ElementSize::POINTER: { + WirePointer* typedPtr = reinterpret_cast(ptr); + auto count = tag->listRef.elementCount() * (ONE * POINTERS / ELEMENTS); + for (auto i: kj::zeroTo(count)) { + zeroObject(segment, capTable, typedPtr + i); + } + zeroMemory(typedPtr, count); + break; + } + case ElementSize::INLINE_COMPOSITE: { + WirePointer* elementTag = reinterpret_cast(ptr); + + KJ_ASSERT(elementTag->kind() == WirePointer::STRUCT, + "Don't know how to handle non-STRUCT inline composite."); + WordCount dataSize = elementTag->structRef.dataSize.get(); + WirePointerCount pointerCount = elementTag->structRef.ptrCount.get(); + + auto count = elementTag->inlineCompositeListElementCount(); + if (pointerCount > ZERO * POINTERS) { + word* pos = ptr + POINTER_SIZE_IN_WORDS; + for (auto i KJ_UNUSED: kj::zeroTo(count)) { + pos += dataSize; + + for (auto j KJ_UNUSED: kj::zeroTo(pointerCount)) { + zeroObject(segment, capTable, reinterpret_cast(pos)); + pos += POINTER_SIZE_IN_WORDS; + } + } + } + + auto wordsPerElement = elementTag->structRef.wordSize() / ELEMENTS; + zeroMemory(ptr, assertMaxBits(POINTER_SIZE_IN_WORDS + + upgradeBound(count) * wordsPerElement, []() { + KJ_FAIL_ASSERT("encountered list pointer in builder which is too large to " + "possibly fit in a segment. Bug in builder code?"); + })); + break; + } + } + break; + } + case WirePointer::FAR: + KJ_FAIL_ASSERT("Unexpected FAR pointer.") { + break; + } + break; + case WirePointer::OTHER: + KJ_FAIL_ASSERT("Unexpected OTHER pointer.") { + break; + } + break; + } + } + + static KJ_ALWAYS_INLINE( + void zeroPointerAndFars(SegmentBuilder* segment, WirePointer* ref)) { + // Zero out the pointer itself and, if it is a far pointer, zero the landing pad as well, but + // do not zero the object body. Used when upgrading. + + if (ref->kind() == WirePointer::FAR) { + SegmentBuilder* padSegment = segment->getArena()->getSegment(ref->farRef.segmentId.get()); + if (padSegment->isWritable()) { // Don't zero external data. + WirePointer* pad = reinterpret_cast(ref->farTarget(padSegment)); + if (ref->isDoubleFar()) { + zeroMemory(pad, G(2) * POINTERS); + } else { + zeroMemory(pad); + } + } + } + + zeroMemory(ref); + } + + + // ----------------------------------------------------------------- + + static MessageSizeCounts totalSize( + SegmentReader* segment, const WirePointer* ref, int nestingLimit) { + // Compute the total size of the object pointed to, not counting far pointer overhead. + + MessageSizeCounts result = { ZERO * WORDS, 0 }; + + if (ref->isNull()) { + return result; + } + + KJ_REQUIRE(nestingLimit > 0, "Message is too deeply-nested.") { + return result; + } + --nestingLimit; + + const word* ptr; + KJ_IF_MAYBE(p, followFars(ref, ref->target(segment), segment)) { + ptr = p; + } else { + return result; + } + + switch (ref->kind()) { + case WirePointer::STRUCT: { + KJ_REQUIRE(boundsCheck(segment, ptr, ref->structRef.wordSize()), + "Message contained out-of-bounds struct pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + return result; + } + result.addWords(ref->structRef.wordSize()); + + const WirePointer* pointerSection = + reinterpret_cast(ptr + ref->structRef.dataSize.get()); + for (auto i: kj::zeroTo(ref->structRef.ptrCount.get())) { + result += totalSize(segment, pointerSection + i, nestingLimit); + } + break; + } + case WirePointer::LIST: { + switch (ref->listRef.elementSize()) { + case ElementSize::VOID: + // Nothing. + break; + case ElementSize::BIT: + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: { + auto totalWords = roundBitsUpToWords( + upgradeBound(ref->listRef.elementCount()) * + dataBitsPerElement(ref->listRef.elementSize())); + KJ_REQUIRE(boundsCheck(segment, ptr, totalWords), + "Message contained out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + return result; + } + result.addWords(totalWords); + break; + } + case ElementSize::POINTER: { + auto count = ref->listRef.elementCount() * (POINTERS / ELEMENTS); + + KJ_REQUIRE(boundsCheck(segment, ptr, count * WORDS_PER_POINTER), + "Message contained out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + return result; + } + + result.addWords(count * WORDS_PER_POINTER); + + for (auto i: kj::zeroTo(count)) { + result += totalSize(segment, reinterpret_cast(ptr) + i, + nestingLimit); + } + break; + } + case ElementSize::INLINE_COMPOSITE: { + auto wordCount = ref->listRef.inlineCompositeWordCount(); + KJ_REQUIRE(boundsCheck(segment, ptr, wordCount + POINTER_SIZE_IN_WORDS), + "Message contained out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + return result; + } + + const WirePointer* elementTag = reinterpret_cast(ptr); + auto count = elementTag->inlineCompositeListElementCount(); + + KJ_REQUIRE(elementTag->kind() == WirePointer::STRUCT, + "Don't know how to handle non-STRUCT inline composite.") { + return result; + } + + auto actualSize = elementTag->structRef.wordSize() / ELEMENTS * + upgradeBound(count); + KJ_REQUIRE(actualSize <= wordCount, + "Struct list pointer's elements overran size. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + return result; + } + + // We count the actual size rather than the claimed word count because that's what + // we'll end up with if we make a copy. + result.addWords(actualSize + POINTER_SIZE_IN_WORDS); + + WordCount dataSize = elementTag->structRef.dataSize.get(); + WirePointerCount pointerCount = elementTag->structRef.ptrCount.get(); + + if (pointerCount > ZERO * POINTERS) { + const word* pos = ptr + POINTER_SIZE_IN_WORDS; + for (auto i KJ_UNUSED: kj::zeroTo(count)) { + pos += dataSize; + + for (auto j KJ_UNUSED: kj::zeroTo(pointerCount)) { + result += totalSize(segment, reinterpret_cast(pos), + nestingLimit); + pos += POINTER_SIZE_IN_WORDS; + } + } + } + break; + } + } + break; + } + case WirePointer::FAR: + KJ_FAIL_REQUIRE("Unexpected FAR pointer.") { + break; + } + break; + case WirePointer::OTHER: + if (ref->isCapability()) { + result.capCount++; + } else { + KJ_FAIL_REQUIRE("Unknown pointer type.") { break; } + } + break; + } + + return result; + } + + // ----------------------------------------------------------------- + // Copy from an unchecked message. + + static KJ_ALWAYS_INLINE( + void copyStruct(SegmentBuilder* segment, CapTableBuilder* capTable, + word* dst, const word* src, + StructDataWordCount dataSize, StructPointerCount pointerCount)) { + copyMemory(dst, src, dataSize); + + const WirePointer* srcRefs = reinterpret_cast(src + dataSize); + WirePointer* dstRefs = reinterpret_cast(dst + dataSize); + + for (auto i: kj::zeroTo(pointerCount)) { + SegmentBuilder* subSegment = segment; + WirePointer* dstRef = dstRefs + i; + copyMessage(subSegment, capTable, dstRef, srcRefs + i); + } + } + + static word* copyMessage( + SegmentBuilder*& segment, CapTableBuilder* capTable, + WirePointer*& dst, const WirePointer* src) { + // Not always-inline because it's recursive. + + switch (src->kind()) { + case WirePointer::STRUCT: { + if (src->isNull()) { + zeroMemory(dst); + return nullptr; + } else { + const word* srcPtr = src->target(nullptr); + word* dstPtr = allocate( + dst, segment, capTable, src->structRef.wordSize(), WirePointer::STRUCT, nullptr); + + copyStruct(segment, capTable, dstPtr, srcPtr, src->structRef.dataSize.get(), + src->structRef.ptrCount.get()); + + dst->structRef.set(src->structRef.dataSize.get(), src->structRef.ptrCount.get()); + return dstPtr; + } + } + case WirePointer::LIST: { + switch (src->listRef.elementSize()) { + case ElementSize::VOID: + case ElementSize::BIT: + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: { + auto wordCount = roundBitsUpToWords( + upgradeBound(src->listRef.elementCount()) * + dataBitsPerElement(src->listRef.elementSize())); + const word* srcPtr = src->target(nullptr); + word* dstPtr = allocate(dst, segment, capTable, wordCount, WirePointer::LIST, nullptr); + copyMemory(dstPtr, srcPtr, wordCount); + + dst->listRef.set(src->listRef.elementSize(), src->listRef.elementCount()); + return dstPtr; + } + + case ElementSize::POINTER: { + const WirePointer* srcRefs = reinterpret_cast(src->target(nullptr)); + WirePointer* dstRefs = reinterpret_cast( + allocate(dst, segment, capTable, src->listRef.elementCount() * + (ONE * POINTERS / ELEMENTS) * WORDS_PER_POINTER, + WirePointer::LIST, nullptr)); + + for (auto i: kj::zeroTo(src->listRef.elementCount() * (ONE * POINTERS / ELEMENTS))) { + SegmentBuilder* subSegment = segment; + WirePointer* dstRef = dstRefs + i; + copyMessage(subSegment, capTable, dstRef, srcRefs + i); + } + + dst->listRef.set(ElementSize::POINTER, src->listRef.elementCount()); + return reinterpret_cast(dstRefs); + } + + case ElementSize::INLINE_COMPOSITE: { + const word* srcPtr = src->target(nullptr); + word* dstPtr = allocate(dst, segment, capTable, + assertMaxBits( + src->listRef.inlineCompositeWordCount() + POINTER_SIZE_IN_WORDS, + []() { KJ_FAIL_ASSERT("list too big to fit in a segment"); }), + WirePointer::LIST, nullptr); + + dst->listRef.setInlineComposite(src->listRef.inlineCompositeWordCount()); + + const WirePointer* srcTag = reinterpret_cast(srcPtr); + copyMemory(reinterpret_cast(dstPtr), srcTag); + + const word* srcElement = srcPtr + POINTER_SIZE_IN_WORDS; + word* dstElement = dstPtr + POINTER_SIZE_IN_WORDS; + + KJ_ASSERT(srcTag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE of lists is not yet supported."); + + for (auto i KJ_UNUSED: kj::zeroTo(srcTag->inlineCompositeListElementCount())) { + copyStruct(segment, capTable, dstElement, srcElement, + srcTag->structRef.dataSize.get(), srcTag->structRef.ptrCount.get()); + srcElement += srcTag->structRef.wordSize(); + dstElement += srcTag->structRef.wordSize(); + } + return dstPtr; + } + } + break; + } + case WirePointer::OTHER: + KJ_FAIL_REQUIRE("Unchecked messages cannot contain OTHER pointers (e.g. capabilities)."); + break; + case WirePointer::FAR: + KJ_FAIL_REQUIRE("Unchecked messages cannot contain far pointers."); + break; + } + + return nullptr; + } + + static void transferPointer(SegmentBuilder* dstSegment, WirePointer* dst, + SegmentBuilder* srcSegment, WirePointer* src) { + // Make *dst point to the same object as *src. Both must reside in the same message, but can + // be in different segments. Not always-inline because this is rarely used. + // + // Caller MUST zero out the source pointer after calling this, to make sure no later code + // mistakenly thinks the source location still owns the object. transferPointer() doesn't do + // this zeroing itself because many callers transfer several pointers in a loop then zero out + // the whole section. + + KJ_DASSERT(dst->isNull()); + // We expect the caller to ensure the target is already null so won't leak. + + if (src->isNull()) { + zeroMemory(dst); + } else if (src->isPositional()) { + transferPointer(dstSegment, dst, srcSegment, src, src->target()); + } else { + // Far and other pointers are position-independent, so we can just copy. + copyMemory(dst, src); + } + } + + static void transferPointer(SegmentBuilder* dstSegment, WirePointer* dst, + SegmentBuilder* srcSegment, const WirePointer* srcTag, + word* srcPtr) { + // Like the other overload, but splits src into a tag and a target. Particularly useful for + // OrphanBuilder. + + if (dstSegment == srcSegment) { + // Same segment, so create a direct pointer. + + if (srcTag->kind() == WirePointer::STRUCT && srcTag->structRef.wordSize() == ZERO * WORDS) { + dst->setKindAndTargetForEmptyStruct(); + } else { + dst->setKindAndTarget(srcTag->kind(), srcPtr, dstSegment); + } + + // We can just copy the upper 32 bits. (Use memcpy() to comply with aliasing rules.) + copyMemory(&dst->upper32Bits, &srcTag->upper32Bits); + } else { + // Need to create a far pointer. Try to allocate it in the same segment as the source, so + // that it doesn't need to be a double-far. + + WirePointer* landingPad = + reinterpret_cast(srcSegment->allocate(G(1) * WORDS)); + if (landingPad == nullptr) { + // Darn, need a double-far. + auto allocation = srcSegment->getArena()->allocate(G(2) * WORDS); + SegmentBuilder* farSegment = allocation.segment; + landingPad = reinterpret_cast(allocation.words); + + landingPad[0].setFar(false, srcSegment->getOffsetTo(srcPtr)); + landingPad[0].farRef.segmentId.set(srcSegment->getSegmentId()); + + landingPad[1].setKindWithZeroOffset(srcTag->kind()); + copyMemory(&landingPad[1].upper32Bits, &srcTag->upper32Bits); + + dst->setFar(true, farSegment->getOffsetTo(reinterpret_cast(landingPad))); + dst->farRef.set(farSegment->getSegmentId()); + } else { + // Simple landing pad is just a pointer. + landingPad->setKindAndTarget(srcTag->kind(), srcPtr, srcSegment); + copyMemory(&landingPad->upper32Bits, &srcTag->upper32Bits); + + dst->setFar(false, srcSegment->getOffsetTo(reinterpret_cast(landingPad))); + dst->farRef.set(srcSegment->getSegmentId()); + } + } + } + + // ----------------------------------------------------------------- + + static KJ_ALWAYS_INLINE(StructBuilder initStructPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, StructSize size, + BuilderArena* orphanArena = nullptr)) { + // Allocate space for the new struct. Newly-allocated space is automatically zeroed. + word* ptr = allocate(ref, segment, capTable, size.total(), WirePointer::STRUCT, orphanArena); + + // Initialize the pointer. + ref->structRef.set(size); + + // Build the StructBuilder. + return StructBuilder(segment, capTable, ptr, reinterpret_cast(ptr + size.data), + size.data * BITS_PER_WORD, size.pointers); + } + + static KJ_ALWAYS_INLINE(StructBuilder getWritableStructPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, StructSize size, + const word* defaultValue)) { + return getWritableStructPointer(ref, ref->target(), segment, capTable, size, defaultValue); + } + + static KJ_ALWAYS_INLINE(StructBuilder getWritableStructPointer( + WirePointer* ref, word* refTarget, SegmentBuilder* segment, CapTableBuilder* capTable, + StructSize size, const word* defaultValue, BuilderArena* orphanArena = nullptr)) { + if (ref->isNull()) { + useDefault: + if (defaultValue == nullptr || + reinterpret_cast(defaultValue)->isNull()) { + return initStructPointer(ref, segment, capTable, size, orphanArena); + } + refTarget = copyMessage(segment, capTable, ref, + reinterpret_cast(defaultValue)); + defaultValue = nullptr; // If the default value is itself invalid, don't use it again. + } + + WirePointer* oldRef = ref; + SegmentBuilder* oldSegment = segment; + word* oldPtr = followFars(oldRef, refTarget, oldSegment); + + KJ_REQUIRE(oldRef->kind() == WirePointer::STRUCT, + "Schema mismatch: Message contains non-struct pointer where struct pointer was expected.") { + goto useDefault; + } + + auto oldDataSize = oldRef->structRef.dataSize.get(); + auto oldPointerCount = oldRef->structRef.ptrCount.get(); + WirePointer* oldPointerSection = + reinterpret_cast(oldPtr + oldDataSize); + + if (oldDataSize < size.data || oldPointerCount < size.pointers) { + // The space allocated for this struct is too small. Unlike with readers, we can't just + // run with it and do bounds checks at access time, because how would we handle writes? + // Instead, we have to copy the struct to a new space now. + + auto newDataSize = kj::max(oldDataSize, size.data); + auto newPointerCount = kj::max(oldPointerCount, size.pointers); + auto totalSize = newDataSize + newPointerCount * WORDS_PER_POINTER; + + // Don't let allocate() zero out the object just yet. + zeroPointerAndFars(segment, ref); + + word* ptr = allocate(ref, segment, capTable, totalSize, WirePointer::STRUCT, orphanArena); + ref->structRef.set(newDataSize, newPointerCount); + + // Copy data section. + copyMemory(ptr, oldPtr, oldDataSize); + + // Copy pointer section. + WirePointer* newPointerSection = reinterpret_cast(ptr + newDataSize); + for (auto i: kj::zeroTo(oldPointerCount)) { + transferPointer(segment, newPointerSection + i, oldSegment, oldPointerSection + i); + } + + // Zero out old location. This has two purposes: + // 1) We don't want to leak the original contents of the struct when the message is written + // out as it may contain secrets that the caller intends to remove from the new copy. + // 2) Zeros will be deflated by packing, making this dead memory almost-free if it ever + // hits the wire. + zeroMemory(oldPtr, oldDataSize + oldPointerCount * WORDS_PER_POINTER); + + return StructBuilder(segment, capTable, ptr, newPointerSection, newDataSize * BITS_PER_WORD, + newPointerCount); + } else { + return StructBuilder(oldSegment, capTable, oldPtr, oldPointerSection, + oldDataSize * BITS_PER_WORD, oldPointerCount); + } + } + + static KJ_ALWAYS_INLINE(ListBuilder initListPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, + ElementCount elementCount, ElementSize elementSize, BuilderArena* orphanArena = nullptr)) { + KJ_DREQUIRE(elementSize != ElementSize::INLINE_COMPOSITE, + "Should have called initStructListPointer() instead."); + + auto checkedElementCount = assertMaxBits(elementCount, + []() { KJ_FAIL_REQUIRE("tried to allocate list with too many elements"); }); + + auto dataSize = dataBitsPerElement(elementSize) * ELEMENTS; + auto pointerCount = pointersPerElement(elementSize) * ELEMENTS; + auto step = bitsPerElementIncludingPointers(elementSize); + KJ_DASSERT(step * ELEMENTS == (dataSize + pointerCount * BITS_PER_POINTER)); + + // Calculate size of the list. + auto wordCount = roundBitsUpToWords(upgradeBound(checkedElementCount) * step); + + // Allocate the list. + word* ptr = allocate(ref, segment, capTable, wordCount, WirePointer::LIST, orphanArena); + + // Initialize the pointer. + ref->listRef.set(elementSize, checkedElementCount); + + // Build the ListBuilder. + return ListBuilder(segment, capTable, ptr, step, checkedElementCount, + dataSize, pointerCount, elementSize); + } + + static KJ_ALWAYS_INLINE(ListBuilder initStructListPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, + ElementCount elementCount, StructSize elementSize, BuilderArena* orphanArena = nullptr)) { + auto checkedElementCount = assertMaxBits(elementCount, + []() { KJ_FAIL_REQUIRE("tried to allocate list with too many elements"); }); + + WordsPerElementN<17> wordsPerElement = elementSize.total() / ELEMENTS; + + // Allocate the list, prefixed by a single WirePointer. + auto wordCount = assertMax() - 1>( + upgradeBound(checkedElementCount) * wordsPerElement, + []() { KJ_FAIL_REQUIRE("total size of struct list is larger than max segment size"); }); + word* ptr = allocate(ref, segment, capTable, POINTER_SIZE_IN_WORDS + wordCount, + WirePointer::LIST, orphanArena); + + // Initialize the pointer. + // INLINE_COMPOSITE lists replace the element count with the word count. + ref->listRef.setInlineComposite(wordCount); + + // Initialize the list tag. + reinterpret_cast(ptr)->setKindAndInlineCompositeListElementCount( + WirePointer::STRUCT, checkedElementCount); + reinterpret_cast(ptr)->structRef.set(elementSize); + ptr += POINTER_SIZE_IN_WORDS; + + // Build the ListBuilder. + return ListBuilder(segment, capTable, ptr, wordsPerElement * BITS_PER_WORD, checkedElementCount, + elementSize.data * BITS_PER_WORD, elementSize.pointers, + ElementSize::INLINE_COMPOSITE); + } + + static KJ_ALWAYS_INLINE(ListBuilder getWritableListPointer( + WirePointer* origRef, SegmentBuilder* origSegment, CapTableBuilder* capTable, + ElementSize elementSize, const word* defaultValue)) { + return getWritableListPointer(origRef, origRef->target(), origSegment, capTable, elementSize, + defaultValue); + } + + static KJ_ALWAYS_INLINE(ListBuilder getWritableListPointer( + WirePointer* origRef, word* origRefTarget, + SegmentBuilder* origSegment, CapTableBuilder* capTable, ElementSize elementSize, + const word* defaultValue, BuilderArena* orphanArena = nullptr)) { + KJ_DREQUIRE(elementSize != ElementSize::INLINE_COMPOSITE, + "Use getWritableStructListPointer() for struct lists."); + + if (origRef->isNull()) { + useDefault: + if (defaultValue == nullptr || + reinterpret_cast(defaultValue)->isNull()) { + return ListBuilder(elementSize); + } + origRefTarget = copyMessage( + origSegment, capTable, origRef, reinterpret_cast(defaultValue)); + defaultValue = nullptr; // If the default value is itself invalid, don't use it again. + } + + // We must verify that the pointer has the right size. Unlike in + // getWritableStructListPointer(), we never need to "upgrade" the data, because this + // method is called only for non-struct lists, and there is no allowed upgrade path *to* + // a non-struct list, only *from* them. + + WirePointer* ref = origRef; + SegmentBuilder* segment = origSegment; + word* ptr = followFars(ref, origRefTarget, segment); + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Called getWritableListPointer() but existing pointer is not a list.") { + goto useDefault; + } + + ElementSize oldSize = ref->listRef.elementSize(); + + if (oldSize == ElementSize::INLINE_COMPOSITE) { + // The existing element size is INLINE_COMPOSITE, though we expected a list of primitives. + // The existing data must have been written with a newer version of the protocol. We + // therefore never need to upgrade the data in this case, but we do need to validate that it + // is a valid upgrade from what we expected. + + // Read the tag to get the actual element count. + WirePointer* tag = reinterpret_cast(ptr); + KJ_REQUIRE(tag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE list with non-STRUCT elements not supported."); + ptr += POINTER_SIZE_IN_WORDS; + + auto dataSize = tag->structRef.dataSize.get(); + auto pointerCount = tag->structRef.ptrCount.get(); + + switch (elementSize) { + case ElementSize::VOID: + // Anything is a valid upgrade from Void. + break; + + case ElementSize::BIT: + KJ_FAIL_REQUIRE( + "Schema mismatch: Found struct list where bit list was expected; upgrading boolean " + "lists to structs is no longer supported.") { + goto useDefault; + } + break; + + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: + KJ_REQUIRE(dataSize >= ONE * WORDS, + "Schema mismatch: Existing list value is incompatible with expected type.") { + goto useDefault; + } + break; + + case ElementSize::POINTER: + KJ_REQUIRE(pointerCount >= ONE * POINTERS, + "Schema mismatch: Existing list value is incompatible with expected type.") { + goto useDefault; + } + // Adjust the pointer to point at the reference segment. + ptr += dataSize; + break; + + case ElementSize::INLINE_COMPOSITE: + KJ_UNREACHABLE; + } + + // OK, looks valid. + + return ListBuilder(segment, capTable, ptr, + tag->structRef.wordSize() * BITS_PER_WORD / ELEMENTS, + tag->inlineCompositeListElementCount(), + dataSize * BITS_PER_WORD, pointerCount, ElementSize::INLINE_COMPOSITE); + } else { + auto dataSize = dataBitsPerElement(oldSize) * ELEMENTS; + auto pointerCount = pointersPerElement(oldSize) * ELEMENTS; + + if (elementSize == ElementSize::BIT) { + KJ_REQUIRE(oldSize == ElementSize::BIT, + "Schema mismatch: Found non-bit list where bit list was expected.") { + goto useDefault; + } + } else { + KJ_REQUIRE(oldSize != ElementSize::BIT, + "Schema mismatch: Found bit list where non-bit list was expected.") { + goto useDefault; + } + KJ_REQUIRE(dataSize >= dataBitsPerElement(elementSize) * ELEMENTS, + "Schema mismatch: Existing list value is incompatible with expected type.") { + goto useDefault; + } + KJ_REQUIRE(pointerCount >= pointersPerElement(elementSize) * ELEMENTS, + "Schema mismatch: Existing list value is incompatible with expected type.") { + goto useDefault; + } + } + + auto step = (dataSize + pointerCount * BITS_PER_POINTER) / ELEMENTS; + return ListBuilder(segment, capTable, ptr, step, ref->listRef.elementCount(), + dataSize, pointerCount, oldSize); + } + } + + static KJ_ALWAYS_INLINE(ListBuilder getWritableListPointerAnySize( + WirePointer* origRef, SegmentBuilder* origSegment, CapTableBuilder* capTable, + const word* defaultValue)) { + return getWritableListPointerAnySize(origRef, origRef->target(), origSegment, + capTable, defaultValue); + } + + static KJ_ALWAYS_INLINE(ListBuilder getWritableListPointerAnySize( + WirePointer* origRef, word* origRefTarget, + SegmentBuilder* origSegment, CapTableBuilder* capTable, + const word* defaultValue, BuilderArena* orphanArena = nullptr)) { + if (origRef->isNull()) { + useDefault: + if (defaultValue == nullptr || + reinterpret_cast(defaultValue)->isNull()) { + return ListBuilder(ElementSize::VOID); + } + origRefTarget = copyMessage( + origSegment, capTable, origRef, reinterpret_cast(defaultValue)); + defaultValue = nullptr; // If the default value is itself invalid, don't use it again. + } + + WirePointer* ref = origRef; + SegmentBuilder* segment = origSegment; + word* ptr = followFars(ref, origRefTarget, segment); + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Called getWritableListPointerAnySize() but existing pointer is not a " + "list.") { + goto useDefault; + } + + ElementSize elementSize = ref->listRef.elementSize(); + + if (elementSize == ElementSize::INLINE_COMPOSITE) { + // Read the tag to get the actual element count. + WirePointer* tag = reinterpret_cast(ptr); + KJ_REQUIRE(tag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE list with non-STRUCT elements not supported."); + ptr += POINTER_SIZE_IN_WORDS; + + return ListBuilder(segment, capTable, ptr, + tag->structRef.wordSize() * BITS_PER_WORD / ELEMENTS, + tag->inlineCompositeListElementCount(), + tag->structRef.dataSize.get() * BITS_PER_WORD, + tag->structRef.ptrCount.get(), ElementSize::INLINE_COMPOSITE); + } else { + auto dataSize = dataBitsPerElement(elementSize) * ELEMENTS; + auto pointerCount = pointersPerElement(elementSize) * ELEMENTS; + + auto step = (dataSize + pointerCount * BITS_PER_POINTER) / ELEMENTS; + return ListBuilder(segment, capTable, ptr, step, ref->listRef.elementCount(), + dataSize, pointerCount, elementSize); + } + } + + static KJ_ALWAYS_INLINE(ListBuilder getWritableStructListPointer( + WirePointer* origRef, SegmentBuilder* origSegment, CapTableBuilder* capTable, + StructSize elementSize, const word* defaultValue)) { + return getWritableStructListPointer(origRef, origRef->target(), origSegment, capTable, + elementSize, defaultValue); + } + static KJ_ALWAYS_INLINE(ListBuilder getWritableStructListPointer( + WirePointer* origRef, word* origRefTarget, + SegmentBuilder* origSegment, CapTableBuilder* capTable, + StructSize elementSize, const word* defaultValue, BuilderArena* orphanArena = nullptr)) { + if (origRef->isNull()) { + useDefault: + if (defaultValue == nullptr || + reinterpret_cast(defaultValue)->isNull()) { + return ListBuilder(ElementSize::INLINE_COMPOSITE); + } + origRefTarget = copyMessage( + origSegment, capTable, origRef, reinterpret_cast(defaultValue)); + defaultValue = nullptr; // If the default value is itself invalid, don't use it again. + } + + // We must verify that the pointer has the right size and potentially upgrade it if not. + + WirePointer* oldRef = origRef; + SegmentBuilder* oldSegment = origSegment; + word* oldPtr = followFars(oldRef, origRefTarget, oldSegment); + + KJ_REQUIRE(oldRef->kind() == WirePointer::LIST, + "Schema mismatch: Called getList{Field,Element}() but existing pointer is not a " + "list.") { + goto useDefault; + } + + ElementSize oldSize = oldRef->listRef.elementSize(); + + if (oldSize == ElementSize::INLINE_COMPOSITE) { + // Existing list is INLINE_COMPOSITE, but we need to verify that the sizes match. + + WirePointer* oldTag = reinterpret_cast(oldPtr); + oldPtr += POINTER_SIZE_IN_WORDS; + KJ_REQUIRE(oldTag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE list with non-STRUCT elements not supported.") { + goto useDefault; + } + + auto oldDataSize = oldTag->structRef.dataSize.get(); + auto oldPointerCount = oldTag->structRef.ptrCount.get(); + auto oldStep = (oldDataSize + oldPointerCount * WORDS_PER_POINTER) / ELEMENTS; + + auto elementCount = oldTag->inlineCompositeListElementCount(); + + if (oldDataSize >= elementSize.data && oldPointerCount >= elementSize.pointers) { + // Old size is at least as large as we need. Ship it. + return ListBuilder(oldSegment, capTable, oldPtr, oldStep * BITS_PER_WORD, elementCount, + oldDataSize * BITS_PER_WORD, oldPointerCount, + ElementSize::INLINE_COMPOSITE); + } + + // The structs in this list are smaller than expected, probably written using an older + // version of the protocol. We need to make a copy and expand them. + + auto newDataSize = kj::max(oldDataSize, elementSize.data); + auto newPointerCount = kj::max(oldPointerCount, elementSize.pointers); + auto newStep = (newDataSize + newPointerCount * WORDS_PER_POINTER) / ELEMENTS; + + auto totalSize = assertMax() - 1>( + newStep * upgradeBound(elementCount), + []() { KJ_FAIL_REQUIRE("total size of struct list is larger than max segment size"); }); + + // Don't let allocate() zero out the object just yet. + zeroPointerAndFars(origSegment, origRef); + + word* newPtr = allocate(origRef, origSegment, capTable, totalSize + POINTER_SIZE_IN_WORDS, + WirePointer::LIST, orphanArena); + origRef->listRef.setInlineComposite(totalSize); + + WirePointer* newTag = reinterpret_cast(newPtr); + newTag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, elementCount); + newTag->structRef.set(newDataSize, newPointerCount); + newPtr += POINTER_SIZE_IN_WORDS; + + word* src = oldPtr; + word* dst = newPtr; + for (auto i KJ_UNUSED: kj::zeroTo(elementCount)) { + // Copy data section. + copyMemory(dst, src, oldDataSize); + + // Copy pointer section. + WirePointer* newPointerSection = reinterpret_cast(dst + newDataSize); + WirePointer* oldPointerSection = reinterpret_cast(src + oldDataSize); + for (auto j: kj::zeroTo(oldPointerCount)) { + transferPointer(origSegment, newPointerSection + j, oldSegment, oldPointerSection + j); + } + + dst += newStep * (ONE * ELEMENTS); + src += oldStep * (ONE * ELEMENTS); + } + + auto oldSize = assertMax() - 1>( + oldStep * upgradeBound(elementCount), + []() { KJ_FAIL_ASSERT("old size overflows but new size doesn't?"); }); + + // Zero out old location. See explanation in getWritableStructPointer(). + // Make sure to include the tag word. + zeroMemory(oldPtr - POINTER_SIZE_IN_WORDS, oldSize + POINTER_SIZE_IN_WORDS); + + return ListBuilder(origSegment, capTable, newPtr, newStep * BITS_PER_WORD, elementCount, + newDataSize * BITS_PER_WORD, newPointerCount, + ElementSize::INLINE_COMPOSITE); + } else { + // We're upgrading from a non-struct list. + + auto oldDataSize = dataBitsPerElement(oldSize) * ELEMENTS; + auto oldPointerCount = pointersPerElement(oldSize) * ELEMENTS; + auto oldStep = (oldDataSize + oldPointerCount * BITS_PER_POINTER) / ELEMENTS; + auto elementCount = oldRef->listRef.elementCount(); + + if (oldSize == ElementSize::VOID) { + // Nothing to copy, just allocate a new list. + return initStructListPointer(origRef, origSegment, capTable, elementCount, elementSize); + } else { + // Upgrading to an inline composite list. + + KJ_REQUIRE(oldSize != ElementSize::BIT, + "Schema mismatch: Found bit list where struct list was expected; upgrading boolean " + "lists to structs is no longer supported.") { + goto useDefault; + } + + auto newDataSize = elementSize.data; + auto newPointerCount = elementSize.pointers; + + if (oldSize == ElementSize::POINTER) { + newPointerCount = kj::max(newPointerCount, ONE * POINTERS); + } else { + // Old list contains data elements, so we need at least 1 word of data. + newDataSize = kj::max(newDataSize, ONE * WORDS); + } + + auto newStep = (newDataSize + newPointerCount * WORDS_PER_POINTER) / ELEMENTS; + auto totalWords = assertMax() - 1>( + newStep * upgradeBound(elementCount), + []() {KJ_FAIL_REQUIRE("total size of struct list is larger than max segment size");}); + + // Don't let allocate() zero out the object just yet. + zeroPointerAndFars(origSegment, origRef); + + word* newPtr = allocate(origRef, origSegment, capTable, totalWords + POINTER_SIZE_IN_WORDS, + WirePointer::LIST, orphanArena); + origRef->listRef.setInlineComposite(totalWords); + + WirePointer* tag = reinterpret_cast(newPtr); + tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, elementCount); + tag->structRef.set(newDataSize, newPointerCount); + newPtr += POINTER_SIZE_IN_WORDS; + + if (oldSize == ElementSize::POINTER) { + WirePointer* dst = reinterpret_cast(newPtr + newDataSize); + WirePointer* src = reinterpret_cast(oldPtr); + for (auto i KJ_UNUSED: kj::zeroTo(elementCount)) { + transferPointer(origSegment, dst, oldSegment, src); + dst += newStep / WORDS_PER_POINTER * (ONE * ELEMENTS); + ++src; + } + } else { + byte* dst = reinterpret_cast(newPtr); + byte* src = reinterpret_cast(oldPtr); + auto newByteStep = newStep * (ONE * ELEMENTS) * BYTES_PER_WORD; + auto oldByteStep = oldDataSize / BITS_PER_BYTE; + for (auto i KJ_UNUSED: kj::zeroTo(elementCount)) { + copyMemory(dst, src, oldByteStep); + src += oldByteStep; + dst += newByteStep; + } + } + + auto oldSize = assertMax() - 1>( + roundBitsUpToWords(oldStep * upgradeBound(elementCount)), + []() { KJ_FAIL_ASSERT("old size overflows but new size doesn't?"); }); + + // Zero out old location. See explanation in getWritableStructPointer(). + zeroMemory(oldPtr, oldSize); + + return ListBuilder(origSegment, capTable, newPtr, newStep * BITS_PER_WORD, elementCount, + newDataSize * BITS_PER_WORD, newPointerCount, + ElementSize::INLINE_COMPOSITE); + } + } + } + + static KJ_ALWAYS_INLINE(SegmentAnd initTextPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, TextSize size, + BuilderArena* orphanArena = nullptr)) { + // The byte list must include a NUL terminator. + auto byteSize = size + ONE * BYTES; + + // Allocate the space. + word* ptr = allocate( + ref, segment, capTable, roundBytesUpToWords(byteSize), WirePointer::LIST, orphanArena); + + // Initialize the pointer. + ref->listRef.set(ElementSize::BYTE, byteSize * (ONE * ELEMENTS / BYTES)); + + // Build the Text::Builder. Note that since allocate()ed memory is pre-zero'd, we don't need + // to initialize the NUL terminator. + return { segment, Text::Builder(reinterpret_cast(ptr), unbound(size / BYTES)) }; + } + + static KJ_ALWAYS_INLINE(SegmentAnd setTextPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, Text::Reader value, + BuilderArena* orphanArena = nullptr)) { + TextSize size = assertMax(bounded(value.size()), + []() { KJ_FAIL_REQUIRE("text blob too big"); }) * BYTES; + + auto allocation = initTextPointer(ref, segment, capTable, size, orphanArena); + copyMemory(allocation.value.begin(), value); + return allocation; + } + + static KJ_ALWAYS_INLINE(Text::Builder getWritableTextPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, + const void* defaultValue, TextSize defaultSize)) { + return getWritableTextPointer(ref, ref->target(), segment,capTable, defaultValue, defaultSize); + } + + static KJ_ALWAYS_INLINE(Text::Builder getWritableTextPointer( + WirePointer* ref, word* refTarget, SegmentBuilder* segment, CapTableBuilder* capTable, + const void* defaultValue, TextSize defaultSize)) { + if (ref->isNull()) { + useDefault: + if (defaultSize == ZERO * BYTES) { + return nullptr; + } else { + Text::Builder builder = initTextPointer(ref, segment, capTable, defaultSize).value; + copyMemory(builder.asBytes().begin(), reinterpret_cast(defaultValue), + defaultSize); + return builder; + } + } else { + word* ptr = followFars(ref, refTarget, segment); + byte* bptr = reinterpret_cast(ptr); + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Called getText{Field,Element}() but existing pointer is not a list.") { + goto useDefault; + } + KJ_REQUIRE(ref->listRef.elementSize() == ElementSize::BYTE, + "Schema mismatch: Called getText{Field,Element}() but existing list pointer is not " + "byte-sized.") { + goto useDefault; + } + + auto maybeSize = trySubtract(ref->listRef.elementCount() * (ONE * BYTES / ELEMENTS), + ONE * BYTES); + KJ_IF_MAYBE(size, maybeSize) { + KJ_REQUIRE(*(bptr + *size) == '\0', "Text blob missing NUL terminator.") { + goto useDefault; + } + + return Text::Builder(reinterpret_cast(bptr), unbound(*size / BYTES)); + } else { + KJ_FAIL_REQUIRE("zero-size blob can't be text (need NUL terminator)") { + goto useDefault; + }; + } + } + } + + static KJ_ALWAYS_INLINE(SegmentAnd initDataPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, BlobSize size, + BuilderArena* orphanArena = nullptr)) { + // Allocate the space. + word* ptr = allocate(ref, segment, capTable, roundBytesUpToWords(size), + WirePointer::LIST, orphanArena); + + // Initialize the pointer. + ref->listRef.set(ElementSize::BYTE, size * (ONE * ELEMENTS / BYTES)); + + // Build the Data::Builder. + return { segment, Data::Builder(reinterpret_cast(ptr), unbound(size / BYTES)) }; + } + + static KJ_ALWAYS_INLINE(SegmentAnd setDataPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, Data::Reader value, + BuilderArena* orphanArena = nullptr)) { + BlobSize size = assertMaxBits(bounded(value.size()), + []() { KJ_FAIL_REQUIRE("text blob too big"); }) * BYTES; + + auto allocation = initDataPointer(ref, segment, capTable, size, orphanArena); + copyMemory(allocation.value.begin(), value); + return allocation; + } + + static KJ_ALWAYS_INLINE(Data::Builder getWritableDataPointer( + WirePointer* ref, SegmentBuilder* segment, CapTableBuilder* capTable, + const void* defaultValue, BlobSize defaultSize)) { + return getWritableDataPointer(ref, ref->target(), segment, capTable, defaultValue, defaultSize); + } + + static KJ_ALWAYS_INLINE(Data::Builder getWritableDataPointer( + WirePointer* ref, word* refTarget, SegmentBuilder* segment, CapTableBuilder* capTable, + const void* defaultValue, BlobSize defaultSize)) { + if (ref->isNull()) { + useDefault: + if (defaultSize == ZERO * BYTES) { + return nullptr; + } else { + Data::Builder builder = initDataPointer(ref, segment, capTable, defaultSize).value; + copyMemory(builder.begin(), reinterpret_cast(defaultValue), defaultSize); + return builder; + } + } else { + word* ptr = followFars(ref, refTarget, segment); + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Called getData{Field,Element}() but existing pointer is not a list.") { + goto useDefault; + } + KJ_REQUIRE(ref->listRef.elementSize() == ElementSize::BYTE, + "Schema mismatch: Called getData{Field,Element}() but existing list pointer is not " + "byte-sized.") { + goto useDefault; + } + + return Data::Builder(reinterpret_cast(ptr), + unbound(ref->listRef.elementCount() / ELEMENTS)); + } + } + + static SegmentAnd setStructPointer( + SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* ref, StructReader value, + BuilderArena* orphanArena = nullptr, bool canonical = false) { + auto dataSize = roundBitsUpToBytes(value.dataSize); + auto ptrCount = value.pointerCount; + + if (canonical) { + // StructReaders should not have bitwidths other than 1, but let's be safe + KJ_REQUIRE((value.dataSize == ONE * BITS) + || (value.dataSize % BITS_PER_BYTE == ZERO * BITS)); + + if (value.dataSize == ONE * BITS) { + // Handle the truncation case where it's a false in a 1-bit struct + if (!value.getDataField(ZERO * ELEMENTS)) { + dataSize = ZERO * BYTES; + } + } else { + // Truncate the data section + auto data = value.getDataSectionAsBlob(); + auto end = data.end(); + while (end > data.begin() && end[-1] == 0) --end; + dataSize = intervalLength(data.begin(), end, MAX_STUCT_DATA_WORDS * BYTES_PER_WORD); + } + + // Truncate pointer section + const WirePointer* ptr = value.pointers + ptrCount; + while (ptr > value.pointers && ptr[-1].isNull()) --ptr; + ptrCount = intervalLength(value.pointers, ptr, MAX_STRUCT_POINTER_COUNT); + } + + auto dataWords = roundBytesUpToWords(dataSize); + + auto totalSize = dataWords + ptrCount * WORDS_PER_POINTER; + + word* ptr = allocate(ref, segment, capTable, totalSize, WirePointer::STRUCT, orphanArena); + ref->structRef.set(dataWords, ptrCount); + + if (value.dataSize == ONE * BITS) { + // Data size could be made 0 by truncation + if (dataSize != ZERO * BYTES) { + *reinterpret_cast(ptr) = value.getDataField(ZERO * ELEMENTS); + } + } else { + copyMemory(reinterpret_cast(ptr), + reinterpret_cast(value.data), + dataSize); + } + + WirePointer* pointerSection = reinterpret_cast(ptr + dataWords); + for (auto i: kj::zeroTo(ptrCount)) { + copyPointer(segment, capTable, pointerSection + i, + value.segment, value.capTable, value.pointers + i, + value.nestingLimit, nullptr, canonical); + } + + return { segment, ptr }; + } + +#if !CAPNP_LITE + static void setCapabilityPointer( + SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* ref, + kj::Own&& cap) { + if (!ref->isNull()) { + zeroObject(segment, capTable, ref); + } + if (cap->isNull()) { + zeroMemory(ref); + } else { + ref->setCap(capTable->injectCap(kj::mv(cap))); + } + } +#endif // !CAPNP_LITE + + static SegmentAnd setListPointer( + SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* ref, ListReader value, + BuilderArena* orphanArena = nullptr, bool canonical = false) { + auto totalSize = assertMax() - 1>( + roundBitsUpToWords(upgradeBound(value.elementCount) * value.step), + []() { KJ_FAIL_ASSERT("encountered impossibly long struct list ListReader"); }); + + if (value.elementSize != ElementSize::INLINE_COMPOSITE) { + // List of non-structs. + word* ptr = allocate(ref, segment, capTable, totalSize, WirePointer::LIST, orphanArena); + + if (value.elementSize == ElementSize::POINTER) { + // List of pointers. + ref->listRef.set(ElementSize::POINTER, value.elementCount); + for (auto i: kj::zeroTo(value.elementCount * (ONE * POINTERS / ELEMENTS))) { + copyPointer(segment, capTable, reinterpret_cast(ptr) + i, + value.segment, value.capTable, + reinterpret_cast(value.ptr) + i, + value.nestingLimit, nullptr, canonical); + } + } else { + // List of data. + ref->listRef.set(value.elementSize, value.elementCount); + + auto wholeByteSize = + assertMax(MAX_SEGMENT_WORDS * BYTES_PER_WORD, + upgradeBound(value.elementCount) * value.step / BITS_PER_BYTE, + []() { KJ_FAIL_ASSERT("encountered impossibly long data ListReader"); }); + copyMemory(reinterpret_cast(ptr), value.ptr, wholeByteSize); + auto leftoverBits = + (upgradeBound(value.elementCount) * value.step) % BITS_PER_BYTE; + if (leftoverBits > ZERO * BITS) { + // We need to copy a partial byte. + uint8_t mask = (1 << unbound(leftoverBits / BITS)) - 1; + *((reinterpret_cast(ptr)) + wholeByteSize) = mask & *(value.ptr + wholeByteSize); + } + } + + return { segment, ptr }; + } else { + // List of structs. + StructDataWordCount declDataSize = value.structDataSize / BITS_PER_WORD; + StructPointerCount declPointerCount = value.structPointerCount; + + StructDataWordCount dataSize = ZERO * WORDS; + StructPointerCount ptrCount = ZERO * POINTERS; + + if (canonical) { + for (auto i: kj::zeroTo(value.elementCount)) { + auto element = value.getStructElement(i); + + // Truncate the data section + auto data = element.getDataSectionAsBlob(); + auto end = data.end(); + while (end > data.begin() && end[-1] == 0) --end; + dataSize = kj::max(dataSize, roundBytesUpToWords( + intervalLength(data.begin(), end, MAX_STUCT_DATA_WORDS * BYTES_PER_WORD))); + + // Truncate pointer section + const WirePointer* ptr = element.pointers + element.pointerCount; + while (ptr > element.pointers && ptr[-1].isNull()) --ptr; + ptrCount = kj::max(ptrCount, + intervalLength(element.pointers, ptr, MAX_STRUCT_POINTER_COUNT)); + } + auto newTotalSize = (dataSize + upgradeBound(ptrCount) * WORDS_PER_POINTER) + / ELEMENTS * value.elementCount; + KJ_ASSERT(newTotalSize <= totalSize); // we've only removed data! + totalSize = assumeMax() - 1>(newTotalSize); + } else { + dataSize = declDataSize; + ptrCount = declPointerCount; + } + + KJ_DASSERT(value.structDataSize % BITS_PER_WORD == ZERO * BITS); + word* ptr = allocate(ref, segment, capTable, totalSize + POINTER_SIZE_IN_WORDS, + WirePointer::LIST, orphanArena); + ref->listRef.setInlineComposite(totalSize); + + WirePointer* tag = reinterpret_cast(ptr); + tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, value.elementCount); + tag->structRef.set(dataSize, ptrCount); + word* dst = ptr + POINTER_SIZE_IN_WORDS; + + const word* src = reinterpret_cast(value.ptr); + for (auto i KJ_UNUSED: kj::zeroTo(value.elementCount)) { + copyMemory(dst, src, dataSize); + dst += dataSize; + src += declDataSize; + + for (auto j: kj::zeroTo(ptrCount)) { + copyPointer(segment, capTable, reinterpret_cast(dst) + j, + value.segment, value.capTable, reinterpret_cast(src) + j, + value.nestingLimit, nullptr, canonical); + } + dst += ptrCount * WORDS_PER_POINTER; + src += declPointerCount * WORDS_PER_POINTER; + } + + return { segment, ptr }; + } + } + + static KJ_ALWAYS_INLINE(SegmentAnd copyPointer( + SegmentBuilder* dstSegment, CapTableBuilder* dstCapTable, WirePointer* dst, + SegmentReader* srcSegment, CapTableReader* srcCapTable, const WirePointer* src, + int nestingLimit, BuilderArena* orphanArena = nullptr, + bool canonical = false)) { + return copyPointer(dstSegment, dstCapTable, dst, + srcSegment, srcCapTable, src, src->target(srcSegment), + nestingLimit, orphanArena, canonical); + } + + static SegmentAnd copyPointer( + SegmentBuilder* dstSegment, CapTableBuilder* dstCapTable, WirePointer* dst, + SegmentReader* srcSegment, CapTableReader* srcCapTable, const WirePointer* src, + const word* srcTarget, int nestingLimit, + BuilderArena* orphanArena = nullptr, bool canonical = false) { + // Deep-copy the object pointed to by src into dst. It turns out we can't reuse + // readStructPointer(), etc. because they do type checking whereas here we want to accept any + // valid pointer. + + if (src->isNull()) { + useDefault: + if (!dst->isNull()) { + zeroObject(dstSegment, dstCapTable, dst); + zeroMemory(dst); + } + return { dstSegment, nullptr }; + } + + const word* ptr; + KJ_IF_MAYBE(p, WireHelpers::followFars(src, srcTarget, srcSegment)) { + ptr = p; + } else { + goto useDefault; + } + + switch (src->kind()) { + case WirePointer::STRUCT: + KJ_REQUIRE(nestingLimit > 0, + "Message is too deeply-nested or contains cycles. See capnp::ReaderOptions.") { + goto useDefault; + } + + KJ_REQUIRE(boundsCheck(srcSegment, ptr, src->structRef.wordSize()), + "Message contained out-of-bounds struct pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + return setStructPointer(dstSegment, dstCapTable, dst, + StructReader(srcSegment, srcCapTable, ptr, + reinterpret_cast(ptr + src->structRef.dataSize.get()), + src->structRef.dataSize.get() * BITS_PER_WORD, + src->structRef.ptrCount.get(), + nestingLimit - 1), + orphanArena, canonical); + + case WirePointer::LIST: { + ElementSize elementSize = src->listRef.elementSize(); + + KJ_REQUIRE(nestingLimit > 0, + "Message is too deeply-nested or contains cycles. See capnp::ReaderOptions.") { + goto useDefault; + } + + if (elementSize == ElementSize::INLINE_COMPOSITE) { + auto wordCount = src->listRef.inlineCompositeWordCount(); + const WirePointer* tag = reinterpret_cast(ptr); + + KJ_REQUIRE(boundsCheck(srcSegment, ptr, wordCount + POINTER_SIZE_IN_WORDS), + "Message contains out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + ptr += POINTER_SIZE_IN_WORDS; + + KJ_REQUIRE(tag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE lists of non-STRUCT type are not supported.") { + goto useDefault; + } + + auto elementCount = tag->inlineCompositeListElementCount(); + auto wordsPerElement = tag->structRef.wordSize() / ELEMENTS; + + KJ_REQUIRE(wordsPerElement * upgradeBound(elementCount) <= wordCount, + "INLINE_COMPOSITE list's elements overrun its word count.") { + goto useDefault; + } + + if (wordsPerElement * (ONE * ELEMENTS) == ZERO * WORDS) { + // Watch out for lists of zero-sized structs, which can claim to be arbitrarily large + // without having sent actual data. + KJ_REQUIRE(amplifiedRead(srcSegment, elementCount * (ONE * WORDS / ELEMENTS)), + "Message contains amplified list pointer.") { + goto useDefault; + } + } + + return setListPointer(dstSegment, dstCapTable, dst, + ListReader(srcSegment, srcCapTable, ptr, + elementCount, wordsPerElement * BITS_PER_WORD, + tag->structRef.dataSize.get() * BITS_PER_WORD, + tag->structRef.ptrCount.get(), ElementSize::INLINE_COMPOSITE, + nestingLimit - 1), + orphanArena, canonical); + } else { + auto dataSize = dataBitsPerElement(elementSize) * ELEMENTS; + auto pointerCount = pointersPerElement(elementSize) * ELEMENTS; + auto step = (dataSize + pointerCount * BITS_PER_POINTER) / ELEMENTS; + auto elementCount = src->listRef.elementCount(); + auto wordCount = roundBitsUpToWords(upgradeBound(elementCount) * step); + + KJ_REQUIRE(boundsCheck(srcSegment, ptr, wordCount), + "Message contains out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + if (elementSize == ElementSize::VOID) { + // Watch out for lists of void, which can claim to be arbitrarily large without having + // sent actual data. + KJ_REQUIRE(amplifiedRead(srcSegment, elementCount * (ONE * WORDS / ELEMENTS)), + "Message contains amplified list pointer.") { + goto useDefault; + } + } + + return setListPointer(dstSegment, dstCapTable, dst, + ListReader(srcSegment, srcCapTable, ptr, elementCount, step, dataSize, pointerCount, + elementSize, nestingLimit - 1), + orphanArena, canonical); + } + } + + case WirePointer::FAR: + KJ_FAIL_REQUIRE("Unexpected FAR pointer.") { + goto useDefault; + } + + case WirePointer::OTHER: { + KJ_REQUIRE(src->isCapability(), "Unknown pointer type.") { + goto useDefault; + } + + if (canonical) { + KJ_FAIL_REQUIRE("Cannot create a canonical message with a capability") { + break; + } + } +#if !CAPNP_LITE + KJ_IF_MAYBE(cap, srcCapTable->extractCap(src->capRef.index.get())) { + setCapabilityPointer(dstSegment, dstCapTable, dst, kj::mv(*cap)); + // Return dummy non-null pointer so OrphanBuilder doesn't end up null. + return { dstSegment, reinterpret_cast(1) }; + } else { +#endif // !CAPNP_LITE + KJ_FAIL_REQUIRE("Message contained invalid capability pointer.") { + goto useDefault; + } +#if !CAPNP_LITE + } +#endif // !CAPNP_LITE + } + } + + KJ_UNREACHABLE; + } + + static void adopt(SegmentBuilder* segment, CapTableBuilder* capTable, + WirePointer* ref, OrphanBuilder&& value) { + KJ_REQUIRE(value.segment == nullptr || value.segment->getArena() == segment->getArena(), + "Adopted object must live in the same message."); + + if (!ref->isNull()) { + zeroObject(segment, capTable, ref); + } + + if (value == nullptr) { + // Set null. + zeroMemory(ref); + } else if (value.tagAsPtr()->isPositional()) { + WireHelpers::transferPointer(segment, ref, value.segment, value.tagAsPtr(), value.location); + } else { + // FAR and OTHER pointers are position-independent, so we can just copy. + copyMemory(ref, value.tagAsPtr()); + } + + // Take ownership away from the OrphanBuilder. + zeroMemory(value.tagAsPtr()); + value.location = nullptr; + value.segment = nullptr; + } + + static OrphanBuilder disown(SegmentBuilder* segment, CapTableBuilder* capTable, + WirePointer* ref) { + word* location; + + if (ref->isNull()) { + location = nullptr; + } else if (ref->kind() == WirePointer::OTHER) { + KJ_REQUIRE(ref->isCapability(), "Unknown pointer type.") { break; } + location = reinterpret_cast(1); // dummy so that it is non-null + } else { + WirePointer* refCopy = ref; + location = followFarsNoWritableCheck(refCopy, ref->target(), segment); + } + + OrphanBuilder result(ref, segment, capTable, location); + + if (!ref->isNull() && ref->isPositional()) { + result.tagAsPtr()->setKindForOrphan(ref->kind()); + } + + // Zero out the pointer that was disowned. + zeroMemory(ref); + + return result; + } + + // ----------------------------------------------------------------- + + static KJ_ALWAYS_INLINE(StructReader readStructPointer( + SegmentReader* segment, CapTableReader* capTable, + const WirePointer* ref, const word* defaultValue, + int nestingLimit)) { + return readStructPointer(segment, capTable, ref, ref->target(segment), + defaultValue, nestingLimit); + } + + static KJ_ALWAYS_INLINE(StructReader readStructPointer( + SegmentReader* segment, CapTableReader* capTable, + const WirePointer* ref, const word* refTarget, + const word* defaultValue, int nestingLimit)) { + if (ref->isNull()) { + useDefault: + if (defaultValue == nullptr || + reinterpret_cast(defaultValue)->isNull()) { + return StructReader(); + } + segment = nullptr; + ref = reinterpret_cast(defaultValue); + refTarget = ref->target(segment); + defaultValue = nullptr; // If the default value is itself invalid, don't use it again. + } + + KJ_REQUIRE(nestingLimit > 0, + "Message is too deeply-nested or contains cycles. See capnp::ReaderOptions.") { + goto useDefault; + } + + const word* ptr; + KJ_IF_MAYBE(p, followFars(ref, refTarget, segment)) { + ptr = p; + } else { + goto useDefault; + } + + KJ_REQUIRE(ref->kind() == WirePointer::STRUCT, + "Schema mismatch: Message contains non-struct pointer where struct pointer" + "was expected.") { + goto useDefault; + } + + KJ_REQUIRE(boundsCheck(segment, ptr, ref->structRef.wordSize()), + "Message contained out-of-bounds struct pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + return StructReader( + segment, capTable, + ptr, reinterpret_cast(ptr + ref->structRef.dataSize.get()), + ref->structRef.dataSize.get() * BITS_PER_WORD, + ref->structRef.ptrCount.get(), + nestingLimit - 1); + } + +#if !CAPNP_LITE + static KJ_ALWAYS_INLINE(kj::Own readCapabilityPointer( + SegmentReader* segment, CapTableReader* capTable, + const WirePointer* ref, int nestingLimit)) { + kj::Maybe> maybeCap; + + auto brokenCapFactory = readGlobalBrokenCapFactoryForLayoutCpp(); + + KJ_REQUIRE(brokenCapFactory != nullptr, + "Trying to read capabilities without ever having created a capability context. " + "To read capabilities from a message, you must imbue it with CapReaderContext, or " + "use the Cap'n Proto RPC system."); + + if (ref->isNull()) { + return brokenCapFactory->newNullCap(); + } else if (!ref->isCapability()) { + KJ_FAIL_REQUIRE( + "Schema mismatch: Message contains non-capability pointer where capability pointer was " + "expected.") { + break; + } + return brokenCapFactory->newBrokenCap( + "Calling capability extracted from a non-capability pointer."); + } else KJ_IF_MAYBE(cap, capTable->extractCap(ref->capRef.index.get())) { + return kj::mv(*cap); + } else { + KJ_FAIL_REQUIRE("Message contains invalid capability pointer.") { + break; + } + return brokenCapFactory->newBrokenCap("Calling invalid capability pointer."); + } + } +#endif // !CAPNP_LITE + + static KJ_ALWAYS_INLINE(ListReader readListPointer( + SegmentReader* segment, CapTableReader* capTable, + const WirePointer* ref, const word* defaultValue, + ElementSize expectedElementSize, int nestingLimit, bool checkElementSize = true)) { + return readListPointer(segment, capTable, ref, ref->target(segment), defaultValue, + expectedElementSize, nestingLimit, checkElementSize); + } + + static KJ_ALWAYS_INLINE(ListReader readListPointer( + SegmentReader* segment, CapTableReader* capTable, + const WirePointer* ref, const word* refTarget, + const word* defaultValue, ElementSize expectedElementSize, int nestingLimit, + bool checkElementSize = true)) { + if (ref->isNull()) { + useDefault: + if (defaultValue == nullptr || + reinterpret_cast(defaultValue)->isNull()) { + return ListReader(expectedElementSize); + } + segment = nullptr; + ref = reinterpret_cast(defaultValue); + refTarget = ref->target(segment); + defaultValue = nullptr; // If the default value is itself invalid, don't use it again. + } + + KJ_REQUIRE(nestingLimit > 0, + "Message is too deeply-nested or contains cycles. See capnp::ReaderOptions.") { + goto useDefault; + } + + const word* ptr; + KJ_IF_MAYBE(p, followFars(ref, refTarget, segment)) { + ptr = p; + } else { + goto useDefault; + } + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Message contains non-list pointer where list pointer was " + "expected.") { + goto useDefault; + } + + ElementSize elementSize = ref->listRef.elementSize(); + if (elementSize == ElementSize::INLINE_COMPOSITE) { + auto wordCount = ref->listRef.inlineCompositeWordCount(); + + // An INLINE_COMPOSITE list points to a tag, which is formatted like a pointer. + const WirePointer* tag = reinterpret_cast(ptr); + + KJ_REQUIRE(boundsCheck(segment, ptr, wordCount + POINTER_SIZE_IN_WORDS), + "Message contains out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + ptr += POINTER_SIZE_IN_WORDS; + + KJ_REQUIRE(tag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE lists of non-STRUCT type are not supported.") { + goto useDefault; + } + + auto size = tag->inlineCompositeListElementCount(); + auto wordsPerElement = tag->structRef.wordSize() / ELEMENTS; + + KJ_REQUIRE(upgradeBound(size) * wordsPerElement <= wordCount, + "INLINE_COMPOSITE list's elements overrun its word count.") { + goto useDefault; + } + + if (wordsPerElement * (ONE * ELEMENTS) == ZERO * WORDS) { + // Watch out for lists of zero-sized structs, which can claim to be arbitrarily large + // without having sent actual data. + KJ_REQUIRE(amplifiedRead(segment, size * (ONE * WORDS / ELEMENTS)), + "Message contains amplified list pointer.") { + goto useDefault; + } + } + + if (checkElementSize) { + // If a struct list was not expected, then presumably a non-struct list was upgraded to a + // struct list. We need to manipulate the pointer to point at the first field of the + // struct. Together with the `step` field, this will allow the struct list to be accessed + // as if it were a primitive list without branching. + + // Check whether the size is compatible. + switch (expectedElementSize) { + case ElementSize::VOID: + break; + + case ElementSize::BIT: + KJ_FAIL_REQUIRE( + "Found struct list where bit list was expected; upgrading boolean lists to structs " + "is no longer supported.") { + goto useDefault; + } + break; + + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: + KJ_REQUIRE(tag->structRef.dataSize.get() > ZERO * WORDS, + "Schema mismatch: Expected a primitive list, but got a list of pointer-only " + "structs.") { + goto useDefault; + } + break; + + case ElementSize::POINTER: + KJ_REQUIRE(tag->structRef.ptrCount.get() > ZERO * POINTERS, + "Schema mismatch: Expected a pointer list, but got a list of data-only " + "structs.") { + goto useDefault; + } + break; + + case ElementSize::INLINE_COMPOSITE: + break; + } + } + + return ListReader( + segment, capTable, ptr, size, wordsPerElement * BITS_PER_WORD, + tag->structRef.dataSize.get() * BITS_PER_WORD, + tag->structRef.ptrCount.get(), ElementSize::INLINE_COMPOSITE, + nestingLimit - 1); + + } else { + // This is a primitive or pointer list, but all such lists can also be interpreted as struct + // lists. We need to compute the data size and pointer count for such structs. + auto dataSize = dataBitsPerElement(ref->listRef.elementSize()) * ELEMENTS; + auto pointerCount = pointersPerElement(ref->listRef.elementSize()) * ELEMENTS; + auto elementCount = ref->listRef.elementCount(); + auto step = (dataSize + pointerCount * BITS_PER_POINTER) / ELEMENTS; + + auto wordCount = roundBitsUpToWords(upgradeBound(elementCount) * step); + KJ_REQUIRE(boundsCheck(segment, ptr, wordCount), + "Message contains out-of-bounds list pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + if (elementSize == ElementSize::VOID) { + // Watch out for lists of void, which can claim to be arbitrarily large without having sent + // actual data. + KJ_REQUIRE(amplifiedRead(segment, elementCount * (ONE * WORDS / ELEMENTS)), + "Message contains amplified list pointer.") { + goto useDefault; + } + } + + if (checkElementSize) { + if (elementSize == ElementSize::BIT && expectedElementSize != ElementSize::BIT) { + KJ_FAIL_REQUIRE( + "Found bit list where struct list was expected; upgrading boolean lists to structs " + "is no longer supported.") { + goto useDefault; + } + } + + // Verify that the elements are at least as large as the expected type. Note that if we + // expected INLINE_COMPOSITE, the expected sizes here will be zero, because bounds checking + // will be performed at field access time. So this check here is for the case where we + // expected a list of some primitive or pointer type. + + BitCount expectedDataBitsPerElement = + dataBitsPerElement(expectedElementSize) * ELEMENTS; + WirePointerCount expectedPointersPerElement = + pointersPerElement(expectedElementSize) * ELEMENTS; + + KJ_REQUIRE(expectedDataBitsPerElement <= dataSize, + "Schema mismatch: Message contained list with incompatible element type.") { + goto useDefault; + } + KJ_REQUIRE(expectedPointersPerElement <= pointerCount, + "Schema mismatch: Message contained list with incompatible element type.") { + goto useDefault; + } + } + + return ListReader(segment, capTable, ptr, elementCount, step, + dataSize, pointerCount, elementSize, nestingLimit - 1); + } + } + + static KJ_ALWAYS_INLINE(Text::Reader readTextPointer( + SegmentReader* segment, const WirePointer* ref, + const void* defaultValue, ByteCount defaultSize)) { + return readTextPointer(segment, ref, ref->target(segment), defaultValue, defaultSize); + } + + static KJ_ALWAYS_INLINE(Text::Reader readTextPointer( + SegmentReader* segment, const WirePointer* ref, const word* refTarget, + const void* defaultValue, ByteCount defaultSize)) { + if (ref->isNull()) { + useDefault: + if (defaultValue == nullptr) defaultValue = ""; + return Text::Reader(reinterpret_cast(defaultValue), + unbound(defaultSize / BYTES)); + } else { + const word* ptr; + KJ_IF_MAYBE(p, followFars(ref, refTarget, segment)) { + ptr = p; + } else { + goto useDefault; + } + + auto size = ref->listRef.elementCount() * (ONE * BYTES / ELEMENTS); + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Message contains non-list pointer where text was expected.") { + goto useDefault; + } + + KJ_REQUIRE(ref->listRef.elementSize() == ElementSize::BYTE, + "Schema mismatch: Message contains list pointer of non-bytes where text was " + "expected.") { + goto useDefault; + } + + KJ_REQUIRE(boundsCheck(segment, ptr, roundBytesUpToWords(size)), + "Message contained out-of-bounds text pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + KJ_REQUIRE(size > ZERO * BYTES, "Message contains text that is not NUL-terminated.") { + goto useDefault; + } + + const char* cptr = reinterpret_cast(ptr); + uint unboundedSize = unbound(size / BYTES) - 1; + + KJ_REQUIRE(cptr[unboundedSize] == '\0', "Message contains text that is not NUL-terminated.") { + goto useDefault; + } + + return Text::Reader(cptr, unboundedSize); + } + } + + static KJ_ALWAYS_INLINE(Data::Reader readDataPointer( + SegmentReader* segment, const WirePointer* ref, + const void* defaultValue, BlobSize defaultSize)) { + return readDataPointer(segment, ref, ref->target(segment), defaultValue, defaultSize); + } + + static KJ_ALWAYS_INLINE(Data::Reader readDataPointer( + SegmentReader* segment, const WirePointer* ref, const word* refTarget, + const void* defaultValue, BlobSize defaultSize)) { + if (ref->isNull()) { + useDefault: + return Data::Reader(reinterpret_cast(defaultValue), + unbound(defaultSize / BYTES)); + } else { + const word* ptr; + KJ_IF_MAYBE(p, followFars(ref, refTarget, segment)) { + ptr = p; + } else { + goto useDefault; + } + + if (KJ_UNLIKELY(ptr == nullptr)) { + // Already reported error. + goto useDefault; + } + + auto size = ref->listRef.elementCount() * (ONE * BYTES / ELEMENTS); + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, + "Schema mismatch: Message contains non-list pointer where data was expected.") { + goto useDefault; + } + + KJ_REQUIRE(ref->listRef.elementSize() == ElementSize::BYTE, + "Schema mismatch: Message contains list pointer of non-bytes where data was " + "expected.") { + goto useDefault; + } + + KJ_REQUIRE(boundsCheck(segment, ptr, roundBytesUpToWords(size)), + "Message contained out-of-bounds data pointer. " + OUT_OF_BOUNDS_ERROR_DETAIL) { + goto useDefault; + } + + return Data::Reader(reinterpret_cast(ptr), unbound(size / BYTES)); + } + } +}; + +// ======================================================================================= +// PointerBuilder + +StructBuilder PointerBuilder::initStruct(StructSize size) { + return WireHelpers::initStructPointer(pointer, segment, capTable, size); +} + +StructBuilder PointerBuilder::getStruct(StructSize size, const word* defaultValue) { + return WireHelpers::getWritableStructPointer(pointer, segment, capTable, size, defaultValue); +} + +ListBuilder PointerBuilder::initList(ElementSize elementSize, ElementCount elementCount) { + return WireHelpers::initListPointer(pointer, segment, capTable, elementCount, elementSize); +} + +ListBuilder PointerBuilder::initStructList(ElementCount elementCount, StructSize elementSize) { + return WireHelpers::initStructListPointer(pointer, segment, capTable, elementCount, elementSize); +} + +ListBuilder PointerBuilder::getList(ElementSize elementSize, const word* defaultValue) { + return WireHelpers::getWritableListPointer(pointer, segment, capTable, elementSize, defaultValue); +} + +ListBuilder PointerBuilder::getStructList(StructSize elementSize, const word* defaultValue) { + return WireHelpers::getWritableStructListPointer( + pointer, segment, capTable, elementSize, defaultValue); +} + +ListBuilder PointerBuilder::getListAnySize(const word* defaultValue) { + return WireHelpers::getWritableListPointerAnySize(pointer, segment, capTable, defaultValue); +} + +template <> +Text::Builder PointerBuilder::initBlob(ByteCount size) { + return WireHelpers::initTextPointer(pointer, segment, capTable, + assertMax(size, ThrowOverflow())).value; +} +template <> +void PointerBuilder::setBlob(Text::Reader value) { + WireHelpers::setTextPointer(pointer, segment, capTable, value); +} +template <> +Text::Builder PointerBuilder::getBlob(const void* defaultValue, ByteCount defaultSize) { + return WireHelpers::getWritableTextPointer(pointer, segment, capTable, defaultValue, + assertMax(defaultSize, ThrowOverflow())); +} + +template <> +Data::Builder PointerBuilder::initBlob(ByteCount size) { + return WireHelpers::initDataPointer(pointer, segment, capTable, + assertMaxBits(size, ThrowOverflow())).value; +} +template <> +void PointerBuilder::setBlob(Data::Reader value) { + WireHelpers::setDataPointer(pointer, segment, capTable, value); +} +template <> +Data::Builder PointerBuilder::getBlob(const void* defaultValue, ByteCount defaultSize) { + return WireHelpers::getWritableDataPointer(pointer, segment, capTable, defaultValue, + assertMaxBits(defaultSize, ThrowOverflow())); +} + +void PointerBuilder::setStruct(const StructReader& value, bool canonical) { + WireHelpers::setStructPointer(segment, capTable, pointer, value, nullptr, canonical); +} + +void PointerBuilder::setList(const ListReader& value, bool canonical) { + WireHelpers::setListPointer(segment, capTable, pointer, value, nullptr, canonical); +} + +#if !CAPNP_LITE +kj::Own PointerBuilder::getCapability() { + return WireHelpers::readCapabilityPointer( + segment, capTable, pointer, kj::maxValue); +} + +void PointerBuilder::setCapability(kj::Own&& cap) { + WireHelpers::setCapabilityPointer(segment, capTable, pointer, kj::mv(cap)); +} +#endif // !CAPNP_LITE + +void PointerBuilder::adopt(OrphanBuilder&& value) { + WireHelpers::adopt(segment, capTable, pointer, kj::mv(value)); +} + +OrphanBuilder PointerBuilder::disown() { + return WireHelpers::disown(segment, capTable, pointer); +} + +void PointerBuilder::clear() { + WireHelpers::zeroObject(segment, capTable, pointer); + WireHelpers::zeroMemory(pointer); +} + +PointerType PointerBuilder::getPointerType() const { + if(pointer->isNull()) { + return PointerType::NULL_; + } else { + WirePointer* ptr = pointer; + SegmentBuilder* sgmt = segment; + WireHelpers::followFars(ptr, ptr->target(), sgmt); + switch(ptr->kind()) { + case WirePointer::FAR: + KJ_FAIL_ASSERT("far pointer not followed?"); + case WirePointer::STRUCT: + return PointerType::STRUCT; + case WirePointer::LIST: + return PointerType::LIST; + case WirePointer::OTHER: + KJ_REQUIRE(ptr->isCapability(), "unknown pointer type"); + return PointerType::CAPABILITY; + } + KJ_UNREACHABLE; + } +} + +void PointerBuilder::transferFrom(PointerBuilder other) { + if (!pointer->isNull()) { + WireHelpers::zeroObject(segment, capTable, pointer); + WireHelpers::zeroMemory(pointer); + } + WireHelpers::transferPointer(segment, pointer, other.segment, other.pointer); + WireHelpers::zeroMemory(other.pointer); +} + +void PointerBuilder::copyFrom(PointerReader other, bool canonical) { + if (other.pointer == nullptr) { + if (!pointer->isNull()) { + WireHelpers::zeroObject(segment, capTable, pointer); + WireHelpers::zeroMemory(pointer); + } + } else { + WireHelpers::copyPointer(segment, capTable, pointer, + other.segment, other.capTable, other.pointer, other.nestingLimit, + nullptr, + canonical); + } +} + +PointerReader PointerBuilder::asReader() const { + return PointerReader(segment, capTable, pointer, kj::maxValue); +} + +BuilderArena* PointerBuilder::getArena() const { + return segment->getArena(); +} + +CapTableBuilder* PointerBuilder::getCapTable() { + return capTable; +} + +PointerBuilder PointerBuilder::imbue(CapTableBuilder* capTable) { + auto result = *this; + result.capTable = capTable; + return result; +} + +// ======================================================================================= +// PointerReader + +PointerReader PointerReader::getRoot(SegmentReader* segment, CapTableReader* capTable, + const word* location, int nestingLimit) { + KJ_REQUIRE(WireHelpers::boundsCheck(segment, location, POINTER_SIZE_IN_WORDS), + "Root location out-of-bounds.") { + location = nullptr; + } + + return PointerReader(segment, capTable, + reinterpret_cast(location), nestingLimit); +} + +StructReader PointerReader::getStruct(const word* defaultValue) const { + const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer; + return WireHelpers::readStructPointer(segment, capTable, ref, defaultValue, nestingLimit); +} + +ListReader PointerReader::getList(ElementSize expectedElementSize, const word* defaultValue) const { + const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer; + return WireHelpers::readListPointer( + segment, capTable, ref, defaultValue, expectedElementSize, nestingLimit); +} + +ListReader PointerReader::getListAnySize(const word* defaultValue) const { + const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer; + return WireHelpers::readListPointer( + segment, capTable, ref, defaultValue, ElementSize::VOID /* dummy */, nestingLimit, false); +} + +template <> +Text::Reader PointerReader::getBlob(const void* defaultValue, ByteCount defaultSize) const { + const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer; + return WireHelpers::readTextPointer(segment, ref, defaultValue, defaultSize); +} + +template <> +Data::Reader PointerReader::getBlob(const void* defaultValue, ByteCount defaultSize) const { + const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer; + return WireHelpers::readDataPointer(segment, ref, defaultValue, + assertMaxBits(defaultSize, ThrowOverflow())); +} + +#if !CAPNP_LITE +kj::Own PointerReader::getCapability() const { + const WirePointer* ref = pointer == nullptr ? &zero.pointer : pointer; + return WireHelpers::readCapabilityPointer(segment, capTable, ref, nestingLimit); +} +#endif // !CAPNP_LITE + +const word* PointerReader::getUnchecked() const { + KJ_REQUIRE(segment == nullptr, "getUncheckedPointer() only allowed on unchecked messages."); + return reinterpret_cast(pointer); +} + +MessageSizeCounts PointerReader::targetSize() const { + return pointer == nullptr ? MessageSizeCounts { ZERO * WORDS, 0 } + : WireHelpers::totalSize(segment, pointer, nestingLimit); +} + +PointerType PointerReader::getPointerType() const { + if(pointer == nullptr || pointer->isNull()) { + return PointerType::NULL_; + } else { + const WirePointer* ptr = pointer; + const word* refTarget = ptr->target(segment); + SegmentReader* sgmt = segment; + if (WireHelpers::followFars(ptr, refTarget, sgmt) == nullptr) return PointerType::NULL_; + switch(ptr->kind()) { + case WirePointer::FAR: + KJ_FAIL_ASSERT("far pointer not followed?") { return PointerType::NULL_; } + case WirePointer::STRUCT: + return PointerType::STRUCT; + case WirePointer::LIST: + return PointerType::LIST; + case WirePointer::OTHER: + KJ_REQUIRE(ptr->isCapability(), "unknown pointer type") { return PointerType::NULL_; } + return PointerType::CAPABILITY; + } + KJ_UNREACHABLE; + } +} + +kj::Maybe PointerReader::getArena() const { + return segment == nullptr ? nullptr : segment->getArena(); +} + +CapTableReader* PointerReader::getCapTable() { + return capTable; +} + +PointerReader PointerReader::imbue(CapTableReader* capTable) const { + auto result = *this; + result.capTable = capTable; + return result; +} + +bool PointerReader::isCanonical(const word **readHead) { + if (!this->pointer) { + // The pointer is null, so we are canonical and do not read + return true; + } + + if (!this->pointer->isPositional()) { + // The pointer is a FAR or OTHER pointer, and is non-canonical + return false; + } + + switch (this->getPointerType()) { + case PointerType::NULL_: + // The pointer is null, we are canonical and do not read + return true; + case PointerType::STRUCT: { + bool dataTrunc = false, ptrTrunc = false; + auto structReader = this->getStruct(nullptr); + if (structReader.getDataSectionSize() == ZERO * BITS && + structReader.getPointerSectionSize() == ZERO * POINTERS) { + return reinterpret_cast(this->pointer) == structReader.getLocation(); + } else { + // Fun fact: Once this call to isCanonical() returns, Clang may re-order the evaluation of + // the && operators. In theory this is wrong because && is short-circuiting, but Clang + // apparently sees that there are no side effects to the right of &&, so decides it is + // safe to skip short-circuiting. It turns out, though, this is observable under + // valgrind: if we don't initialize `dataTrunc` when declaring it above, then valgrind + // reports "Conditional jump or move depends on uninitialised value(s)". Specifically + // this happens in cases where structReader.isCanonical() returns false -- it is allowed + // to skip initializing `dataTrunc` in that case. The short-circuiting && should mean + // that we don't read `dataTrunc` in that case, except Clang's optimizations. Ultimately + // the uninitialized read is fine because eventually the whole expression evaluates false + // either way. But, to make valgrind happy, we initialize the bools above... + return structReader.isCanonical(readHead, readHead, &dataTrunc, &ptrTrunc) && dataTrunc && ptrTrunc; + } + } + case PointerType::LIST: + return this->getListAnySize(nullptr).isCanonical(readHead, pointer); + case PointerType::CAPABILITY: + KJ_FAIL_ASSERT("Capabilities are not positional"); + } + KJ_UNREACHABLE; +} + +// ======================================================================================= +// StructBuilder + +void StructBuilder::clearAll() { + if (dataSize == ONE * BITS) { + setDataField(ONE * ELEMENTS, false); + } else { + WireHelpers::zeroMemory(reinterpret_cast(data), dataSize / BITS_PER_BYTE); + } + + for (auto i: kj::zeroTo(pointerCount)) { + WireHelpers::zeroObject(segment, capTable, pointers + i); + } + WireHelpers::zeroMemory(pointers, pointerCount); +} + +void StructBuilder::transferContentFrom(StructBuilder other) { + // Determine the amount of data the builders have in common. + auto sharedDataSize = kj::min(dataSize, other.dataSize); + + if (dataSize > sharedDataSize) { + // Since the target is larger than the source, make sure to zero out the extra bits that the + // source doesn't have. + if (dataSize == ONE * BITS) { + setDataField(ZERO * ELEMENTS, false); + } else { + byte* unshared = reinterpret_cast(data) + sharedDataSize / BITS_PER_BYTE; + // Note: this subtraction can't fail due to the if() above + WireHelpers::zeroMemory(unshared, + subtractChecked(dataSize, sharedDataSize, []() {}) / BITS_PER_BYTE); + } + } + + // Copy over the shared part. + if (sharedDataSize == ONE * BITS) { + setDataField(ZERO * ELEMENTS, other.getDataField(ZERO * ELEMENTS)); + } else { + WireHelpers::copyMemory(reinterpret_cast(data), + reinterpret_cast(other.data), + sharedDataSize / BITS_PER_BYTE); + } + + // Zero out all pointers in the target. + for (auto i: kj::zeroTo(pointerCount)) { + WireHelpers::zeroObject(segment, capTable, pointers + i); + } + WireHelpers::zeroMemory(pointers, pointerCount); + + // Transfer the pointers. + auto sharedPointerCount = kj::min(pointerCount, other.pointerCount); + for (auto i: kj::zeroTo(sharedPointerCount)) { + WireHelpers::transferPointer(segment, pointers + i, other.segment, other.pointers + i); + } + + // Zero out the pointers that were transferred in the source because it no longer has ownership. + // If the source had any extra pointers that the destination didn't have space for, we + // intentionally leave them be, so that they'll be cleaned up later. + WireHelpers::zeroMemory(other.pointers, sharedPointerCount); +} + +void StructBuilder::copyContentFrom(StructReader other) { + // Determine the amount of data the builders have in common. + auto sharedDataSize = kj::min(dataSize, other.dataSize); + auto sharedPointerCount = kj::min(pointerCount, other.pointerCount); + + if ((sharedDataSize > ZERO * BITS && other.data == data) || + (sharedPointerCount > ZERO * POINTERS && other.pointers == pointers)) { + // At least one of the section pointers is pointing to ourself. Verify that the other is two + // (but ignore empty sections). + KJ_ASSERT((sharedDataSize == ZERO * BITS || other.data == data) && + (sharedPointerCount == ZERO * POINTERS || other.pointers == pointers)); + // So `other` appears to be a reader for this same struct. No coping is needed. + return; + } + + if (dataSize > sharedDataSize) { + // Since the target is larger than the source, make sure to zero out the extra bits that the + // source doesn't have. + if (dataSize == ONE * BITS) { + setDataField(ZERO * ELEMENTS, false); + } else { + byte* unshared = reinterpret_cast(data) + sharedDataSize / BITS_PER_BYTE; + WireHelpers::zeroMemory(unshared, + subtractChecked(dataSize, sharedDataSize, []() {}) / BITS_PER_BYTE); + } + } + + // Copy over the shared part. + if (sharedDataSize == ONE * BITS) { + setDataField(ZERO * ELEMENTS, other.getDataField(ZERO * ELEMENTS)); + } else { + WireHelpers::copyMemory(reinterpret_cast(data), + reinterpret_cast(other.data), + sharedDataSize / BITS_PER_BYTE); + } + + // Zero out all pointers in the target. + for (auto i: kj::zeroTo(pointerCount)) { + WireHelpers::zeroObject(segment, capTable, pointers + i); + } + WireHelpers::zeroMemory(pointers, pointerCount); + + // Copy the pointers. + for (auto i: kj::zeroTo(sharedPointerCount)) { + WireHelpers::copyPointer(segment, capTable, pointers + i, + other.segment, other.capTable, other.pointers + i, other.nestingLimit); + } +} + +StructReader StructBuilder::asReader() const { + return StructReader(segment, capTable, data, pointers, + dataSize, pointerCount, kj::maxValue); +} + +BuilderArena* StructBuilder::getArena() { + return segment->getArena(); +} + +CapTableBuilder* StructBuilder::getCapTable() { + return capTable; +} + +StructBuilder StructBuilder::imbue(CapTableBuilder* capTable) { + auto result = *this; + result.capTable = capTable; + return result; +} + +// ======================================================================================= +// StructReader + +MessageSizeCounts StructReader::totalSize() const { + MessageSizeCounts result = { + WireHelpers::roundBitsUpToWords(dataSize) + pointerCount * WORDS_PER_POINTER, 0 }; + + for (auto i: kj::zeroTo(pointerCount)) { + result += WireHelpers::totalSize(segment, pointers + i, nestingLimit); + } + + if (segment != nullptr) { + // This traversal should not count against the read limit, because it's highly likely that + // the caller is going to traverse the object again, e.g. to copy it. + segment->unread(result.wordCount); + } + + return result; +} + +kj::Array StructReader::canonicalize() { + auto size = totalSize().wordCount + POINTER_SIZE_IN_WORDS; + kj::Array backing = kj::heapArray(unbound(size / WORDS)); + WireHelpers::zeroMemory(backing.asPtr()); + FlatMessageBuilder builder(backing); + _::PointerHelpers::getInternalBuilder(builder.initRoot()).setStruct(*this, true); + KJ_ASSERT(builder.isCanonical()); + auto output = builder.getSegmentsForOutput()[0]; + kj::Array trunc = kj::heapArray(output.size()); + WireHelpers::copyMemory(trunc.begin(), output); + return trunc; +} + +CapTableReader* StructReader::getCapTable() { + return capTable; +} + +StructReader StructReader::imbue(CapTableReader* capTable) const { + auto result = *this; + result.capTable = capTable; + return result; +} + +bool StructReader::isCanonical(const word **readHead, + const word **ptrHead, + bool *dataTrunc, + bool *ptrTrunc) { + if (this->getLocation() != *readHead) { + // Our target area is not at the readHead, preorder fails + return false; + } + + if (this->getDataSectionSize() % BITS_PER_WORD != ZERO * BITS) { + // Using legacy non-word-size structs, reject + return false; + } + auto dataSize = this->getDataSectionSize() / BITS_PER_WORD; + + // Mark whether the struct is properly truncated + KJ_IF_MAYBE(diff, trySubtract(dataSize, ONE * WORDS)) { + *dataTrunc = this->getDataField(*diff / WORDS * ELEMENTS) != 0; + } else { + // Data segment empty. + *dataTrunc = true; + } + + KJ_IF_MAYBE(diff, trySubtract(this->pointerCount, ONE * POINTERS)) { + *ptrTrunc = !this->getPointerField(*diff).isNull(); + } else { + *ptrTrunc = true; + } + + // Advance the read head + *readHead += (dataSize + (this->pointerCount * WORDS_PER_POINTER)); + + // Check each pointer field for canonicity + for (auto ptrIndex: kj::zeroTo(this->pointerCount)) { + if (!this->getPointerField(ptrIndex).isCanonical(ptrHead)) { + return false; + } + } + + return true; +} + +// ======================================================================================= +// ListBuilder + +Text::Builder ListBuilder::asText() { + KJ_REQUIRE(structDataSize == G(8) * BITS && structPointerCount == ZERO * POINTERS, + "Expected Text, got list of non-bytes.") { + return Text::Builder(); + } + + size_t size = unbound(elementCount / ELEMENTS); + + KJ_REQUIRE(size > 0, "Message contains text that is not NUL-terminated.") { + return Text::Builder(); + } + + char* cptr = reinterpret_cast(ptr); + --size; // NUL terminator + + KJ_REQUIRE(cptr[size] == '\0', "Message contains text that is not NUL-terminated.") { + return Text::Builder(); + } + + return Text::Builder(cptr, size); +} + +Data::Builder ListBuilder::asData() { + KJ_REQUIRE(structDataSize == G(8) * BITS && structPointerCount == ZERO * POINTERS, + "Expected Text, got list of non-bytes.") { + return Data::Builder(); + } + + return Data::Builder(reinterpret_cast(ptr), unbound(elementCount / ELEMENTS)); +} + +StructBuilder ListBuilder::getStructElement(ElementCount index) { + auto indexBit = upgradeBound(index) * step; + byte* structData = ptr + indexBit / BITS_PER_BYTE; + KJ_DASSERT(indexBit % BITS_PER_BYTE == ZERO * BITS); + return StructBuilder(segment, capTable, structData, + reinterpret_cast(structData + structDataSize / BITS_PER_BYTE), + structDataSize, structPointerCount); +} + +ListReader ListBuilder::asReader() const { + return ListReader(segment, capTable, ptr, elementCount, step, structDataSize, structPointerCount, + elementSize, kj::maxValue); +} + +BuilderArena* ListBuilder::getArena() { + return segment->getArena(); +} + +CapTableBuilder* ListBuilder::getCapTable() { + return capTable; +} + +ListBuilder ListBuilder::imbue(CapTableBuilder* capTable) { + auto result = *this; + result.capTable = capTable; + return result; +} + +// ======================================================================================= +// ListReader + +Text::Reader ListReader::asText() { + KJ_REQUIRE(structDataSize == G(8) * BITS && structPointerCount == ZERO * POINTERS, + "Schema mismatch: Expected Text, got list of non-bytes.") { + return Text::Reader(); + } + + size_t size = unbound(elementCount / ELEMENTS); + + KJ_REQUIRE(size > 0, "Message contains text that is not NUL-terminated.") { + return Text::Reader(); + } + + const char* cptr = reinterpret_cast(ptr); + --size; // NUL terminator + + KJ_REQUIRE(cptr[size] == '\0', "Message contains text that is not NUL-terminated.") { + return Text::Reader(); + } + + return Text::Reader(cptr, size); +} + +Data::Reader ListReader::asData() { + KJ_REQUIRE(structDataSize == G(8) * BITS && structPointerCount == ZERO * POINTERS, + "Schema mismatch: Expected Text, got list of non-bytes.") { + return Data::Reader(); + } + + return Data::Reader(reinterpret_cast(ptr), unbound(elementCount / ELEMENTS)); +} + +kj::ArrayPtr ListReader::asRawBytes() const { + KJ_REQUIRE(structPointerCount == ZERO * POINTERS, + "Schema mismatch: Expected data only, got pointers.") { + return kj::ArrayPtr(); + } + + return arrayPtr(reinterpret_cast(ptr), + WireHelpers::roundBitsUpToBytes( + upgradeBound(elementCount) * (structDataSize / ELEMENTS))); +} + +StructReader ListReader::getStructElement(ElementCount index) const { + KJ_REQUIRE(nestingLimit > 0, + "Message is too deeply-nested or contains cycles. See capnp::ReaderOptions.") { + return StructReader(); + } + + auto indexBit = upgradeBound(index) * step; + const byte* structData = ptr + indexBit / BITS_PER_BYTE; + const WirePointer* structPointers = + reinterpret_cast(structData + structDataSize / BITS_PER_BYTE); + + KJ_DASSERT(indexBit % BITS_PER_BYTE == ZERO * BITS); + return StructReader( + segment, capTable, structData, structPointers, + structDataSize, structPointerCount, + nestingLimit - 1); +} + +MessageSizeCounts ListReader::totalSize() const { + // TODO(cleanup): This is kind of a lot of logic duplicated from WireHelpers::totalSize(), but + // it's unclear how to share it effectively. + + MessageSizeCounts result = { ZERO * WORDS, 0 }; + + switch (elementSize) { + case ElementSize::VOID: + // Nothing. + break; + case ElementSize::BIT: + case ElementSize::BYTE: + case ElementSize::TWO_BYTES: + case ElementSize::FOUR_BYTES: + case ElementSize::EIGHT_BYTES: + result.addWords(WireHelpers::roundBitsUpToWords( + upgradeBound(elementCount) * dataBitsPerElement(elementSize))); + break; + case ElementSize::POINTER: { + auto count = elementCount * (POINTERS / ELEMENTS); + result.addWords(count * WORDS_PER_POINTER); + + for (auto i: kj::zeroTo(count)) { + result += WireHelpers::totalSize(segment, reinterpret_cast(ptr) + i, + nestingLimit); + } + break; + } + case ElementSize::INLINE_COMPOSITE: { + // Don't forget to count the tag word. + auto wordSize = upgradeBound(elementCount) * step / BITS_PER_WORD; + result.addWords(wordSize + POINTER_SIZE_IN_WORDS); + + if (structPointerCount > ZERO * POINTERS) { + const word* pos = reinterpret_cast(ptr); + for (auto i KJ_UNUSED: kj::zeroTo(elementCount)) { + pos += structDataSize / BITS_PER_WORD; + + for (auto j KJ_UNUSED: kj::zeroTo(structPointerCount)) { + result += WireHelpers::totalSize(segment, reinterpret_cast(pos), + nestingLimit); + pos += POINTER_SIZE_IN_WORDS; + } + } + } + break; + } + } + + if (segment != nullptr) { + // This traversal should not count against the read limit, because it's highly likely that + // the caller is going to traverse the object again, e.g. to copy it. + segment->unread(result.wordCount); + } + + return result; +} + +CapTableReader* ListReader::getCapTable() { + return capTable; +} + +ListReader ListReader::imbue(CapTableReader* capTable) const { + auto result = *this; + result.capTable = capTable; + return result; +} + +bool ListReader::isCanonical(const word **readHead, const WirePointer *ref) { + switch (this->getElementSize()) { + case ElementSize::INLINE_COMPOSITE: { + *readHead += 1; + if (reinterpret_cast(this->ptr) != *readHead) { + // The next word to read is the tag word, but the pointer is in + // front of it, so our check is slightly different + return false; + } + if (this->structDataSize % BITS_PER_WORD != ZERO * BITS) { + return false; + } + auto elementSize = StructSize(this->structDataSize / BITS_PER_WORD, + this->structPointerCount).total() / ELEMENTS; + auto totalSize = upgradeBound(this->elementCount) * elementSize; + if (totalSize != ref->listRef.inlineCompositeWordCount()) { + return false; + } + if (elementSize == ZERO * WORDS / ELEMENTS) { + return true; + } + auto listEnd = *readHead + totalSize; + auto pointerHead = listEnd; + bool listDataTrunc = false; + bool listPtrTrunc = false; + for (auto ec: kj::zeroTo(this->elementCount)) { + bool dataTrunc, ptrTrunc; + if (!this->getStructElement(ec).isCanonical(readHead, + &pointerHead, + &dataTrunc, + &ptrTrunc)) { + return false; + } + listDataTrunc |= dataTrunc; + listPtrTrunc |= ptrTrunc; + } + KJ_REQUIRE(*readHead == listEnd, *readHead, listEnd); + *readHead = pointerHead; + return listDataTrunc && listPtrTrunc; + } + case ElementSize::POINTER: { + if (reinterpret_cast(this->ptr) != *readHead) { + return false; + } + *readHead += this->elementCount * (POINTERS / ELEMENTS) * WORDS_PER_POINTER; + for (auto ec: kj::zeroTo(this->elementCount)) { + if (!this->getPointerElement(ec).isCanonical(readHead)) { + return false; + } + } + return true; + } + default: { + if (reinterpret_cast(this->ptr) != *readHead) { + return false; + } + + auto bitSize = upgradeBound(this->elementCount) * + dataBitsPerElement(this->elementSize); + auto truncatedByteSize = bitSize / BITS_PER_BYTE; + auto byteReadHead = reinterpret_cast(*readHead) + truncatedByteSize; + auto readHeadEnd = *readHead + WireHelpers::roundBitsUpToWords(bitSize); + + auto leftoverBits = bitSize % BITS_PER_BYTE; + if (leftoverBits > ZERO * BITS) { + auto mask = ~((1 << unbound(leftoverBits / BITS)) - 1); + + if (mask & *byteReadHead) { + return false; + } + byteReadHead += 1; + } + + while (byteReadHead != reinterpret_cast(readHeadEnd)) { + if (*byteReadHead != 0) { + return false; + } + byteReadHead += 1; + } + + *readHead = readHeadEnd; + return true; + } + } + KJ_UNREACHABLE; +} + +// ======================================================================================= +// OrphanBuilder + +OrphanBuilder OrphanBuilder::initStruct( + BuilderArena* arena, CapTableBuilder* capTable, StructSize size) { + OrphanBuilder result; + StructBuilder builder = WireHelpers::initStructPointer( + result.tagAsPtr(), nullptr, capTable, size, arena); + result.segment = builder.segment; + result.capTable = capTable; + result.location = builder.getLocation(); + return result; +} + +OrphanBuilder OrphanBuilder::initList( + BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, ElementSize elementSize) { + OrphanBuilder result; + ListBuilder builder = WireHelpers::initListPointer( + result.tagAsPtr(), nullptr, capTable, elementCount, elementSize, arena); + result.segment = builder.segment; + result.capTable = capTable; + result.location = builder.getLocation(); + return result; +} + +OrphanBuilder OrphanBuilder::initStructList( + BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, StructSize elementSize) { + OrphanBuilder result; + ListBuilder builder = WireHelpers::initStructListPointer( + result.tagAsPtr(), nullptr, capTable, elementCount, elementSize, arena); + result.segment = builder.segment; + result.capTable = capTable; + result.location = builder.getLocation(); + return result; +} + +OrphanBuilder OrphanBuilder::initText( + BuilderArena* arena, CapTableBuilder* capTable, ByteCount size) { + OrphanBuilder result; + auto allocation = WireHelpers::initTextPointer(result.tagAsPtr(), nullptr, capTable, + assertMax(size, ThrowOverflow()), arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value.begin()); + return result; +} + +OrphanBuilder OrphanBuilder::initData( + BuilderArena* arena, CapTableBuilder* capTable, ByteCount size) { + OrphanBuilder result; + auto allocation = WireHelpers::initDataPointer(result.tagAsPtr(), nullptr, capTable, + assertMaxBits(size), arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value.begin()); + return result; +} + +OrphanBuilder OrphanBuilder::copy( + BuilderArena* arena, CapTableBuilder* capTable, StructReader copyFrom) { + OrphanBuilder result; + auto allocation = WireHelpers::setStructPointer( + nullptr, capTable, result.tagAsPtr(), copyFrom, arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value); + return result; +} + +OrphanBuilder OrphanBuilder::copy( + BuilderArena* arena, CapTableBuilder* capTable, ListReader copyFrom) { + OrphanBuilder result; + auto allocation = WireHelpers::setListPointer( + nullptr, capTable, result.tagAsPtr(), copyFrom, arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value); + return result; +} + +OrphanBuilder OrphanBuilder::copy( + BuilderArena* arena, CapTableBuilder* capTable, PointerReader copyFrom) { + OrphanBuilder result; + auto allocation = WireHelpers::copyPointer( + nullptr, capTable, result.tagAsPtr(), + copyFrom.segment, copyFrom.capTable, copyFrom.pointer, copyFrom.nestingLimit, arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value); + return result; +} + +OrphanBuilder OrphanBuilder::copy( + BuilderArena* arena, CapTableBuilder* capTable, Text::Reader copyFrom) { + OrphanBuilder result; + auto allocation = WireHelpers::setTextPointer( + result.tagAsPtr(), nullptr, capTable, copyFrom, arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value.begin()); + return result; +} + +OrphanBuilder OrphanBuilder::copy( + BuilderArena* arena, CapTableBuilder* capTable, Data::Reader copyFrom) { + OrphanBuilder result; + auto allocation = WireHelpers::setDataPointer( + result.tagAsPtr(), nullptr, capTable, copyFrom, arena); + result.segment = allocation.segment; + result.capTable = capTable; + result.location = reinterpret_cast(allocation.value.begin()); + return result; +} + +#if !CAPNP_LITE +OrphanBuilder OrphanBuilder::copy( + BuilderArena* arena, CapTableBuilder* capTable, kj::Own copyFrom) { + OrphanBuilder result; + WireHelpers::setCapabilityPointer(nullptr, capTable, result.tagAsPtr(), kj::mv(copyFrom)); + result.segment = arena->getSegment(SegmentId(0)); + result.capTable = capTable; + result.location = &result.tag; // dummy to make location non-null + return result; +} +#endif // !CAPNP_LITE + +OrphanBuilder OrphanBuilder::concat( + BuilderArena* arena, CapTableBuilder* capTable, + ElementSize elementSize, StructSize structSize, + kj::ArrayPtr lists) { + KJ_REQUIRE(lists.size() > 0, "Can't concat empty list "); + + // Find the overall element count and size. + ListElementCount elementCount = ZERO * ELEMENTS; + for (auto& list: lists) { + elementCount = assertMaxBits(elementCount + list.elementCount, + []() { KJ_FAIL_REQUIRE("concatenated list exceeds list size limit"); }); + if (list.elementSize != elementSize) { + // If element sizes don't all match, upgrade to struct list. + KJ_REQUIRE(list.elementSize != ElementSize::BIT && elementSize != ElementSize::BIT, + "can't upgrade bit lists to struct lists"); + elementSize = ElementSize::INLINE_COMPOSITE; + } + structSize.data = kj::max(structSize.data, + WireHelpers::roundBitsUpToWords(list.structDataSize)); + structSize.pointers = kj::max(structSize.pointers, list.structPointerCount); + } + + // Allocate the list. + OrphanBuilder result; + ListBuilder builder = (elementSize == ElementSize::INLINE_COMPOSITE) + ? WireHelpers::initStructListPointer( + result.tagAsPtr(), nullptr, capTable, elementCount, structSize, arena) + : WireHelpers::initListPointer( + result.tagAsPtr(), nullptr, capTable, elementCount, elementSize, arena); + + // Copy elements. + switch (elementSize) { + case ElementSize::INLINE_COMPOSITE: { + ListElementCount pos = ZERO * ELEMENTS; + for (auto& list: lists) { + for (auto i: kj::zeroTo(list.size())) { + builder.getStructElement(pos).copyContentFrom(list.getStructElement(i)); + // assumeBits() safe because we checked total size earlier. + pos = assumeBits(pos + ONE * ELEMENTS); + } + } + break; + } + case ElementSize::POINTER: { + ListElementCount pos = ZERO * ELEMENTS; + for (auto& list: lists) { + for (auto i: kj::zeroTo(list.size())) { + builder.getPointerElement(pos).copyFrom(list.getPointerElement(i)); + // assumeBits() safe because we checked total size earlier. + pos = assumeBits(pos + ONE * ELEMENTS); + } + } + break; + } + case ElementSize::BIT: { + // It's difficult to memcpy() bits since a list could start or end mid-byte. For now we + // do a slow, naive loop. Probably no one will ever care. + ListElementCount pos = ZERO * ELEMENTS; + for (auto& list: lists) { + for (auto i: kj::zeroTo(list.size())) { + builder.setDataElement(pos, list.getDataElement(i)); + // assumeBits() safe because we checked total size earlier. + pos = assumeBits(pos + ONE * ELEMENTS); + } + } + break; + } + default: { + // We know all the inputs are primitives with identical size because otherwise we would have + // chosen INLINE_COMPOSITE. Therefore, we can safely use memcpy() here instead of copying + // each element manually. + byte* target = builder.ptr; + auto step = builder.step / BITS_PER_BYTE; + for (auto& list: lists) { + auto count = step * upgradeBound(list.size()); + WireHelpers::copyMemory(target, list.ptr, assumeBits(count)); + target += count; + } + break; + } + } + + // Return orphan. + result.segment = builder.segment; + result.capTable = capTable; + result.location = builder.getLocation(); + return result; +} + +OrphanBuilder OrphanBuilder::referenceExternalData(BuilderArena* arena, Data::Reader data) { + KJ_REQUIRE(reinterpret_cast(data.begin()) % sizeof(void*) == 0, + "Cannot referenceExternalData() that is not aligned."); + + auto checkedSize = assertMaxBits(bounded(data.size())); + auto wordCount = WireHelpers::roundBytesUpToWords(checkedSize * BYTES); + kj::ArrayPtr words(reinterpret_cast(data.begin()), + unbound(wordCount / WORDS)); + + OrphanBuilder result; + result.tagAsPtr()->setKindForOrphan(WirePointer::LIST); + result.tagAsPtr()->listRef.set(ElementSize::BYTE, checkedSize * ELEMENTS); + result.segment = arena->addExternalSegment(words); + + // External data cannot possibly contain capabilities. + result.capTable = nullptr; + + // const_cast OK here because we will check whether the segment is writable when we try to get + // a builder. + result.location = const_cast(words.begin()); + + return result; +} + +StructBuilder OrphanBuilder::asStruct(StructSize size) { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + + StructBuilder result = WireHelpers::getWritableStructPointer( + tagAsPtr(), location, segment, capTable, size, nullptr, segment->getArena()); + + // Watch out, the pointer could have been updated if the object had to be relocated. + location = reinterpret_cast(result.data); + + return result; +} + +ListBuilder OrphanBuilder::asList(ElementSize elementSize) { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + + ListBuilder result = WireHelpers::getWritableListPointer( + tagAsPtr(), location, segment, capTable, elementSize, nullptr, segment->getArena()); + + // Watch out, the pointer could have been updated if the object had to be relocated. + // (Actually, currently this is not true for primitive lists, but let's not turn into a bug if + // it changes!) + location = result.getLocation(); + + return result; +} + +ListBuilder OrphanBuilder::asStructList(StructSize elementSize) { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + + ListBuilder result = WireHelpers::getWritableStructListPointer( + tagAsPtr(), location, segment, capTable, elementSize, nullptr, segment->getArena()); + + // Watch out, the pointer could have been updated if the object had to be relocated. + location = result.getLocation(); + + return result; +} + +ListBuilder OrphanBuilder::asListAnySize() { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + + ListBuilder result = WireHelpers::getWritableListPointerAnySize( + tagAsPtr(), location, segment, capTable, nullptr, segment->getArena()); + + // Watch out, the pointer could have been updated if the object had to be relocated. + location = result.getLocation(); + + return result; +} + +Text::Builder OrphanBuilder::asText() { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + + // Never relocates. + return WireHelpers::getWritableTextPointer( + tagAsPtr(), location, segment, capTable, nullptr, ZERO * BYTES); +} + +Data::Builder OrphanBuilder::asData() { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + + // Never relocates. + return WireHelpers::getWritableDataPointer( + tagAsPtr(), location, segment, capTable, nullptr, ZERO * BYTES); +} + +StructReader OrphanBuilder::asStructReader(StructSize size) const { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + return WireHelpers::readStructPointer( + segment, capTable, tagAsPtr(), location, nullptr, kj::maxValue); +} + +ListReader OrphanBuilder::asListReader(ElementSize elementSize) const { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + return WireHelpers::readListPointer( + segment, capTable, tagAsPtr(), location, nullptr, elementSize, kj::maxValue); +} + +ListReader OrphanBuilder::asListReaderAnySize() const { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + return WireHelpers::readListPointer( + segment, capTable, tagAsPtr(), location, nullptr, ElementSize::VOID /* dummy */, + kj::maxValue); +} + +#if !CAPNP_LITE +kj::Own OrphanBuilder::asCapability() const { + return WireHelpers::readCapabilityPointer(segment, capTable, tagAsPtr(), kj::maxValue); +} +#endif // !CAPNP_LITE + +Text::Reader OrphanBuilder::asTextReader() const { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + return WireHelpers::readTextPointer(segment, tagAsPtr(), location, nullptr, ZERO * BYTES); +} + +Data::Reader OrphanBuilder::asDataReader() const { + KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr)); + return WireHelpers::readDataPointer(segment, tagAsPtr(), location, nullptr, ZERO * BYTES); +} + +bool OrphanBuilder::truncate(ElementCount uncheckedSize, bool isText) { + ListElementCount size = assertMaxBits(uncheckedSize, + []() { KJ_FAIL_REQUIRE("requested list size is too large"); }); + + WirePointer* ref = tagAsPtr(); + SegmentBuilder* segment = this->segment; + + word* target = WireHelpers::followFars(ref, location, segment); + + if (ref->isNull()) { + // We don't know the right element size, so we can't resize this list. + return size == ZERO * ELEMENTS; + } + + KJ_REQUIRE(ref->kind() == WirePointer::LIST, "Schema mismatch: Can't truncate non-list.") { + return false; + } + + if (isText) { + // Add space for the NUL terminator. + size = assertMaxBits(size + ONE * ELEMENTS, + []() { KJ_FAIL_REQUIRE("requested list size is too large"); }); + } + + auto elementSize = ref->listRef.elementSize(); + + if (elementSize == ElementSize::INLINE_COMPOSITE) { + auto oldWordCount = ref->listRef.inlineCompositeWordCount(); + + WirePointer* tag = reinterpret_cast(target); + ++target; + KJ_REQUIRE(tag->kind() == WirePointer::STRUCT, + "INLINE_COMPOSITE lists of non-STRUCT type are not supported.") { + return false; + } + StructSize structSize(tag->structRef.dataSize.get(), tag->structRef.ptrCount.get()); + auto elementStep = structSize.total() / ELEMENTS; + + auto oldSize = tag->inlineCompositeListElementCount(); + + SegmentWordCount sizeWords = assertMaxBits( + upgradeBound(size) * elementStep, + []() { KJ_FAIL_ASSERT("requested list size too large to fit in message segment"); }); + SegmentWordCount oldSizeWords = assertMaxBits( + upgradeBound(oldSize) * elementStep, + []() { KJ_FAIL_ASSERT("prior to truncate, list is larger than max segment size?"); }); + + word* newEndWord = target + sizeWords; + word* oldEndWord = target + oldWordCount; + + if (size <= oldSize) { + // Zero the trailing elements. + for (auto i: kj::range(size, oldSize)) { + // assumeBits() safe because we checked that both sizeWords and oldSizeWords are in-range + // above. + WireHelpers::zeroObject(segment, capTable, tag, target + + assumeBits(upgradeBound(i) * elementStep)); + } + ref->listRef.setInlineComposite(sizeWords); + tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, size); + segment->tryTruncate(oldEndWord, newEndWord); + } else if (newEndWord <= oldEndWord) { + // Apparently the old list was over-allocated? The word count is more than needed to store + // the elements. This is "valid" but shouldn't happen in practice unless someone is toying + // with us. + word* expectedEnd = target + oldSizeWords; + KJ_ASSERT(newEndWord >= expectedEnd); + WireHelpers::zeroMemory(expectedEnd, + intervalLength(expectedEnd, newEndWord, MAX_SEGMENT_WORDS)); + tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, size); + } else { + if (segment->tryExtend(oldEndWord, newEndWord)) { + // Done in-place. Nothing else to do now; the new memory is already zero'd. + ref->listRef.setInlineComposite(sizeWords); + tag->setKindAndInlineCompositeListElementCount(WirePointer::STRUCT, size); + } else { + // Need to re-allocate and transfer. + OrphanBuilder replacement = initStructList(segment->getArena(), capTable, size, structSize); + + ListBuilder newList = replacement.asStructList(structSize); + for (auto i: kj::zeroTo(oldSize)) { + // assumeBits() safe because we checked that both sizeWords and oldSizeWords are in-range + // above. + word* element = target + + assumeBits(upgradeBound(i) * elementStep); + newList.getStructElement(i).transferContentFrom( + StructBuilder(segment, capTable, element, + reinterpret_cast(element + structSize.data), + structSize.data * BITS_PER_WORD, structSize.pointers)); + } + + *this = kj::mv(replacement); + } + } + } else if (elementSize == ElementSize::POINTER) { + // TODO(cleanup): GCC won't let me declare this constexpr, claiming POINTERS is not constexpr, + // but it is? + const auto POINTERS_PER_ELEMENT = ONE * POINTERS / ELEMENTS; + + auto oldSize = ref->listRef.elementCount(); + word* newEndWord = target + size * POINTERS_PER_ELEMENT * WORDS_PER_POINTER; + word* oldEndWord = target + oldSize * POINTERS_PER_ELEMENT * WORDS_PER_POINTER; + + if (size <= oldSize) { + // Zero the trailing elements. + for (WirePointer* element = reinterpret_cast(newEndWord); + element < reinterpret_cast(oldEndWord); ++element) { + WireHelpers::zeroPointerAndFars(segment, element); + } + ref->listRef.set(ElementSize::POINTER, size); + segment->tryTruncate(oldEndWord, newEndWord); + } else { + if (segment->tryExtend(oldEndWord, newEndWord)) { + // Done in-place. Nothing else to do now; the new memory is already zero'd. + ref->listRef.set(ElementSize::POINTER, size); + } else { + // Need to re-allocate and transfer. + OrphanBuilder replacement = initList( + segment->getArena(), capTable, size, ElementSize::POINTER); + ListBuilder newList = replacement.asList(ElementSize::POINTER); + WirePointer* oldPointers = reinterpret_cast(target); + for (auto i: kj::zeroTo(oldSize)) { + newList.getPointerElement(i).transferFrom( + PointerBuilder(segment, capTable, oldPointers + i * POINTERS_PER_ELEMENT)); + } + *this = kj::mv(replacement); + } + } + } else { + auto oldSize = ref->listRef.elementCount(); + auto step = dataBitsPerElement(elementSize); + const auto MAX_STEP_BYTES = ONE * WORDS / ELEMENTS * BYTES_PER_WORD; + word* newEndWord = target + WireHelpers::roundBitsUpToWords( + upgradeBound(size) * step); + word* oldEndWord = target + WireHelpers::roundBitsUpToWords( + upgradeBound(oldSize) * step); + + if (size <= oldSize) { + // When truncating text, we want to set the null terminator as well, so we'll do our zeroing + // at the byte level. + byte* begin = reinterpret_cast(target); + byte* newEndByte = begin + WireHelpers::roundBitsUpToBytes( + upgradeBound(size) * step) - isText; + byte* oldEndByte = reinterpret_cast(oldEndWord); + + WireHelpers::zeroMemory(newEndByte, + intervalLength(newEndByte, oldEndByte, MAX_LIST_ELEMENTS * MAX_STEP_BYTES)); + ref->listRef.set(elementSize, size); + segment->tryTruncate(oldEndWord, newEndWord); + } else { + // We're trying to extend, not truncate. + if (segment->tryExtend(oldEndWord, newEndWord)) { + // Done in-place. Nothing else to do now; the memory is already zero'd. + ref->listRef.set(elementSize, size); + } else { + // Need to re-allocate and transfer. + OrphanBuilder replacement = initList(segment->getArena(), capTable, size, elementSize); + ListBuilder newList = replacement.asList(elementSize); + auto words = WireHelpers::roundBitsUpToWords( + dataBitsPerElement(elementSize) * upgradeBound(oldSize)); + WireHelpers::copyMemory(reinterpret_cast(newList.ptr), target, words); + *this = kj::mv(replacement); + } + } + } + + return true; +} + +void OrphanBuilder::truncate(ElementCount size, ElementSize elementSize) { + if (!truncate(size, false)) { + // assumeBits() safe since it's checked inside truncate() + *this = initList(segment->getArena(), capTable, + assumeBits(size), elementSize); + } +} + +void OrphanBuilder::truncate(ElementCount size, StructSize elementSize) { + if (!truncate(size, false)) { + // assumeBits() safe since it's checked inside truncate() + *this = initStructList(segment->getArena(), capTable, + assumeBits(size), elementSize); + } +} + +void OrphanBuilder::truncateText(ElementCount size) { + if (!truncate(size, true)) { + // assumeBits() safe since it's checked inside truncate() + *this = initText(segment->getArena(), capTable, + assumeBits(size) * (ONE * BYTES / ELEMENTS)); + } +} + +void OrphanBuilder::euthanize() { + // Carefully catch any exceptions and rethrow them as recoverable exceptions since we may be in + // a destructor. + auto exception = kj::runCatchingExceptions([&]() { + if (tagAsPtr()->isPositional()) { + WireHelpers::zeroObject(segment, capTable, tagAsPtr(), location); + } else { + WireHelpers::zeroObject(segment, capTable, tagAsPtr()); + } + + WireHelpers::zeroMemory(&tag, ONE * WORDS); + segment = nullptr; + location = nullptr; + }); + + KJ_IF_MAYBE(e, exception) { + kj::getExceptionCallback().onRecoverableException(kj::mv(*e)); + } +} + +} // namespace _ (private) +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/layout.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/layout.h new file mode 100644 index 000000000..7a27f68a1 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/layout.h @@ -0,0 +1,1271 @@ +// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file is NOT intended for use by clients, except in generated code. +// +// This file defines low-level, non-type-safe classes for traversing the Cap'n Proto memory layout +// (which is also its wire format). Code generated by the Cap'n Proto compiler uses these classes, +// as does other parts of the Cap'n proto library which provide a higher-level interface for +// dynamic introspection. + +#pragma once + +#include +#include +#include "common.h" +#include "blob.h" +#include "endian.h" +#include // work-around macro conflict with `VOID` + +CAPNP_BEGIN_HEADER + +#if (defined(__mips__) || defined(__hppa__)) && !defined(CAPNP_CANONICALIZE_NAN) +#define CAPNP_CANONICALIZE_NAN 1 +// Explicitly detect NaNs and canonicalize them to the quiet NaN value as would be returned by +// __builtin_nan("") on systems implementing the IEEE-754 recommended (but not required) NaN +// signalling/quiet differentiation (such as x86). Unfortunately, some architectures -- in +// particular, MIPS -- represent quiet vs. signalling nans differently than the rest of the world. +// Canonicalizing them makes output consistent (which is important!), but hurts performance +// slightly. +// +// Note that trying to convert MIPS NaNs to standard NaNs without losing data doesn't work. +// Signaling vs. quiet is indicated by a bit, with the meaning being the opposite on MIPS vs. +// everyone else. It would be great if we could just flip that bit, but we can't, because if the +// significand is all-zero, then the value is infinity rather than NaN. This means that on most +// machines, where the bit indicates quietness, there is one more quiet NaN value than signalling +// NaN value, whereas on MIPS there is one more sNaN than qNaN, and thus there is no isomorphic +// mapping that properly preserves quietness. Instead of doing something hacky, we just give up +// and blow away NaN payloads, because no one uses them anyway. +#endif + +namespace capnp { + +class ClientHook; + +namespace _ { // private + +class PointerBuilder; +class PointerReader; +class StructBuilder; +class StructReader; +class ListBuilder; +class ListReader; +class OrphanBuilder; +struct WirePointer; +struct WireHelpers; +class SegmentReader; +class SegmentBuilder; +class Arena; +class BuilderArena; + +// ============================================================================= + +#if CAPNP_DEBUG_TYPES +typedef kj::UnitRatio, BitLabel, ElementLabel> BitsPerElementTableType; +#else +typedef uint BitsPerElementTableType; +#endif + +static constexpr BitsPerElementTableType BITS_PER_ELEMENT_TABLE[8] = { + bounded< 0>() * BITS / ELEMENTS, + bounded< 1>() * BITS / ELEMENTS, + bounded< 8>() * BITS / ELEMENTS, + bounded<16>() * BITS / ELEMENTS, + bounded<32>() * BITS / ELEMENTS, + bounded<64>() * BITS / ELEMENTS, + bounded< 0>() * BITS / ELEMENTS, + bounded< 0>() * BITS / ELEMENTS +}; + +inline KJ_CONSTEXPR() BitsPerElementTableType dataBitsPerElement(ElementSize size) { + return _::BITS_PER_ELEMENT_TABLE[static_cast(size)]; +} + +inline constexpr PointersPerElementN<1> pointersPerElement(ElementSize size) { + return size == ElementSize::POINTER + ? PointersPerElementN<1>(ONE * POINTERS / ELEMENTS) + : PointersPerElementN<1>(ZERO * POINTERS / ELEMENTS); +} + +static constexpr BitsPerElementTableType BITS_PER_ELEMENT_INCLUDING_PONITERS_TABLE[8] = { + bounded< 0>() * BITS / ELEMENTS, + bounded< 1>() * BITS / ELEMENTS, + bounded< 8>() * BITS / ELEMENTS, + bounded<16>() * BITS / ELEMENTS, + bounded<32>() * BITS / ELEMENTS, + bounded<64>() * BITS / ELEMENTS, + bounded<64>() * BITS / ELEMENTS, + bounded< 0>() * BITS / ELEMENTS +}; + +inline KJ_CONSTEXPR() BitsPerElementTableType bitsPerElementIncludingPointers(ElementSize size) { + return _::BITS_PER_ELEMENT_INCLUDING_PONITERS_TABLE[static_cast(size)]; +} + +template struct ElementSizeForByteSize; +template <> struct ElementSizeForByteSize<1> { static constexpr ElementSize value = ElementSize::BYTE; }; +template <> struct ElementSizeForByteSize<2> { static constexpr ElementSize value = ElementSize::TWO_BYTES; }; +template <> struct ElementSizeForByteSize<4> { static constexpr ElementSize value = ElementSize::FOUR_BYTES; }; +template <> struct ElementSizeForByteSize<8> { static constexpr ElementSize value = ElementSize::EIGHT_BYTES; }; + +template struct ElementSizeForType { + static constexpr ElementSize value = + // Primitive types that aren't special-cased below can be determined from sizeof(). + CAPNP_KIND(T) == Kind::PRIMITIVE ? ElementSizeForByteSize::value : + CAPNP_KIND(T) == Kind::ENUM ? ElementSize::TWO_BYTES : + CAPNP_KIND(T) == Kind::STRUCT ? ElementSize::INLINE_COMPOSITE : + + // Everything else is a pointer. + ElementSize::POINTER; +}; + +// Void and bool are special. +template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::VOID; }; +template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::BIT; }; + +// Lists and blobs are pointers, not structs. +template struct ElementSizeForType> { + static constexpr ElementSize value = ElementSize::POINTER; +}; +template <> struct ElementSizeForType { + static constexpr ElementSize value = ElementSize::POINTER; +}; +template <> struct ElementSizeForType { + static constexpr ElementSize value = ElementSize::POINTER; +}; + +template +inline constexpr ElementSize elementSizeForType() { + return ElementSizeForType::value; +} + +struct MessageSizeCounts { + WordCountN<61, uint64_t> wordCount; // 2^64 bytes + uint capCount; + + MessageSizeCounts& operator+=(const MessageSizeCounts& other) { + // OK to truncate unchecked because this class is used to count actual stuff in memory, and + // we couldn't possibly have anywhere near 2^61 words. + wordCount = assumeBits<61>(wordCount + other.wordCount); + capCount += other.capCount; + return *this; + } + + void addWords(WordCountN<61, uint64_t> other) { + wordCount = assumeBits<61>(wordCount + other); + } + + MessageSize asPublic() { + return MessageSize { unbound(wordCount / WORDS), capCount }; + } +}; + +// ============================================================================= + +template +union AlignedData { + // Useful for declaring static constant data blobs as an array of bytes, but forcing those + // bytes to be word-aligned. + + uint8_t bytes[wordCount * sizeof(word)]; + word words[wordCount]; +}; + +struct StructSize { + StructDataWordCount data; + StructPointerCount pointers; + + inline constexpr WordCountN<17> total() const { return data + pointers * WORDS_PER_POINTER; } + + StructSize() = default; + inline constexpr StructSize(StructDataWordCount data, StructPointerCount pointers) + : data(data), pointers(pointers) {} +}; + +template +inline constexpr StructSize structSize() { + return StructSize(bounded(CapnpPrivate::dataWordSize) * WORDS, + bounded(CapnpPrivate::pointerCount) * POINTERS); +} + +template > +inline constexpr StructSize minStructSizeForElement() { + // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough + // to hold a T. + + return StructSize(bounded(CapnpPrivate::dataWordSize) * WORDS, + bounded(CapnpPrivate::pointerCount) * POINTERS); +} + +template > +inline constexpr StructSize minStructSizeForElement() { + // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough + // to hold a T. + + return StructSize( + dataBitsPerElement(elementSizeForType()) * ELEMENTS > ZERO * BITS + ? StructDataWordCount(ONE * WORDS) : StructDataWordCount(ZERO * WORDS), + pointersPerElement(elementSizeForType()) * ELEMENTS); +} + +// ------------------------------------------------------------------- +// Masking of default values + +template struct Mask_; +template struct Mask_ { typedef T Type; }; +template struct Mask_ { typedef uint16_t Type; }; +template <> struct Mask_ { typedef uint32_t Type; }; +template <> struct Mask_ { typedef uint64_t Type; }; + +template struct Mask_ { + // Union discriminants end up here. + static_assert(sizeof(T) == 2, "Don't know how to mask this type."); + typedef uint16_t Type; +}; + +template +using Mask = typename Mask_::Type; + +template +KJ_ALWAYS_INLINE(Mask mask(T value, Mask mask)); +template +KJ_ALWAYS_INLINE(T unmask(Mask value, Mask mask)); + +template +inline Mask mask(T value, Mask mask) { + return static_cast >(value) ^ mask; +} + +template <> +inline uint32_t mask(float value, uint32_t mask) { +#if CAPNP_CANONICALIZE_NAN + if (value != value) { + return 0x7fc00000u ^ mask; + } +#endif + + uint32_t i; + static_assert(sizeof(i) == sizeof(value), "float is not 32 bits?"); + memcpy(&i, &value, sizeof(value)); + return i ^ mask; +} + +template <> +inline uint64_t mask(double value, uint64_t mask) { +#if CAPNP_CANONICALIZE_NAN + if (value != value) { + return 0x7ff8000000000000ull ^ mask; + } +#endif + + uint64_t i; + static_assert(sizeof(i) == sizeof(value), "double is not 64 bits?"); + memcpy(&i, &value, sizeof(value)); + return i ^ mask; +} + +template +inline T unmask(Mask value, Mask mask) { + return static_cast(value ^ mask); +} + +template <> +inline float unmask(uint32_t value, uint32_t mask) { + value ^= mask; + float result; + static_assert(sizeof(result) == sizeof(value), "float is not 32 bits?"); + memcpy(&result, &value, sizeof(value)); + return result; +} + +template <> +inline double unmask(uint64_t value, uint64_t mask) { + value ^= mask; + double result; + static_assert(sizeof(result) == sizeof(value), "double is not 64 bits?"); + memcpy(&result, &value, sizeof(value)); + return result; +} + +// ------------------------------------------------------------------- + +class CapTableReader { +public: + virtual kj::Maybe> extractCap(uint index) = 0; + // Extract the capability at the given index. If the index is invalid, returns null. +}; + +class CapTableBuilder: public CapTableReader { +public: + virtual uint injectCap(kj::Own&& cap) = 0; + // Add the capability to the message and return its index. If the same ClientHook is injected + // twice, this may return the same index both times, but in this case dropCap() needs to be + // called an equal number of times to actually remove the cap. + + virtual void dropCap(uint index) = 0; + // Remove a capability injected earlier. Called when the pointer is overwritten or zero'd out. +}; + +// ------------------------------------------------------------------- + +class PointerBuilder: public kj::DisallowConstCopy { + // Represents a single pointer, usually embedded in a struct or a list. + +public: + inline PointerBuilder(): segment(nullptr), capTable(nullptr), pointer(nullptr) {} + + static inline PointerBuilder getRoot( + SegmentBuilder* segment, CapTableBuilder* capTable, word* location); + // Get a PointerBuilder representing a message root located in the given segment at the given + // location. + + inline bool isNull() { return getPointerType() == PointerType::NULL_; } + PointerType getPointerType() const; + + StructBuilder getStruct(StructSize size, const word* defaultValue); + ListBuilder getList(ElementSize elementSize, const word* defaultValue); + ListBuilder getStructList(StructSize elementSize, const word* defaultValue); + ListBuilder getListAnySize(const word* defaultValue); + template typename T::Builder getBlob( + const void* defaultValue, ByteCount defaultSize); +#if !CAPNP_LITE + kj::Own getCapability(); +#endif // !CAPNP_LITE + // Get methods: Get the value. If it is null, initialize it to a copy of the default value. + // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a + // simple byte array for blobs. + + StructBuilder initStruct(StructSize size); + ListBuilder initList(ElementSize elementSize, ElementCount elementCount); + ListBuilder initStructList(ElementCount elementCount, StructSize size); + template typename T::Builder initBlob(ByteCount size); + // Init methods: Initialize the pointer to a newly-allocated object, discarding the existing + // object. + + void setStruct(const StructReader& value, bool canonical = false); + void setList(const ListReader& value, bool canonical = false); + template void setBlob(typename T::Reader value); +#if !CAPNP_LITE + void setCapability(kj::Own&& cap); +#endif // !CAPNP_LITE + // Set methods: Initialize the pointer to a newly-allocated copy of the given value, discarding + // the existing object. + + void adopt(OrphanBuilder&& orphan); + // Set the pointer to point at the given orphaned value. + + OrphanBuilder disown(); + // Set the pointer to null and return its previous value as an orphan. + + void clear(); + // Clear the pointer to null, discarding its previous value. + + void transferFrom(PointerBuilder other); + // Equivalent to `adopt(other.disown())`. + + void copyFrom(PointerReader other, bool canonical = false); + // Equivalent to `set(other.get())`. + // If you set the canonical flag, it will attempt to lay the target out + // canonically, provided enough space is available. + + PointerReader asReader() const; + + BuilderArena* getArena() const; + // Get the arena containing this pointer. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + PointerBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the pointer resides. + CapTableBuilder* capTable; // Table of capability indexes. + WirePointer* pointer; // Pointer to the pointer. + + inline PointerBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* pointer) + : segment(segment), capTable(capTable), pointer(pointer) {} + + friend class StructBuilder; + friend class ListBuilder; + friend class OrphanBuilder; +}; + +class PointerReader { +public: + inline PointerReader() + : segment(nullptr), capTable(nullptr), pointer(nullptr), nestingLimit(0x7fffffff) {} + + static PointerReader getRoot(SegmentReader* segment, CapTableReader* capTable, + const word* location, int nestingLimit); + // Get a PointerReader representing a message root located in the given segment at the given + // location. + + static inline PointerReader getRootUnchecked(const word* location); + // Get a PointerReader for an unchecked message. + + MessageSizeCounts targetSize() const; + // Return the total size of the target object and everything to which it points. Does not count + // far pointer overhead. This is useful for deciding how much space is needed to copy the object + // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, + // use the result as a hint for allocating the first segment, do the copy, and then throw an + // exception if it overruns. + + inline bool isNull() const { return getPointerType() == PointerType::NULL_; } + PointerType getPointerType() const; + + StructReader getStruct(const word* defaultValue) const; + ListReader getList(ElementSize expectedElementSize, const word* defaultValue) const; + ListReader getListAnySize(const word* defaultValue) const; + template + typename T::Reader getBlob(const void* defaultValue, ByteCount defaultSize) const; +#if !CAPNP_LITE + kj::Own getCapability() const; +#endif // !CAPNP_LITE + // Get methods: Get the value. If it is null, return the default value instead. + // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a + // simple byte array for blobs. + + const word* getUnchecked() const; + // If this is an unchecked message, get a word* pointing at the location of the pointer. This + // word* can actually be passed to readUnchecked() to read the designated sub-object later. If + // this isn't an unchecked message, throws an exception. + + kj::Maybe getArena() const; + // Get the arena containing this pointer. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + PointerReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + +private: + SegmentReader* segment; // Memory segment in which the pointer resides. + CapTableReader* capTable; // Table of capability indexes. + const WirePointer* pointer; // Pointer to the pointer. null = treat as null pointer. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + + inline PointerReader(SegmentReader* segment, CapTableReader* capTable, + const WirePointer* pointer, int nestingLimit) + : segment(segment), capTable(capTable), pointer(pointer), nestingLimit(nestingLimit) {} + + friend class StructReader; + friend class ListReader; + friend class PointerBuilder; + friend class OrphanBuilder; +}; + +// ------------------------------------------------------------------- + +class StructBuilder: public kj::DisallowConstCopy { +public: + inline StructBuilder(): segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr) {} + + inline word* getLocation() { return reinterpret_cast(data); } + // Get the object's location. Only valid for independently-allocated objects (i.e. not list + // elements). + + inline StructDataBitCount getDataSectionSize() const { return dataSize; } + inline StructPointerCount getPointerSectionSize() const { return pointerCount; } + inline kj::ArrayPtr getDataSectionAsBlob(); + inline _::ListBuilder getPointerSectionAsList(); + + template + KJ_ALWAYS_INLINE(bool hasDataField(StructDataOffset offset)); + // Return true if the field is set to something other than its default value. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset)); + // Gets the data field value of the given type at the given offset. The offset is measured in + // multiples of the field size, determined by the type. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset, Mask mask)); + // Like getDataField() but applies the given XOR mask to the data on load. Used for reading + // fields with non-zero default values. + + template + KJ_ALWAYS_INLINE(void setDataField(StructDataOffset offset, kj::NoInfer value)); + // Sets the data field value at the given offset. + + template + KJ_ALWAYS_INLINE(void setDataField(StructDataOffset offset, + kj::NoInfer value, Mask mask)); + // Like setDataField() but applies the given XOR mask before storing. Used for writing fields + // with non-zero default values. + + KJ_ALWAYS_INLINE(PointerBuilder getPointerField(StructPointerOffset ptrIndex)); + // Get a builder for a pointer field given the index within the pointer section. + + void clearAll(); + // Clear all pointers and data. + + void transferContentFrom(StructBuilder other); + // Adopt all pointers from `other`, and also copy all data. If `other`'s sections are larger + // than this, the extra data is not transferred, meaning there is a risk of data loss when + // transferring from messages built with future versions of the protocol. + + void copyContentFrom(StructReader other); + // Copy content from `other`. If `other`'s sections are larger than this, the extra data is not + // copied, meaning there is a risk of data loss when copying from messages built with future + // versions of the protocol. + + StructReader asReader() const; + // Gets a StructReader pointing at the same memory. + + BuilderArena* getArena(); + // Gets the arena in which this object is allocated. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + StructBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the struct resides. + CapTableBuilder* capTable; // Table of capability indexes. + void* data; // Pointer to the encoded data. + WirePointer* pointers; // Pointer to the encoded pointers. + + StructDataBitCount dataSize; + // Size of data section. We use a bit count rather than a word count to more easily handle the + // case of struct lists encoded with less than a word per element. + + StructPointerCount pointerCount; // Size of the pointer section. + + inline StructBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, + void* data, WirePointer* pointers, + StructDataBitCount dataSize, StructPointerCount pointerCount) + : segment(segment), capTable(capTable), data(data), pointers(pointers), + dataSize(dataSize), pointerCount(pointerCount) {} + + friend class ListBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +class StructReader { +public: + inline StructReader() + : segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr), + dataSize(ZERO * BITS), pointerCount(ZERO * POINTERS), nestingLimit(0x7fffffff) {} + inline StructReader(kj::ArrayPtr data) + : segment(nullptr), capTable(nullptr), data(data.begin()), pointers(nullptr), + dataSize(assumeBits(data.size()) * WORDS * BITS_PER_WORD), + pointerCount(ZERO * POINTERS), nestingLimit(0x7fffffff) {} + + const void* getLocation() const { return data; } + + inline StructDataBitCount getDataSectionSize() const { return dataSize; } + inline StructPointerCount getPointerSectionSize() const { return pointerCount; } + inline kj::ArrayPtr getDataSectionAsBlob() const; + inline _::ListReader getPointerSectionAsList() const; + + kj::Array canonicalize(); + + template + KJ_ALWAYS_INLINE(bool hasDataField(StructDataOffset offset) const); + // Return true if the field is set to something other than its default value. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset) const); + // Get the data field value of the given type at the given offset. The offset is measured in + // multiples of the field size, determined by the type. Returns zero if the offset is past the + // end of the struct's data section. + + template + KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset, Mask mask) const); + // Like getDataField(offset), but applies the given XOR mask to the result. Used for reading + // fields with non-zero default values. + + KJ_ALWAYS_INLINE(PointerReader getPointerField(StructPointerOffset ptrIndex) const); + // Get a reader for a pointer field given the index within the pointer section. If the index + // is out-of-bounds, returns a null pointer. + + MessageSizeCounts totalSize() const; + // Return the total size of the struct and everything to which it points. Does not count far + // pointer overhead. This is useful for deciding how much space is needed to copy the struct + // into a flat array. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + StructReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead, const word **ptrHead, + bool *dataTrunc, bool *ptrTrunc); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + // + // If this function returns false, the struct is non-canonical. If it + // returns true, then: + // * If it is a composite in a list, it is canonical if at least one struct + // in the list outputs dataTrunc = 1, and at least one outputs ptrTrunc = 1 + // * If it is derived from a struct pointer, it is canonical if + // dataTrunc = 1 AND ptrTrunc = 1 + +private: + SegmentReader* segment; // Memory segment in which the struct resides. + CapTableReader* capTable; // Table of capability indexes. + + const void* data; + const WirePointer* pointers; + + StructDataBitCount dataSize; + // Size of data section. We use a bit count rather than a word count to more easily handle the + // case of struct lists encoded with less than a word per element. + + StructPointerCount pointerCount; // Size of the pointer section. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + // TODO(perf): Limit to 16 bits for better packing? + + inline StructReader(SegmentReader* segment, CapTableReader* capTable, + const void* data, const WirePointer* pointers, + StructDataBitCount dataSize, StructPointerCount pointerCount, + int nestingLimit) + : segment(segment), capTable(capTable), data(data), pointers(pointers), + dataSize(dataSize), pointerCount(pointerCount), + nestingLimit(nestingLimit) {} + + friend class ListReader; + friend class StructBuilder; + friend struct WireHelpers; +}; + +// ------------------------------------------------------------------- + +class ListBuilder: public kj::DisallowConstCopy { +public: + inline explicit ListBuilder(ElementSize elementSize) + : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(ZERO * ELEMENTS), + step(ZERO * BITS / ELEMENTS), structDataSize(ZERO * BITS), + structPointerCount(ZERO * POINTERS), elementSize(elementSize) {} + + inline word* getLocation() { + // Get the object's location. + + if (elementSize == ElementSize::INLINE_COMPOSITE && ptr != nullptr) { + return reinterpret_cast(ptr) - POINTER_SIZE_IN_WORDS; + } else { + return reinterpret_cast(ptr); + } + } + + inline ElementSize getElementSize() const { return elementSize; } + + inline ListElementCount size() const; + // The number of elements in the list. + + Text::Builder asText(); + Data::Builder asData(); + // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. + + template + KJ_ALWAYS_INLINE(T getDataElement(ElementCount index)); + // Get the element of the given type at the given index. + + template + KJ_ALWAYS_INLINE(void setDataElement(ElementCount index, kj::NoInfer value)); + // Set the element at the given index. + + KJ_ALWAYS_INLINE(PointerBuilder getPointerElement(ElementCount index)); + + StructBuilder getStructElement(ElementCount index); + + ListReader asReader() const; + // Get a ListReader pointing at the same memory. + + BuilderArena* getArena(); + // Gets the arena in which this object is allocated. + + CapTableBuilder* getCapTable(); + // Gets the capability context in which this object is operating. + + ListBuilder imbue(CapTableBuilder* capTable); + // Return a copy of this builder except using the given capability context. + +private: + SegmentBuilder* segment; // Memory segment in which the list resides. + CapTableBuilder* capTable; // Table of capability indexes. + + byte* ptr; // Pointer to list content. + + ListElementCount elementCount; // Number of elements in the list. + + BitsPerElementN<23> step; + // The distance between elements. The maximum value occurs when a struct contains 2^16-1 data + // words and 2^16-1 pointers, i.e. 2^17 - 2 words, or 2^23 - 128 bits. + + StructDataBitCount structDataSize; + StructPointerCount structPointerCount; + // The struct properties to use when interpreting the elements as structs. All lists can be + // interpreted as struct lists, so these are always filled in. + + ElementSize elementSize; + // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE + // from other types when the overall size is exactly zero or one words. + + inline ListBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, void* ptr, + BitsPerElementN<23> step, ListElementCount size, + StructDataBitCount structDataSize, StructPointerCount structPointerCount, + ElementSize elementSize) + : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), + elementCount(size), step(step), structDataSize(structDataSize), + structPointerCount(structPointerCount), elementSize(elementSize) {} + + friend class StructBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +class ListReader { +public: + inline explicit ListReader(ElementSize elementSize) + : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(ZERO * ELEMENTS), + step(ZERO * BITS / ELEMENTS), structDataSize(ZERO * BITS), + structPointerCount(ZERO * POINTERS), elementSize(elementSize), nestingLimit(0x7fffffff) {} + + inline ListElementCount size() const; + // The number of elements in the list. + + inline ElementSize getElementSize() const { return elementSize; } + + Text::Reader asText(); + Data::Reader asData(); + // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. + + kj::ArrayPtr asRawBytes() const; + + template + KJ_ALWAYS_INLINE(T getDataElement(ElementCount index) const); + // Get the element of the given type at the given index. + + KJ_ALWAYS_INLINE(PointerReader getPointerElement(ElementCount index) const); + + StructReader getStructElement(ElementCount index) const; + + MessageSizeCounts totalSize() const; + // Like StructReader::totalSize(). Note that for struct lists, the size includes the list tag. + + CapTableReader* getCapTable(); + // Gets the capability context in which this object is operating. + + ListReader imbue(CapTableReader* capTable) const; + // Return a copy of this reader except using the given capability context. + + bool isCanonical(const word **readHead, const WirePointer* ref); + // Validate this pointer's canonicity, subject to the conditions: + // * All data to the left of readHead has been read thus far (for pointer + // ordering) + // * All pointers in preorder have already been checked + // * This pointer is in the first and only segment of the message + +private: + SegmentReader* segment; // Memory segment in which the list resides. + CapTableReader* capTable; // Table of capability indexes. + + const byte* ptr; // Pointer to list content. + + ListElementCount elementCount; // Number of elements in the list. + + BitsPerElementN<23> step; + // The distance between elements. The maximum value occurs when a struct contains 2^16-1 data + // words and 2^16-1 pointers, i.e. 2^17 - 2 words, or 2^23 - 2 bits. + + StructDataBitCount structDataSize; + StructPointerCount structPointerCount; + // The struct properties to use when interpreting the elements as structs. All lists can be + // interpreted as struct lists, so these are always filled in. + + ElementSize elementSize; + // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE + // from other types when the overall size is exactly zero or one words. + + int nestingLimit; + // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. + // Once this reaches zero, further pointers will be pruned. + + inline ListReader(SegmentReader* segment, CapTableReader* capTable, const void* ptr, + ListElementCount elementCount, BitsPerElementN<23> step, + StructDataBitCount structDataSize, StructPointerCount structPointerCount, + ElementSize elementSize, int nestingLimit) + : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), + elementCount(elementCount), step(step), structDataSize(structDataSize), + structPointerCount(structPointerCount), elementSize(elementSize), + nestingLimit(nestingLimit) {} + + friend class StructReader; + friend class ListBuilder; + friend struct WireHelpers; + friend class OrphanBuilder; +}; + +// ------------------------------------------------------------------- + +class OrphanBuilder { +public: + inline OrphanBuilder(): segment(nullptr), capTable(nullptr), location(nullptr) { + memset(&tag, 0, sizeof(tag)); + } + OrphanBuilder(const OrphanBuilder& other) = delete; + inline OrphanBuilder(OrphanBuilder&& other) noexcept; + inline ~OrphanBuilder() noexcept(false); + + static OrphanBuilder initStruct(BuilderArena* arena, CapTableBuilder* capTable, StructSize size); + static OrphanBuilder initList(BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, ElementSize elementSize); + static OrphanBuilder initStructList(BuilderArena* arena, CapTableBuilder* capTable, + ElementCount elementCount, StructSize elementSize); + static OrphanBuilder initText(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); + static OrphanBuilder initData(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); + + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, StructReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, ListReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, PointerReader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Text::Reader copyFrom); + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Data::Reader copyFrom); +#if !CAPNP_LITE + static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, + kj::Own copyFrom); +#endif // !CAPNP_LITE + + static OrphanBuilder concat(BuilderArena* arena, CapTableBuilder* capTable, + ElementSize expectedElementSize, StructSize expectedStructSize, + kj::ArrayPtr lists); + + static OrphanBuilder referenceExternalData(BuilderArena* arena, Data::Reader data); + + OrphanBuilder& operator=(const OrphanBuilder& other) = delete; + inline OrphanBuilder& operator=(OrphanBuilder&& other); + + inline bool operator==(decltype(nullptr)) const { return location == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return location != nullptr; } + + StructBuilder asStruct(StructSize size); + // Interpret as a struct, or throw an exception if not a struct. + + ListBuilder asList(ElementSize elementSize); + // Interpret as a list, or throw an exception if not a list. elementSize cannot be + // INLINE_COMPOSITE -- use asStructList() instead. + + ListBuilder asStructList(StructSize elementSize); + // Interpret as a struct list, or throw an exception if not a list. + + ListBuilder asListAnySize(); + // For AnyList. + + Text::Builder asText(); + Data::Builder asData(); + // Interpret as a blob, or throw an exception if not a blob. + + StructReader asStructReader(StructSize size) const; + ListReader asListReader(ElementSize elementSize) const; + ListReader asListReaderAnySize() const; +#if !CAPNP_LITE + kj::Own asCapability() const; +#endif // !CAPNP_LITE + Text::Reader asTextReader() const; + Data::Reader asDataReader() const; + + bool truncate(ElementCount size, bool isText) KJ_WARN_UNUSED_RESULT; + // Resize the orphan list to the given size. Returns false if the list is currently empty but + // the requested size is non-zero, in which case the caller will need to allocate a new list. + + void truncate(ElementCount size, ElementSize elementSize); + void truncate(ElementCount size, StructSize elementSize); + void truncateText(ElementCount size); + // Versions of truncate() that know how to allocate a new list if needed. + +private: + static_assert(ONE * POINTERS * WORDS_PER_POINTER == ONE * WORDS, + "This struct assumes a pointer is one word."); + word tag; + // Contains an encoded WirePointer representing this object. WirePointer is defined in + // layout.c++, but fits in a word. + // + // This may be a FAR pointer. Even in that case, `location` points to the eventual destination + // of that far pointer. The reason we keep the far pointer around rather than just making `tag` + // represent the final destination is because if the eventual adopter of the pointer is not in + // the target's segment then it may be useful to reuse the far pointer landing pad. + // + // If `tag` is not a far pointer, its offset is garbage; only `location` points to the actual + // target. + + SegmentBuilder* segment; + // Segment in which the object resides. + + CapTableBuilder* capTable; + // Table of capability indexes. + + word* location; + // Pointer to the object, or nullptr if the pointer is null. For capabilities, we make this + // 0x1 just so that it is non-null for operator==, but it is never used. + + inline OrphanBuilder(const void* tagPtr, SegmentBuilder* segment, + CapTableBuilder* capTable, word* location) + : segment(segment), capTable(capTable), location(location) { + memcpy(&tag, tagPtr, sizeof(tag)); + } + + inline WirePointer* tagAsPtr() { return reinterpret_cast(&tag); } + inline const WirePointer* tagAsPtr() const { return reinterpret_cast(&tag); } + + void euthanize(); + // Erase the target object, zeroing it out and possibly reclaiming the memory. Called when + // the OrphanBuilder is being destroyed or overwritten and it is non-null. + + friend struct WireHelpers; +}; + +// ======================================================================================= +// Internal implementation details... + +// These are defined in the source file. +template <> typename Text::Builder PointerBuilder::initBlob(ByteCount size); +template <> void PointerBuilder::setBlob(typename Text::Reader value); +template <> typename Text::Builder PointerBuilder::getBlob( + const void* defaultValue, ByteCount defaultSize); +template <> typename Text::Reader PointerReader::getBlob( + const void* defaultValue, ByteCount defaultSize) const; + +template <> typename Data::Builder PointerBuilder::initBlob(ByteCount size); +template <> void PointerBuilder::setBlob(typename Data::Reader value); +template <> typename Data::Builder PointerBuilder::getBlob( + const void* defaultValue, ByteCount defaultSize); +template <> typename Data::Reader PointerReader::getBlob( + const void* defaultValue, ByteCount defaultSize) const; + +inline PointerBuilder PointerBuilder::getRoot( + SegmentBuilder* segment, CapTableBuilder* capTable, word* location) { + return PointerBuilder(segment, capTable, reinterpret_cast(location)); +} + +inline PointerReader PointerReader::getRootUnchecked(const word* location) { + return PointerReader(nullptr, nullptr, + reinterpret_cast(location), 0x7fffffff); +} + +// ------------------------------------------------------------------- + +inline kj::ArrayPtr StructBuilder::getDataSectionAsBlob() { + return kj::ArrayPtr(reinterpret_cast(data), + unbound(dataSize / BITS_PER_BYTE / BYTES)); +} + +inline _::ListBuilder StructBuilder::getPointerSectionAsList() { + return _::ListBuilder(segment, capTable, pointers, ONE * POINTERS * BITS_PER_POINTER / ELEMENTS, + pointerCount * (ONE * ELEMENTS / POINTERS), + ZERO * BITS, ONE * POINTERS, ElementSize::POINTER); +} + +template +inline bool StructBuilder::hasDataField(StructDataOffset offset) { + return getDataField>(offset) != 0; +} + +template <> +inline bool StructBuilder::hasDataField(StructDataOffset offset) { + return false; +} + +template +inline T StructBuilder::getDataField(StructDataOffset offset) { + return reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].get(); +} + +template <> +inline bool StructBuilder::getDataField(StructDataOffset offset) { + BitCount32 boffset = offset * (ONE * BITS / ELEMENTS); + byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (boffset % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void StructBuilder::getDataField(StructDataOffset offset) { + return VOID; +} + +template +inline T StructBuilder::getDataField(StructDataOffset offset, Mask mask) { + return unmask(getDataField >(offset), mask); +} + +template +inline void StructBuilder::setDataField(StructDataOffset offset, kj::NoInfer value) { + reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].set(value); +} + +#if CAPNP_CANONICALIZE_NAN +// Use mask() on floats and doubles to make sure we canonicalize NaNs. +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, float value) { + setDataField(offset, mask(value, 0)); +} +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, double value) { + setDataField(offset, mask(value, 0)); +} +#endif + +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, bool value) { + auto boffset = offset * (ONE * BITS / ELEMENTS); + byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; + uint bitnum = unboundMaxBits<3>(boffset % BITS_PER_BYTE / BITS); + *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << bitnum)) + | (static_cast(value) << bitnum); +} + +template <> +inline void StructBuilder::setDataField(StructDataOffset offset, Void value) {} + +template +inline void StructBuilder::setDataField(StructDataOffset offset, + kj::NoInfer value, Mask m) { + setDataField >(offset, mask(value, m)); +} + +inline PointerBuilder StructBuilder::getPointerField(StructPointerOffset ptrIndex) { + // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). + return PointerBuilder(segment, capTable, reinterpret_cast( + reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER)); +} + +// ------------------------------------------------------------------- + +inline kj::ArrayPtr StructReader::getDataSectionAsBlob() const { + return kj::ArrayPtr(reinterpret_cast(data), + unbound(dataSize / BITS_PER_BYTE / BYTES)); +} + +inline _::ListReader StructReader::getPointerSectionAsList() const { + return _::ListReader(segment, capTable, pointers, pointerCount * (ONE * ELEMENTS / POINTERS), + ONE * POINTERS * BITS_PER_POINTER / ELEMENTS, ZERO * BITS, ONE * POINTERS, + ElementSize::POINTER, nestingLimit); +} + +template +inline bool StructReader::hasDataField(StructDataOffset offset) const { + return getDataField>(offset) != 0; +} + +template <> +inline bool StructReader::hasDataField(StructDataOffset offset) const { + return false; +} + +template +inline T StructReader::getDataField(StructDataOffset offset) const { + if ((offset + ONE * ELEMENTS) * capnp::bitsPerElement() <= dataSize) { + return reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].get(); + } else { + return static_cast(0); + } +} + +template <> +inline bool StructReader::getDataField(StructDataOffset offset) const { + auto boffset = offset * (ONE * BITS / ELEMENTS); + if (boffset < dataSize) { + const byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (boffset % BITS_PER_BYTE / BITS))) != 0; + } else { + return false; + } +} + +template <> +inline Void StructReader::getDataField(StructDataOffset offset) const { + return VOID; +} + +template +T StructReader::getDataField(StructDataOffset offset, Mask mask) const { + return unmask(getDataField >(offset), mask); +} + +inline PointerReader StructReader::getPointerField(StructPointerOffset ptrIndex) const { + if (ptrIndex < pointerCount) { + // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). + return PointerReader(segment, capTable, reinterpret_cast( + reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER), nestingLimit); + } else{ + return PointerReader(); + } +} + +// ------------------------------------------------------------------- + +inline ListElementCount ListBuilder::size() const { return elementCount; } + +template +inline T ListBuilder::getDataElement(ElementCount index) { + return reinterpret_cast*>( + ptr + upgradeBound(index) * step / BITS_PER_BYTE)->get(); + + // TODO(perf): Benchmark this alternate implementation, which I suspect may make better use of + // the x86 SIB byte. Also use it for all the other getData/setData implementations below, and + // the various non-inline methods that look up pointers. + // Also if using this, consider changing ptr back to void* instead of byte*. +// return reinterpret_cast*>(ptr)[ +// index / ELEMENTS * (step / capnp::bitsPerElement())].get(); +} + +template <> +inline bool ListBuilder::getDataElement(ElementCount index) { + // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. + auto bindex = index * (ONE * BITS / ELEMENTS); + byte* b = ptr + bindex / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (bindex % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void ListBuilder::getDataElement(ElementCount index) { + return VOID; +} + +template +inline void ListBuilder::setDataElement(ElementCount index, kj::NoInfer value) { + reinterpret_cast*>( + ptr + upgradeBound(index) * step / BITS_PER_BYTE)->set(value); +} + +#if CAPNP_CANONICALIZE_NAN +// Use mask() on floats and doubles to make sure we canonicalize NaNs. +template <> +inline void ListBuilder::setDataElement(ElementCount index, float value) { + setDataElement(index, mask(value, 0)); +} +template <> +inline void ListBuilder::setDataElement(ElementCount index, double value) { + setDataElement(index, mask(value, 0)); +} +#endif + +template <> +inline void ListBuilder::setDataElement(ElementCount index, bool value) { + // Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists. + auto bindex = index * (ONE * BITS / ELEMENTS); + byte* b = ptr + bindex / BITS_PER_BYTE; + auto bitnum = bindex % BITS_PER_BYTE / BITS; + *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << unbound(bitnum))) + | (static_cast(value) << unbound(bitnum)); +} + +template <> +inline void ListBuilder::setDataElement(ElementCount index, Void value) {} + +inline PointerBuilder ListBuilder::getPointerElement(ElementCount index) { + return PointerBuilder(segment, capTable, reinterpret_cast(ptr + + upgradeBound(index) * step / BITS_PER_BYTE)); +} + +// ------------------------------------------------------------------- + +inline ListElementCount ListReader::size() const { return elementCount; } + +template +inline T ListReader::getDataElement(ElementCount index) const { + return reinterpret_cast*>( + ptr + upgradeBound(index) * step / BITS_PER_BYTE)->get(); +} + +template <> +inline bool ListReader::getDataElement(ElementCount index) const { + // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. + auto bindex = index * (ONE * BITS / ELEMENTS); + const byte* b = ptr + bindex / BITS_PER_BYTE; + return (*reinterpret_cast(b) & + unbound(ONE << (bindex % BITS_PER_BYTE / BITS))) != 0; +} + +template <> +inline Void ListReader::getDataElement(ElementCount index) const { + return VOID; +} + +inline PointerReader ListReader::getPointerElement(ElementCount index) const { + // If the list elements have data sections we need to skip those. Note that for pointers to be + // present at all (which already must be true if we get here), then `structDataSize` must be a + // whole number of words, so we don't have to worry about unaligned reads here. + auto offset = structDataSize / BITS_PER_BYTE; + return PointerReader(segment, capTable, reinterpret_cast( + ptr + offset + upgradeBound(index) * step / BITS_PER_BYTE), nestingLimit); +} + +// ------------------------------------------------------------------- + +inline OrphanBuilder::OrphanBuilder(OrphanBuilder&& other) noexcept + : segment(other.segment), capTable(other.capTable), location(other.location) { + memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. + other.segment = nullptr; + other.location = nullptr; +} + +inline OrphanBuilder::~OrphanBuilder() noexcept(false) { + if (segment != nullptr) euthanize(); +} + +inline OrphanBuilder& OrphanBuilder::operator=(OrphanBuilder&& other) { + // With normal smart pointers, it's important to handle the case where the incoming pointer + // is actually transitively owned by this one. In this case, euthanize() would destroy `other` + // before we copied it. This isn't possible in the case of `OrphanBuilder` because it only + // owns message objects, and `other` is not itself a message object, therefore cannot possibly + // be transitively owned by `this`. + + if (segment != nullptr) euthanize(); + segment = other.segment; + capTable = other.capTable; + location = other.location; + memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. + other.segment = nullptr; + other.location = nullptr; + return *this; +} + +} // namespace _ (private) +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/list.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/list.cc new file mode 100644 index 000000000..176c21f10 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/list.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "list.h" + +namespace capnp { + +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/list.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/list.h new file mode 100644 index 000000000..2c777f817 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/list.h @@ -0,0 +1,552 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "layout.h" +#include "orphan.h" +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace _ { // private + +template +class TemporaryPointer { + // This class is a little hack which lets us define operator->() in cases where it needs to + // return a pointer to a temporary value. We instead construct a TemporaryPointer and return that + // (by value). The compiler then invokes operator->() on the TemporaryPointer, which itself is + // able to return a real pointer to its member. + +public: + TemporaryPointer(T&& value): value(kj::mv(value)) {} + TemporaryPointer(const T& value): value(value) {} + + inline T* operator->() { return &value; } +private: + T value; +}; + +// By default this isn't compatible with STL algorithms. To add STL support either define +// KJ_STD_COMPAT at the top of your compilation unit or include capnp/compat/std-iterator.h. +template +class IndexingIterator { +public: + IndexingIterator() = default; + + inline Element operator*() const { return (*container)[index]; } + inline TemporaryPointer operator->() const { + return TemporaryPointer((*container)[index]); + } + inline Element operator[]( int off) const { return (*container)[index]; } + inline Element operator[](uint off) const { return (*container)[index]; } + + inline IndexingIterator& operator++() { ++index; return *this; } + inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; } + inline IndexingIterator& operator--() { --index; return *this; } + inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; } + + inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); } + inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); } + inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); } + inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); } + + inline int operator-(const IndexingIterator& other) const { return index - other.index; } + + inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; } + inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; } + inline IndexingIterator& operator+=( int amount) { index += amount; return *this; } + inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; } + + // STL says comparing iterators of different containers is not allowed, so we only compare + // indices here. + inline bool operator==(const IndexingIterator& other) const { return index == other.index; } + inline bool operator!=(const IndexingIterator& other) const { return index != other.index; } + inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; } + inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; } + inline bool operator< (const IndexingIterator& other) const { return index < other.index; } + inline bool operator> (const IndexingIterator& other) const { return index > other.index; } + +private: + Container* container; + uint index; + + friend Container; + inline IndexingIterator(Container* container, uint index) + : container(container), index(index) {} +}; + +} // namespace _ (private) + +template +struct List { + // List of primitives. + + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(_::elementSizeForType()) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline T operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return reader.template getDataElement(bounded(index) * ELEMENTS); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + inline Builder(): builder(_::elementSizeForType()) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline T operator[](uint index) { + KJ_IREQUIRE(index < size()); + return builder.template getDataElement(bounded(index) * ELEMENTS); + } + inline void set(uint index, T value) { + // Alas, it is not possible to make operator[] return a reference to which you can assign, + // since the encoded representation does not necessarily match the compiler's representation + // of the type. We can't even return a clever class that implements operator T() and + // operator=() because it will lead to surprising behavior when using type inference (e.g. + // calling a template function with inferred argument types, or using "auto" or "decltype"). + + builder.template setDataElement(bounded(index) * ELEMENTS, value); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(_::elementSizeForType(), bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(_::elementSizeForType(), defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(_::elementSizeForType(), defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +template +struct List: public List {}; + +template +struct List { + // List of structs. + + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename T::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename T::Reader(reader.getStructElement(bounded(index) * ELEMENTS)); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + inline Builder(): builder(ElementSize::INLINE_COMPOSITE) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename T::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename T::Builder(builder.getStructElement(bounded(index) * ELEMENTS)); + } + + inline void adoptWithCaveats(uint index, Orphan&& orphan) { + // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from + // the fact that structs in a struct list are allocated inline rather than by pointer: + // * This actually performs a shallow copy, effectively adopting each of the orphan's + // children rather than adopting the orphan itself. The orphan ends up being discarded, + // possibly wasting space in the message object. + // * If the orphan is larger than the target struct -- say, because the orphan was built + // using a newer version of the schema that has additional fields -- it will be truncated, + // losing data. + + KJ_IREQUIRE(index < size()); + + // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be + // expanded under any circumstances. We're just going to throw it away anyway, and + // transferContentFrom() already carefully compares the struct sizes before transferring. + builder.getStructElement(bounded(index) * ELEMENTS).transferContentFrom( + orphan.builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); + } + inline void setWithCaveats(uint index, const typename T::Reader& reader) { + // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from + // the fact that structs in a struct list are allocated inline rather than by pointer: + // If the source struct is larger than the target struct -- say, because the source was built + // using a newer version of the schema that has additional fields -- it will be truncated, + // losing data. + // + // Note: If you are trying to concatenate some lists, use Orphanage::newOrphanConcat() to + // do it without losing any data in case the source lists come from a newer version of the + // protocol. (Plus, it's easier to use anyhow.) + + KJ_IREQUIRE(index < size()); + builder.getStructElement(bounded(index) * ELEMENTS).copyContentFrom(reader._reader); + } + + // There are no init(), set(), adopt(), or disown() methods for lists of structs because the + // elements of the list are inlined and are initialized when the list is initialized. This + // means that init() would be redundant, and set() would risk data loss if the input struct + // were from a newer version of the protocol. + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initStructList(bounded(size) * ELEMENTS, _::structSize()); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getStructList(_::structSize(), defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::INLINE_COMPOSITE, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +template +struct List, Kind::LIST> { + // List of lists. + + List() = delete; + + class Reader { + public: + typedef List> Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename List::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return typename List::Reader(_::PointerHelpers>::get( + reader.getPointerElement(bounded(index) * ELEMENTS))); + } + + typedef _::IndexingIterator::Reader> Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List> Builds; + + inline Builder(): builder(ElementSize::POINTER) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename List::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return typename List::Builder(_::PointerHelpers>::get( + builder.getPointerElement(bounded(index) * ELEMENTS))); + } + inline typename List::Builder init(uint index, uint size) { + KJ_IREQUIRE(index < this->size()); + return typename List::Builder(_::PointerHelpers>::init( + builder.getPointerElement(bounded(index) * ELEMENTS), size)); + } + inline void set(uint index, typename List::Reader value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).setList(value.reader); + } + void set(uint index, std::initializer_list> value) { + KJ_IREQUIRE(index < size()); + auto l = init(index, value.size()); + uint i = 0; + for (auto& element: value) { + l.set(i++, element); + } + } + inline void adopt(uint index, Orphan>&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder)); + } + inline Orphan> disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan>(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); + } + + typedef _::IndexingIterator::Builder> Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +template +struct List { + List() = delete; + + class Reader { + public: + typedef List Reads; + + inline Reader(): reader(ElementSize::POINTER) {} + inline explicit Reader(_::ListReader reader): reader(reader) {} + + inline uint size() const { return unbound(reader.size() / ELEMENTS); } + inline typename T::Reader operator[](uint index) const { + KJ_IREQUIRE(index < size()); + return reader.getPointerElement(bounded(index) * ELEMENTS) + .template getBlob(nullptr, ZERO * BYTES); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + + inline MessageSize totalSize() const { + return reader.totalSize().asPublic(); + } + + private: + _::ListReader reader; + template + friend struct _::PointerHelpers; + template + friend struct List; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Builder { + public: + typedef List Builds; + + inline Builder(): builder(ElementSize::POINTER) {} + inline Builder(decltype(nullptr)): Builder() {} + inline explicit Builder(_::ListBuilder builder): builder(builder) {} + + inline operator Reader() const { return Reader(builder.asReader()); } + inline Reader asReader() const { return Reader(builder.asReader()); } + + inline uint size() const { return unbound(builder.size() / ELEMENTS); } + inline typename T::Builder operator[](uint index) { + KJ_IREQUIRE(index < size()); + return builder.getPointerElement(bounded(index) * ELEMENTS) + .template getBlob(nullptr, ZERO * BYTES); + } + inline void set(uint index, typename T::Reader value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).template setBlob(value); + } + inline typename T::Builder init(uint index, uint size) { + KJ_IREQUIRE(index < this->size()); + return builder.getPointerElement(bounded(index) * ELEMENTS) + .template initBlob(bounded(size) * BYTES); + } + inline void adopt(uint index, Orphan&& value) { + KJ_IREQUIRE(index < size()); + builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder)); + } + inline Orphan disown(uint index) { + KJ_IREQUIRE(index < size()); + return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() { return Iterator(this, 0); } + inline Iterator end() { return Iterator(this, size()); } + + private: + _::ListBuilder builder; + template + friend struct _::PointerHelpers; + friend class Orphanage; + template + friend struct ToDynamic_; + }; + + class Pipeline {}; + +private: + inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { + return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); + } + inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { + return builder.getList(ElementSize::POINTER, defaultValue); + } + inline static _::ListReader getFromPointer( + const _::PointerReader& reader, const word* defaultValue) { + return reader.getList(ElementSize::POINTER, defaultValue); + } + + template + friend struct List; + template + friend struct _::PointerHelpers; +}; + +} // namespace capnp + +#ifdef KJ_STD_COMPAT +#include "compat/std-iterator.h" +#endif // KJ_STD_COMPAT + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/membrane.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/membrane.h new file mode 100644 index 000000000..60629cb4d --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/membrane.h @@ -0,0 +1,299 @@ +// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +// In capability theory, a "membrane" is a wrapper around a capability which (usually) forwards +// calls but recursively wraps capabilities in those calls in the same membrane. The purpose of a +// membrane is to enforce a barrier between two capabilities that cannot be bypassed by merely +// introducing new objects. +// +// The most common use case for a membrane is revocation: Say Alice wants to give Bob a capability +// to access Carol, but wants to be able to revoke this capability later. Alice can accomplish this +// by wrapping Carol in a revokable wrapper which passes through calls until such a time as Alice +// indicates it should be revoked, after which all calls through the wrapper will throw exceptions. +// However, a naive wrapper approach has a problem: if Bob makes a call to Carol and sends a new +// capability in that call, or if Carol returns a capability to Bob in the response to a call, then +// the two are now able to communicate using this new capability, which Alice cannot revoke. In +// order to avoid this problem, Alice must use not just a wrapper but a "membrane", which +// recursively wraps all objects that pass through it in either direction. Thus, all connections +// formed between Bob and Carol (originating from Alice's original introduction) can be revoked +// together by revoking the membrane. +// +// Note that when a capability is passed into a membrane and then passed back out, the result is +// the original capability, not a double-membraned capability. This means that in our revocation +// example, if Bob uses his capability to Carol to obtain another capability from her, then send +// it back to her, the capability Carol receives back will NOT be revoked when Bob's access to +// Carol is revoked. Thus Bob can create long-term irrevocable connections. In most practical use +// cases, this is what you want. APIs commonly rely on the fact that a capability obtained and then +// passed back can be recognized as the original capability. +// +// Mark Miller on membranes: http://www.eros-os.org/pipermail/e-lang/2003-January/008434.html + +#include "capability.h" +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class MembranePolicy { + // Applications may implement this interface to define a membrane policy, which allows some + // calls crossing the membrane to be blocked or redirected. + +public: + virtual kj::Maybe inboundCall( + uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; + // Given an inbound call (a call originating "outside" the membrane destined for an object + // "inside" the membrane), decides what to do with it. The policy may: + // + // - Return null to indicate that the call should proceed to the destination. All capabilities + // in the parameters or result will be properly wrapped in the same membrane. + // - Return a capability to have the call redirected to that capability. Note that the redirect + // capability will be treated as outside the membrane, so the params and results will not be + // auto-wrapped; however, the callee can easily wrap the returned capability in the membrane + // itself before returning to achieve this effect. + // - Throw an exception to cause the call to fail with that exception. + // + // `target` is the underlying capability (*inside* the membrane) for which the call is destined. + // Generally, the only way you should use `target` is to wrap it in some capability which you + // return as a redirect. The redirect capability may modify the call in some way and send it to + // `target`. Be careful to use `copyIntoMembrane()` and `copyOutOfMembrane()` as appropriate when + // copying parameters or results across the membrane. + // + // Note that since `target` is inside the capability, if you were to directly return it (rather + // than return null), the effect would be that the membrane would be broken: the call would + // proceed directly and any new capabilities introduced through it would not be membraned. You + // generally should not do that. + + virtual kj::Maybe outboundCall( + uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; + // Like `inboundCall()`, but applies to calls originating *inside* the membrane and terminating + // outside. + // + // Note: It is strongly recommended that `outboundCall()` returns null in exactly the same cases + // that `inboundCall()` return null. Conversely, for any case where `inboundCall()` would + // redirect or throw, `outboundCall()` should also redirect or throw. Otherwise, you can run + // into inconsistent behavion when a promise is returned across a membrane, and that promise + // later resolves to a capability on the other side of the membrane: calls on the promise + // will enter and then exit the membrane, but calls on the eventual resolution will not cross + // the membrane at all, so it is important that these two cases behave the same. + + virtual kj::Own addRef() = 0; + // Return a new owned pointer to the same policy. + // + // Typically an implementation of MembranePolicy should also inherit kj::Refcounted and implement + // `addRef()` as `return kj::addRef(*this);`. + // + // Note that the membraning system considers two membranes created with the same MembranePolicy + // object actually to be the *same* membrane. This is relevant when an object passes into the + // membrane and then back out (or out and then back in): instead of double-wrapping the object, + // the wrapping will be removed. + + virtual kj::Maybe> onRevoked() { return nullptr; } + // If this returns non-null, then it is a promise that will reject (throw an exception) when the + // membrane should be revoked. On revocation, all capabilities pointing across the membrane will + // be dropped and all outstanding calls canceled. The exception thrown by the promise will be + // propagated to all these calls. It is an error for the promise to resolve without throwing. + // + // After the revocation promise has rejected, inboundCall() and outboundCall() will still be + // invoked for new calls, but the `target` passed to them will be a capability that always + // rethrows the revocation exception. + + virtual bool shouldResolveBeforeRedirecting() { return false; } + // If this returns true, then when inboundCall() or outboundCall() returns a redirect, but the + // original target is a promise, then the membrane will discard the redirect and instead wait + // for the promise to become more resolved and try again. + // + // This behavior is important in particular when implementing a membrane that wants to intercept + // calls that would otherwise terminate inside the membrane, but needs to be careful not to + // intercept calls that might be reflected back out of the membrane. If the promise eventually + // resolves to a capability outside the membrane, then the call will be forwarded to that + // capability without applying the policy at all. + // + // However, some membranes don't need this behavior, and may be negatively impacted by the + // unnecessary waiting. Such membranes can keep this disabled. + // + // TODO(cleanup): Consider a backwards-incompatible revamp of the MembranePolicy API with a + // better design here. Maybe we should more carefully distinguish between MembranePolicies + // which are reversible vs. those which are one-way? + + virtual bool allowFdPassthrough() { return false; } + // Should file descriptors be allowed to pass through this membrane? + // + // A MembranePolicy obviously cannot mediate nor revoke access to a file descriptor once it has + // passed through, so this must be used with caution. If you only want to allow file descriptors + // on certain methods, you could do so by implementing inboundCall()/outboundCall() to + // special-case those methods. + + // --------------------------------------------------------------------------- + // Control over importing and exporting. + // + // Most membranes should not override these methods. The default behavior is that a capability + // that crosses the membrane is wrapped in it, and if the wrapped version crosses back the other + // way, it is unwrapped. + + virtual Capability::Client importExternal(Capability::Client external); + // An external capability is crossing into the membrane. Returns the capability that should + // substitute for it when called from the inside. + // + // The default implementation creates a capability that invokes this MembranePolicy. E.g. all + // calls will invoke outboundCall(). + // + // Note that reverseMembrane(cap, policy) normally calls policy->importExternal(cap), unless + // `cap` itself was originally returned by the default implementation of exportInternal(), in + // which case importInternal() is called instead. + + virtual Capability::Client exportInternal(Capability::Client internal); + // An internal capability is crossing out of the membrane. Returns the capability that should + // substitute for it when called from the outside. + // + // The default implementation creates a capability that invokes this MembranePolicy. E.g. all + // calls will invoke inboundCall(). + // + // Note that membrane(cap, policy) normally calls policy->exportInternal(cap), unless `cap` + // itself was originally returned by the default implementation of exportInternal(), in which + // case importInternal() is called instead. + + virtual MembranePolicy& rootPolicy() { return *this; } + // If two policies return the same value for rootPolicy(), then a capability imported through + // one can be exported through the other, and vice versa. `importInternal()` and + // `exportExternal()` will always be called on the root policy, passing the two child policies + // as parameters. If you don't override rootPolicy(), then the policy references passed to + // importInternal() and exportExternal() will always be references to *this. + + virtual Capability::Client importInternal( + Capability::Client internal, MembranePolicy& exportPolicy, MembranePolicy& importPolicy); + // An internal capability which was previously exported is now being re-imported, i.e. a + // capability passed out of the membrane and then back in. + // + // The default implementation simply returns `internal`. + + virtual Capability::Client exportExternal( + Capability::Client external, MembranePolicy& importPolicy, MembranePolicy& exportPolicy); + // An external capability which was previously imported is now being re-exported, i.e. a + // capability passed into the membrane and then back out. + // + // The default implementation simply returns `external`. + +private: + kj::HashMap wrappers; + kj::HashMap reverseWrappers; + // Tracks capabilities that already have wrappers instantiated. The maps map from pointer to + // inner capability to pointer to wrapper. When a wrapper is destroyed it removes itself from + // the map. + + friend class MembraneHook; +}; + +Capability::Client membrane(Capability::Client inner, kj::Own policy); +// Wrap `inner` in a membrane specified by `policy`. `inner` is considered "inside" the membrane, +// while the returned capability should only be called from outside the membrane. + +Capability::Client reverseMembrane(Capability::Client outer, kj::Own policy); +// Like `membrane` but treat the input capability as "outside" the membrane, and return a +// capability appropriate for use inside. +// +// Applications typically won't use this directly; the membraning code automatically sets up +// reverse membranes where needed. + +template +ClientType membrane(ClientType inner, kj::Own policy); +template +ClientType reverseMembrane(ClientType inner, kj::Own policy); +// Convenience templates which return the same interface type as the input. + +template +typename ServerType::Serves::Client membrane( + kj::Own inner, kj::Own policy); +template +typename ServerType::Serves::Client reverseMembrane( + kj::Own inner, kj::Own policy); +// Convenience templates which input a capability server type and return the appropriate client +// type. + +template +Orphan::Reads> copyIntoMembrane( + Reader&& from, Orphanage to, kj::Own policy); +// Copy a Cap'n Proto object (e.g. struct or list), adding the given membrane to any capabilities +// found within it. `from` is interpreted as "outside" the membrane while `to` is "inside". + +template +Orphan::Reads> copyOutOfMembrane( + Reader&& from, Orphanage to, kj::Own policy); +// Like copyIntoMembrane() except that `from` is "inside" the membrane and `to` is "outside". + +// ======================================================================================= +// inline implementation details + +template +ClientType membrane(ClientType inner, kj::Own policy) { + return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} +template +ClientType reverseMembrane(ClientType inner, kj::Own policy) { + return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} + +template +typename ServerType::Serves::Client membrane( + kj::Own inner, kj::Own policy) { + return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} +template +typename ServerType::Serves::Client reverseMembrane( + kj::Own inner, kj::Own policy) { + return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) + .castAs(); +} + +namespace _ { // private + +OrphanBuilder copyOutOfMembrane(PointerReader from, Orphanage to, + kj::Own policy, bool reverse); +OrphanBuilder copyOutOfMembrane(StructReader from, Orphanage to, + kj::Own policy, bool reverse); +OrphanBuilder copyOutOfMembrane(ListReader from, Orphanage to, + kj::Own policy, bool reverse); + +} // namespace _ (private) + +template +Orphan::Reads> copyIntoMembrane( + Reader&& from, Orphanage to, kj::Own policy) { + return _::copyOutOfMembrane( + _::PointerHelpers::Reads>::getInternalReader(from), + to, kj::mv(policy), true); +} + +template +Orphan::Reads> copyOutOfMembrane( + Reader&& from, Orphanage to, kj::Own policy) { + return _::copyOutOfMembrane( + _::PointerHelpers::Reads>::getInternalReader(from), + to, kj::mv(policy), false); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/message.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/message.cc new file mode 100644 index 000000000..90a66cca1 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/message.cc @@ -0,0 +1,308 @@ +// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#define CAPNP_PRIVATE +#include "message.h" +#include +#include "arena.h" +#include "orphan.h" +#include +#include + +namespace capnp { + +namespace { + +class DummyCapTableReader: public _::CapTableReader { +public: + kj::Maybe> extractCap(uint index) override { +#if CAPNP_LITE + KJ_UNIMPLEMENTED("no cap tables in lite mode"); +#else + return nullptr; +#endif + } +}; +static KJ_CONSTEXPR(const) DummyCapTableReader dummyCapTableReader = DummyCapTableReader(); + +} // namespace + +MessageReader::MessageReader(ReaderOptions options): options(options), allocatedArena(false) {} +MessageReader::~MessageReader() noexcept(false) { + if (allocatedArena) { + arena()->~ReaderArena(); + } +} + +bool MessageReader::isCanonical() { + if (!allocatedArena) { + static_assert(sizeof(_::ReaderArena) <= sizeof(arenaSpace), + "arenaSpace is too small to hold a ReaderArena. Please increase it. This will break " + "ABI compatibility."); + kj::ctor(*arena(), this); + allocatedArena = true; + } + + _::SegmentReader *segment = arena()->tryGetSegment(_::SegmentId(0)); + + if (segment == NULL) { + // The message has no segments + return false; + } + + if (arena()->tryGetSegment(_::SegmentId(1))) { + // The message has more than one segment + return false; + } + + const word* readHead = segment->getStartPtr() + 1; + bool rootIsCanonical = _::PointerReader::getRoot(segment, nullptr, + segment->getStartPtr(), + this->getOptions().nestingLimit) + .isCanonical(&readHead); + bool allWordsConsumed = segment->getOffsetTo(readHead) == segment->getSize(); + return rootIsCanonical && allWordsConsumed; +} + +size_t MessageReader::sizeInWords() { + return arena()->sizeInWords(); +} + +AnyPointer::Reader MessageReader::getRootInternal() { + if (!allocatedArena) { + static_assert(sizeof(_::ReaderArena) <= sizeof(arenaSpace), + "arenaSpace is too small to hold a ReaderArena. Please increase it. This will break " + "ABI compatibility."); + kj::ctor(*arena(), this); + allocatedArena = true; + } + + _::SegmentReader* segment = arena()->tryGetSegment(_::SegmentId(0)); + KJ_REQUIRE(segment != nullptr && + segment->checkObject(segment->getStartPtr(), ONE * WORDS), + "Message did not contain a root pointer.") { + return AnyPointer::Reader(); + } + + // const_cast here is safe because dummyCapTableReader has no state. + return AnyPointer::Reader(_::PointerReader::getRoot( + segment, const_cast(&dummyCapTableReader), + segment->getStartPtr(), options.nestingLimit)); +} + +// ------------------------------------------------------------------- + +MessageBuilder::MessageBuilder(): allocatedArena(false) {} + +MessageBuilder::~MessageBuilder() noexcept(false) { + if (allocatedArena) { + kj::dtor(*arena()); + } +} + +MessageBuilder::MessageBuilder(kj::ArrayPtr segments) + : allocatedArena(false) { + kj::ctor(*arena(), this, segments); + allocatedArena = true; +} + +_::SegmentBuilder* MessageBuilder::getRootSegment() { + if (allocatedArena) { + return arena()->getSegment(_::SegmentId(0)); + } else { + static_assert(sizeof(_::BuilderArena) <= sizeof(arenaSpace), + "arenaSpace is too small to hold a BuilderArena. Please increase it."); + kj::ctor(*arena(), this); + allocatedArena = true; + + auto allocation = arena()->allocate(POINTER_SIZE_IN_WORDS); + + KJ_ASSERT(allocation.segment->getSegmentId() == _::SegmentId(0), + "First allocated word of new arena was not in segment ID 0."); + KJ_ASSERT(allocation.words == allocation.segment->getPtrUnchecked(ZERO * WORDS), + "First allocated word of new arena was not the first word in its segment."); + return allocation.segment; + } +} + +AnyPointer::Builder MessageBuilder::getRootInternal() { + _::SegmentBuilder* rootSegment = getRootSegment(); + return AnyPointer::Builder(_::PointerBuilder::getRoot( + rootSegment, arena()->getLocalCapTable(), rootSegment->getPtrUnchecked(ZERO * WORDS))); +} + +kj::ArrayPtr> MessageBuilder::getSegmentsForOutput() { + if (allocatedArena) { + return arena()->getSegmentsForOutput(); + } else { + return nullptr; + } +} + +Orphanage MessageBuilder::getOrphanage() { + // We must ensure that the arena and root pointer have been allocated before the Orphanage + // can be used. + if (!allocatedArena) getRootSegment(); + + return Orphanage(arena(), arena()->getLocalCapTable()); +} + +bool MessageBuilder::isCanonical() { + _::SegmentReader *segment = getRootSegment(); + + if (segment == NULL) { + // The message has no segments + return false; + } + + if (arena()->tryGetSegment(_::SegmentId(1))) { + // The message has more than one segment + return false; + } + + const word* readHead = segment->getStartPtr() + 1; + return _::PointerReader::getRoot(segment, nullptr, segment->getStartPtr(), kj::maxValue) + .isCanonical(&readHead); +} + +size_t MessageBuilder::sizeInWords() { + return arena()->sizeInWords(); +} + +kj::Own<_::CapTableBuilder> MessageBuilder::releaseBuiltinCapTable() { + return arena()->releaseLocalCapTable(); +} + +// ======================================================================================= + +SegmentArrayMessageReader::SegmentArrayMessageReader( + kj::ArrayPtr> segments, ReaderOptions options) + : MessageReader(options), segments(segments) {} + +SegmentArrayMessageReader::~SegmentArrayMessageReader() noexcept(false) {} + +kj::ArrayPtr SegmentArrayMessageReader::getSegment(uint id) { + if (id < segments.size()) { + return segments[id]; + } else { + return nullptr; + } +} + +// ------------------------------------------------------------------- + +MallocMessageBuilder::MallocMessageBuilder( + uint firstSegmentWords, AllocationStrategy allocationStrategy) + : nextSize(firstSegmentWords), allocationStrategy(allocationStrategy), + ownFirstSegment(true), returnedFirstSegment(false), firstSegment(nullptr) {} + +MallocMessageBuilder::MallocMessageBuilder( + kj::ArrayPtr firstSegment, AllocationStrategy allocationStrategy) + : nextSize(firstSegment.size()), allocationStrategy(allocationStrategy), + ownFirstSegment(false), returnedFirstSegment(false), firstSegment(firstSegment.begin()) { + KJ_REQUIRE(firstSegment.size() > 0, "First segment size must be non-zero."); + + // Checking just the first word should catch most cases of failing to zero the segment. + KJ_REQUIRE(*reinterpret_cast(firstSegment.begin()) == 0, + "First segment must be zeroed."); +} + +MallocMessageBuilder::~MallocMessageBuilder() noexcept(false) { + if (returnedFirstSegment) { + if (ownFirstSegment) { + free(firstSegment); + } else { + // Must zero first segment. + kj::ArrayPtr> segments = getSegmentsForOutput(); + if (segments.size() > 0) { + KJ_ASSERT(segments[0].begin() == firstSegment, + "First segment in getSegmentsForOutput() is not the first segment allocated?"); + memset(firstSegment, 0, segments[0].size() * sizeof(word)); + } + } + + for (void* ptr: moreSegments) { + free(ptr); + } + } +} + +kj::ArrayPtr MallocMessageBuilder::allocateSegment(uint minimumSize) { + KJ_REQUIRE(bounded(minimumSize) * WORDS <= MAX_SEGMENT_WORDS, + "MallocMessageBuilder asked to allocate segment above maximum serializable size."); + KJ_ASSERT(bounded(nextSize) * WORDS <= MAX_SEGMENT_WORDS, + "MallocMessageBuilder nextSize out of bounds."); + + if (!returnedFirstSegment && !ownFirstSegment) { + kj::ArrayPtr result = kj::arrayPtr(reinterpret_cast(firstSegment), nextSize); + if (result.size() >= minimumSize) { + returnedFirstSegment = true; + return result; + } + // If the provided first segment wasn't big enough, we discard it and proceed to allocate + // our own. This never happens in practice since minimumSize is always 1 for the first + // segment. + ownFirstSegment = true; + } + + uint size = kj::max(minimumSize, nextSize); + + void* result = calloc(size, sizeof(word)); + if (result == nullptr) { + KJ_FAIL_SYSCALL("calloc(size, sizeof(word))", ENOMEM, size); + } + + if (!returnedFirstSegment) { + firstSegment = result; + returnedFirstSegment = true; + + // After the first segment, we want nextSize to equal the total size allocated so far. + if (allocationStrategy == AllocationStrategy::GROW_HEURISTICALLY) nextSize = size; + } else { + moreSegments.add(result); + if (allocationStrategy == AllocationStrategy::GROW_HEURISTICALLY) { + // set nextSize = min(nextSize+size, MAX_SEGMENT_WORDS) + // while protecting against possible overflow of (nextSize+size) + nextSize = (size <= unbound(MAX_SEGMENT_WORDS / WORDS) - nextSize) + ? nextSize + size : unbound(MAX_SEGMENT_WORDS / WORDS); + } + } + + return kj::arrayPtr(reinterpret_cast(result), size); +} + +// ------------------------------------------------------------------- + +FlatMessageBuilder::FlatMessageBuilder(kj::ArrayPtr array): array(array), allocated(false) {} +FlatMessageBuilder::~FlatMessageBuilder() noexcept(false) {} + +void FlatMessageBuilder::requireFilled() { + KJ_REQUIRE(getSegmentsForOutput()[0].end() == array.end(), + "FlatMessageBuilder's buffer was too large."); +} + +kj::ArrayPtr FlatMessageBuilder::allocateSegment(uint minimumSize) { + KJ_REQUIRE(!allocated, "FlatMessageBuilder's buffer was not large enough."); + allocated = true; + return array; +} + +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/message.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/message.h new file mode 100644 index 000000000..af87aec81 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/message.h @@ -0,0 +1,558 @@ +// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include "common.h" +#include "layout.h" +#include "any.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +namespace _ { // private + class ReaderArena; + class BuilderArena; + struct CloneImpl; +} + +class StructSchema; +class Orphanage; +template +class Orphan; + +// ======================================================================================= + +struct ReaderOptions { + // Options controlling how data is read. + + uint64_t traversalLimitInWords = 8 * 1024 * 1024; + // Limits how many total words of data are allowed to be traversed. Traversal is counted when + // a new struct or list builder is obtained, e.g. from a get() accessor. This means that calling + // the getter for the same sub-struct multiple times will cause it to be double-counted. Once + // the traversal limit is reached, an error will be reported. + // + // This limit exists for security reasons. It is possible for an attacker to construct a message + // in which multiple pointers point at the same location. This is technically invalid, but hard + // to detect. Using such a message, an attacker could cause a message which is small on the wire + // to appear much larger when actually traversed, possibly exhausting server resources leading to + // denial-of-service. + // + // It makes sense to set a traversal limit that is much larger than the underlying message. + // Together with sensible coding practices (e.g. trying to avoid calling sub-object getters + // multiple times, which is expensive anyway), this should provide adequate protection without + // inconvenience. + // + // The default limit is 64 MiB. This may or may not be a sensible number for any given use case, + // but probably at least prevents easy exploitation while also avoiding causing problems in most + // typical cases. + + int nestingLimit = 64; + // Limits how deeply-nested a message structure can be, e.g. structs containing other structs or + // lists of structs. + // + // Like the traversal limit, this limit exists for security reasons. Since it is common to use + // recursive code to traverse recursive data structures, an attacker could easily cause a stack + // overflow by sending a very-deeply-nested (or even cyclic) message, without the message even + // being very large. The default limit of 64 is probably low enough to prevent any chance of + // stack overflow, yet high enough that it is never a problem in practice. +}; + +class MessageReader { + // Abstract interface for an object used to read a Cap'n Proto message. Subclasses of + // MessageReader are responsible for reading the raw, flat message content. Callers should + // usually call `messageReader.getRoot()` to get a `MyStructType::Reader` + // representing the root of the message, then use that to traverse the message content. + // + // Some common subclasses of `MessageReader` include `SegmentArrayMessageReader`, whose + // constructor accepts pointers to the raw data, and `StreamFdMessageReader` (from + // `serialize.h`), which reads the message from a file descriptor. One might implement other + // subclasses to handle things like reading from shared memory segments, mmap()ed files, etc. + +public: + MessageReader(ReaderOptions options); + // It is suggested that subclasses take ReaderOptions as a constructor parameter, but give it a + // default value of "ReaderOptions()". The base class constructor doesn't have a default value + // in order to remind subclasses that they really need to give the user a way to provide this. + + virtual ~MessageReader() noexcept(false); + + virtual kj::ArrayPtr getSegment(uint id) = 0; + // Gets the segment with the given ID, or returns null if no such segment exists. This method + // will be called at most once for each segment ID. + + inline const ReaderOptions& getOptions(); + // Get the options passed to the constructor. + + template + typename RootType::Reader getRoot(); + // Get the root struct of the message, interpreting it as the given struct type. + + template + typename RootType::Reader getRoot(SchemaType schema); + // Dynamically interpret the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include to + // use this. + + bool isCanonical(); + // Returns whether the message encoded in the reader is in canonical form. + + size_t sizeInWords(); + // Add up the size of all segments. + +private: + ReaderOptions options; + +#if defined(__EMSCRIPTEN__) || (defined(__APPLE__) && defined(__ppc__)) + static constexpr size_t arenaSpacePadding = 19; +#else + static constexpr size_t arenaSpacePadding = 18; +#endif + + // Space in which we can construct a ReaderArena. We don't use ReaderArena directly here + // because we don't want clients to have to #include arena.h, which itself includes a bunch of + // other headers. We don't use a pointer to a ReaderArena because that would require an + // extra malloc on every message which could be expensive when processing small messages. + alignas(8) void* arenaSpace[arenaSpacePadding + sizeof(kj::MutexGuarded) / sizeof(void*)]; + bool allocatedArena; + + _::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); } + AnyPointer::Reader getRootInternal(); +}; + +class MessageBuilder { + // Abstract interface for an object used to allocate and build a message. Subclasses of + // MessageBuilder are responsible for allocating the space in which the message will be written. + // The most common subclass is `MallocMessageBuilder`, but other subclasses may be used to do + // tricky things like allocate messages in shared memory or mmap()ed files. + // + // Creating a new message ususually means allocating a new MessageBuilder (ideally on the stack) + // and then calling `messageBuilder.initRoot()` to get a `MyStructType::Builder`. + // That, in turn, can be used to fill in the message content. When done, you can call + // `messageBuilder.getSegmentsForOutput()` to get a list of flat data arrays containing the + // message. + +public: + MessageBuilder(); + virtual ~MessageBuilder() noexcept(false); + KJ_DISALLOW_COPY_AND_MOVE(MessageBuilder); + + struct SegmentInit { + kj::ArrayPtr space; + + size_t wordsUsed; + // Number of words in `space` which are used; the rest are free space in which additional + // objects may be allocated. + }; + + explicit MessageBuilder(kj::ArrayPtr segments); + // Create a MessageBuilder backed by existing memory. This is an advanced interface that most + // people should not use. THIS METHOD IS INSECURE; see below. + // + // This allows a MessageBuilder to be constructed to modify an in-memory message without first + // making a copy of the content. This is especially useful in conjunction with mmap(). + // + // The contents of each segment must outlive the MessageBuilder, but the SegmentInit array itself + // only need outlive the constructor. + // + // SECURITY: Do not use this in conjunction with untrusted data. This constructor assumes that + // the input message is valid. This constructor is designed to be used with data you control, + // e.g. an mmap'd file which is owned and accessed by only one program. When reading data you + // do not trust, you *must* load it into a Reader and then copy into a Builder as a means of + // validating the content. + // + // WARNING: It is NOT safe to initialize a MessageBuilder in this way from memory that is + // currently in use by another MessageBuilder or MessageReader. Other readers/builders will + // not observe changes to the segment sizes nor newly-allocated segments caused by allocating + // new objects in this message. + + virtual kj::ArrayPtr allocateSegment(uint minimumSize) = 0; + // Allocates an array of at least the given number of zero'd words, throwing an exception or + // crashing if this is not possible. It is expected that this method will usually return more + // space than requested, and the caller should use that extra space as much as possible before + // allocating more. The returned space remains valid at least until the MessageBuilder is + // destroyed. + // + // allocateSegment() is responsible for zeroing the memory before returning. This is required + // because otherwise the Cap'n Proto implementation would have to zero the memory anyway, and + // many allocators are able to provide already-zero'd memory more efficiently. + + template + typename RootType::Builder initRoot(); + // Initialize the root struct of the message as the given struct type. + + template + void setRoot(Reader&& value); + // Set the root struct to a deep copy of the given struct. + + template + typename RootType::Builder getRoot(); + // Get the root struct of the message, interpreting it as the given struct type. + + template + typename RootType::Builder getRoot(SchemaType schema); + // Dynamically interpret the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include to + // use this. + + template + typename RootType::Builder initRoot(SchemaType schema); + // Dynamically init the root struct of the message using the given schema (a StructSchema). + // RootType in this case must be DynamicStruct, and you must #include to + // use this. + + template + void adoptRoot(Orphan&& orphan); + // Like setRoot() but adopts the orphan without copying. + + kj::ArrayPtr> getSegmentsForOutput(); + // Get the raw data that makes up the message. + + Orphanage getOrphanage(); + + bool isCanonical(); + // Check whether the message builder is in canonical form + + size_t sizeInWords(); + // Add up the allocated space from all segments. + +private: + alignas(8) void* arenaSpace[22]; + // Space in which we can construct a BuilderArena. We don't use BuilderArena directly here + // because we don't want clients to have to #include arena.h, which itself includes a bunch of + // big STL headers. We don't use a pointer to a BuilderArena because that would require an + // extra malloc on every message which could be expensive when processing small messages. + + bool allocatedArena = false; + // We have to initialize the arena lazily because when we do so we want to allocate the root + // pointer immediately, and this will allocate a segment, which requires a virtual function + // call on the MessageBuilder. We can't do such a call in the constructor since the subclass + // isn't constructed yet. This is kind of annoying because it means that getOrphanage() is + // not thread-safe, but that shouldn't be a huge deal... + + _::BuilderArena* arena() { return reinterpret_cast<_::BuilderArena*>(arenaSpace); } + _::SegmentBuilder* getRootSegment(); + AnyPointer::Builder getRootInternal(); + + kj::Own<_::CapTableBuilder> releaseBuiltinCapTable(); + // Hack for clone() to extract the cap table. + + friend struct _::CloneImpl; + // We can't declare clone() as a friend directly because old versions of GCC incorrectly demand + // that the first declaration (even if it is a friend declaration) specify the default type args, + // whereas correct compilers do not permit default type args to be specified on a friend decl. +}; + +template +typename RootType::Reader readMessageUnchecked(const word* data); +// IF THE INPUT IS INVALID, THIS MAY CRASH, CORRUPT MEMORY, CREATE A SECURITY HOLE IN YOUR APP, +// MURDER YOUR FIRST-BORN CHILD, AND/OR BRING ABOUT ETERNAL DAMNATION ON ALL OF HUMANITY. DO NOT +// USE UNLESS YOU UNDERSTAND THE CONSEQUENCES. +// +// Given a pointer to a known-valid message located in a single contiguous memory segment, +// returns a reader for that message. No bounds-checking will be done while traversing this +// message. Use this only if you have already verified that all pointers are valid and in-bounds, +// and there are no far pointers in the message. +// +// To create a message that can be passed to this function, build a message using a MallocAllocator +// whose preferred segment size is larger than the message size. This guarantees that the message +// will be allocated as a single segment, meaning getSegmentsForOutput() returns a single word +// array. That word array is your message; you may pass a pointer to its first word into +// readMessageUnchecked() to read the message. +// +// This can be particularly handy for embedding messages in generated code: you can +// embed the raw bytes (using AlignedData) then make a Reader for it using this. This is the way +// default values are embedded in code generated by the Cap'n Proto compiler. E.g., if you have +// a message MyMessage, you can read its default value like so: +// MyMessage::Reader reader = Message::readMessageUnchecked(MyMessage::DEFAULT.words); +// +// To sanitize a message from an untrusted source such that it can be safely passed to +// readMessageUnchecked(), use copyToUnchecked(). + +template +void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer); +// Copy the content of the given reader into the given buffer, such that it can safely be passed to +// readMessageUnchecked(). The buffer's size must be exactly reader.totalSizeInWords() + 1, +// otherwise an exception will be thrown. The buffer must be zero'd before calling. + +template +typename RootType::Reader readDataStruct(kj::ArrayPtr data); +// Interprets the given data as a single, data-only struct. Only primitive fields (booleans, +// numbers, and enums) will be readable; all pointers will be null. This is useful if you want +// to use Cap'n Proto as a language/platform-neutral way to pack some bits. +// +// The input is a word array rather than a byte array to enforce alignment. If you have a byte +// array which you know is word-aligned (or if your platform supports unaligned reads and you don't +// mind the performance penalty), then you can use `reinterpret_cast` to convert a byte array into +// a word array: +// +// kj::arrayPtr(reinterpret_cast(bytes.begin()), +// reinterpret_cast(bytes.end())) + +template +typename kj::ArrayPtr writeDataStruct(BuilderType builder); +// Given a struct builder, get the underlying data section as a word array, suitable for passing +// to `readDataStruct()`. +// +// Note that you may call `.toBytes()` on the returned value to convert to `ArrayPtr`. + +template +static typename Type::Reader defaultValue(); +// Get a default instance of the given struct or list type. +// +// TODO(cleanup): Find a better home for this function? + +template > +kj::Own> clone(Reader&& reader); +// Make a deep copy of the given Reader on the heap, producing an owned pointer. + +// ======================================================================================= + +class SegmentArrayMessageReader: public MessageReader { + // A simple MessageReader that reads from an array of word arrays representing all segments. + // In particular you can read directly from the output of MessageBuilder::getSegmentsForOutput() + // (although it would probably make more sense to call builder.getRoot().asReader() in that case). + +public: + SegmentArrayMessageReader(kj::ArrayPtr> segments, + ReaderOptions options = ReaderOptions()); + // Creates a message pointing at the given segment array, without taking ownership of the + // segments. All arrays passed in must remain valid until the MessageReader is destroyed. + + KJ_DISALLOW_COPY_AND_MOVE(SegmentArrayMessageReader); + ~SegmentArrayMessageReader() noexcept(false); + + virtual kj::ArrayPtr getSegment(uint id) override; + +private: + kj::ArrayPtr> segments; +}; + +enum class AllocationStrategy: uint8_t { + FIXED_SIZE, + // The builder will prefer to allocate the same amount of space for each segment with no + // heuristic growth. It will still allocate larger segments when the preferred size is too small + // for some single object. This mode is generally not recommended, but can be particularly useful + // for testing in order to force a message to allocate a predictable number of segments. Note + // that you can force every single object in the message to be located in a separate segment by + // using this mode with firstSegmentWords = 0. + + GROW_HEURISTICALLY + // The builder will heuristically decide how much space to allocate for each segment. Each + // allocated segment will be progressively larger than the previous segments on the assumption + // that message sizes are exponentially distributed. The total number of segments that will be + // allocated for a message of size n is O(log n). +}; + +constexpr uint SUGGESTED_FIRST_SEGMENT_WORDS = 1024; +constexpr AllocationStrategy SUGGESTED_ALLOCATION_STRATEGY = AllocationStrategy::GROW_HEURISTICALLY; + +class MallocMessageBuilder: public MessageBuilder { + // A simple MessageBuilder that uses malloc() (actually, calloc()) to allocate segments. This + // implementation should be reasonable for any case that doesn't require writing the message to + // a specific location in memory. + +public: + explicit MallocMessageBuilder(uint firstSegmentWords = SUGGESTED_FIRST_SEGMENT_WORDS, + AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); + // Creates a BuilderContext which allocates at least the given number of words for the first + // segment, and then uses the given strategy to decide how much to allocate for subsequent + // segments. When choosing a value for firstSegmentWords, consider that: + // 1) Reading and writing messages gets slower when multiple segments are involved, so it's good + // if most messages fit in a single segment. + // 2) Unused bytes will not be written to the wire, so generally it is not a big deal to allocate + // more space than you need. It only becomes problematic if you are allocating many messages + // in parallel and thus use lots of memory, or if you allocate so much extra space that just + // zeroing it out becomes a bottleneck. + // The defaults have been chosen to be reasonable for most people, so don't change them unless you + // have reason to believe you need to. + + explicit MallocMessageBuilder(kj::ArrayPtr firstSegment, + AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); + // This version always returns the given array for the first segment, and then proceeds with the + // allocation strategy. This is useful for optimization when building lots of small messages in + // a tight loop: you can reuse the space for the first segment. + // + // firstSegment MUST be zero-initialized. MallocMessageBuilder's destructor will write new zeros + // over any space that was used so that it can be reused. + + KJ_DISALLOW_COPY_AND_MOVE(MallocMessageBuilder); + virtual ~MallocMessageBuilder() noexcept(false); + + virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; + +private: + uint nextSize; + AllocationStrategy allocationStrategy; + + bool ownFirstSegment; + bool returnedFirstSegment; + + void* firstSegment; + kj::Vector moreSegments; +}; + +class FlatMessageBuilder: public MessageBuilder { + // THIS IS NOT THE CLASS YOU'RE LOOKING FOR. + // + // If you want to write a message into already-existing scratch space, use `MallocMessageBuilder` + // and pass the scratch space to its constructor. It will then only fall back to malloc() if + // the scratch space is not large enough. + // + // Do NOT use this class unless you really know what you're doing. This class is problematic + // because it requires advance knowledge of the size of your message, which is usually impossible + // to determine without actually building the message. The class was created primarily to + // implement `copyToUnchecked()`, which itself exists only to support other internal parts of + // the Cap'n Proto implementation. + +public: + explicit FlatMessageBuilder(kj::ArrayPtr array); + KJ_DISALLOW_COPY_AND_MOVE(FlatMessageBuilder); + virtual ~FlatMessageBuilder() noexcept(false); + + void requireFilled(); + // Throws an exception if the flat array is not exactly full. + + virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; + +private: + kj::ArrayPtr array; + bool allocated; +}; + +// ======================================================================================= +// implementation details + +inline const ReaderOptions& MessageReader::getOptions() { + return options; +} + +template +inline typename RootType::Reader MessageReader::getRoot() { + return getRootInternal().getAs(); +} + +template +inline typename RootType::Builder MessageBuilder::initRoot() { + return getRootInternal().initAs(); +} + +template +inline void MessageBuilder::setRoot(Reader&& value) { + getRootInternal().setAs>(value); +} + +template +inline typename RootType::Builder MessageBuilder::getRoot() { + return getRootInternal().getAs(); +} + +template +void MessageBuilder::adoptRoot(Orphan&& orphan) { + return getRootInternal().adopt(kj::mv(orphan)); +} + +template +typename RootType::Reader MessageReader::getRoot(SchemaType schema) { + return getRootInternal().getAs(schema); +} + +template +typename RootType::Builder MessageBuilder::getRoot(SchemaType schema) { + return getRootInternal().getAs(schema); +} + +template +typename RootType::Builder MessageBuilder::initRoot(SchemaType schema) { + return getRootInternal().initAs(schema); +} + +template +typename RootType::Reader readMessageUnchecked(const word* data) { + return AnyPointer::Reader(_::PointerReader::getRootUnchecked(data)).getAs(); +} + +template +void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer) { + FlatMessageBuilder builder(uncheckedBuffer); + builder.setRoot(kj::fwd(reader)); + builder.requireFilled(); +} + +template +typename RootType::Reader readDataStruct(kj::ArrayPtr data) { + return typename RootType::Reader(_::StructReader(data)); +} + +template +typename kj::ArrayPtr writeDataStruct(BuilderType builder) { + auto bytes = _::PointerHelpers>::getInternalBuilder(kj::mv(builder)) + .getDataSectionAsBlob(); + return kj::arrayPtr(reinterpret_cast(bytes.begin()), + reinterpret_cast(bytes.end())); +} + +template +static typename Type::Reader defaultValue() { + return typename Type::Reader(_::StructReader()); +} + +namespace _ { + struct CloneImpl { + static inline kj::Own<_::CapTableBuilder> releaseBuiltinCapTable(MessageBuilder& message) { + return message.releaseBuiltinCapTable(); + } + }; +}; + +template +kj::Own> clone(Reader&& reader) { + auto size = reader.totalSize(); + auto buffer = kj::heapArray(size.wordCount + 1); + memset(buffer.asBytes().begin(), 0, buffer.asBytes().size()); + if (size.capCount == 0) { + copyToUnchecked(reader, buffer); + auto result = readMessageUnchecked>(buffer.begin()); + return kj::attachVal(result, kj::mv(buffer)); + } else { + FlatMessageBuilder builder(buffer); + builder.setRoot(kj::fwd(reader)); + builder.requireFilled(); + auto capTable = _::CloneImpl::releaseBuiltinCapTable(builder); + AnyPointer::Reader raw(_::PointerReader::getRootUnchecked(buffer.begin()).imbue(capTable)); + return kj::attachVal(raw.getAs>(), kj::mv(buffer), kj::mv(capTable)); + } +} + +template +kj::Array canonicalize(T&& reader) { + return _::PointerHelpers>::getInternalReader(reader).canonicalize(); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/orphan.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/orphan.h new file mode 100644 index 000000000..0ef4a671c --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/orphan.h @@ -0,0 +1,437 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "layout.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class StructSchema; +class ListSchema; +struct DynamicStruct; +struct DynamicList; +namespace _ { struct OrphanageInternal; } + +template +class Orphan { + // Represents an object which is allocated within some message builder but has no pointers + // pointing at it. An Orphan can later be "adopted" by some other object as one of that object's + // fields, without having to copy the orphan. For a field `foo` of pointer type, the generated + // code will define builder methods `void adoptFoo(Orphan)` and `Orphan disownFoo()`. + // Orphans can also be created independently of any parent using an Orphanage. + // + // `Orphan` can be moved but not copied, like `Own`, so that it is impossible for one + // orphan to be adopted multiple times. If an orphan is destroyed without being adopted, its + // contents are zero'd out (and possibly reused, if we ever implement the ability to reuse space + // in a message arena). + +public: + Orphan() = default; + KJ_DISALLOW_COPY(Orphan); + Orphan(Orphan&&) = default; + Orphan& operator=(Orphan&&) = default; + inline Orphan(_::OrphanBuilder&& builder): builder(kj::mv(builder)) {} + + inline BuilderFor get(); + // Get the underlying builder. If the orphan is null, this will allocate and return a default + // object rather than crash. This is done for security -- otherwise, you might enable a DoS + // attack any time you disown a field and fail to check if it is null. In the case of structs, + // this means that the orphan is no longer null after get() returns. In the case of lists, + // no actual object is allocated since a simple empty ListBuilder can be returned. + + inline ReaderFor getReader() const; + + inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } + + inline void truncate(uint size); + // Resize an object (which must be a list or a blob) to the given size. + // + // If the new size is less than the original, the remaining elements will be discarded. The + // list is never moved in this case. If the list happens to be located at the end of its segment + // (which is always true if the list was the last thing allocated), the removed memory will be + // reclaimed (reducing the message size), otherwise it is simply zeroed. The reclaiming behavior + // is particularly useful for allocating buffer space when you aren't sure how much space you + // actually need: you can pre-allocate, say, a 4k byte array, read() from a file into it, and + // then truncate it back to the amount of space actually used. + // + // If the new size is greater than the original, the list is extended with default values. If + // the list is the last object in its segment *and* there is enough space left in the segment to + // extend it to cover the new values, then the list is extended in-place. Otherwise, it must be + // moved to a new location, leaving a zero'd hole in the previous space that won't be filled. + // This copy is shallow; sub-objects will simply be reparented, not copied. + // + // Any existing readers or builders pointing at the object are invalidated by this call (even if + // it doesn't move). You must call `get()` or `getReader()` again to get the new, valid pointer. + +private: + _::OrphanBuilder builder; + + template + friend struct _::PointerHelpers; + template + friend struct List; + template + friend class Orphan; + friend class Orphanage; + friend class MessageBuilder; +}; + +class Orphanage: private kj::DisallowConstCopy { + // Use to directly allocate Orphan objects, without having a parent object allocate and then + // disown the object. + +public: + inline Orphanage(): arena(nullptr) {} + + template + static Orphanage getForMessageContaining(BuilderType builder); + // Construct an Orphanage that allocates within the message containing the given Builder. This + // allows the constructed Orphans to be adopted by objects within said message. + // + // This constructor takes the builder rather than having the builder have a getOrphanage() method + // because this is an advanced feature and we don't want to pollute the builder APIs with it. + // + // Note that if you have a direct pointer to the `MessageBuilder`, you can simply call its + // `getOrphanage()` method. + + template + Orphan newOrphan() const; + // Allocate a new orphaned struct. + + template + Orphan newOrphan(uint size) const; + // Allocate a new orphaned list or blob. + + Orphan newOrphan(StructSchema schema) const; + // Dynamically create an orphan struct with the given schema. You must + // #include to use this. + + Orphan newOrphan(ListSchema schema, uint size) const; + // Dynamically create an orphan list with the given schema. You must #include + // to use this. + + template + Orphan> newOrphanCopy(Reader copyFrom) const; + // Allocate a new orphaned object (struct, list, or blob) and initialize it as a copy of the + // given object. + + template + Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; + template + Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; + // Given an array of List readers, copy and concatenate the lists, creating a new Orphan. + // + // Note that compared to allocating the list yourself and using `setWithCaveats()` to set each + // item, this method avoids the "caveats": the new list will be allocated with the element size + // being the maximum of that from all the input lists. This is particularly important when + // concatenating struct lists: if the lists were created using a newer version of the protocol + // in which some new fields had been added to the struct, using `setWithCaveats()` would + // truncate off those new fields. + + Orphan referenceExternalData(Data::Reader data) const; + // Creates an Orphan that points at an existing region of memory (e.g. from another message) + // without copying it. There are some SEVERE restrictions on how this can be used: + // - The memory must remain valid until the `MessageBuilder` is destroyed (even if the orphan is + // abandoned). + // - Because the data is const, you will not be allowed to obtain a `Data::Builder` + // for this blob. Any call which would return such a builder will throw an exception. You + // can, however, obtain a Reader, e.g. via orphan.getReader() or from a parent Reader (once + // the orphan is adopted). It is your responsibility to make sure your code can deal with + // these problems when using this optimization; if you can't, allocate a copy instead. + // - `data.begin()` must be aligned to a machine word boundary (32-bit or 64-bit depending on + // the CPU). Any pointer returned by malloc() as well as any data blob obtained from another + // Cap'n Proto message satisfies this. + // - If `data.size()` is not a multiple of 8, extra bytes past data.end() up until the next 8-byte + // boundary will be visible in the raw message when it is written out. Thus, there must be no + // secrets in these bytes. Data blobs obtained from other Cap'n Proto messages should be safe + // as these bytes should be zero (unless the sender had the same problem). + // + // The array will actually become one of the message's segments. The data can thus be adopted + // into the message tree without copying it. This is particularly useful when referencing very + // large blobs, such as whole mmap'd files. + +private: + _::BuilderArena* arena; + _::CapTableBuilder* capTable; + + inline explicit Orphanage(_::BuilderArena* arena, _::CapTableBuilder* capTable) + : arena(arena), capTable(capTable) {} + + template + struct GetInnerBuilder; + template + struct GetInnerReader; + template + struct NewOrphanListImpl; + + friend class MessageBuilder; + friend struct _::OrphanageInternal; +}; + +// ======================================================================================= +// Inline implementation details. + +namespace _ { // private + +template +struct OrphanGetImpl; + +template +struct OrphanGetImpl { + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::elementSizeForType()); + } +}; + +template +struct OrphanGetImpl { + static inline typename T::Builder apply(_::OrphanBuilder& builder) { + return typename T::Builder(builder.asStruct(_::structSize())); + } + static inline typename T::Reader applyReader(const _::OrphanBuilder& builder) { + return typename T::Reader(builder.asStructReader(_::structSize())); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, _::structSize()); + } +}; + +#if !CAPNP_LITE +template +struct OrphanGetImpl { + static inline typename T::Client apply(_::OrphanBuilder& builder) { + return typename T::Client(builder.asCapability()); + } + static inline typename T::Client applyReader(const _::OrphanBuilder& builder) { + return typename T::Client(builder.asCapability()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; +#endif // !CAPNP_LITE + +template +struct OrphanGetImpl, Kind::LIST> { + static inline typename List::Builder apply(_::OrphanBuilder& builder) { + return typename List::Builder(builder.asList(_::ElementSizeForType::value)); + } + static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { + return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template +struct OrphanGetImpl, Kind::LIST> { + static inline typename List::Builder apply(_::OrphanBuilder& builder) { + return typename List::Builder(builder.asStructList(_::structSize())); + } + static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { + return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <> +struct OrphanGetImpl { + static inline Text::Builder apply(_::OrphanBuilder& builder) { + return Text::Builder(builder.asText()); + } + static inline Text::Reader applyReader(const _::OrphanBuilder& builder) { + return Text::Reader(builder.asTextReader()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +template <> +struct OrphanGetImpl { + static inline Data::Builder apply(_::OrphanBuilder& builder) { + return Data::Builder(builder.asData()); + } + static inline Data::Reader applyReader(const _::OrphanBuilder& builder) { + return Data::Reader(builder.asDataReader()); + } + static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { + builder.truncate(size, ElementSize::POINTER); + } +}; + +struct OrphanageInternal { + static inline _::BuilderArena* getArena(Orphanage orphanage) { return orphanage.arena; } + static inline _::CapTableBuilder* getCapTable(Orphanage orphanage) { return orphanage.capTable; } +}; + +} // namespace _ (private) + +template +inline BuilderFor Orphan::get() { + return _::OrphanGetImpl::apply(builder); +} + +template +inline ReaderFor Orphan::getReader() const { + return _::OrphanGetImpl::applyReader(builder); +} + +template +inline void Orphan::truncate(uint size) { + _::OrphanGetImpl>::truncateListOf(builder, bounded(size) * ELEMENTS); +} + +template <> +inline void Orphan::truncate(uint size) { + builder.truncateText(bounded(size) * ELEMENTS); +} + +template <> +inline void Orphan::truncate(uint size) { + builder.truncate(bounded(size) * ELEMENTS, ElementSize::BYTE); +} + +template +struct Orphanage::GetInnerBuilder { + static inline _::StructBuilder apply(typename T::Builder& t) { + return t._builder; + } +}; + +template +struct Orphanage::GetInnerBuilder { + static inline _::ListBuilder apply(typename T::Builder& t) { + return t.builder; + } +}; + +template +Orphanage Orphanage::getForMessageContaining(BuilderType builder) { + auto inner = GetInnerBuilder>::apply(builder); + return Orphanage(inner.getArena(), inner.getCapTable()); +} + +template +Orphan Orphanage::newOrphan() const { + return Orphan(_::OrphanBuilder::initStruct(arena, capTable, _::structSize())); +} + +template +struct Orphanage::NewOrphanListImpl> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initList( + arena, capTable, bounded(size) * ELEMENTS, _::ElementSizeForType::value); + } +}; + +template +struct Orphanage::NewOrphanListImpl> { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initStructList( + arena, capTable, bounded(size) * ELEMENTS, _::structSize()); + } +}; + +template <> +struct Orphanage::NewOrphanListImpl { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initText(arena, capTable, bounded(size) * BYTES); + } +}; + +template <> +struct Orphanage::NewOrphanListImpl { + static inline _::OrphanBuilder apply( + _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { + return _::OrphanBuilder::initData(arena, capTable, bounded(size) * BYTES); + } +}; + +template +Orphan Orphanage::newOrphan(uint size) const { + return Orphan(NewOrphanListImpl::apply(arena, capTable, size)); +} + +template +struct Orphanage::GetInnerReader { + static inline _::StructReader apply(const typename T::Reader& t) { + return t._reader; + } +}; + +template +struct Orphanage::GetInnerReader { + static inline _::ListReader apply(const typename T::Reader& t) { + return t.reader; + } +}; + +template +struct Orphanage::GetInnerReader { + static inline const typename T::Reader& apply(const typename T::Reader& t) { + return t; + } +}; + +template +inline Orphan> Orphanage::newOrphanCopy(Reader copyFrom) const { + return Orphan>(_::OrphanBuilder::copy( + arena, capTable, GetInnerReader>::apply(copyFrom))); +} + +template +inline Orphan>>> +Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { + return newOrphanConcat(kj::implicitCast>(lists)); +} +template +inline Orphan>>> +Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { + // Optimization / simplification: Rely on List::Reader containing nothing except a + // _::ListReader. + static_assert(sizeof(T) == sizeof(_::ListReader), "lists are not bare readers?"); + kj::ArrayPtr raw( + reinterpret_cast(lists.begin()), lists.size()); + typedef ListElementType> Element; + return Orphan>( + _::OrphanBuilder::concat(arena, capTable, + _::elementSizeForType(), + _::minStructSizeForElement(), raw)); +} + +inline Orphan Orphanage::referenceExternalData(Data::Reader data) const { + return Orphan(_::OrphanBuilder::referenceExternalData(arena, data)); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/pointer-helpers.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/pointer-helpers.h new file mode 100644 index 000000000..c5ce57452 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/pointer-helpers.h @@ -0,0 +1,157 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "layout.h" +#include "list.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace _ { // private + +// PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in +// layout.h with the high-level public API and generated types. This way, the code generator +// and other templates do not have to specialize on each kind of pointer. + +template +struct PointerHelpers { + static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { + return typename T::Reader(reader.getStruct(defaultValue)); + } + static inline typename T::Builder get(PointerBuilder builder, + const word* defaultValue = nullptr) { + return typename T::Builder(builder.getStruct(structSize(), defaultValue)); + } + static inline void set(PointerBuilder builder, typename T::Reader value) { + builder.setStruct(value._reader); + } + static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { + builder.setStruct(value._reader, true); + } + static inline typename T::Builder init(PointerBuilder builder) { + return typename T::Builder(builder.initStruct(structSize())); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } + static inline _::StructReader getInternalReader(const typename T::Reader& reader) { + return reader._reader; + } + static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { + return builder._builder; + } +}; + +template +struct PointerHelpers, Kind::LIST> { + static inline typename List::Reader get(PointerReader reader, + const word* defaultValue = nullptr) { + return typename List::Reader(List::getFromPointer(reader, defaultValue)); + } + static inline typename List::Builder get(PointerBuilder builder, + const word* defaultValue = nullptr) { + return typename List::Builder(List::getFromPointer(builder, defaultValue)); + } + static inline void set(PointerBuilder builder, typename List::Reader value) { + builder.setList(value.reader); + } + static inline void setCanonical(PointerBuilder builder, typename List::Reader value) { + builder.setList(value.reader, true); + } + static void set(PointerBuilder builder, kj::ArrayPtr> value) { + auto l = init(builder, value.size()); + uint i = 0; + for (auto& element: value) { + l.set(i++, element); + } + } + static inline typename List::Builder init(PointerBuilder builder, uint size) { + return typename List::Builder(List::initPointer(builder, size)); + } + static inline void adopt(PointerBuilder builder, Orphan>&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan> disown(PointerBuilder builder) { + return Orphan>(builder.disown()); + } + static inline _::ListReader getInternalReader(const typename List::Reader& reader) { + return reader.reader; + } + static inline _::ListBuilder getInternalBuilder(typename List::Builder&& builder) { + return builder.builder; + } +}; + +template +struct PointerHelpers { + static inline typename T::Reader get(PointerReader reader, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return reader.getBlob(defaultValue, bounded(defaultBytes) * BYTES); + } + static inline typename T::Builder get(PointerBuilder builder, + const void* defaultValue = nullptr, + uint defaultBytes = 0) { + return builder.getBlob(defaultValue, bounded(defaultBytes) * BYTES); + } + static inline void set(PointerBuilder builder, typename T::Reader value) { + builder.setBlob(value); + } + static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { + builder.setBlob(value); + } + static inline typename T::Builder init(PointerBuilder builder, uint size) { + return builder.initBlob(bounded(size) * BYTES); + } + static inline void adopt(PointerBuilder builder, Orphan&& value) { + builder.adopt(kj::mv(value.builder)); + } + static inline Orphan disown(PointerBuilder builder) { + return Orphan(builder.disown()); + } +}; + +struct UncheckedMessage { + typedef const word* Reader; +}; + +template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; + +template <> +struct PointerHelpers { + // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing + // message is itself unchecked. This hack is currently private. It is used to locate default + // values within encoded schemas. + + static inline const word* get(PointerReader reader) { + return reader.getUnchecked(); + } +}; + +} // namespace _ (private) +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/pretty-print.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/pretty-print.h new file mode 100644 index 000000000..f3c6ced82 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/pretty-print.h @@ -0,0 +1,44 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "dynamic.h" +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +kj::StringTree prettyPrint(DynamicStruct::Reader value); +kj::StringTree prettyPrint(DynamicStruct::Builder value); +kj::StringTree prettyPrint(DynamicList::Reader value); +kj::StringTree prettyPrint(DynamicList::Builder value); +// Print the given Cap'n Proto struct or list with nice indentation. Note that you can pass any +// struct or list reader or builder type to this method, since they can be implicitly converted +// to one of the dynamic types. +// +// If you don't want indentation, just use the value's KJ stringifier (e.g. pass it to kj::str(), +// any of the KJ debug macros, etc.). + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/raw-schema.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/raw-schema.h new file mode 100644 index 000000000..44b696c5c --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/raw-schema.h @@ -0,0 +1,242 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "common.h" // for uint and friends + +#if _MSC_VER && !defined(__clang__) +#include +#endif + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace _ { // private + +struct RawSchema; + +struct RawBrandedSchema { + // Represents a combination of a schema and bindings for its generic parameters. + // + // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for + // every _instance_ of a generic type -- or, at least, every instance that is actually used. For + // generated-code types, we use template magic to initialize these. + + const RawSchema* generic; + // Generic type which we're branding. + + struct Binding { + uint8_t which; // Numeric value of one of schema::Type::Which. + + bool isImplicitParameter; + // For AnyPointer, true if it's an implicit method parameter. + + uint16_t listDepth; // Number of times to wrap the base type in List(). + + uint16_t paramIndex; + // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter + // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric + // value of one of schema::Type::AnyPointer::Unconstrained::Which. + + union { + const RawBrandedSchema* schema; // for struct, enum, interface + uint64_t scopeId; // for AnyPointer, if it's a type parameter + }; + + Binding() = default; + inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema) + : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0), + schema(schema) {} + inline constexpr Binding(uint8_t which, uint16_t listDepth, + uint64_t scopeId, uint16_t paramIndex) + : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex), + scopeId(scopeId) {} + inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex) + : which(which), isImplicitParameter(true), listDepth(listDepth), + paramIndex(implicitParamIndex), scopeId(0) {} + }; + + struct Scope { + uint64_t typeId; + // Type ID whose parameters are being bound. + + const Binding* bindings; + uint bindingCount; + // Bindings for those parameters. + + bool isUnbound; + // This scope is unbound, in the sense of SchemaLoader::getUnbound(). + }; + + const Scope* scopes; + // Array of enclosing scopes for which generic variables have been bound, sorted by type ID. + + struct Dependency { + uint location; + const RawBrandedSchema* schema; + }; + + const Dependency* dependencies; + // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that + // are branded are included in this map; if a dependency is missing, use its `defaultBrand`. + + uint32_t scopeCount; + uint32_t dependencyCount; + + enum class DepKind { + // Component of a Dependency::location. Specifies what sort of dependency this is. + + INVALID, + // Mostly defined to ensure that zero is not a valid location. + + FIELD, + // Binding needed for a field's type. The index is the field index (NOT ordinal!). + + METHOD_PARAMS, + // Bindings needed for a method's params type. The index is the method number. + + METHOD_RESULTS, + // Bindings needed for a method's results type. The index is the method ordinal. + + SUPERCLASS, + // Bindings needed for a superclass type. The index is the superclass's index in the + // "extends" list. + + CONST_TYPE + // Bindings needed for the type of a constant. The index is zero. + }; + + static inline uint makeDepLocation(DepKind kind, uint index) { + // Make a number representing the location of a particular dependency within its parent + // schema. + + return (static_cast(kind) << 24) | index; + } + + class Initializer { + public: + virtual void init(const RawBrandedSchema* generic) const = 0; + }; + + const Initializer* lazyInitializer; + // Lazy initializer, invoked by ensureInitialized(). + + inline void ensureInitialized() const { + // Lazy initialization support. Invoke to ensure that initialization has taken place. This + // is required in particular when traversing the dependency list. RawSchemas for compiled-in + // types are always initialized; only dynamically-loaded schemas may be lazy. + +#if __GNUC__ || defined(__clang__) + const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); +#elif _MSC_VER + const Initializer* i = *static_cast(&lazyInitializer); + std::atomic_thread_fence(std::memory_order_acquire); +#else +#error "Platform not supported" +#endif + if (i != nullptr) i->init(this); + } + + inline bool isUnbound() const; + // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case + // binding lookups need to be handled specially. +}; + +struct RawSchema { + // The generated code defines a constant RawSchema for every compiled declaration. + // + // This is an internal structure which could change in the future. + + uint64_t id; + + const word* encodedNode; + // Encoded SchemaNode, readable via readMessageUnchecked(encodedNode). + + uint32_t encodedSize; + // Size of encodedNode, in words. + + const RawSchema* const* dependencies; + // Pointers to other types on which this one depends, sorted by ID. The schemas in this table + // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before + // using it. + // + // TODO(someday): Make this a hashtable. + + const uint16_t* membersByName; + // Indexes of members sorted by name. Used to implement name lookup. + // TODO(someday): Make this a hashtable. + + uint32_t dependencyCount; + uint32_t memberCount; + // Sizes of above tables. + + const uint16_t* membersByDiscriminant; + // List of all member indexes ordered by discriminant value. Those which don't have a + // discriminant value are listed at the end, in order by ordinal. + + const RawSchema* canCastTo; + // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue + // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on + // dynamically-loaded types. + + class Initializer { + public: + virtual void init(const RawSchema* schema) const = 0; + }; + + const Initializer* lazyInitializer; + // Lazy initializer, invoked by ensureInitialized(). + + inline void ensureInitialized() const { + // Lazy initialization support. Invoke to ensure that initialization has taken place. This + // is required in particular when traversing the dependency list. RawSchemas for compiled-in + // types are always initialized; only dynamically-loaded schemas may be lazy. + +#if __GNUC__ || defined(__clang__) + const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); +#elif _MSC_VER + const Initializer* i = *static_cast(&lazyInitializer); + std::atomic_thread_fence(std::memory_order_acquire); +#else +#error "Platform not supported" +#endif + if (i != nullptr) i->init(this); + } + + RawBrandedSchema defaultBrand; + // Specifies the brand to use for this schema if no generic parameters have been bound to + // anything. Generally, in the default brand, all generic parameters are treated as if they were + // bound to `AnyPointer`. + + bool mayContainCapabilities = true; + // See StructSchema::mayContainCapabilities. +}; + +inline bool RawBrandedSchema::isUnbound() const { + // The unbound schema is the only one that has no scopes but is not the default schema. + return scopeCount == 0 && this != &generic->defaultBrand; +} + +} // namespace _ (private) +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-lite.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-lite.h new file mode 100644 index 000000000..0d7b91567 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-lite.h @@ -0,0 +1,45 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include "message.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +template +inline schema::Node::Reader schemaProto() { + // Get the schema::Node for this type's schema. This function works even in lite mode. + return readMessageUnchecked(CapnpPrivate::encodedSchema()); +} + +template ::typeId> +inline schema::Node::Reader schemaProto() { + // Get the schema::Node for this type's schema. This function works even in lite mode. + return readMessageUnchecked(schemas::EnumInfo::encodedSchema()); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-loader.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-loader.h new file mode 100644 index 000000000..5db8364c4 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-loader.h @@ -0,0 +1,183 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "schema.h" +#include +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class SchemaLoader { + // Class which can be used to construct Schema objects from schema::Nodes as defined in + // schema.capnp. + // + // It is a bad idea to use this class on untrusted input with exceptions disabled -- you may + // be exposing yourself to denial-of-service attacks, as attackers can easily construct schemas + // that are subtly inconsistent in a way that causes exceptions to be thrown either by + // SchemaLoader or by the dynamic API when the schemas are subsequently used. If you enable and + // properly catch exceptions, you should be OK -- assuming no bugs in the Cap'n Proto + // implementation, of course. + +public: + class LazyLoadCallback { + public: + virtual void load(const SchemaLoader& loader, uint64_t id) const = 0; + // Request that the schema node with the given ID be loaded into the given SchemaLoader. If + // the callback is able to find a schema for this ID, it should invoke `loadOnce()` on + // `loader` to load it. If no such node exists, it should simply do nothing and return. + // + // The callback is allowed to load schema nodes other than the one requested, e.g. because it + // expects they will be needed soon. + // + // If the `SchemaLoader` is used from multiple threads, the callback must be thread-safe. + // In particular, it's possible for multiple threads to invoke `load()` with the same ID. + // If the callback performs a large amount of work to look up IDs, it should be sure to + // de-dup these requests. + }; + + SchemaLoader(); + + SchemaLoader(const LazyLoadCallback& callback); + // Construct a SchemaLoader which will invoke the given callback when a schema node is requested + // that isn't already loaded. + + ~SchemaLoader() noexcept(false); + KJ_DISALLOW_COPY_AND_MOVE(SchemaLoader); + + Schema get(uint64_t id, schema::Brand::Reader brand = schema::Brand::Reader(), + Schema scope = Schema()) const; + // Gets the schema for the given ID, throwing an exception if it isn't present. + // + // The returned schema may be invalidated if load() is called with a new schema for the same ID. + // In general, you should not call load() while a schema from this loader is in-use. + // + // `brand` and `scope` are used to determine brand bindings where relevant. `brand` gives + // parameter bindings for the target type's brand parameters that were specified at the reference + // site. `scope` specifies the scope in which the type ID appeared -- if `brand` itself contains + // parameter references or indicates that some parameters will be inherited, these will be + // interpreted within / inherited from `scope`. + + kj::Maybe tryGet(uint64_t id, schema::Brand::Reader bindings = schema::Brand::Reader(), + Schema scope = Schema()) const; + // Like get() but doesn't throw. + + Schema getUnbound(uint64_t id) const; + // Gets a special version of the schema in which all brand parameters are "unbound". This means + // that if you look up a type via the Schema API, and it resolves to a brand parameter, the + // returned Type's getBrandParameter() method will return info about that parameter. Otherwise, + // normally, all brand parameters that aren't otherwise bound are assumed to simply be + // "AnyPointer". + + Type getType(schema::Type::Reader type, Schema scope = Schema()) const; + // Convenience method which interprets a schema::Type to produce a Type object. Implemented in + // terms of get(). + + Schema load(const schema::Node::Reader& reader); + // Loads the given schema node. Validates the node and throws an exception if invalid. This + // makes a copy of the schema, so the object passed in can be destroyed after this returns. + // + // If the node has any dependencies which are not already loaded, they will be initialized as + // stubs -- empty schemas of whichever kind is expected. + // + // If another schema for the given reader has already been seen, the loader will inspect both + // schemas to determine which one is newer, and use that that one. If the two versions are + // found to be incompatible, an exception is thrown. If the two versions differ but are + // compatible and the loader cannot determine which is newer (e.g., the only changes are renames), + // the existing schema will be preferred. Note that in any case, the loader will end up keeping + // around copies of both schemas, so you shouldn't repeatedly reload schemas into the same loader. + // + // The following properties of the schema node are validated: + // - Struct size and preferred list encoding are valid and consistent. + // - Struct members are fields or unions. + // - Union members are fields. + // - Field offsets are in-bounds. + // - Ordinals and codeOrders are sequential starting from zero. + // - Values are of the right union case to match their types. + // + // You should assume anything not listed above is NOT validated. In particular, things that are + // not validated now, but could be in the future, include but are not limited to: + // - Names. + // - Annotation values. (This is hard because the annotation declaration is not always + // available.) + // - Content of default/constant values of pointer type. (Validating these would require knowing + // their schema, but even if the schemas are available at validation time, they could be + // updated by a subsequent load(), invalidating existing values. Instead, these values are + // validated at the time they are used, as usual for Cap'n Proto objects.) + // + // Also note that unknown types are not considered invalid. Instead, the dynamic API returns + // a DynamicValue with type UNKNOWN for these. + + Schema loadOnce(const schema::Node::Reader& reader) const; + // Like `load()` but does nothing if a schema with the same ID is already loaded. In contrast, + // `load()` would attempt to compare the schemas and take the newer one. `loadOnce()` is safe + // to call even while concurrently using schemas from this loader. It should be considered an + // error to call `loadOnce()` with two non-identical schemas that share the same ID, although + // this error may or may not actually be detected by the implementation. + + template + void loadCompiledTypeAndDependencies(); + // Load the schema for the given compiled-in type and all of its dependencies. + // + // If you want to be able to cast a DynamicValue built from this SchemaLoader to the compiled-in + // type using as(), you must call this method before constructing the DynamicValue. Otherwise, + // as() will throw an exception complaining about type mismatch. + + kj::Array getAllLoaded() const; + // Get a complete list of all loaded schema nodes. It is particularly useful to call this after + // loadCompiledTypeAndDependencies() in order to get a flat list of all of T's transitive + // dependencies. + + void computeOptimizationHints(); + // Call after all interesting schemas have been loaded to compute optimization hints. In + // particular, this initializes `hasNoCapabilities` for every struct type. Before this is called, + // that value is initialized to false for all types (which ensures correct behavior but does not + // allow the optimization). + // + // If any loaded struct types contain fields of types for which no schema has been loaded, they + // will be presumed to possibly contain capabilities. `LazyLoadCallback` will NOT be invoked to + // load any types that haven't been loaded yet. + // + // TODO(someday): Perhaps we could dynamically initialize the hints on-demand, but it would be + // much more work to implement. + +private: + class Validator; + class CompatibilityChecker; + class Impl; + class InitializerImpl; + class BrandedInitializerImpl; + kj::MutexGuarded> impl; + + void loadNative(const _::RawSchema* nativeSchema); +}; + +template +inline void SchemaLoader::loadCompiledTypeAndDependencies() { + loadNative(&_::rawSchema()); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-parser.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-parser.h new file mode 100644 index 000000000..6c4876377 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema-parser.h @@ -0,0 +1,293 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "schema-loader.h" +#include +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class ParsedSchema; +class SchemaFile; + +class SchemaParser { + // Parses `.capnp` files to produce `Schema` objects. + // + // This class is thread-safe, hence all its methods are const. + +public: + SchemaParser(); + ~SchemaParser() noexcept(false); + + ParsedSchema parseFromDirectory( + const kj::ReadableDirectory& baseDir, kj::Path path, + kj::ArrayPtr importPath) const; + // Parse a file from the KJ filesystem API. Throws an exception if the file doesn't exist. + // + // `baseDir` and `path` are used together to resolve relative imports. `path` is the source + // file's path within `baseDir`. Relative imports will be interpreted relative to `path` and + // will be opened using `baseDir`. Note that the KJ filesystem API prohibits "breaking out" of + // a directory using "..", so relative imports will be restricted to children of `baseDir`. + // + // `importPath` is used for absolute imports (imports that start with a '/'). Each directory in + // the array will be searched in order until a file is found. + // + // All `ReadableDirectory` objects must remain valid until the `SchemaParser` is destroyed. Also, + // the `importPath` array must remain valid. `path` will be copied; it need not remain valid. + // + // This method is a shortcut, equivalent to: + // parser.parseFile(SchemaFile::newDiskFile(baseDir, path, importPath))`; + // + // This method throws an exception if any errors are encountered in the file or in anything the + // file depends on. Note that merely importing another file does not count as a dependency on + // anything in the imported file -- only the imported types which are actually used are + // "dependencies". + // + // Hint: Use kj::newDiskFilesystem() to initialize the KJ filesystem API. Usually you should do + // this at a high level in your program, e.g. the main() function, and then pass down the + // appropriate File/Directory objects to the components that need them. Example: + // + // auto fs = kj::newDiskFilesystem(); + // SchemaParser parser; + // auto schema = parser.parseFromDirectory(fs->getCurrent(), + // kj::Path::parse("foo/bar.capnp"), nullptr); + // + // Hint: To use in-memory data rather than real disk, you can use kj::newInMemoryDirectory(), + // write the files you want, then pass it to SchemaParser. Example: + // + // auto dir = kj::newInMemoryDirectory(kj::nullClock()); + // auto path = kj::Path::parse("foo/bar.capnp"); + // dir->openFile(path, kj::WriteMode::CREATE | kj::WriteMode::CREATE_PARENT) + // ->writeAll("struct Foo {}"); + // auto schema = parser.parseFromDirectory(*dir, path, nullptr); + // + // Hint: You can create an in-memory directory but then populate it with real files from disk, + // in order to control what is visible while also avoiding reading files yourself or making + // extra copies. Example: + // + // auto fs = kj::newDiskFilesystem(); + // auto dir = kj::newInMemoryDirectory(kj::nullClock()); + // auto fakePath = kj::Path::parse("foo/bar.capnp"); + // auto realPath = kj::Path::parse("path/to/some/file.capnp"); + // dir->transfer(fakePath, kj::WriteMode::CREATE | kj::WriteMode::CREATE_PARENT, + // fs->getCurrent(), realPath, kj::TransferMode::LINK); + // auto schema = parser.parseFromDirectory(*dir, fakePath, nullptr); + // + // In this example, note that any imports in the file will fail, since the in-memory directory + // you created contains no files except the specific one you linked in. + + ParsedSchema parseDiskFile(kj::StringPtr displayName, kj::StringPtr diskPath, + kj::ArrayPtr importPath) const + CAPNP_DEPRECATED("Use parseFromDirectory() instead."); + // Creates a private kj::Filesystem and uses it to parse files from the real disk. + // + // DO NOT USE in new code. Use parseFromDirectory() instead. + // + // This API has a serious problem: the file can import and embed files located anywhere on disk + // using relative paths. Even if you specify no `importPath`, relative imports still work. By + // using `parseFromDirectory()`, you can arrange so that imports are only allowed within a + // particular directory, or even set up a dummy filesystem where other files are not visible. + + void setDiskFilesystem(kj::Filesystem& fs) + CAPNP_DEPRECATED("Use parseFromDirectory() instead."); + // Call before calling parseDiskFile() to choose an alternative disk filesystem implementation. + // This exists mostly for testing purposes; new code should use parseFromDirectory() instead. + // + // If parseDiskFile() is called without having called setDiskFilesystem(), then + // kj::newDiskFilesystem() will be used instead. + + ParsedSchema parseFile(kj::Own&& file) const; + // Advanced interface for parsing a file that may or may not be located in any global namespace. + // Most users will prefer `parseFromDirectory()`. + // + // If the file has already been parsed (that is, a SchemaFile that compares equal to this one + // was parsed previously), the existing schema will be returned again. + // + // This method reports errors by calling SchemaFile::reportError() on the file where the error + // is located. If that call does not throw an exception, `parseFile()` may in fact return + // normally. In this case, the result is a best-effort attempt to compile the schema, but it + // may be invalid or corrupt, and using it for anything may cause exceptions to be thrown. + + kj::Maybe getSourceInfo(Schema schema) const; + // Look up source info (e.g. doc comments) for the given schema, which must have come from this + // SchemaParser. Note that this will also work for implicit group and param types that don't have + // a type name hence don't have a `ParsedSchema`. + + template + inline void loadCompiledTypeAndDependencies() { + // See SchemaLoader::loadCompiledTypeAndDependencies(). + getLoader().loadCompiledTypeAndDependencies(); + } + + kj::Array getAllLoaded() const { + // Gets an array of all schema nodes that have been parsed so far. + return getLoader().getAllLoaded(); + } + + void setFileIdsRequired(bool value) { fileIdsRequired = value; } + // By befault, capnp files must declare a file-level type ID (like `@0xbe702824338d3f7f;`). + // Use `setFileIdsReqired(false)` to lift this requirement. + // + // If no ID is specified, a random one will be assigned. This will cause all types declared in + // the file to have randomized IDs as well (unless they declare an ID explicitly), which means + // that parsing the same file twice will appear to to produce a totally new, incompatible set of + // types. In particular, this means that you will not be able to use any interface types in the + // file for RPC, since the RPC protocol uses type IDs to identify methods. + // + // Setting this false is particularly useful when using Cap'n Proto as a config format. Typically + // type IDs are irrelevant for config files, and the requirement to specify one is cumbersome. + // For this reason, `capnp eval` does not require type ID to be present. + +private: + struct Impl; + struct DiskFileCompat; + class ModuleImpl; + kj::Own impl; + mutable bool hadErrors = false; + bool fileIdsRequired = true; + + ModuleImpl& getModuleImpl(kj::Own&& file) const; + const SchemaLoader& getLoader() const; + SchemaLoader& getLoader(); + + friend class ParsedSchema; +}; + +class ParsedSchema: public Schema { + // ParsedSchema is an extension of Schema which also has the ability to look up nested nodes + // by name. See `SchemaParser`. + + class ParsedSchemaList; + friend class ParsedSchemaList; + +public: + inline ParsedSchema(): parser(nullptr) {} + + kj::Maybe findNested(kj::StringPtr name) const; + // Gets the nested node with the given name, or returns null if there is no such nested + // declaration. + + ParsedSchema getNested(kj::StringPtr name) const; + // Gets the nested node with the given name, or throws an exception if there is no such nested + // declaration. + + ParsedSchemaList getAllNested() const; + // Get all the nested nodes + + schema::Node::SourceInfo::Reader getSourceInfo() const; + // Get the source info for this schema. + +private: + inline ParsedSchema(Schema inner, const SchemaParser& parser): Schema(inner), parser(&parser) {} + + const SchemaParser* parser; + friend class SchemaParser; +}; + +class ParsedSchema::ParsedSchemaList { +public: + ParsedSchemaList() = default; // empty list + + inline uint size() const { return list.size(); } + ParsedSchema operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + ParsedSchema parent; + List::Reader list; + + inline ParsedSchemaList(ParsedSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class ParsedSchema; +}; + +// ======================================================================================= +// Advanced API + +class SchemaFile { + // Abstract interface representing a schema file. You can implement this yourself in order to + // gain more control over how the compiler resolves imports and reads files. For the + // common case of files on disk or other global filesystem-like namespaces, use + // `SchemaFile::newDiskFile()`. + +public: + // Note: Cap'n Proto 0.6.x and below had classes FileReader and DiskFileReader and a method + // newDiskFile() defined here. These were removed when SchemaParser was transitioned to use the + // KJ filesystem API. You should be able to get the same effect by subclassing + // kj::ReadableDirectory, or using kj::newInMemoryDirectory(). + + static kj::Own newFromDirectory( + const kj::ReadableDirectory& baseDir, kj::Path path, + kj::ArrayPtr importPath, + kj::Maybe displayNameOverride = nullptr); + // Construct a SchemaFile representing a file in a kj::ReadableDirectory. This is used to + // implement SchemaParser::parseFromDirectory(); see there for details. + // + // The SchemaFile compares equal to any other SchemaFile that has exactly the same `baseDir` + // object (by identity) and `path` (by value). + + // ----------------------------------------------------------------- + // For more control, you can implement this interface. + + virtual kj::StringPtr getDisplayName() const = 0; + // Get the file's name, as it should appear in the schema. + + virtual kj::Array readContent() const = 0; + // Read the file's entire content and return it as a byte array. + + virtual kj::Maybe> import(kj::StringPtr path) const = 0; + // Resolve an import, relative to this file. + // + // `path` is exactly what appears between quotes after the `import` keyword in the source code. + // It is entirely up to the `SchemaFile` to decide how to map this to another file. Typically, + // a leading '/' means that the file is an "absolute" path and is searched for in some list of + // schema file repositories. On the other hand, a path that doesn't start with '/' is relative + // to the importing file. + + virtual bool operator==(const SchemaFile& other) const = 0; + virtual bool operator!=(const SchemaFile& other) const = 0; + virtual size_t hashCode() const = 0; + // Compare two SchemaFiles to see if they refer to the same underlying file. This is an + // optimization used to avoid the need to re-parse a file to check its ID. + + struct SourcePos { + uint byte; + uint line; + uint column; + }; + virtual void reportError(SourcePos start, SourcePos end, kj::StringPtr message) const = 0; + // Report that the file contains an error at the given interval. + +private: + class DiskSchemaFile; +}; + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.capnp.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.capnp.cc new file mode 100644 index 000000000..1b7c7c2ef --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.capnp.cc @@ -0,0 +1,3988 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: schema.capnp + +#include "schema.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<225> b_e682ab4cf923a417 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 19, 0, 0, 0, 1, 0, 5, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 6, 0, 7, 0, 0, 0, 6, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 194, 0, 0, 0, + 29, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 23, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 0, + 12, 0, 0, 0, 1, 0, 1, 0, + 177, 163, 15, 241, 204, 27, 82, 185, + 17, 0, 0, 0, 82, 0, 0, 0, + 66, 194, 15, 250, 187, 85, 191, 222, + 17, 0, 0, 0, 90, 0, 0, 0, + 174, 87, 19, 4, 227, 29, 142, 243, + 17, 0, 0, 0, 90, 0, 0, 0, + 80, 97, 114, 97, 109, 101, 116, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 78, 101, 115, 116, 101, 100, 78, 111, + 100, 101, 0, 0, 0, 0, 0, 0, + 83, 111, 117, 114, 99, 101, 73, 110, + 102, 111, 0, 0, 0, 0, 0, 0, + 56, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 121, 1, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 1, 0, 0, 3, 0, 1, 0, + 128, 1, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 125, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 124, 1, 0, 0, 3, 0, 1, 0, + 136, 1, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 133, 1, 0, 0, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 136, 1, 0, 0, 3, 0, 1, 0, + 148, 1, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 145, 1, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 140, 1, 0, 0, 3, 0, 1, 0, + 152, 1, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 149, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 148, 1, 0, 0, 3, 0, 1, 0, + 176, 1, 0, 0, 2, 0, 1, 0, + 7, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 173, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 172, 1, 0, 0, 3, 0, 1, 0, + 200, 1, 0, 0, 2, 0, 1, 0, + 8, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 197, 1, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 192, 1, 0, 0, 3, 0, 1, 0, + 204, 1, 0, 0, 2, 0, 1, 0, + 9, 0, 254, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 53, 68, 251, 55, 155, 177, 160, 158, + 201, 1, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 253, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 152, 245, 51, 67, 54, 179, 74, 181, + 177, 1, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 252, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 143, 33, 194, 240, 207, 83, 39, 232, + 153, 1, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 251, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 32, 148, 13, 122, 172, 165, 138, 177, + 133, 1, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 250, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 144, 2, 10, 64, 212, 25, 22, 236, + 109, 1, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 89, 1, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 1, 0, 0, 3, 0, 1, 0, + 116, 1, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 32, 1, 0, 0, + 0, 0, 1, 0, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 113, 1, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 1, 0, 0, 3, 0, 1, 0, + 124, 1, 0, 0, 2, 0, 1, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 112, 108, 97, 121, 78, + 97, 109, 101, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 112, 108, 97, 121, 78, + 97, 109, 101, 80, 114, 101, 102, 105, + 120, 76, 101, 110, 103, 116, 104, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 99, 111, 112, 101, 73, 100, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 101, 115, 116, 101, 100, 78, 111, + 100, 101, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 66, 194, 15, 250, 187, 85, 191, 222, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 110, 110, 111, 116, 97, 116, 105, + 111, 110, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 66, 117, 37, 171, 13, 149, 200, 241, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 105, 108, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 116, 114, 117, 99, 116, 0, 0, + 101, 110, 117, 109, 0, 0, 0, 0, + 105, 110, 116, 101, 114, 102, 97, 99, + 101, 0, 0, 0, 0, 0, 0, 0, + 99, 111, 110, 115, 116, 0, 0, 0, + 97, 110, 110, 111, 116, 97, 116, 105, + 111, 110, 0, 0, 0, 0, 0, 0, + 112, 97, 114, 97, 109, 101, 116, 101, + 114, 115, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 177, 163, 15, 241, 204, 27, 82, 185, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 115, 71, 101, 110, 101, 114, 105, + 99, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_e682ab4cf923a417 = b_e682ab4cf923a417.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_e682ab4cf923a417[] = { + &s_9ea0b19b37fb4435, + &s_b18aa5ac7a0d9420, + &s_b54ab3364333f598, + &s_b9521bccf10fa3b1, + &s_debf55bbfa0fc242, + &s_e82753cff0c2218f, + &s_ec1619d4400a0290, + &s_f1c8950dab257542, +}; +static const uint16_t m_e682ab4cf923a417[] = {11, 5, 10, 1, 2, 8, 6, 0, 9, 13, 4, 12, 3, 7}; +static const uint16_t i_e682ab4cf923a417[] = {6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 12, 13}; +const ::capnp::_::RawSchema s_e682ab4cf923a417 = { + 0xe682ab4cf923a417, b_e682ab4cf923a417.words, 225, d_e682ab4cf923a417, m_e682ab4cf923a417, + 8, 14, i_e682ab4cf923a417, nullptr, nullptr, { &s_e682ab4cf923a417, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<34> b_b9521bccf10fa3b1 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 177, 163, 15, 241, 204, 27, 82, 185, + 24, 0, 0, 0, 1, 0, 0, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 18, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 80, 97, 114, 97, 109, 101, 116, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 20, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b9521bccf10fa3b1 = b_b9521bccf10fa3b1.words; +#if !CAPNP_LITE +static const uint16_t m_b9521bccf10fa3b1[] = {0}; +static const uint16_t i_b9521bccf10fa3b1[] = {0}; +const ::capnp::_::RawSchema s_b9521bccf10fa3b1 = { + 0xb9521bccf10fa3b1, b_b9521bccf10fa3b1.words, 34, nullptr, m_b9521bccf10fa3b1, + 0, 1, i_b9521bccf10fa3b1, nullptr, nullptr, { &s_b9521bccf10fa3b1, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<49> b_debf55bbfa0fc242 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 66, 194, 15, 250, 187, 85, 191, 222, + 24, 0, 0, 0, 1, 0, 1, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 26, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 78, 101, 115, 116, 101, 100, 78, 111, + 100, 101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_debf55bbfa0fc242 = b_debf55bbfa0fc242.words; +#if !CAPNP_LITE +static const uint16_t m_debf55bbfa0fc242[] = {1, 0}; +static const uint16_t i_debf55bbfa0fc242[] = {0, 1}; +const ::capnp::_::RawSchema s_debf55bbfa0fc242 = { + 0xdebf55bbfa0fc242, b_debf55bbfa0fc242.words, 49, nullptr, m_debf55bbfa0fc242, + 0, 2, i_debf55bbfa0fc242, nullptr, nullptr, { &s_debf55bbfa0fc242, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<72> b_f38e1de3041357ae = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 174, 87, 19, 4, 227, 29, 142, 243, + 24, 0, 0, 0, 1, 0, 1, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 26, 1, 0, 0, + 37, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 83, 111, 117, 114, 99, 101, 73, 110, + 102, 111, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 162, 31, 142, 137, 56, 144, 186, 194, + 1, 0, 0, 0, 58, 0, 0, 0, + 77, 101, 109, 98, 101, 114, 0, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 111, 99, 67, 111, 109, 109, 101, + 110, 116, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 101, 109, 98, 101, 114, 115, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 162, 31, 142, 137, 56, 144, 186, 194, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_f38e1de3041357ae = b_f38e1de3041357ae.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_f38e1de3041357ae[] = { + &s_c2ba9038898e1fa2, +}; +static const uint16_t m_f38e1de3041357ae[] = {1, 0, 2}; +static const uint16_t i_f38e1de3041357ae[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_f38e1de3041357ae = { + 0xf38e1de3041357ae, b_f38e1de3041357ae.words, 72, d_f38e1de3041357ae, m_f38e1de3041357ae, + 1, 3, i_f38e1de3041357ae, nullptr, nullptr, { &s_f38e1de3041357ae, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<36> b_c2ba9038898e1fa2 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 162, 31, 142, 137, 56, 144, 186, 194, + 35, 0, 0, 0, 1, 0, 0, 0, + 174, 87, 19, 4, 227, 29, 142, 243, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 82, 1, 0, 0, + 41, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 37, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 83, 111, 117, 114, 99, 101, 73, 110, + 102, 111, 46, 77, 101, 109, 98, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 24, 0, 0, 0, 2, 0, 1, 0, + 100, 111, 99, 67, 111, 109, 109, 101, + 110, 116, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c2ba9038898e1fa2 = b_c2ba9038898e1fa2.words; +#if !CAPNP_LITE +static const uint16_t m_c2ba9038898e1fa2[] = {0}; +static const uint16_t i_c2ba9038898e1fa2[] = {0}; +const ::capnp::_::RawSchema s_c2ba9038898e1fa2 = { + 0xc2ba9038898e1fa2, b_c2ba9038898e1fa2.words, 36, nullptr, m_c2ba9038898e1fa2, + 0, 1, i_c2ba9038898e1fa2, nullptr, nullptr, { &s_c2ba9038898e1fa2, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<134> b_9ea0b19b37fb4435 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 53, 68, 251, 55, 155, 177, 160, 158, + 24, 0, 0, 0, 1, 0, 5, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 6, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 143, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 115, 116, 114, 117, 99, 116, 0, 0, + 28, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 181, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 180, 0, 0, 0, 3, 0, 1, 0, + 192, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 1, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 189, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 188, 0, 0, 0, 3, 0, 1, 0, + 200, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 13, 0, 0, 0, + 0, 0, 1, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 197, 0, 0, 0, 178, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 200, 0, 0, 0, 3, 0, 1, 0, + 212, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 224, 0, 0, 0, + 0, 0, 1, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 209, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 204, 0, 0, 0, 3, 0, 1, 0, + 216, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 15, 0, 0, 0, + 0, 0, 1, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 0, 0, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 216, 0, 0, 0, 3, 0, 1, 0, + 228, 0, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 1, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 225, 0, 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 228, 0, 0, 0, 3, 0, 1, 0, + 240, 0, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 232, 0, 0, 0, 3, 0, 1, 0, + 4, 1, 0, 0, 2, 0, 1, 0, + 100, 97, 116, 97, 87, 111, 114, 100, + 67, 111, 117, 110, 116, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 111, 105, 110, 116, 101, 114, 67, + 111, 117, 110, 116, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 114, 101, 102, 101, 114, 114, 101, + 100, 76, 105, 115, 116, 69, 110, 99, + 111, 100, 105, 110, 103, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 38, 25, 82, 186, 125, 143, 149, 209, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 115, 71, 114, 111, 117, 112, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 99, 114, 105, 109, 105, + 110, 97, 110, 116, 67, 111, 117, 110, + 116, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 99, 114, 105, 109, 105, + 110, 97, 110, 116, 79, 102, 102, 115, + 101, 116, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 105, 101, 108, 100, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 95, 244, 74, 31, 164, 80, 173, 154, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9ea0b19b37fb4435 = b_9ea0b19b37fb4435.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9ea0b19b37fb4435[] = { + &s_9aad50a41f4af45f, + &s_d1958f7dba521926, + &s_e682ab4cf923a417, +}; +static const uint16_t m_9ea0b19b37fb4435[] = {0, 4, 5, 6, 3, 1, 2}; +static const uint16_t i_9ea0b19b37fb4435[] = {0, 1, 2, 3, 4, 5, 6}; +const ::capnp::_::RawSchema s_9ea0b19b37fb4435 = { + 0x9ea0b19b37fb4435, b_9ea0b19b37fb4435.words, 134, d_9ea0b19b37fb4435, m_9ea0b19b37fb4435, + 3, 7, i_9ea0b19b37fb4435, nullptr, nullptr, { &s_9ea0b19b37fb4435, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<37> b_b54ab3364333f598 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 152, 245, 51, 67, 54, 179, 74, 181, + 24, 0, 0, 0, 1, 0, 5, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 6, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 101, 110, 117, 109, 0, 0, 0, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 40, 0, 0, 0, 2, 0, 1, 0, + 101, 110, 117, 109, 101, 114, 97, 110, + 116, 115, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 77, 154, 84, 220, 235, 124, 138, 151, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b54ab3364333f598 = b_b54ab3364333f598.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_b54ab3364333f598[] = { + &s_978a7cebdc549a4d, + &s_e682ab4cf923a417, +}; +static const uint16_t m_b54ab3364333f598[] = {0}; +static const uint16_t i_b54ab3364333f598[] = {0}; +const ::capnp::_::RawSchema s_b54ab3364333f598 = { + 0xb54ab3364333f598, b_b54ab3364333f598.words, 37, d_b54ab3364333f598, m_b54ab3364333f598, + 2, 1, i_b54ab3364333f598, nullptr, nullptr, { &s_b54ab3364333f598, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<57> b_e82753cff0c2218f = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 143, 33, 194, 240, 207, 83, 39, 232, + 24, 0, 0, 0, 1, 0, 5, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 6, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 18, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 105, 110, 116, 101, 114, 102, 97, 99, + 101, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 64, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 1, 0, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 61, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 60, 0, 0, 0, 3, 0, 1, 0, + 88, 0, 0, 0, 2, 0, 1, 0, + 109, 101, 116, 104, 111, 100, 115, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 128, 77, 51, 59, 226, 204, 0, 149, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 117, 112, 101, 114, 99, 108, 97, + 115, 115, 101, 115, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 248, 215, 164, 208, 158, 42, 150, 169, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_e82753cff0c2218f = b_e82753cff0c2218f.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_e82753cff0c2218f[] = { + &s_9500cce23b334d80, + &s_a9962a9ed0a4d7f8, + &s_e682ab4cf923a417, +}; +static const uint16_t m_e82753cff0c2218f[] = {0, 1}; +static const uint16_t i_e82753cff0c2218f[] = {0, 1}; +const ::capnp::_::RawSchema s_e82753cff0c2218f = { + 0xe82753cff0c2218f, b_e82753cff0c2218f.words, 57, d_e82753cff0c2218f, m_e82753cff0c2218f, + 3, 2, i_e82753cff0c2218f, nullptr, nullptr, { &s_e82753cff0c2218f, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_b18aa5ac7a0d9420 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 32, 148, 13, 122, 172, 165, 138, 177, + 24, 0, 0, 0, 1, 0, 5, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 6, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 99, 111, 110, 115, 116, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 1, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 116, 121, 112, 101, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 108, 117, 101, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 155, 12, 176, 215, 210, 220, 35, 206, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_b18aa5ac7a0d9420 = b_b18aa5ac7a0d9420.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_b18aa5ac7a0d9420[] = { + &s_ce23dcd2d7b00c9b, + &s_d07378ede1f9cc60, + &s_e682ab4cf923a417, +}; +static const uint16_t m_b18aa5ac7a0d9420[] = {0, 1}; +static const uint16_t i_b18aa5ac7a0d9420[] = {0, 1}; +const ::capnp::_::RawSchema s_b18aa5ac7a0d9420 = { + 0xb18aa5ac7a0d9420, b_b18aa5ac7a0d9420.words, 47, d_b18aa5ac7a0d9420, m_b18aa5ac7a0d9420, + 3, 2, i_b18aa5ac7a0d9420, nullptr, nullptr, { &s_b18aa5ac7a0d9420, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<228> b_ec1619d4400a0290 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 144, 2, 10, 64, 212, 25, 22, 236, + 24, 0, 0, 0, 1, 0, 5, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 6, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 26, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 223, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 78, 111, 100, 101, 46, + 97, 110, 110, 111, 116, 97, 116, 105, + 111, 110, 0, 0, 0, 0, 0, 0, + 52, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 93, 1, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 1, 0, 0, 3, 0, 1, 0, + 100, 1, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 112, 0, 0, 0, + 0, 0, 1, 0, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 1, 0, 0, 3, 0, 1, 0, + 108, 1, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 113, 0, 0, 0, + 0, 0, 1, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 1, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 1, 0, 0, 3, 0, 1, 0, + 116, 1, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 1, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 113, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 1, 0, 0, 3, 0, 1, 0, + 124, 1, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 115, 0, 0, 0, + 0, 0, 1, 0, 22, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 121, 1, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 124, 1, 0, 0, 3, 0, 1, 0, + 136, 1, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 116, 0, 0, 0, + 0, 0, 1, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 133, 1, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 132, 1, 0, 0, 3, 0, 1, 0, + 144, 1, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 117, 0, 0, 0, + 0, 0, 1, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 141, 1, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 140, 1, 0, 0, 3, 0, 1, 0, + 152, 1, 0, 0, 2, 0, 1, 0, + 7, 0, 0, 0, 118, 0, 0, 0, + 0, 0, 1, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 149, 1, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 148, 1, 0, 0, 3, 0, 1, 0, + 160, 1, 0, 0, 2, 0, 1, 0, + 8, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 1, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 157, 1, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 156, 1, 0, 0, 3, 0, 1, 0, + 168, 1, 0, 0, 2, 0, 1, 0, + 9, 0, 0, 0, 120, 0, 0, 0, + 0, 0, 1, 0, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 165, 1, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 168, 1, 0, 0, 3, 0, 1, 0, + 180, 1, 0, 0, 2, 0, 1, 0, + 10, 0, 0, 0, 121, 0, 0, 0, + 0, 0, 1, 0, 28, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 177, 1, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 176, 1, 0, 0, 3, 0, 1, 0, + 188, 1, 0, 0, 2, 0, 1, 0, + 11, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 1, 0, 29, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 185, 1, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 184, 1, 0, 0, 3, 0, 1, 0, + 196, 1, 0, 0, 2, 0, 1, 0, + 12, 0, 0, 0, 123, 0, 0, 0, + 0, 0, 1, 0, 30, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 193, 1, 0, 0, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 196, 1, 0, 0, 3, 0, 1, 0, + 208, 1, 0, 0, 2, 0, 1, 0, + 116, 121, 112, 101, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 70, + 105, 108, 101, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 67, + 111, 110, 115, 116, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 69, + 110, 117, 109, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 69, + 110, 117, 109, 101, 114, 97, 110, 116, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 83, + 116, 114, 117, 99, 116, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 70, + 105, 101, 108, 100, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 85, + 110, 105, 111, 110, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 71, + 114, 111, 117, 112, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 73, + 110, 116, 101, 114, 102, 97, 99, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 77, + 101, 116, 104, 111, 100, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 80, + 97, 114, 97, 109, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 97, 114, 103, 101, 116, 115, 65, + 110, 110, 111, 116, 97, 116, 105, 111, + 110, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ec1619d4400a0290 = b_ec1619d4400a0290.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ec1619d4400a0290[] = { + &s_d07378ede1f9cc60, + &s_e682ab4cf923a417, +}; +static const uint16_t m_ec1619d4400a0290[] = {12, 2, 3, 4, 6, 1, 8, 9, 10, 11, 5, 7, 0}; +static const uint16_t i_ec1619d4400a0290[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +const ::capnp::_::RawSchema s_ec1619d4400a0290 = { + 0xec1619d4400a0290, b_ec1619d4400a0290.words, 228, d_ec1619d4400a0290, m_ec1619d4400a0290, + 2, 13, i_ec1619d4400a0290, nullptr, nullptr, { &s_ec1619d4400a0290, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<114> b_9aad50a41f4af45f = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 95, 244, 74, 31, 164, 80, 173, 154, + 19, 0, 0, 0, 1, 0, 3, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 4, 0, 7, 0, 0, 0, 2, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 143, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 70, 105, 101, 108, 100, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 18, 199, 254, 124, 190, 76, 177, 151, + 1, 0, 0, 0, 122, 0, 0, 0, + 110, 111, 68, 105, 115, 99, 114, 105, + 109, 105, 110, 97, 110, 116, 0, 0, + 28, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 181, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 176, 0, 0, 0, 3, 0, 1, 0, + 188, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 185, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 184, 0, 0, 0, 3, 0, 1, 0, + 196, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 193, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 0, 0, 3, 0, 1, 0, + 220, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 217, 0, 0, 0, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 220, 0, 0, 0, 3, 0, 1, 0, + 232, 0, 0, 0, 2, 0, 1, 0, + 4, 0, 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 111, 116, 180, 107, 71, 5, 35, 196, + 229, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 254, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 17, 29, 219, 104, 219, 205, 252, 202, + 205, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 230, 11, 135, 135, 194, 213, 144, 187, + 181, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 111, 100, 101, 79, 114, 100, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 110, 110, 111, 116, 97, 116, 105, + 111, 110, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 66, 117, 37, 171, 13, 149, 200, 241, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 105, 115, 99, 114, 105, 109, 105, + 110, 97, 110, 116, 86, 97, 108, 117, + 101, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 108, 111, 116, 0, 0, 0, 0, + 103, 114, 111, 117, 112, 0, 0, 0, + 111, 114, 100, 105, 110, 97, 108, 0, } +}; +::capnp::word const* const bp_9aad50a41f4af45f = b_9aad50a41f4af45f.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9aad50a41f4af45f[] = { + &s_bb90d5c287870be6, + &s_c42305476bb4746f, + &s_cafccddb68db1d11, + &s_f1c8950dab257542, +}; +static const uint16_t m_9aad50a41f4af45f[] = {2, 1, 3, 5, 0, 6, 4}; +static const uint16_t i_9aad50a41f4af45f[] = {4, 5, 0, 1, 2, 3, 6}; +const ::capnp::_::RawSchema s_9aad50a41f4af45f = { + 0x9aad50a41f4af45f, b_9aad50a41f4af45f.words, 114, d_9aad50a41f4af45f, m_9aad50a41f4af45f, + 4, 7, i_9aad50a41f4af45f, nullptr, nullptr, { &s_9aad50a41f4af45f, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<25> b_97b14cbe7cfec712 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 18, 199, 254, 124, 190, 76, 177, 151, + 25, 0, 0, 0, 4, 0, 0, 0, + 95, 244, 74, 31, 164, 80, 173, 154, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 66, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 0, 0, 0, 3, 0, 1, 0, + 44, 0, 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 70, 105, 101, 108, 100, + 46, 110, 111, 68, 105, 115, 99, 114, + 105, 109, 105, 110, 97, 110, 116, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_97b14cbe7cfec712 = b_97b14cbe7cfec712.words; +#if !CAPNP_LITE +const ::capnp::_::RawSchema s_97b14cbe7cfec712 = { + 0x97b14cbe7cfec712, b_97b14cbe7cfec712.words, 25, nullptr, nullptr, + 0, 0, nullptr, nullptr, nullptr, { &s_97b14cbe7cfec712, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<80> b_c42305476bb4746f = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 111, 116, 180, 107, 71, 5, 35, 196, + 25, 0, 0, 0, 1, 0, 3, 0, + 95, 244, 74, 31, 164, 80, 173, 154, + 4, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 70, 105, 101, 108, 100, + 46, 115, 108, 111, 116, 0, 0, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 0, 0, 0, 3, 0, 1, 0, + 116, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 128, 0, 0, 0, + 0, 0, 1, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 113, 0, 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 0, 0, 0, 3, 0, 1, 0, + 128, 0, 0, 0, 2, 0, 1, 0, + 111, 102, 102, 115, 101, 116, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 121, 112, 101, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 101, 102, 97, 117, 108, 116, 86, + 97, 108, 117, 101, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 155, 12, 176, 215, 210, 220, 35, 206, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 104, 97, 100, 69, 120, 112, 108, 105, + 99, 105, 116, 68, 101, 102, 97, 117, + 108, 116, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c42305476bb4746f = b_c42305476bb4746f.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c42305476bb4746f[] = { + &s_9aad50a41f4af45f, + &s_ce23dcd2d7b00c9b, + &s_d07378ede1f9cc60, +}; +static const uint16_t m_c42305476bb4746f[] = {2, 3, 0, 1}; +static const uint16_t i_c42305476bb4746f[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_c42305476bb4746f = { + 0xc42305476bb4746f, b_c42305476bb4746f.words, 80, d_c42305476bb4746f, m_c42305476bb4746f, + 3, 4, i_c42305476bb4746f, nullptr, nullptr, { &s_c42305476bb4746f, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<32> b_cafccddb68db1d11 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 17, 29, 219, 104, 219, 205, 252, 202, + 25, 0, 0, 0, 1, 0, 3, 0, + 95, 244, 74, 31, 164, 80, 173, 154, + 4, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 70, 105, 101, 108, 100, + 46, 103, 114, 111, 117, 112, 0, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 20, 0, 0, 0, 2, 0, 1, 0, + 116, 121, 112, 101, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_cafccddb68db1d11 = b_cafccddb68db1d11.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_cafccddb68db1d11[] = { + &s_9aad50a41f4af45f, +}; +static const uint16_t m_cafccddb68db1d11[] = {0}; +static const uint16_t i_cafccddb68db1d11[] = {0}; +const ::capnp::_::RawSchema s_cafccddb68db1d11 = { + 0xcafccddb68db1d11, b_cafccddb68db1d11.words, 32, d_cafccddb68db1d11, m_cafccddb68db1d11, + 1, 1, i_cafccddb68db1d11, nullptr, nullptr, { &s_cafccddb68db1d11, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<50> b_bb90d5c287870be6 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 230, 11, 135, 135, 194, 213, 144, 187, + 25, 0, 0, 0, 1, 0, 3, 0, + 95, 244, 74, 31, 164, 80, 173, 154, + 4, 0, 7, 0, 1, 0, 2, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 10, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 70, 105, 101, 108, 100, + 46, 111, 114, 100, 105, 110, 97, 108, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 6, 0, 0, 0, + 0, 0, 1, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 0, 0, 0, 3, 0, 1, 0, + 60, 0, 0, 0, 2, 0, 1, 0, + 105, 109, 112, 108, 105, 99, 105, 116, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 120, 112, 108, 105, 99, 105, 116, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_bb90d5c287870be6 = b_bb90d5c287870be6.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_bb90d5c287870be6[] = { + &s_9aad50a41f4af45f, +}; +static const uint16_t m_bb90d5c287870be6[] = {1, 0}; +static const uint16_t i_bb90d5c287870be6[] = {0, 1}; +const ::capnp::_::RawSchema s_bb90d5c287870be6 = { + 0xbb90d5c287870be6, b_bb90d5c287870be6.words, 50, d_bb90d5c287870be6, m_bb90d5c287870be6, + 1, 2, i_bb90d5c287870be6, nullptr, nullptr, { &s_bb90d5c287870be6, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<69> b_978a7cebdc549a4d = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 77, 154, 84, 220, 235, 124, 138, 151, + 19, 0, 0, 0, 1, 0, 1, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 69, 110, 117, 109, 101, + 114, 97, 110, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 111, 100, 101, 79, 114, 100, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 110, 110, 111, 116, 97, 116, 105, + 111, 110, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 66, 117, 37, 171, 13, 149, 200, 241, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_978a7cebdc549a4d = b_978a7cebdc549a4d.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_978a7cebdc549a4d[] = { + &s_f1c8950dab257542, +}; +static const uint16_t m_978a7cebdc549a4d[] = {2, 1, 0}; +static const uint16_t i_978a7cebdc549a4d[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_978a7cebdc549a4d = { + 0x978a7cebdc549a4d, b_978a7cebdc549a4d.words, 69, d_978a7cebdc549a4d, m_978a7cebdc549a4d, + 1, 3, i_978a7cebdc549a4d, nullptr, nullptr, { &s_978a7cebdc549a4d, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<48> b_a9962a9ed0a4d7f8 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 248, 215, 164, 208, 158, 42, 150, 169, + 19, 0, 0, 0, 1, 0, 1, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 83, 117, 112, 101, 114, + 99, 108, 97, 115, 115, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 114, 97, 110, 100, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_a9962a9ed0a4d7f8 = b_a9962a9ed0a4d7f8.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_a9962a9ed0a4d7f8[] = { + &s_903455f06065422b, +}; +static const uint16_t m_a9962a9ed0a4d7f8[] = {1, 0}; +static const uint16_t i_a9962a9ed0a4d7f8[] = {0, 1}; +const ::capnp::_::RawSchema s_a9962a9ed0a4d7f8 = { + 0xa9962a9ed0a4d7f8, b_a9962a9ed0a4d7f8.words, 48, d_a9962a9ed0a4d7f8, m_a9962a9ed0a4d7f8, + 1, 2, i_a9962a9ed0a4d7f8, nullptr, nullptr, { &s_a9962a9ed0a4d7f8, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<155> b_9500cce23b334d80 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 128, 77, 51, 59, 226, 204, 0, 149, + 19, 0, 0, 0, 1, 0, 3, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 5, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 210, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 199, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 77, 101, 116, 104, 111, + 100, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 32, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 209, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 204, 0, 0, 0, 3, 0, 1, 0, + 216, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 212, 0, 0, 0, 3, 0, 1, 0, + 224, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 221, 0, 0, 0, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 220, 0, 0, 0, 3, 0, 1, 0, + 232, 0, 0, 0, 2, 0, 1, 0, + 5, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 229, 0, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 232, 0, 0, 0, 3, 0, 1, 0, + 244, 0, 0, 0, 2, 0, 1, 0, + 7, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 241, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 3, 0, 1, 0, + 12, 1, 0, 0, 2, 0, 1, 0, + 4, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 1, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 1, 0, 0, 3, 0, 1, 0, + 20, 1, 0, 0, 2, 0, 1, 0, + 6, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 1, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 1, 0, 0, 3, 0, 1, 0, + 28, 1, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 1, 0, 0, 154, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 28, 1, 0, 0, 3, 0, 1, 0, + 56, 1, 0, 0, 2, 0, 1, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 111, 100, 101, 79, 114, 100, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 97, 114, 97, 109, 83, 116, 114, + 117, 99, 116, 84, 121, 112, 101, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 115, 117, 108, 116, 83, 116, + 114, 117, 99, 116, 84, 121, 112, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 110, 110, 111, 116, 97, 116, 105, + 111, 110, 115, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 66, 117, 37, 171, 13, 149, 200, 241, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 97, 114, 97, 109, 66, 114, 97, + 110, 100, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 115, 117, 108, 116, 66, 114, + 97, 110, 100, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 109, 112, 108, 105, 99, 105, 116, + 80, 97, 114, 97, 109, 101, 116, 101, + 114, 115, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 177, 163, 15, 241, 204, 27, 82, 185, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9500cce23b334d80 = b_9500cce23b334d80.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9500cce23b334d80[] = { + &s_903455f06065422b, + &s_b9521bccf10fa3b1, + &s_f1c8950dab257542, +}; +static const uint16_t m_9500cce23b334d80[] = {4, 1, 7, 0, 5, 2, 6, 3}; +static const uint16_t i_9500cce23b334d80[] = {0, 1, 2, 3, 4, 5, 6, 7}; +const ::capnp::_::RawSchema s_9500cce23b334d80 = { + 0x9500cce23b334d80, b_9500cce23b334d80.words, 155, d_9500cce23b334d80, m_9500cce23b334d80, + 3, 8, i_9500cce23b334d80, nullptr, nullptr, { &s_9500cce23b334d80, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<269> b_d07378ede1f9cc60 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 19, 0, 0, 0, 1, 0, 3, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 1, 0, 7, 0, 0, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 194, 0, 0, 0, + 29, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 47, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 76, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 3, 0, 1, 0, + 12, 2, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 2, 0, 0, 3, 0, 1, 0, + 16, 2, 0, 0, 2, 0, 1, 0, + 2, 0, 253, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 2, 0, 0, 3, 0, 1, 0, + 20, 2, 0, 0, 2, 0, 1, 0, + 3, 0, 252, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 2, 0, 0, 3, 0, 1, 0, + 24, 2, 0, 0, 2, 0, 1, 0, + 4, 0, 251, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 2, 0, 0, 3, 0, 1, 0, + 28, 2, 0, 0, 2, 0, 1, 0, + 5, 0, 250, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 2, 0, 0, 3, 0, 1, 0, + 32, 2, 0, 0, 2, 0, 1, 0, + 6, 0, 249, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 24, 2, 0, 0, 3, 0, 1, 0, + 36, 2, 0, 0, 2, 0, 1, 0, + 7, 0, 248, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 28, 2, 0, 0, 3, 0, 1, 0, + 40, 2, 0, 0, 2, 0, 1, 0, + 8, 0, 247, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 37, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 2, 0, 0, 3, 0, 1, 0, + 44, 2, 0, 0, 2, 0, 1, 0, + 9, 0, 246, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 2, 0, 0, 3, 0, 1, 0, + 48, 2, 0, 0, 2, 0, 1, 0, + 10, 0, 245, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 2, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 2, 0, 0, 3, 0, 1, 0, + 52, 2, 0, 0, 2, 0, 1, 0, + 11, 0, 244, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 2, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 2, 0, 0, 3, 0, 1, 0, + 56, 2, 0, 0, 2, 0, 1, 0, + 12, 0, 243, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 53, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 2, 0, 0, 3, 0, 1, 0, + 60, 2, 0, 0, 2, 0, 1, 0, + 13, 0, 242, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 57, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 52, 2, 0, 0, 3, 0, 1, 0, + 64, 2, 0, 0, 2, 0, 1, 0, + 14, 0, 241, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 151, 234, 96, 10, 37, 57, 231, 135, + 61, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 240, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 169, 135, 127, 26, 113, 120, 14, 158, + 37, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 239, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 211, 198, 76, 239, 96, 111, 58, 172, + 13, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 238, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 191, 12, 251, 247, 105, 202, 139, 237, + 245, 1, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 237, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 241, 73, 62, 162, 232, 63, 87, 194, + 225, 1, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 111, 105, 100, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 111, 111, 108, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 56, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 49, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 51, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 54, 52, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 49, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 51, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 54, 52, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 108, 111, 97, 116, 51, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 108, 111, 97, 116, 54, 52, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 101, 120, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 97, 116, 97, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 115, 116, 0, 0, 0, 0, + 101, 110, 117, 109, 0, 0, 0, 0, + 115, 116, 114, 117, 99, 116, 0, 0, + 105, 110, 116, 101, 114, 102, 97, 99, + 101, 0, 0, 0, 0, 0, 0, 0, + 97, 110, 121, 80, 111, 105, 110, 116, + 101, 114, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_d07378ede1f9cc60 = b_d07378ede1f9cc60.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_d07378ede1f9cc60[] = { + &s_87e739250a60ea97, + &s_9e0e78711a7f87a9, + &s_ac3a6f60ef4cc6d3, + &s_c2573fe8a23e49f1, + &s_ed8bca69f7fb0cbf, +}; +static const uint16_t m_d07378ede1f9cc60[] = {18, 1, 13, 15, 10, 11, 3, 4, 5, 2, 17, 14, 16, 12, 7, 8, 9, 6, 0}; +static const uint16_t i_d07378ede1f9cc60[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +const ::capnp::_::RawSchema s_d07378ede1f9cc60 = { + 0xd07378ede1f9cc60, b_d07378ede1f9cc60.words, 269, d_d07378ede1f9cc60, m_d07378ede1f9cc60, + 5, 19, i_d07378ede1f9cc60, nullptr, nullptr, { &s_d07378ede1f9cc60, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<33> b_87e739250a60ea97 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 151, 234, 96, 10, 37, 57, 231, 135, + 24, 0, 0, 0, 1, 0, 3, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 108, 105, 115, 116, 0, 0, 0, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 98, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 24, 0, 0, 0, 2, 0, 1, 0, + 101, 108, 101, 109, 101, 110, 116, 84, + 121, 112, 101, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_87e739250a60ea97 = b_87e739250a60ea97.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_87e739250a60ea97[] = { + &s_d07378ede1f9cc60, +}; +static const uint16_t m_87e739250a60ea97[] = {0}; +static const uint16_t i_87e739250a60ea97[] = {0}; +const ::capnp::_::RawSchema s_87e739250a60ea97 = { + 0x87e739250a60ea97, b_87e739250a60ea97.words, 33, d_87e739250a60ea97, m_87e739250a60ea97, + 1, 1, i_87e739250a60ea97, nullptr, nullptr, { &s_87e739250a60ea97, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_9e0e78711a7f87a9 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 169, 135, 127, 26, 113, 120, 14, 158, + 24, 0, 0, 0, 1, 0, 3, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 101, 110, 117, 109, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 116, 121, 112, 101, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 114, 97, 110, 100, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9e0e78711a7f87a9 = b_9e0e78711a7f87a9.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9e0e78711a7f87a9[] = { + &s_903455f06065422b, + &s_d07378ede1f9cc60, +}; +static const uint16_t m_9e0e78711a7f87a9[] = {1, 0}; +static const uint16_t i_9e0e78711a7f87a9[] = {0, 1}; +const ::capnp::_::RawSchema s_9e0e78711a7f87a9 = { + 0x9e0e78711a7f87a9, b_9e0e78711a7f87a9.words, 47, d_9e0e78711a7f87a9, m_9e0e78711a7f87a9, + 2, 2, i_9e0e78711a7f87a9, nullptr, nullptr, { &s_9e0e78711a7f87a9, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<47> b_ac3a6f60ef4cc6d3 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 211, 198, 76, 239, 96, 111, 58, 172, + 24, 0, 0, 0, 1, 0, 3, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 115, 116, 114, 117, 99, 116, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 22, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 116, 121, 112, 101, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 114, 97, 110, 100, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ac3a6f60ef4cc6d3 = b_ac3a6f60ef4cc6d3.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ac3a6f60ef4cc6d3[] = { + &s_903455f06065422b, + &s_d07378ede1f9cc60, +}; +static const uint16_t m_ac3a6f60ef4cc6d3[] = {1, 0}; +static const uint16_t i_ac3a6f60ef4cc6d3[] = {0, 1}; +const ::capnp::_::RawSchema s_ac3a6f60ef4cc6d3 = { + 0xac3a6f60ef4cc6d3, b_ac3a6f60ef4cc6d3.words, 47, d_ac3a6f60ef4cc6d3, m_ac3a6f60ef4cc6d3, + 2, 2, i_ac3a6f60ef4cc6d3, nullptr, nullptr, { &s_ac3a6f60ef4cc6d3, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<48> b_ed8bca69f7fb0cbf = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 191, 12, 251, 247, 105, 202, 139, 237, + 24, 0, 0, 0, 1, 0, 3, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 18, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 105, 110, 116, 101, 114, 102, 97, 99, + 101, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 116, 121, 112, 101, 73, 100, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 114, 97, 110, 100, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ed8bca69f7fb0cbf = b_ed8bca69f7fb0cbf.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_ed8bca69f7fb0cbf[] = { + &s_903455f06065422b, + &s_d07378ede1f9cc60, +}; +static const uint16_t m_ed8bca69f7fb0cbf[] = {1, 0}; +static const uint16_t i_ed8bca69f7fb0cbf[] = {0, 1}; +const ::capnp::_::RawSchema s_ed8bca69f7fb0cbf = { + 0xed8bca69f7fb0cbf, b_ed8bca69f7fb0cbf.words, 48, d_ed8bca69f7fb0cbf, m_ed8bca69f7fb0cbf, + 2, 2, i_ed8bca69f7fb0cbf, nullptr, nullptr, { &s_ed8bca69f7fb0cbf, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<46> b_c2573fe8a23e49f1 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 241, 73, 62, 162, 232, 63, 87, 194, + 24, 0, 0, 0, 1, 0, 3, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 1, 0, 7, 0, 1, 0, 3, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 26, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 97, 110, 121, 80, 111, 105, 110, 116, + 101, 114, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 86, 54, 89, 254, 121, 95, 59, 142, + 69, 0, 0, 0, 114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 254, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 133, 74, 97, 244, 36, 247, 209, 157, + 49, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 253, 255, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 116, 226, 86, 12, 18, 201, 239, 186, + 29, 0, 0, 0, 194, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 110, 99, 111, 110, 115, 116, 114, + 97, 105, 110, 101, 100, 0, 0, 0, + 112, 97, 114, 97, 109, 101, 116, 101, + 114, 0, 0, 0, 0, 0, 0, 0, + 105, 109, 112, 108, 105, 99, 105, 116, + 77, 101, 116, 104, 111, 100, 80, 97, + 114, 97, 109, 101, 116, 101, 114, 0, } +}; +::capnp::word const* const bp_c2573fe8a23e49f1 = b_c2573fe8a23e49f1.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c2573fe8a23e49f1[] = { + &s_8e3b5f79fe593656, + &s_9dd1f724f4614a85, + &s_baefc9120c56e274, + &s_d07378ede1f9cc60, +}; +static const uint16_t m_c2573fe8a23e49f1[] = {2, 1, 0}; +static const uint16_t i_c2573fe8a23e49f1[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_c2573fe8a23e49f1 = { + 0xc2573fe8a23e49f1, b_c2573fe8a23e49f1.words, 46, d_c2573fe8a23e49f1, m_c2573fe8a23e49f1, + 4, 3, i_c2573fe8a23e49f1, nullptr, nullptr, { &s_c2573fe8a23e49f1, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<81> b_8e3b5f79fe593656 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 86, 54, 89, 254, 121, 95, 59, 142, + 35, 0, 0, 0, 1, 0, 3, 0, + 241, 73, 62, 162, 232, 63, 87, 194, + 1, 0, 7, 0, 1, 0, 4, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 138, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 37, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 97, 110, 121, 80, 111, 105, 110, 116, + 101, 114, 46, 117, 110, 99, 111, 110, + 115, 116, 114, 97, 105, 110, 101, 100, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 3, 0, 1, 0, + 108, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 253, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 0, 0, 0, 3, 0, 1, 0, + 112, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 252, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 3, 0, 1, 0, + 120, 0, 0, 0, 2, 0, 1, 0, + 97, 110, 121, 75, 105, 110, 100, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 116, 114, 117, 99, 116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 115, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 97, 98, 105, 108, 105, + 116, 121, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_8e3b5f79fe593656 = b_8e3b5f79fe593656.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_8e3b5f79fe593656[] = { + &s_c2573fe8a23e49f1, +}; +static const uint16_t m_8e3b5f79fe593656[] = {0, 3, 2, 1}; +static const uint16_t i_8e3b5f79fe593656[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_8e3b5f79fe593656 = { + 0x8e3b5f79fe593656, b_8e3b5f79fe593656.words, 81, d_8e3b5f79fe593656, m_8e3b5f79fe593656, + 1, 4, i_8e3b5f79fe593656, nullptr, nullptr, { &s_8e3b5f79fe593656, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<50> b_9dd1f724f4614a85 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 133, 74, 97, 244, 36, 247, 209, 157, + 35, 0, 0, 0, 1, 0, 3, 0, + 241, 73, 62, 162, 232, 63, 87, 194, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 106, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 97, 110, 121, 80, 111, 105, 110, 116, + 101, 114, 46, 112, 97, 114, 97, 109, + 101, 116, 101, 114, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 20, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 0, 0, 0, 3, 0, 1, 0, + 56, 0, 0, 0, 2, 0, 1, 0, + 115, 99, 111, 112, 101, 73, 100, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 112, 97, 114, 97, 109, 101, 116, 101, + 114, 73, 110, 100, 101, 120, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_9dd1f724f4614a85 = b_9dd1f724f4614a85.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_9dd1f724f4614a85[] = { + &s_c2573fe8a23e49f1, +}; +static const uint16_t m_9dd1f724f4614a85[] = {1, 0}; +static const uint16_t i_9dd1f724f4614a85[] = {0, 1}; +const ::capnp::_::RawSchema s_9dd1f724f4614a85 = { + 0x9dd1f724f4614a85, b_9dd1f724f4614a85.words, 50, d_9dd1f724f4614a85, m_9dd1f724f4614a85, + 1, 2, i_9dd1f724f4614a85, nullptr, nullptr, { &s_9dd1f724f4614a85, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<37> b_baefc9120c56e274 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 116, 226, 86, 12, 18, 201, 239, 186, + 35, 0, 0, 0, 1, 0, 3, 0, + 241, 73, 62, 162, 232, 63, 87, 194, + 1, 0, 7, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 218, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 84, 121, 112, 101, 46, + 97, 110, 121, 80, 111, 105, 110, 116, + 101, 114, 46, 105, 109, 112, 108, 105, + 99, 105, 116, 77, 101, 116, 104, 111, + 100, 80, 97, 114, 97, 109, 101, 116, + 101, 114, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 1, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 3, 0, 1, 0, + 24, 0, 0, 0, 2, 0, 1, 0, + 112, 97, 114, 97, 109, 101, 116, 101, + 114, 73, 110, 100, 101, 120, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_baefc9120c56e274 = b_baefc9120c56e274.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_baefc9120c56e274[] = { + &s_c2573fe8a23e49f1, +}; +static const uint16_t m_baefc9120c56e274[] = {0}; +static const uint16_t i_baefc9120c56e274[] = {0}; +const ::capnp::_::RawSchema s_baefc9120c56e274 = { + 0xbaefc9120c56e274, b_baefc9120c56e274.words, 37, d_baefc9120c56e274, m_baefc9120c56e274, + 1, 1, i_baefc9120c56e274, nullptr, nullptr, { &s_baefc9120c56e274, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<43> b_903455f06065422b = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 19, 0, 0, 0, 1, 0, 0, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 39, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 66, 114, 97, 110, 100, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 1, 0, 1, 0, + 201, 107, 99, 169, 133, 52, 215, 171, + 9, 0, 0, 0, 50, 0, 0, 0, + 252, 231, 158, 150, 22, 205, 99, 200, + 5, 0, 0, 0, 66, 0, 0, 0, + 83, 99, 111, 112, 101, 0, 0, 0, + 66, 105, 110, 100, 105, 110, 103, 0, + 4, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 3, 0, 1, 0, + 36, 0, 0, 0, 2, 0, 1, 0, + 115, 99, 111, 112, 101, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 201, 107, 99, 169, 133, 52, 215, 171, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_903455f06065422b = b_903455f06065422b.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_903455f06065422b[] = { + &s_abd73485a9636bc9, +}; +static const uint16_t m_903455f06065422b[] = {0}; +static const uint16_t i_903455f06065422b[] = {0}; +const ::capnp::_::RawSchema s_903455f06065422b = { + 0x903455f06065422b, b_903455f06065422b.words, 43, d_903455f06065422b, m_903455f06065422b, + 1, 1, i_903455f06065422b, nullptr, nullptr, { &s_903455f06065422b, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<67> b_abd73485a9636bc9 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 201, 107, 99, 169, 133, 52, 215, 171, + 25, 0, 0, 0, 1, 0, 2, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 1, 0, 7, 0, 0, 0, 2, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 66, 114, 97, 110, 100, + 46, 83, 99, 111, 112, 101, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 68, 0, 0, 0, 3, 0, 1, 0, + 96, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 254, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 93, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 0, 0, 0, 3, 0, 1, 0, + 100, 0, 0, 0, 2, 0, 1, 0, + 115, 99, 111, 112, 101, 73, 100, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 105, 110, 100, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 252, 231, 158, 150, 22, 205, 99, 200, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 104, 101, 114, 105, 116, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_abd73485a9636bc9 = b_abd73485a9636bc9.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_abd73485a9636bc9[] = { + &s_c863cd16969ee7fc, +}; +static const uint16_t m_abd73485a9636bc9[] = {1, 2, 0}; +static const uint16_t i_abd73485a9636bc9[] = {1, 2, 0}; +const ::capnp::_::RawSchema s_abd73485a9636bc9 = { + 0xabd73485a9636bc9, b_abd73485a9636bc9.words, 67, d_abd73485a9636bc9, m_abd73485a9636bc9, + 1, 3, i_abd73485a9636bc9, nullptr, nullptr, { &s_abd73485a9636bc9, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<49> b_c863cd16969ee7fc = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 252, 231, 158, 150, 22, 205, 99, 200, + 25, 0, 0, 0, 1, 0, 1, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 1, 0, 7, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 10, 1, 0, 0, + 37, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 66, 114, 97, 110, 100, + 46, 66, 105, 110, 100, 105, 110, 103, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 117, 110, 98, 111, 117, 110, 100, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 121, 112, 101, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 96, 204, 249, 225, 237, 120, 115, 208, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_c863cd16969ee7fc = b_c863cd16969ee7fc.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_c863cd16969ee7fc[] = { + &s_d07378ede1f9cc60, +}; +static const uint16_t m_c863cd16969ee7fc[] = {1, 0}; +static const uint16_t i_c863cd16969ee7fc[] = {0, 1}; +const ::capnp::_::RawSchema s_c863cd16969ee7fc = { + 0xc863cd16969ee7fc, b_c863cd16969ee7fc.words, 49, d_c863cd16969ee7fc, m_c863cd16969ee7fc, + 1, 2, i_c863cd16969ee7fc, nullptr, nullptr, { &s_c863cd16969ee7fc, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<305> b_ce23dcd2d7b00c9b = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 155, 12, 176, 215, 210, 220, 35, 206, + 19, 0, 0, 0, 1, 0, 2, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 1, 0, 7, 0, 0, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 202, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 47, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 86, 97, 108, 117, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 76, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 255, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 3, 0, 1, 0, + 12, 2, 0, 0, 2, 0, 1, 0, + 1, 0, 254, 255, 16, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 2, 0, 0, 3, 0, 1, 0, + 16, 2, 0, 0, 2, 0, 1, 0, + 2, 0, 253, 255, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 2, 0, 0, 3, 0, 1, 0, + 20, 2, 0, 0, 2, 0, 1, 0, + 3, 0, 252, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 2, 0, 0, 3, 0, 1, 0, + 24, 2, 0, 0, 2, 0, 1, 0, + 4, 0, 251, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 2, 0, 0, 3, 0, 1, 0, + 28, 2, 0, 0, 2, 0, 1, 0, + 5, 0, 250, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 25, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 2, 0, 0, 3, 0, 1, 0, + 32, 2, 0, 0, 2, 0, 1, 0, + 6, 0, 249, 255, 2, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 2, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 24, 2, 0, 0, 3, 0, 1, 0, + 36, 2, 0, 0, 2, 0, 1, 0, + 7, 0, 248, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 33, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 28, 2, 0, 0, 3, 0, 1, 0, + 40, 2, 0, 0, 2, 0, 1, 0, + 8, 0, 247, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 37, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32, 2, 0, 0, 3, 0, 1, 0, + 44, 2, 0, 0, 2, 0, 1, 0, + 9, 0, 246, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 2, 0, 0, 3, 0, 1, 0, + 48, 2, 0, 0, 2, 0, 1, 0, + 10, 0, 245, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 2, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 2, 0, 0, 3, 0, 1, 0, + 52, 2, 0, 0, 2, 0, 1, 0, + 11, 0, 244, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 2, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 44, 2, 0, 0, 3, 0, 1, 0, + 56, 2, 0, 0, 2, 0, 1, 0, + 12, 0, 243, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 12, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 53, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 2, 0, 0, 3, 0, 1, 0, + 60, 2, 0, 0, 2, 0, 1, 0, + 13, 0, 242, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 57, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 52, 2, 0, 0, 3, 0, 1, 0, + 64, 2, 0, 0, 2, 0, 1, 0, + 14, 0, 241, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 61, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 56, 2, 0, 0, 3, 0, 1, 0, + 68, 2, 0, 0, 2, 0, 1, 0, + 15, 0, 240, 255, 1, 0, 0, 0, + 0, 0, 1, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 65, 2, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 60, 2, 0, 0, 3, 0, 1, 0, + 72, 2, 0, 0, 2, 0, 1, 0, + 16, 0, 239, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 2, 0, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 2, 0, 0, 3, 0, 1, 0, + 76, 2, 0, 0, 2, 0, 1, 0, + 17, 0, 238, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 2, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 2, 0, 0, 3, 0, 1, 0, + 84, 2, 0, 0, 2, 0, 1, 0, + 18, 0, 237, 255, 0, 0, 0, 0, + 0, 0, 1, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 81, 2, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 80, 2, 0, 0, 3, 0, 1, 0, + 92, 2, 0, 0, 2, 0, 1, 0, + 118, 111, 105, 100, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 111, 111, 108, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 56, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 49, 54, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 51, 50, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 54, 52, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 56, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 49, 54, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 51, 50, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 105, 110, 116, 54, 52, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 108, 111, 97, 116, 51, 50, 0, + 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 108, 111, 97, 116, 54, 52, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 101, 120, 116, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 100, 97, 116, 97, 0, 0, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 108, 105, 115, 116, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 110, 117, 109, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 116, 114, 117, 99, 116, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 110, 116, 101, 114, 102, 97, 99, + 101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 110, 121, 80, 111, 105, 110, 116, + 101, 114, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ce23dcd2d7b00c9b = b_ce23dcd2d7b00c9b.words; +#if !CAPNP_LITE +static const uint16_t m_ce23dcd2d7b00c9b[] = {18, 1, 13, 15, 10, 11, 3, 4, 5, 2, 17, 14, 16, 12, 7, 8, 9, 6, 0}; +static const uint16_t i_ce23dcd2d7b00c9b[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +const ::capnp::_::RawSchema s_ce23dcd2d7b00c9b = { + 0xce23dcd2d7b00c9b, b_ce23dcd2d7b00c9b.words, 305, nullptr, m_ce23dcd2d7b00c9b, + 0, 19, i_ce23dcd2d7b00c9b, nullptr, nullptr, { &s_ce23dcd2d7b00c9b, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<63> b_f1c8950dab257542 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 66, 117, 37, 171, 13, 149, 200, 241, + 19, 0, 0, 0, 1, 0, 1, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 242, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 65, 110, 110, 111, 116, + 97, 116, 105, 111, 110, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 68, 0, 0, 0, 3, 0, 1, 0, + 80, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 77, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 118, 97, 108, 117, 101, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 155, 12, 176, 215, 210, 220, 35, 206, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 114, 97, 110, 100, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 43, 66, 101, 96, 240, 85, 52, 144, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_f1c8950dab257542 = b_f1c8950dab257542.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_f1c8950dab257542[] = { + &s_903455f06065422b, + &s_ce23dcd2d7b00c9b, +}; +static const uint16_t m_f1c8950dab257542[] = {2, 0, 1}; +static const uint16_t i_f1c8950dab257542[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_f1c8950dab257542 = { + 0xf1c8950dab257542, b_f1c8950dab257542.words, 63, d_f1c8950dab257542, m_f1c8950dab257542, + 2, 3, i_f1c8950dab257542, nullptr, nullptr, { &s_f1c8950dab257542, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<54> b_d1958f7dba521926 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 38, 25, 82, 186, 125, 143, 149, 209, + 19, 0, 0, 0, 2, 0, 0, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 250, 0, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 199, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 69, 108, 101, 109, 101, + 110, 116, 83, 105, 122, 101, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 32, 0, 0, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 89, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 65, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 61, 0, 0, 0, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 101, 109, 112, 116, 121, 0, 0, 0, + 98, 105, 116, 0, 0, 0, 0, 0, + 98, 121, 116, 101, 0, 0, 0, 0, + 116, 119, 111, 66, 121, 116, 101, 115, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 111, 117, 114, 66, 121, 116, 101, + 115, 0, 0, 0, 0, 0, 0, 0, + 101, 105, 103, 104, 116, 66, 121, 116, + 101, 115, 0, 0, 0, 0, 0, 0, + 112, 111, 105, 110, 116, 101, 114, 0, + 105, 110, 108, 105, 110, 101, 67, 111, + 109, 112, 111, 115, 105, 116, 101, 0, } +}; +::capnp::word const* const bp_d1958f7dba521926 = b_d1958f7dba521926.words; +#if !CAPNP_LITE +static const uint16_t m_d1958f7dba521926[] = {1, 2, 5, 0, 4, 7, 6, 3}; +const ::capnp::_::RawSchema s_d1958f7dba521926 = { + 0xd1958f7dba521926, b_d1958f7dba521926.words, 54, nullptr, m_d1958f7dba521926, + 0, 8, nullptr, nullptr, nullptr, { &s_d1958f7dba521926, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +CAPNP_DEFINE_ENUM(ElementSize_d1958f7dba521926, d1958f7dba521926); +static const ::capnp::_::AlignedData<63> b_d85d305b7d839963 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 99, 153, 131, 125, 91, 48, 93, 216, + 19, 0, 0, 0, 1, 0, 1, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 2, 1, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 29, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 67, 97, 112, 110, 112, + 86, 101, 114, 115, 105, 111, 110, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 68, 0, 0, 0, 3, 0, 1, 0, + 80, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 77, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 109, 97, 106, 111, 114, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 105, 110, 111, 114, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 109, 105, 99, 114, 111, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_d85d305b7d839963 = b_d85d305b7d839963.words; +#if !CAPNP_LITE +static const uint16_t m_d85d305b7d839963[] = {0, 2, 1}; +static const uint16_t i_d85d305b7d839963[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_d85d305b7d839963 = { + 0xd85d305b7d839963, b_d85d305b7d839963.words, 63, nullptr, m_d85d305b7d839963, + 0, 3, i_d85d305b7d839963, nullptr, nullptr, { &s_d85d305b7d839963, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<98> b_bfc546f6210ad7ce = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 206, 215, 10, 33, 246, 70, 197, 191, + 19, 0, 0, 0, 1, 0, 0, 0, + 217, 114, 76, 98, 9, 197, 63, 169, + 4, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 66, 1, 0, 0, + 37, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 0, 0, 231, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 67, 111, 100, 101, 71, + 101, 110, 101, 114, 97, 116, 111, 114, + 82, 101, 113, 117, 101, 115, 116, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 98, 0, 129, 46, 176, 14, 234, 207, + 1, 0, 0, 0, 114, 0, 0, 0, + 82, 101, 113, 117, 101, 115, 116, 101, + 100, 70, 105, 108, 101, 0, 0, 0, + 16, 0, 0, 0, 3, 0, 4, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 97, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 3, 0, 1, 0, + 120, 0, 0, 0, 2, 0, 1, 0, + 3, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 117, 0, 0, 0, 122, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 116, 0, 0, 0, 3, 0, 1, 0, + 144, 0, 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 141, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 140, 0, 0, 0, 3, 0, 1, 0, + 152, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 1, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 149, 0, 0, 0, 90, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 148, 0, 0, 0, 3, 0, 1, 0, + 176, 0, 0, 0, 2, 0, 1, 0, + 110, 111, 100, 101, 115, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 23, 164, 35, 249, 76, 171, 130, 230, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 114, 101, 113, 117, 101, 115, 116, 101, + 100, 70, 105, 108, 101, 115, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 98, 0, 129, 46, 176, 14, 234, 207, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 86, 101, 114, + 115, 105, 111, 110, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 99, 153, 131, 125, 91, 48, 93, 216, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 115, 111, 117, 114, 99, 101, 73, 110, + 102, 111, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 174, 87, 19, 4, 227, 29, 142, 243, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_bfc546f6210ad7ce = b_bfc546f6210ad7ce.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_bfc546f6210ad7ce[] = { + &s_cfea0eb02e810062, + &s_d85d305b7d839963, + &s_e682ab4cf923a417, + &s_f38e1de3041357ae, +}; +static const uint16_t m_bfc546f6210ad7ce[] = {2, 0, 1, 3}; +static const uint16_t i_bfc546f6210ad7ce[] = {0, 1, 2, 3}; +const ::capnp::_::RawSchema s_bfc546f6210ad7ce = { + 0xbfc546f6210ad7ce, b_bfc546f6210ad7ce.words, 98, d_bfc546f6210ad7ce, m_bfc546f6210ad7ce, + 4, 4, i_bfc546f6210ad7ce, nullptr, nullptr, { &s_bfc546f6210ad7ce, nullptr, nullptr, 0, 0, nullptr }, true +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<74> b_cfea0eb02e810062 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 98, 0, 129, 46, 176, 14, 234, 207, + 40, 0, 0, 0, 1, 0, 1, 0, + 206, 215, 10, 33, 246, 70, 197, 191, + 2, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 178, 1, 0, 0, + 45, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 67, 111, 100, 101, 71, + 101, 110, 101, 114, 97, 116, 111, 114, + 82, 101, 113, 117, 101, 115, 116, 46, + 82, 101, 113, 117, 101, 115, 116, 101, + 100, 70, 105, 108, 101, 0, 0, 0, + 4, 0, 0, 0, 1, 0, 1, 0, + 229, 87, 35, 18, 147, 65, 80, 174, + 1, 0, 0, 0, 58, 0, 0, 0, + 73, 109, 112, 111, 114, 116, 0, 0, + 12, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 69, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 3, 0, 1, 0, + 76, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 73, 0, 0, 0, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 3, 0, 1, 0, + 84, 0, 0, 0, 2, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 81, 0, 0, 0, 66, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 0, 0, 3, 0, 1, 0, + 104, 0, 0, 0, 2, 0, 1, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 102, 105, 108, 101, 110, 97, 109, 101, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 105, 109, 112, 111, 114, 116, 115, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 1, 0, + 16, 0, 0, 0, 0, 0, 0, 0, + 229, 87, 35, 18, 147, 65, 80, 174, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_cfea0eb02e810062 = b_cfea0eb02e810062.words; +#if !CAPNP_LITE +static const ::capnp::_::RawSchema* const d_cfea0eb02e810062[] = { + &s_ae504193122357e5, +}; +static const uint16_t m_cfea0eb02e810062[] = {1, 0, 2}; +static const uint16_t i_cfea0eb02e810062[] = {0, 1, 2}; +const ::capnp::_::RawSchema s_cfea0eb02e810062 = { + 0xcfea0eb02e810062, b_cfea0eb02e810062.words, 74, d_cfea0eb02e810062, m_cfea0eb02e810062, + 1, 3, i_cfea0eb02e810062, nullptr, nullptr, { &s_cfea0eb02e810062, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +static const ::capnp::_::AlignedData<52> b_ae504193122357e5 = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 229, 87, 35, 18, 147, 65, 80, 174, + 54, 0, 0, 0, 1, 0, 1, 0, + 98, 0, 129, 46, 176, 14, 234, 207, + 1, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 234, 1, 0, 0, + 49, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 119, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 99, + 104, 101, 109, 97, 46, 99, 97, 112, + 110, 112, 58, 67, 111, 100, 101, 71, + 101, 110, 101, 114, 97, 116, 111, 114, + 82, 101, 113, 117, 101, 115, 116, 46, + 82, 101, 113, 117, 101, 115, 116, 101, + 100, 70, 105, 108, 101, 46, 73, 109, + 112, 111, 114, 116, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 8, 0, 0, 0, 3, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 41, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 3, 0, 1, 0, + 48, 0, 0, 0, 2, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 40, 0, 0, 0, 3, 0, 1, 0, + 52, 0, 0, 0, 2, 0, 1, 0, + 105, 100, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 110, 97, 109, 101, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +::capnp::word const* const bp_ae504193122357e5 = b_ae504193122357e5.words; +#if !CAPNP_LITE +static const uint16_t m_ae504193122357e5[] = {0, 1}; +static const uint16_t i_ae504193122357e5[] = {0, 1}; +const ::capnp::_::RawSchema s_ae504193122357e5 = { + 0xae504193122357e5, b_ae504193122357e5.words, 52, nullptr, m_ae504193122357e5, + 0, 2, i_ae504193122357e5, nullptr, nullptr, { &s_ae504193122357e5, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace capnp { +namespace schema { + +// Node +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::Parameter +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::Parameter::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::Parameter::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::Parameter::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::Parameter::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::NestedNode +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::NestedNode::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::NestedNode::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::NestedNode::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::NestedNode::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::SourceInfo +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::SourceInfo::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::SourceInfo::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::SourceInfo::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::SourceInfo::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::SourceInfo::Member +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::SourceInfo::Member::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::SourceInfo::Member::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::SourceInfo::Member::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::SourceInfo::Member::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::Struct +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::Struct::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::Struct::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::Struct::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::Struct::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::Enum +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::Enum::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::Enum::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::Enum::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::Enum::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::Interface +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::Interface::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::Interface::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::Interface::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::Interface::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::Const +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::Const::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::Const::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::Const::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::Const::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Node::Annotation +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Node::Annotation::_capnpPrivate::dataWordSize; +constexpr uint16_t Node::Annotation::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Node::Annotation::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Node::Annotation::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Field +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Field::_capnpPrivate::dataWordSize; +constexpr uint16_t Field::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Field::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Field::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::uint16_t Field::NO_DISCRIMINANT; +#endif +// Field::Slot +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Field::Slot::_capnpPrivate::dataWordSize; +constexpr uint16_t Field::Slot::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Field::Slot::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Field::Slot::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Field::Group +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Field::Group::_capnpPrivate::dataWordSize; +constexpr uint16_t Field::Group::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Field::Group::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Field::Group::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Field::Ordinal +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Field::Ordinal::_capnpPrivate::dataWordSize; +constexpr uint16_t Field::Ordinal::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Field::Ordinal::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Field::Ordinal::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Enumerant +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Enumerant::_capnpPrivate::dataWordSize; +constexpr uint16_t Enumerant::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Enumerant::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Enumerant::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Superclass +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Superclass::_capnpPrivate::dataWordSize; +constexpr uint16_t Superclass::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Superclass::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Superclass::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Method +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Method::_capnpPrivate::dataWordSize; +constexpr uint16_t Method::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Method::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Method::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::List +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::List::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::List::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::List::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::List::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::Enum +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::Enum::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::Enum::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::Enum::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::Enum::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::Struct +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::Struct::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::Struct::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::Struct::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::Struct::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::Interface +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::Interface::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::Interface::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::Interface::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::Interface::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::AnyPointer +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::AnyPointer::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::AnyPointer::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::AnyPointer::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::AnyPointer::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::AnyPointer::Unconstrained +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::AnyPointer::Unconstrained::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::AnyPointer::Unconstrained::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::AnyPointer::Unconstrained::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::AnyPointer::Unconstrained::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::AnyPointer::Parameter +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::AnyPointer::Parameter::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::AnyPointer::Parameter::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::AnyPointer::Parameter::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::AnyPointer::Parameter::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Type::AnyPointer::ImplicitMethodParameter +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Type::AnyPointer::ImplicitMethodParameter::_capnpPrivate::dataWordSize; +constexpr uint16_t Type::AnyPointer::ImplicitMethodParameter::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Type::AnyPointer::ImplicitMethodParameter::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Type::AnyPointer::ImplicitMethodParameter::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Brand +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Brand::_capnpPrivate::dataWordSize; +constexpr uint16_t Brand::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Brand::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Brand::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Brand::Scope +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Brand::Scope::_capnpPrivate::dataWordSize; +constexpr uint16_t Brand::Scope::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Brand::Scope::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Brand::Scope::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Brand::Binding +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Brand::Binding::_capnpPrivate::dataWordSize; +constexpr uint16_t Brand::Binding::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Brand::Binding::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Brand::Binding::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Value +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Value::_capnpPrivate::dataWordSize; +constexpr uint16_t Value::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Value::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Value::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// Annotation +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t Annotation::_capnpPrivate::dataWordSize; +constexpr uint16_t Annotation::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind Annotation::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* Annotation::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CapnpVersion +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CapnpVersion::_capnpPrivate::dataWordSize; +constexpr uint16_t CapnpVersion::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CapnpVersion::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CapnpVersion::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CodeGeneratorRequest +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CodeGeneratorRequest::_capnpPrivate::dataWordSize; +constexpr uint16_t CodeGeneratorRequest::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CodeGeneratorRequest::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CodeGeneratorRequest::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CodeGeneratorRequest::RequestedFile +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CodeGeneratorRequest::RequestedFile::_capnpPrivate::dataWordSize; +constexpr uint16_t CodeGeneratorRequest::RequestedFile::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CodeGeneratorRequest::RequestedFile::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CodeGeneratorRequest::RequestedFile::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + +// CodeGeneratorRequest::RequestedFile::Import +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t CodeGeneratorRequest::RequestedFile::Import::_capnpPrivate::dataWordSize; +constexpr uint16_t CodeGeneratorRequest::RequestedFile::Import::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind CodeGeneratorRequest::RequestedFile::Import::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* CodeGeneratorRequest::RequestedFile::Import::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace +} // namespace + diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.capnp.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.capnp.h new file mode 100644 index 000000000..ef601439a --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.capnp.h @@ -0,0 +1,8237 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: schema.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(e682ab4cf923a417); +CAPNP_DECLARE_SCHEMA(b9521bccf10fa3b1); +CAPNP_DECLARE_SCHEMA(debf55bbfa0fc242); +CAPNP_DECLARE_SCHEMA(f38e1de3041357ae); +CAPNP_DECLARE_SCHEMA(c2ba9038898e1fa2); +CAPNP_DECLARE_SCHEMA(9ea0b19b37fb4435); +CAPNP_DECLARE_SCHEMA(b54ab3364333f598); +CAPNP_DECLARE_SCHEMA(e82753cff0c2218f); +CAPNP_DECLARE_SCHEMA(b18aa5ac7a0d9420); +CAPNP_DECLARE_SCHEMA(ec1619d4400a0290); +CAPNP_DECLARE_SCHEMA(9aad50a41f4af45f); +CAPNP_DECLARE_SCHEMA(97b14cbe7cfec712); +CAPNP_DECLARE_SCHEMA(c42305476bb4746f); +CAPNP_DECLARE_SCHEMA(cafccddb68db1d11); +CAPNP_DECLARE_SCHEMA(bb90d5c287870be6); +CAPNP_DECLARE_SCHEMA(978a7cebdc549a4d); +CAPNP_DECLARE_SCHEMA(a9962a9ed0a4d7f8); +CAPNP_DECLARE_SCHEMA(9500cce23b334d80); +CAPNP_DECLARE_SCHEMA(d07378ede1f9cc60); +CAPNP_DECLARE_SCHEMA(87e739250a60ea97); +CAPNP_DECLARE_SCHEMA(9e0e78711a7f87a9); +CAPNP_DECLARE_SCHEMA(ac3a6f60ef4cc6d3); +CAPNP_DECLARE_SCHEMA(ed8bca69f7fb0cbf); +CAPNP_DECLARE_SCHEMA(c2573fe8a23e49f1); +CAPNP_DECLARE_SCHEMA(8e3b5f79fe593656); +CAPNP_DECLARE_SCHEMA(9dd1f724f4614a85); +CAPNP_DECLARE_SCHEMA(baefc9120c56e274); +CAPNP_DECLARE_SCHEMA(903455f06065422b); +CAPNP_DECLARE_SCHEMA(abd73485a9636bc9); +CAPNP_DECLARE_SCHEMA(c863cd16969ee7fc); +CAPNP_DECLARE_SCHEMA(ce23dcd2d7b00c9b); +CAPNP_DECLARE_SCHEMA(f1c8950dab257542); +CAPNP_DECLARE_SCHEMA(d1958f7dba521926); +enum class ElementSize_d1958f7dba521926: uint16_t { + EMPTY, + BIT, + BYTE, + TWO_BYTES, + FOUR_BYTES, + EIGHT_BYTES, + POINTER, + INLINE_COMPOSITE, +}; +CAPNP_DECLARE_ENUM(ElementSize, d1958f7dba521926); +CAPNP_DECLARE_SCHEMA(d85d305b7d839963); +CAPNP_DECLARE_SCHEMA(bfc546f6210ad7ce); +CAPNP_DECLARE_SCHEMA(cfea0eb02e810062); +CAPNP_DECLARE_SCHEMA(ae504193122357e5); + +} // namespace schemas +} // namespace capnp + +namespace capnp { +namespace schema { + +struct Node { + Node() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + FILE, + STRUCT, + ENUM, + INTERFACE, + CONST, + ANNOTATION, + }; + struct Parameter; + struct NestedNode; + struct SourceInfo; + struct Struct; + struct Enum; + struct Interface; + struct Const; + struct Annotation; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e682ab4cf923a417, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Parameter { + Parameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b9521bccf10fa3b1, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::NestedNode { + NestedNode() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(debf55bbfa0fc242, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::SourceInfo { + SourceInfo() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Member; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f38e1de3041357ae, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::SourceInfo::Member { + Member() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c2ba9038898e1fa2, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Struct { + Struct() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9ea0b19b37fb4435, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Enum { + Enum() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b54ab3364333f598, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Interface { + Interface() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(e82753cff0c2218f, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Const { + Const() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(b18aa5ac7a0d9420, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Node::Annotation { + Annotation() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ec1619d4400a0290, 5, 6) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field { + Field() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + SLOT, + GROUP, + }; + static constexpr ::uint16_t NO_DISCRIMINANT = 65535u; + struct Slot; + struct Group; + struct Ordinal; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9aad50a41f4af45f, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field::Slot { + Slot() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c42305476bb4746f, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field::Group { + Group() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cafccddb68db1d11, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Field::Ordinal { + Ordinal() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + IMPLICIT, + EXPLICIT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bb90d5c287870be6, 3, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Enumerant { + Enumerant() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(978a7cebdc549a4d, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Superclass { + Superclass() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(a9962a9ed0a4d7f8, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Method { + Method() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9500cce23b334d80, 3, 5) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type { + Type() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + VOID, + BOOL, + INT8, + INT16, + INT32, + INT64, + UINT8, + UINT16, + UINT32, + UINT64, + FLOAT32, + FLOAT64, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + INTERFACE, + ANY_POINTER, + }; + struct List; + struct Enum; + struct Struct; + struct Interface; + struct AnyPointer; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d07378ede1f9cc60, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::List { + List() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(87e739250a60ea97, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::Enum { + Enum() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9e0e78711a7f87a9, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::Struct { + Struct() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ac3a6f60ef4cc6d3, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::Interface { + Interface() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ed8bca69f7fb0cbf, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer { + AnyPointer() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNCONSTRAINED, + PARAMETER, + IMPLICIT_METHOD_PARAMETER, + }; + struct Unconstrained; + struct Parameter; + struct ImplicitMethodParameter; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c2573fe8a23e49f1, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::Unconstrained { + Unconstrained() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + ANY_KIND, + STRUCT, + LIST, + CAPABILITY, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(8e3b5f79fe593656, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::Parameter { + Parameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(9dd1f724f4614a85, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Type::AnyPointer::ImplicitMethodParameter { + ImplicitMethodParameter() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(baefc9120c56e274, 3, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Brand { + Brand() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Scope; + struct Binding; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(903455f06065422b, 0, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Brand::Scope { + Scope() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + BIND, + INHERIT, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(abd73485a9636bc9, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Brand::Binding { + Binding() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + UNBOUND, + TYPE, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(c863cd16969ee7fc, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Value { + Value() = delete; + + class Reader; + class Builder; + class Pipeline; + enum Which: uint16_t { + VOID, + BOOL, + INT8, + INT16, + INT32, + INT64, + UINT8, + UINT16, + UINT32, + UINT64, + FLOAT32, + FLOAT64, + TEXT, + DATA, + LIST, + ENUM, + STRUCT, + INTERFACE, + ANY_POINTER, + }; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ce23dcd2d7b00c9b, 2, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct Annotation { + Annotation() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(f1c8950dab257542, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +typedef ::capnp::schemas::ElementSize_d1958f7dba521926 ElementSize; + +struct CapnpVersion { + CapnpVersion() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(d85d305b7d839963, 1, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest { + CodeGeneratorRequest() = delete; + + class Reader; + class Builder; + class Pipeline; + struct RequestedFile; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(bfc546f6210ad7ce, 0, 4) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest::RequestedFile { + RequestedFile() = delete; + + class Reader; + class Builder; + class Pipeline; + struct Import; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(cfea0eb02e810062, 1, 2) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +struct CodeGeneratorRequest::RequestedFile::Import { + Import() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(ae504193122357e5, 1, 1) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class Node::Reader { +public: + typedef Node Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline ::uint64_t getId() const; + + inline bool hasDisplayName() const; + inline ::capnp::Text::Reader getDisplayName() const; + + inline ::uint32_t getDisplayNamePrefixLength() const; + + inline ::uint64_t getScopeId() const; + + inline bool hasNestedNodes() const; + inline ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Reader getNestedNodes() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader getAnnotations() const; + + inline bool isFile() const; + inline ::capnp::Void getFile() const; + + inline bool isStruct() const; + inline typename Struct::Reader getStruct() const; + + inline bool isEnum() const; + inline typename Enum::Reader getEnum() const; + + inline bool isInterface() const; + inline typename Interface::Reader getInterface() const; + + inline bool isConst() const; + inline typename Const::Reader getConst() const; + + inline bool isAnnotation() const; + inline typename Annotation::Reader getAnnotation() const; + + inline bool hasParameters() const; + inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader getParameters() const; + + inline bool getIsGeneric() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Builder { +public: + typedef Node Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasDisplayName(); + inline ::capnp::Text::Builder getDisplayName(); + inline void setDisplayName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initDisplayName(unsigned int size); + inline void adoptDisplayName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownDisplayName(); + + inline ::uint32_t getDisplayNamePrefixLength(); + inline void setDisplayNamePrefixLength( ::uint32_t value); + + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline bool hasNestedNodes(); + inline ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Builder getNestedNodes(); + inline void setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Builder initNestedNodes(unsigned int size); + inline void adoptNestedNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>> disownNestedNodes(); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> disownAnnotations(); + + inline bool isFile(); + inline ::capnp::Void getFile(); + inline void setFile( ::capnp::Void value = ::capnp::VOID); + + inline bool isStruct(); + inline typename Struct::Builder getStruct(); + inline typename Struct::Builder initStruct(); + + inline bool isEnum(); + inline typename Enum::Builder getEnum(); + inline typename Enum::Builder initEnum(); + + inline bool isInterface(); + inline typename Interface::Builder getInterface(); + inline typename Interface::Builder initInterface(); + + inline bool isConst(); + inline typename Const::Builder getConst(); + inline typename Const::Builder initConst(); + + inline bool isAnnotation(); + inline typename Annotation::Builder getAnnotation(); + inline typename Annotation::Builder initAnnotation(); + + inline bool hasParameters(); + inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder getParameters(); + inline void setParameters( ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder initParameters(unsigned int size); + inline void adoptParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>> disownParameters(); + + inline bool getIsGeneric(); + inline void setIsGeneric(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Pipeline { +public: + typedef Node Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Parameter::Reader { +public: + typedef Parameter Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Parameter::Builder { +public: + typedef Parameter Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Parameter::Pipeline { +public: + typedef Parameter Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::NestedNode::Reader { +public: + typedef NestedNode Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint64_t getId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::NestedNode::Builder { +public: + typedef NestedNode Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::NestedNode::Pipeline { +public: + typedef NestedNode Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::SourceInfo::Reader { +public: + typedef SourceInfo Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasDocComment() const; + inline ::capnp::Text::Reader getDocComment() const; + + inline bool hasMembers() const; + inline ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Reader getMembers() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::SourceInfo::Builder { +public: + typedef SourceInfo Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasDocComment(); + inline ::capnp::Text::Builder getDocComment(); + inline void setDocComment( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initDocComment(unsigned int size); + inline void adoptDocComment(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownDocComment(); + + inline bool hasMembers(); + inline ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Builder getMembers(); + inline void setMembers( ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Builder initMembers(unsigned int size); + inline void adoptMembers(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>> disownMembers(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::SourceInfo::Pipeline { +public: + typedef SourceInfo Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::SourceInfo::Member::Reader { +public: + typedef Member Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasDocComment() const; + inline ::capnp::Text::Reader getDocComment() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::SourceInfo::Member::Builder { +public: + typedef Member Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasDocComment(); + inline ::capnp::Text::Builder getDocComment(); + inline void setDocComment( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initDocComment(unsigned int size); + inline void adoptDocComment(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownDocComment(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::SourceInfo::Member::Pipeline { +public: + typedef Member Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Struct::Reader { +public: + typedef Struct Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint16_t getDataWordCount() const; + + inline ::uint16_t getPointerCount() const; + + inline ::capnp::schema::ElementSize getPreferredListEncoding() const; + + inline bool getIsGroup() const; + + inline ::uint16_t getDiscriminantCount() const; + + inline ::uint32_t getDiscriminantOffset() const; + + inline bool hasFields() const; + inline ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Reader getFields() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Struct::Builder { +public: + typedef Struct Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint16_t getDataWordCount(); + inline void setDataWordCount( ::uint16_t value); + + inline ::uint16_t getPointerCount(); + inline void setPointerCount( ::uint16_t value); + + inline ::capnp::schema::ElementSize getPreferredListEncoding(); + inline void setPreferredListEncoding( ::capnp::schema::ElementSize value); + + inline bool getIsGroup(); + inline void setIsGroup(bool value); + + inline ::uint16_t getDiscriminantCount(); + inline void setDiscriminantCount( ::uint16_t value); + + inline ::uint32_t getDiscriminantOffset(); + inline void setDiscriminantOffset( ::uint32_t value); + + inline bool hasFields(); + inline ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Builder getFields(); + inline void setFields( ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Builder initFields(unsigned int size); + inline void adoptFields(::capnp::Orphan< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>> disownFields(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Struct::Pipeline { +public: + typedef Struct Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Enum::Reader { +public: + typedef Enum Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasEnumerants() const; + inline ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Reader getEnumerants() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Enum::Builder { +public: + typedef Enum Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasEnumerants(); + inline ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Builder getEnumerants(); + inline void setEnumerants( ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Builder initEnumerants(unsigned int size); + inline void adoptEnumerants(::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>> disownEnumerants(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Enum::Pipeline { +public: + typedef Enum Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Interface::Reader { +public: + typedef Interface Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasMethods() const; + inline ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Reader getMethods() const; + + inline bool hasSuperclasses() const; + inline ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Reader getSuperclasses() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Interface::Builder { +public: + typedef Interface Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasMethods(); + inline ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Builder getMethods(); + inline void setMethods( ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Builder initMethods(unsigned int size); + inline void adoptMethods(::capnp::Orphan< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>> disownMethods(); + + inline bool hasSuperclasses(); + inline ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Builder getSuperclasses(); + inline void setSuperclasses( ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Builder initSuperclasses(unsigned int size); + inline void adoptSuperclasses(::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>> disownSuperclasses(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Interface::Pipeline { +public: + typedef Interface Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Const::Reader { +public: + typedef Const Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool hasValue() const; + inline ::capnp::schema::Value::Reader getValue() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Const::Builder { +public: + typedef Const Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool hasValue(); + inline ::capnp::schema::Value::Builder getValue(); + inline void setValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Const::Pipeline { +public: + typedef Const Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); + inline ::capnp::schema::Value::Pipeline getValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Node::Annotation::Reader { +public: + typedef Annotation Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool getTargetsFile() const; + + inline bool getTargetsConst() const; + + inline bool getTargetsEnum() const; + + inline bool getTargetsEnumerant() const; + + inline bool getTargetsStruct() const; + + inline bool getTargetsField() const; + + inline bool getTargetsUnion() const; + + inline bool getTargetsGroup() const; + + inline bool getTargetsInterface() const; + + inline bool getTargetsMethod() const; + + inline bool getTargetsParam() const; + + inline bool getTargetsAnnotation() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Node::Annotation::Builder { +public: + typedef Annotation Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool getTargetsFile(); + inline void setTargetsFile(bool value); + + inline bool getTargetsConst(); + inline void setTargetsConst(bool value); + + inline bool getTargetsEnum(); + inline void setTargetsEnum(bool value); + + inline bool getTargetsEnumerant(); + inline void setTargetsEnumerant(bool value); + + inline bool getTargetsStruct(); + inline void setTargetsStruct(bool value); + + inline bool getTargetsField(); + inline void setTargetsField(bool value); + + inline bool getTargetsUnion(); + inline void setTargetsUnion(bool value); + + inline bool getTargetsGroup(); + inline void setTargetsGroup(bool value); + + inline bool getTargetsInterface(); + inline void setTargetsInterface(bool value); + + inline bool getTargetsMethod(); + inline void setTargetsMethod(bool value); + + inline bool getTargetsParam(); + inline void setTargetsParam(bool value); + + inline bool getTargetsAnnotation(); + inline void setTargetsAnnotation(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Node::Annotation::Pipeline { +public: + typedef Annotation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Reader { +public: + typedef Field Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader getAnnotations() const; + + inline ::uint16_t getDiscriminantValue() const; + + inline bool isSlot() const; + inline typename Slot::Reader getSlot() const; + + inline bool isGroup() const; + inline typename Group::Reader getGroup() const; + + inline typename Ordinal::Reader getOrdinal() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Builder { +public: + typedef Field Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> disownAnnotations(); + + inline ::uint16_t getDiscriminantValue(); + inline void setDiscriminantValue( ::uint16_t value); + + inline bool isSlot(); + inline typename Slot::Builder getSlot(); + inline typename Slot::Builder initSlot(); + + inline bool isGroup(); + inline typename Group::Builder getGroup(); + inline typename Group::Builder initGroup(); + + inline typename Ordinal::Builder getOrdinal(); + inline typename Ordinal::Builder initOrdinal(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Pipeline { +public: + typedef Field Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline typename Ordinal::Pipeline getOrdinal(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Slot::Reader { +public: + typedef Slot Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint32_t getOffset() const; + + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + + inline bool hasDefaultValue() const; + inline ::capnp::schema::Value::Reader getDefaultValue() const; + + inline bool getHadExplicitDefault() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Slot::Builder { +public: + typedef Slot Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint32_t getOffset(); + inline void setOffset( ::uint32_t value); + + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + + inline bool hasDefaultValue(); + inline ::capnp::schema::Value::Builder getDefaultValue(); + inline void setDefaultValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initDefaultValue(); + inline void adoptDefaultValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownDefaultValue(); + + inline bool getHadExplicitDefault(); + inline void setHadExplicitDefault(bool value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Slot::Pipeline { +public: + typedef Slot Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getType(); + inline ::capnp::schema::Value::Pipeline getDefaultValue(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Group::Reader { +public: + typedef Group Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Group::Builder { +public: + typedef Group Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Group::Pipeline { +public: + typedef Group Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Field::Ordinal::Reader { +public: + typedef Ordinal Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isImplicit() const; + inline ::capnp::Void getImplicit() const; + + inline bool isExplicit() const; + inline ::uint16_t getExplicit() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Field::Ordinal::Builder { +public: + typedef Ordinal Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isImplicit(); + inline ::capnp::Void getImplicit(); + inline void setImplicit( ::capnp::Void value = ::capnp::VOID); + + inline bool isExplicit(); + inline ::uint16_t getExplicit(); + inline void setExplicit( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Field::Ordinal::Pipeline { +public: + typedef Ordinal Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Enumerant::Reader { +public: + typedef Enumerant Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader getAnnotations() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Enumerant::Builder { +public: + typedef Enumerant Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> disownAnnotations(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Enumerant::Pipeline { +public: + typedef Enumerant Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Superclass::Reader { +public: + typedef Superclass Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Superclass::Builder { +public: + typedef Superclass Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Superclass::Pipeline { +public: + typedef Superclass Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Method::Reader { +public: + typedef Method Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + + inline ::uint16_t getCodeOrder() const; + + inline ::uint64_t getParamStructType() const; + + inline ::uint64_t getResultStructType() const; + + inline bool hasAnnotations() const; + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader getAnnotations() const; + + inline bool hasParamBrand() const; + inline ::capnp::schema::Brand::Reader getParamBrand() const; + + inline bool hasResultBrand() const; + inline ::capnp::schema::Brand::Reader getResultBrand() const; + + inline bool hasImplicitParameters() const; + inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader getImplicitParameters() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Method::Builder { +public: + typedef Method Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + + inline ::uint16_t getCodeOrder(); + inline void setCodeOrder( ::uint16_t value); + + inline ::uint64_t getParamStructType(); + inline void setParamStructType( ::uint64_t value); + + inline ::uint64_t getResultStructType(); + inline void setResultStructType( ::uint64_t value); + + inline bool hasAnnotations(); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder getAnnotations(); + inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder initAnnotations(unsigned int size); + inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> disownAnnotations(); + + inline bool hasParamBrand(); + inline ::capnp::schema::Brand::Builder getParamBrand(); + inline void setParamBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initParamBrand(); + inline void adoptParamBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownParamBrand(); + + inline bool hasResultBrand(); + inline ::capnp::schema::Brand::Builder getResultBrand(); + inline void setResultBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initResultBrand(); + inline void adoptResultBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownResultBrand(); + + inline bool hasImplicitParameters(); + inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder getImplicitParameters(); + inline void setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder initImplicitParameters(unsigned int size); + inline void adoptImplicitParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>> disownImplicitParameters(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Method::Pipeline { +public: + typedef Method Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getParamBrand(); + inline ::capnp::schema::Brand::Pipeline getResultBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Reader { +public: + typedef Type Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isVoid() const; + inline ::capnp::Void getVoid() const; + + inline bool isBool() const; + inline ::capnp::Void getBool() const; + + inline bool isInt8() const; + inline ::capnp::Void getInt8() const; + + inline bool isInt16() const; + inline ::capnp::Void getInt16() const; + + inline bool isInt32() const; + inline ::capnp::Void getInt32() const; + + inline bool isInt64() const; + inline ::capnp::Void getInt64() const; + + inline bool isUint8() const; + inline ::capnp::Void getUint8() const; + + inline bool isUint16() const; + inline ::capnp::Void getUint16() const; + + inline bool isUint32() const; + inline ::capnp::Void getUint32() const; + + inline bool isUint64() const; + inline ::capnp::Void getUint64() const; + + inline bool isFloat32() const; + inline ::capnp::Void getFloat32() const; + + inline bool isFloat64() const; + inline ::capnp::Void getFloat64() const; + + inline bool isText() const; + inline ::capnp::Void getText() const; + + inline bool isData() const; + inline ::capnp::Void getData() const; + + inline bool isList() const; + inline typename List::Reader getList() const; + + inline bool isEnum() const; + inline typename Enum::Reader getEnum() const; + + inline bool isStruct() const; + inline typename Struct::Reader getStruct() const; + + inline bool isInterface() const; + inline typename Interface::Reader getInterface() const; + + inline bool isAnyPointer() const; + inline typename AnyPointer::Reader getAnyPointer() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Builder { +public: + typedef Type Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isVoid(); + inline ::capnp::Void getVoid(); + inline void setVoid( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline ::capnp::Void getBool(); + inline void setBool( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt8(); + inline ::capnp::Void getInt8(); + inline void setInt8( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt16(); + inline ::capnp::Void getInt16(); + inline void setInt16( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt32(); + inline ::capnp::Void getInt32(); + inline void setInt32( ::capnp::Void value = ::capnp::VOID); + + inline bool isInt64(); + inline ::capnp::Void getInt64(); + inline void setInt64( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint8(); + inline ::capnp::Void getUint8(); + inline void setUint8( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint16(); + inline ::capnp::Void getUint16(); + inline void setUint16( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint32(); + inline ::capnp::Void getUint32(); + inline void setUint32( ::capnp::Void value = ::capnp::VOID); + + inline bool isUint64(); + inline ::capnp::Void getUint64(); + inline void setUint64( ::capnp::Void value = ::capnp::VOID); + + inline bool isFloat32(); + inline ::capnp::Void getFloat32(); + inline void setFloat32( ::capnp::Void value = ::capnp::VOID); + + inline bool isFloat64(); + inline ::capnp::Void getFloat64(); + inline void setFloat64( ::capnp::Void value = ::capnp::VOID); + + inline bool isText(); + inline ::capnp::Void getText(); + inline void setText( ::capnp::Void value = ::capnp::VOID); + + inline bool isData(); + inline ::capnp::Void getData(); + inline void setData( ::capnp::Void value = ::capnp::VOID); + + inline bool isList(); + inline typename List::Builder getList(); + inline typename List::Builder initList(); + + inline bool isEnum(); + inline typename Enum::Builder getEnum(); + inline typename Enum::Builder initEnum(); + + inline bool isStruct(); + inline typename Struct::Builder getStruct(); + inline typename Struct::Builder initStruct(); + + inline bool isInterface(); + inline typename Interface::Builder getInterface(); + inline typename Interface::Builder initInterface(); + + inline bool isAnyPointer(); + inline typename AnyPointer::Builder getAnyPointer(); + inline typename AnyPointer::Builder initAnyPointer(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Pipeline { +public: + typedef Type Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::List::Reader { +public: + typedef List Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasElementType() const; + inline ::capnp::schema::Type::Reader getElementType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::List::Builder { +public: + typedef List Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasElementType(); + inline ::capnp::schema::Type::Builder getElementType(); + inline void setElementType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initElementType(); + inline void adoptElementType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownElementType(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::List::Pipeline { +public: + typedef List Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Type::Pipeline getElementType(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Enum::Reader { +public: + typedef Enum Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Enum::Builder { +public: + typedef Enum Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Enum::Pipeline { +public: + typedef Enum Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Struct::Reader { +public: + typedef Struct Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Struct::Builder { +public: + typedef Struct Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Struct::Pipeline { +public: + typedef Struct Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::Interface::Reader { +public: + typedef Interface Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::Interface::Builder { +public: + typedef Interface Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getTypeId(); + inline void setTypeId( ::uint64_t value); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::Interface::Pipeline { +public: + typedef Interface Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Reader { +public: + typedef AnyPointer Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isUnconstrained() const; + inline typename Unconstrained::Reader getUnconstrained() const; + + inline bool isParameter() const; + inline typename Parameter::Reader getParameter() const; + + inline bool isImplicitMethodParameter() const; + inline typename ImplicitMethodParameter::Reader getImplicitMethodParameter() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::Builder { +public: + typedef AnyPointer Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isUnconstrained(); + inline typename Unconstrained::Builder getUnconstrained(); + inline typename Unconstrained::Builder initUnconstrained(); + + inline bool isParameter(); + inline typename Parameter::Builder getParameter(); + inline typename Parameter::Builder initParameter(); + + inline bool isImplicitMethodParameter(); + inline typename ImplicitMethodParameter::Builder getImplicitMethodParameter(); + inline typename ImplicitMethodParameter::Builder initImplicitMethodParameter(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::Pipeline { +public: + typedef AnyPointer Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Unconstrained::Reader { +public: + typedef Unconstrained Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isAnyKind() const; + inline ::capnp::Void getAnyKind() const; + + inline bool isStruct() const; + inline ::capnp::Void getStruct() const; + + inline bool isList() const; + inline ::capnp::Void getList() const; + + inline bool isCapability() const; + inline ::capnp::Void getCapability() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::Unconstrained::Builder { +public: + typedef Unconstrained Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isAnyKind(); + inline ::capnp::Void getAnyKind(); + inline void setAnyKind( ::capnp::Void value = ::capnp::VOID); + + inline bool isStruct(); + inline ::capnp::Void getStruct(); + inline void setStruct( ::capnp::Void value = ::capnp::VOID); + + inline bool isList(); + inline ::capnp::Void getList(); + inline void setList( ::capnp::Void value = ::capnp::VOID); + + inline bool isCapability(); + inline ::capnp::Void getCapability(); + inline void setCapability( ::capnp::Void value = ::capnp::VOID); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::Unconstrained::Pipeline { +public: + typedef Unconstrained Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::Parameter::Reader { +public: + typedef Parameter Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getScopeId() const; + + inline ::uint16_t getParameterIndex() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::Parameter::Builder { +public: + typedef Parameter Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline ::uint16_t getParameterIndex(); + inline void setParameterIndex( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::Parameter::Pipeline { +public: + typedef Parameter Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Type::AnyPointer::ImplicitMethodParameter::Reader { +public: + typedef ImplicitMethodParameter Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint16_t getParameterIndex() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Type::AnyPointer::ImplicitMethodParameter::Builder { +public: + typedef ImplicitMethodParameter Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint16_t getParameterIndex(); + inline void setParameterIndex( ::uint16_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Type::AnyPointer::ImplicitMethodParameter::Pipeline { +public: + typedef ImplicitMethodParameter Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Brand::Reader { +public: + typedef Brand Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasScopes() const; + inline ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Reader getScopes() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Brand::Builder { +public: + typedef Brand Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasScopes(); + inline ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Builder getScopes(); + inline void setScopes( ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Builder initScopes(unsigned int size); + inline void adoptScopes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>> disownScopes(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Brand::Pipeline { +public: + typedef Brand Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Brand::Scope::Reader { +public: + typedef Scope Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline ::uint64_t getScopeId() const; + + inline bool isBind() const; + inline bool hasBind() const; + inline ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Reader getBind() const; + + inline bool isInherit() const; + inline ::capnp::Void getInherit() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Brand::Scope::Builder { +public: + typedef Scope Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline ::uint64_t getScopeId(); + inline void setScopeId( ::uint64_t value); + + inline bool isBind(); + inline bool hasBind(); + inline ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Builder getBind(); + inline void setBind( ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Builder initBind(unsigned int size); + inline void adoptBind(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>> disownBind(); + + inline bool isInherit(); + inline ::capnp::Void getInherit(); + inline void setInherit( ::capnp::Void value = ::capnp::VOID); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Brand::Scope::Pipeline { +public: + typedef Scope Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Brand::Binding::Reader { +public: + typedef Binding Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isUnbound() const; + inline ::capnp::Void getUnbound() const; + + inline bool isType() const; + inline bool hasType() const; + inline ::capnp::schema::Type::Reader getType() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Brand::Binding::Builder { +public: + typedef Binding Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isUnbound(); + inline ::capnp::Void getUnbound(); + inline void setUnbound( ::capnp::Void value = ::capnp::VOID); + + inline bool isType(); + inline bool hasType(); + inline ::capnp::schema::Type::Builder getType(); + inline void setType( ::capnp::schema::Type::Reader value); + inline ::capnp::schema::Type::Builder initType(); + inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); + inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Brand::Binding::Pipeline { +public: + typedef Binding Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Value::Reader { +public: + typedef Value Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline Which which() const; + inline bool isVoid() const; + inline ::capnp::Void getVoid() const; + + inline bool isBool() const; + inline bool getBool() const; + + inline bool isInt8() const; + inline ::int8_t getInt8() const; + + inline bool isInt16() const; + inline ::int16_t getInt16() const; + + inline bool isInt32() const; + inline ::int32_t getInt32() const; + + inline bool isInt64() const; + inline ::int64_t getInt64() const; + + inline bool isUint8() const; + inline ::uint8_t getUint8() const; + + inline bool isUint16() const; + inline ::uint16_t getUint16() const; + + inline bool isUint32() const; + inline ::uint32_t getUint32() const; + + inline bool isUint64() const; + inline ::uint64_t getUint64() const; + + inline bool isFloat32() const; + inline float getFloat32() const; + + inline bool isFloat64() const; + inline double getFloat64() const; + + inline bool isText() const; + inline bool hasText() const; + inline ::capnp::Text::Reader getText() const; + + inline bool isData() const; + inline bool hasData() const; + inline ::capnp::Data::Reader getData() const; + + inline bool isList() const; + inline bool hasList() const; + inline ::capnp::AnyPointer::Reader getList() const; + + inline bool isEnum() const; + inline ::uint16_t getEnum() const; + + inline bool isStruct() const; + inline bool hasStruct() const; + inline ::capnp::AnyPointer::Reader getStruct() const; + + inline bool isInterface() const; + inline ::capnp::Void getInterface() const; + + inline bool isAnyPointer() const; + inline bool hasAnyPointer() const; + inline ::capnp::AnyPointer::Reader getAnyPointer() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Value::Builder { +public: + typedef Value Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline Which which(); + inline bool isVoid(); + inline ::capnp::Void getVoid(); + inline void setVoid( ::capnp::Void value = ::capnp::VOID); + + inline bool isBool(); + inline bool getBool(); + inline void setBool(bool value); + + inline bool isInt8(); + inline ::int8_t getInt8(); + inline void setInt8( ::int8_t value); + + inline bool isInt16(); + inline ::int16_t getInt16(); + inline void setInt16( ::int16_t value); + + inline bool isInt32(); + inline ::int32_t getInt32(); + inline void setInt32( ::int32_t value); + + inline bool isInt64(); + inline ::int64_t getInt64(); + inline void setInt64( ::int64_t value); + + inline bool isUint8(); + inline ::uint8_t getUint8(); + inline void setUint8( ::uint8_t value); + + inline bool isUint16(); + inline ::uint16_t getUint16(); + inline void setUint16( ::uint16_t value); + + inline bool isUint32(); + inline ::uint32_t getUint32(); + inline void setUint32( ::uint32_t value); + + inline bool isUint64(); + inline ::uint64_t getUint64(); + inline void setUint64( ::uint64_t value); + + inline bool isFloat32(); + inline float getFloat32(); + inline void setFloat32(float value); + + inline bool isFloat64(); + inline double getFloat64(); + inline void setFloat64(double value); + + inline bool isText(); + inline bool hasText(); + inline ::capnp::Text::Builder getText(); + inline void setText( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initText(unsigned int size); + inline void adoptText(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownText(); + + inline bool isData(); + inline bool hasData(); + inline ::capnp::Data::Builder getData(); + inline void setData( ::capnp::Data::Reader value); + inline ::capnp::Data::Builder initData(unsigned int size); + inline void adoptData(::capnp::Orphan< ::capnp::Data>&& value); + inline ::capnp::Orphan< ::capnp::Data> disownData(); + + inline bool isList(); + inline bool hasList(); + inline ::capnp::AnyPointer::Builder getList(); + inline ::capnp::AnyPointer::Builder initList(); + + inline bool isEnum(); + inline ::uint16_t getEnum(); + inline void setEnum( ::uint16_t value); + + inline bool isStruct(); + inline bool hasStruct(); + inline ::capnp::AnyPointer::Builder getStruct(); + inline ::capnp::AnyPointer::Builder initStruct(); + + inline bool isInterface(); + inline ::capnp::Void getInterface(); + inline void setInterface( ::capnp::Void value = ::capnp::VOID); + + inline bool isAnyPointer(); + inline bool hasAnyPointer(); + inline ::capnp::AnyPointer::Builder getAnyPointer(); + inline ::capnp::AnyPointer::Builder initAnyPointer(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Value::Pipeline { +public: + typedef Value Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class Annotation::Reader { +public: + typedef Annotation Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasValue() const; + inline ::capnp::schema::Value::Reader getValue() const; + + inline bool hasBrand() const; + inline ::capnp::schema::Brand::Reader getBrand() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class Annotation::Builder { +public: + typedef Annotation Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasValue(); + inline ::capnp::schema::Value::Builder getValue(); + inline void setValue( ::capnp::schema::Value::Reader value); + inline ::capnp::schema::Value::Builder initValue(); + inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); + inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); + + inline bool hasBrand(); + inline ::capnp::schema::Brand::Builder getBrand(); + inline void setBrand( ::capnp::schema::Brand::Reader value); + inline ::capnp::schema::Brand::Builder initBrand(); + inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); + inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class Annotation::Pipeline { +public: + typedef Annotation Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::Value::Pipeline getValue(); + inline ::capnp::schema::Brand::Pipeline getBrand(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CapnpVersion::Reader { +public: + typedef CapnpVersion Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint16_t getMajor() const; + + inline ::uint8_t getMinor() const; + + inline ::uint8_t getMicro() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CapnpVersion::Builder { +public: + typedef CapnpVersion Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint16_t getMajor(); + inline void setMajor( ::uint16_t value); + + inline ::uint8_t getMinor(); + inline void setMinor( ::uint8_t value); + + inline ::uint8_t getMicro(); + inline void setMicro( ::uint8_t value); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CapnpVersion::Pipeline { +public: + typedef CapnpVersion Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::Reader { +public: + typedef CodeGeneratorRequest Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline bool hasNodes() const; + inline ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Reader getNodes() const; + + inline bool hasRequestedFiles() const; + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Reader getRequestedFiles() const; + + inline bool hasCapnpVersion() const; + inline ::capnp::schema::CapnpVersion::Reader getCapnpVersion() const; + + inline bool hasSourceInfo() const; + inline ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Reader getSourceInfo() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CodeGeneratorRequest::Builder { +public: + typedef CodeGeneratorRequest Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline bool hasNodes(); + inline ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Builder getNodes(); + inline void setNodes( ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Builder initNodes(unsigned int size); + inline void adoptNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>> disownNodes(); + + inline bool hasRequestedFiles(); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Builder getRequestedFiles(); + inline void setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Builder initRequestedFiles(unsigned int size); + inline void adoptRequestedFiles(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>> disownRequestedFiles(); + + inline bool hasCapnpVersion(); + inline ::capnp::schema::CapnpVersion::Builder getCapnpVersion(); + inline void setCapnpVersion( ::capnp::schema::CapnpVersion::Reader value); + inline ::capnp::schema::CapnpVersion::Builder initCapnpVersion(); + inline void adoptCapnpVersion(::capnp::Orphan< ::capnp::schema::CapnpVersion>&& value); + inline ::capnp::Orphan< ::capnp::schema::CapnpVersion> disownCapnpVersion(); + + inline bool hasSourceInfo(); + inline ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Builder getSourceInfo(); + inline void setSourceInfo( ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Builder initSourceInfo(unsigned int size); + inline void adoptSourceInfo(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>> disownSourceInfo(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CodeGeneratorRequest::Pipeline { +public: + typedef CodeGeneratorRequest Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + + inline ::capnp::schema::CapnpVersion::Pipeline getCapnpVersion(); +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::RequestedFile::Reader { +public: + typedef RequestedFile Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasFilename() const; + inline ::capnp::Text::Reader getFilename() const; + + inline bool hasImports() const; + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Reader getImports() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CodeGeneratorRequest::RequestedFile::Builder { +public: + typedef RequestedFile Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasFilename(); + inline ::capnp::Text::Builder getFilename(); + inline void setFilename( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initFilename(unsigned int size); + inline void adoptFilename(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownFilename(); + + inline bool hasImports(); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Builder getImports(); + inline void setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Reader value); + inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Builder initImports(unsigned int size); + inline void adoptImports(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>&& value); + inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>> disownImports(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CodeGeneratorRequest::RequestedFile::Pipeline { +public: + typedef RequestedFile Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +class CodeGeneratorRequest::RequestedFile::Import::Reader { +public: + typedef Import Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + + inline ::uint64_t getId() const; + + inline bool hasName() const; + inline ::capnp::Text::Reader getName() const; + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class CodeGeneratorRequest::RequestedFile::Import::Builder { +public: + typedef Import Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + + inline ::uint64_t getId(); + inline void setId( ::uint64_t value); + + inline bool hasName(); + inline ::capnp::Text::Builder getName(); + inline void setName( ::capnp::Text::Reader value); + inline ::capnp::Text::Builder initName(unsigned int size); + inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); + inline ::capnp::Orphan< ::capnp::Text> disownName(); + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class CodeGeneratorRequest::RequestedFile::Import::Pipeline { +public: + typedef Import Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +inline ::capnp::schema::Node::Which Node::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Node::Which Node::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::hasDisplayName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasDisplayName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::Reader::getDisplayName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::Builder::getDisplayName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setDisplayName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::Builder::initDisplayName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptDisplayName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::Builder::disownDisplayName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint32_t Node::Reader::getDisplayNamePrefixLength() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Node::Builder::getDisplayNamePrefixLength() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setDisplayNamePrefixLength( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Node::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::hasNestedNodes() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasNestedNodes() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Reader Node::Reader::getNestedNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Builder Node::Builder::getNestedNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>::Builder Node::Builder::initNestedNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptNestedNodes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>> Node::Builder::disownNestedNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Node::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader Node::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Node::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Node::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> Node::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Node::Reader::isFile() const { + return which() == Node::FILE; +} +inline bool Node::Builder::isFile() { + return which() == Node::FILE; +} +inline ::capnp::Void Node::Reader::getFile() const { + KJ_IREQUIRE((which() == Node::FILE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Node::Builder::getFile() { + KJ_IREQUIRE((which() == Node::FILE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setFile( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::FILE); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Reader::isStruct() const { + return which() == Node::STRUCT; +} +inline bool Node::Builder::isStruct() { + return which() == Node::STRUCT; +} +inline typename Node::Struct::Reader Node::Reader::getStruct() const { + KJ_IREQUIRE((which() == Node::STRUCT), + "Must check which() before get()ing a union member."); + return typename Node::Struct::Reader(_reader); +} +inline typename Node::Struct::Builder Node::Builder::getStruct() { + KJ_IREQUIRE((which() == Node::STRUCT), + "Must check which() before get()ing a union member."); + return typename Node::Struct::Builder(_builder); +} +inline typename Node::Struct::Builder Node::Builder::initStruct() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::STRUCT); + _builder.setDataField< ::uint16_t>(::capnp::bounded<7>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<12>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<13>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<224>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<15>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint32_t>(::capnp::bounded<8>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Node::Struct::Builder(_builder); +} +inline bool Node::Reader::isEnum() const { + return which() == Node::ENUM; +} +inline bool Node::Builder::isEnum() { + return which() == Node::ENUM; +} +inline typename Node::Enum::Reader Node::Reader::getEnum() const { + KJ_IREQUIRE((which() == Node::ENUM), + "Must check which() before get()ing a union member."); + return typename Node::Enum::Reader(_reader); +} +inline typename Node::Enum::Builder Node::Builder::getEnum() { + KJ_IREQUIRE((which() == Node::ENUM), + "Must check which() before get()ing a union member."); + return typename Node::Enum::Builder(_builder); +} +inline typename Node::Enum::Builder Node::Builder::initEnum() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::ENUM); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Node::Enum::Builder(_builder); +} +inline bool Node::Reader::isInterface() const { + return which() == Node::INTERFACE; +} +inline bool Node::Builder::isInterface() { + return which() == Node::INTERFACE; +} +inline typename Node::Interface::Reader Node::Reader::getInterface() const { + KJ_IREQUIRE((which() == Node::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Node::Interface::Reader(_reader); +} +inline typename Node::Interface::Builder Node::Builder::getInterface() { + KJ_IREQUIRE((which() == Node::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Node::Interface::Builder(_builder); +} +inline typename Node::Interface::Builder Node::Builder::initInterface() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::INTERFACE); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + _builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear(); + return typename Node::Interface::Builder(_builder); +} +inline bool Node::Reader::isConst() const { + return which() == Node::CONST; +} +inline bool Node::Builder::isConst() { + return which() == Node::CONST; +} +inline typename Node::Const::Reader Node::Reader::getConst() const { + KJ_IREQUIRE((which() == Node::CONST), + "Must check which() before get()ing a union member."); + return typename Node::Const::Reader(_reader); +} +inline typename Node::Const::Builder Node::Builder::getConst() { + KJ_IREQUIRE((which() == Node::CONST), + "Must check which() before get()ing a union member."); + return typename Node::Const::Builder(_builder); +} +inline typename Node::Const::Builder Node::Builder::initConst() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::CONST); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + _builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear(); + return typename Node::Const::Builder(_builder); +} +inline bool Node::Reader::isAnnotation() const { + return which() == Node::ANNOTATION; +} +inline bool Node::Builder::isAnnotation() { + return which() == Node::ANNOTATION; +} +inline typename Node::Annotation::Reader Node::Reader::getAnnotation() const { + KJ_IREQUIRE((which() == Node::ANNOTATION), + "Must check which() before get()ing a union member."); + return typename Node::Annotation::Reader(_reader); +} +inline typename Node::Annotation::Builder Node::Builder::getAnnotation() { + KJ_IREQUIRE((which() == Node::ANNOTATION), + "Must check which() before get()ing a union member."); + return typename Node::Annotation::Builder(_builder); +} +inline typename Node::Annotation::Builder Node::Builder::initAnnotation() { + _builder.setDataField( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::ANNOTATION); + _builder.setDataField(::capnp::bounded<112>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<113>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<114>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<115>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<116>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<117>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<118>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<119>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<120>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<121>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<122>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<123>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Node::Annotation::Builder(_builder); +} +inline bool Node::Reader::hasParameters() const { + return !_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Builder::hasParameters() { + return !_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader Node::Reader::getParameters() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder Node::Builder::getParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} +inline void Node::Builder::setParameters( ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder Node::Builder::initParameters(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), size); +} +inline void Node::Builder::adoptParameters( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>> Node::Builder::disownParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<5>() * ::capnp::POINTERS)); +} + +inline bool Node::Reader::getIsGeneric() const { + return _reader.getDataField( + ::capnp::bounded<288>() * ::capnp::ELEMENTS); +} + +inline bool Node::Builder::getIsGeneric() { + return _builder.getDataField( + ::capnp::bounded<288>() * ::capnp::ELEMENTS); +} +inline void Node::Builder::setIsGeneric(bool value) { + _builder.setDataField( + ::capnp::bounded<288>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Parameter::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Parameter::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::Parameter::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::Parameter::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::Parameter::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::Parameter::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::Parameter::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::Parameter::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Node::NestedNode::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::NestedNode::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::NestedNode::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::NestedNode::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::NestedNode::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::NestedNode::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::NestedNode::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::NestedNode::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Node::NestedNode::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::NestedNode::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::NestedNode::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Node::SourceInfo::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Node::SourceInfo::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Node::SourceInfo::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::SourceInfo::Reader::hasDocComment() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::SourceInfo::Builder::hasDocComment() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::SourceInfo::Reader::getDocComment() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::SourceInfo::Builder::getDocComment() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::SourceInfo::Builder::setDocComment( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::SourceInfo::Builder::initDocComment(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::SourceInfo::Builder::adoptDocComment( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::SourceInfo::Builder::disownDocComment() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Node::SourceInfo::Reader::hasMembers() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::SourceInfo::Builder::hasMembers() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Reader Node::SourceInfo::Reader::getMembers() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Builder Node::SourceInfo::Builder::getMembers() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Node::SourceInfo::Builder::setMembers( ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>::Builder Node::SourceInfo::Builder::initMembers(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Node::SourceInfo::Builder::adoptMembers( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>> Node::SourceInfo::Builder::disownMembers() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo::Member, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Node::SourceInfo::Member::Reader::hasDocComment() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::SourceInfo::Member::Builder::hasDocComment() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Node::SourceInfo::Member::Reader::getDocComment() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Node::SourceInfo::Member::Builder::getDocComment() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Node::SourceInfo::Member::Builder::setDocComment( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Node::SourceInfo::Member::Builder::initDocComment(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Node::SourceInfo::Member::Builder::adoptDocComment( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Node::SourceInfo::Member::Builder::disownDocComment() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Node::Struct::Reader::getDataWordCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<7>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getDataWordCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<7>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDataWordCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<7>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getPointerCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getPointerCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setPointerCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<12>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::ElementSize Node::Struct::Reader::getPreferredListEncoding() const { + return _reader.getDataField< ::capnp::schema::ElementSize>( + ::capnp::bounded<13>() * ::capnp::ELEMENTS); +} + +inline ::capnp::schema::ElementSize Node::Struct::Builder::getPreferredListEncoding() { + return _builder.getDataField< ::capnp::schema::ElementSize>( + ::capnp::bounded<13>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setPreferredListEncoding( ::capnp::schema::ElementSize value) { + _builder.setDataField< ::capnp::schema::ElementSize>( + ::capnp::bounded<13>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Struct::Reader::getIsGroup() const { + return _reader.getDataField( + ::capnp::bounded<224>() * ::capnp::ELEMENTS); +} + +inline bool Node::Struct::Builder::getIsGroup() { + return _builder.getDataField( + ::capnp::bounded<224>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setIsGroup(bool value) { + _builder.setDataField( + ::capnp::bounded<224>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Node::Struct::Reader::getDiscriminantCount() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<15>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Node::Struct::Builder::getDiscriminantCount() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<15>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDiscriminantCount( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<15>() * ::capnp::ELEMENTS, value); +} + +inline ::uint32_t Node::Struct::Reader::getDiscriminantOffset() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<8>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Node::Struct::Builder::getDiscriminantOffset() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<8>() * ::capnp::ELEMENTS); +} +inline void Node::Struct::Builder::setDiscriminantOffset( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<8>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Struct::Reader::hasFields() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Struct::Builder::hasFields() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Reader Node::Struct::Reader::getFields() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Builder Node::Struct::Builder::getFields() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Struct::Builder::setFields( ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>::Builder Node::Struct::Builder::initFields(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Node::Struct::Builder::adoptFields( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>> Node::Struct::Builder::disownFields() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Enum::Reader::hasEnumerants() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Enum::Builder::hasEnumerants() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Reader Node::Enum::Reader::getEnumerants() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Builder Node::Enum::Builder::getEnumerants() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Enum::Builder::setEnumerants( ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>::Builder Node::Enum::Builder::initEnumerants(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Node::Enum::Builder::adoptEnumerants( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>> Node::Enum::Builder::disownEnumerants() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Interface::Reader::hasMethods() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Interface::Builder::hasMethods() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Reader Node::Interface::Reader::getMethods() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Builder Node::Interface::Builder::getMethods() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Interface::Builder::setMethods( ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>::Builder Node::Interface::Builder::initMethods(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void Node::Interface::Builder::adoptMethods( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>> Node::Interface::Builder::disownMethods() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Interface::Reader::hasSuperclasses() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Interface::Builder::hasSuperclasses() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Reader Node::Interface::Reader::getSuperclasses() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Builder Node::Interface::Builder::getSuperclasses() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Node::Interface::Builder::setSuperclasses( ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>::Builder Node::Interface::Builder::initSuperclasses(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), size); +} +inline void Node::Interface::Builder::adoptSuperclasses( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>> Node::Interface::Builder::disownSuperclasses() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline bool Node::Const::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Const::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Node::Const::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Node::Const::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Node::Const::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Node::Const::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Node::Const::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Const::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Node::Const::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Const::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Const::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Node::Const::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Node::Const::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Node::Const::Pipeline::getValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(4)); +} +#endif // !CAPNP_LITE +inline void Node::Const::Builder::setValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Node::Const::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Node::Const::Builder::adoptValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Node::Const::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline bool Node::Annotation::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Node::Annotation::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Node::Annotation::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Node::Annotation::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Node::Annotation::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Node::Annotation::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Node::Annotation::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Node::Annotation::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Node::Annotation::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Node::Annotation::Reader::getTargetsFile() const { + return _reader.getDataField( + ::capnp::bounded<112>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsFile() { + return _builder.getDataField( + ::capnp::bounded<112>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsFile(bool value) { + _builder.setDataField( + ::capnp::bounded<112>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsConst() const { + return _reader.getDataField( + ::capnp::bounded<113>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsConst() { + return _builder.getDataField( + ::capnp::bounded<113>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsConst(bool value) { + _builder.setDataField( + ::capnp::bounded<113>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsEnum() const { + return _reader.getDataField( + ::capnp::bounded<114>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsEnum() { + return _builder.getDataField( + ::capnp::bounded<114>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsEnum(bool value) { + _builder.setDataField( + ::capnp::bounded<114>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsEnumerant() const { + return _reader.getDataField( + ::capnp::bounded<115>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsEnumerant() { + return _builder.getDataField( + ::capnp::bounded<115>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsEnumerant(bool value) { + _builder.setDataField( + ::capnp::bounded<115>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsStruct() const { + return _reader.getDataField( + ::capnp::bounded<116>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsStruct() { + return _builder.getDataField( + ::capnp::bounded<116>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsStruct(bool value) { + _builder.setDataField( + ::capnp::bounded<116>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsField() const { + return _reader.getDataField( + ::capnp::bounded<117>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsField() { + return _builder.getDataField( + ::capnp::bounded<117>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsField(bool value) { + _builder.setDataField( + ::capnp::bounded<117>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsUnion() const { + return _reader.getDataField( + ::capnp::bounded<118>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsUnion() { + return _builder.getDataField( + ::capnp::bounded<118>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsUnion(bool value) { + _builder.setDataField( + ::capnp::bounded<118>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsGroup() const { + return _reader.getDataField( + ::capnp::bounded<119>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsGroup() { + return _builder.getDataField( + ::capnp::bounded<119>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsGroup(bool value) { + _builder.setDataField( + ::capnp::bounded<119>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsInterface() const { + return _reader.getDataField( + ::capnp::bounded<120>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsInterface() { + return _builder.getDataField( + ::capnp::bounded<120>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsInterface(bool value) { + _builder.setDataField( + ::capnp::bounded<120>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsMethod() const { + return _reader.getDataField( + ::capnp::bounded<121>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsMethod() { + return _builder.getDataField( + ::capnp::bounded<121>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsMethod(bool value) { + _builder.setDataField( + ::capnp::bounded<121>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsParam() const { + return _reader.getDataField( + ::capnp::bounded<122>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsParam() { + return _builder.getDataField( + ::capnp::bounded<122>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsParam(bool value) { + _builder.setDataField( + ::capnp::bounded<122>() * ::capnp::ELEMENTS, value); +} + +inline bool Node::Annotation::Reader::getTargetsAnnotation() const { + return _reader.getDataField( + ::capnp::bounded<123>() * ::capnp::ELEMENTS); +} + +inline bool Node::Annotation::Builder::getTargetsAnnotation() { + return _builder.getDataField( + ::capnp::bounded<123>() * ::capnp::ELEMENTS); +} +inline void Node::Annotation::Builder::setTargetsAnnotation(bool value) { + _builder.setDataField( + ::capnp::bounded<123>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Field::Which Field::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Field::Which Field::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} + +inline bool Field::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Field::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Field::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Field::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Field::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Field::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Field::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Field::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Field::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Field::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Field::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader Field::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Field::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Field::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Field::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Field::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> Field::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Field::Reader::getDiscriminantValue() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, 65535u); +} + +inline ::uint16_t Field::Builder::getDiscriminantValue() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, 65535u); +} +inline void Field::Builder::setDiscriminantValue( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value, 65535u); +} + +inline bool Field::Reader::isSlot() const { + return which() == Field::SLOT; +} +inline bool Field::Builder::isSlot() { + return which() == Field::SLOT; +} +inline typename Field::Slot::Reader Field::Reader::getSlot() const { + KJ_IREQUIRE((which() == Field::SLOT), + "Must check which() before get()ing a union member."); + return typename Field::Slot::Reader(_reader); +} +inline typename Field::Slot::Builder Field::Builder::getSlot() { + KJ_IREQUIRE((which() == Field::SLOT), + "Must check which() before get()ing a union member."); + return typename Field::Slot::Builder(_builder); +} +inline typename Field::Slot::Builder Field::Builder::initSlot() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Field::SLOT); + _builder.setDataField< ::uint32_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.setDataField(::capnp::bounded<128>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<2>() * ::capnp::POINTERS).clear(); + _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); + return typename Field::Slot::Builder(_builder); +} +inline bool Field::Reader::isGroup() const { + return which() == Field::GROUP; +} +inline bool Field::Builder::isGroup() { + return which() == Field::GROUP; +} +inline typename Field::Group::Reader Field::Reader::getGroup() const { + KJ_IREQUIRE((which() == Field::GROUP), + "Must check which() before get()ing a union member."); + return typename Field::Group::Reader(_reader); +} +inline typename Field::Group::Builder Field::Builder::getGroup() { + KJ_IREQUIRE((which() == Field::GROUP), + "Must check which() before get()ing a union member."); + return typename Field::Group::Builder(_builder); +} +inline typename Field::Group::Builder Field::Builder::initGroup() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Field::GROUP); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Field::Group::Builder(_builder); +} +inline typename Field::Ordinal::Reader Field::Reader::getOrdinal() const { + return typename Field::Ordinal::Reader(_reader); +} +inline typename Field::Ordinal::Builder Field::Builder::getOrdinal() { + return typename Field::Ordinal::Builder(_builder); +} +#if !CAPNP_LITE +inline typename Field::Ordinal::Pipeline Field::Pipeline::getOrdinal() { + return typename Field::Ordinal::Pipeline(_typeless.noop()); +} +#endif // !CAPNP_LITE +inline typename Field::Ordinal::Builder Field::Builder::initOrdinal() { + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<6>() * ::capnp::ELEMENTS, 0); + return typename Field::Ordinal::Builder(_builder); +} +inline ::uint32_t Field::Slot::Reader::getOffset() const { + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Field::Slot::Builder::getOffset() { + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Field::Slot::Builder::setOffset( ::uint32_t value) { + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Field::Slot::Reader::hasType() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Slot::Builder::hasType() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Field::Slot::Reader::getType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Field::Slot::Builder::getType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Field::Slot::Pipeline::getType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Field::Slot::Builder::setType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Field::Slot::Builder::initType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Field::Slot::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Field::Slot::Builder::disownType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Field::Slot::Reader::hasDefaultValue() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Field::Slot::Builder::hasDefaultValue() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Field::Slot::Reader::getDefaultValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Field::Slot::Builder::getDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Field::Slot::Pipeline::getDefaultValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Field::Slot::Builder::setDefaultValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Field::Slot::Builder::initDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Field::Slot::Builder::adoptDefaultValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Field::Slot::Builder::disownDefaultValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Field::Slot::Reader::getHadExplicitDefault() const { + return _reader.getDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS); +} + +inline bool Field::Slot::Builder::getHadExplicitDefault() { + return _builder.getDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS); +} +inline void Field::Slot::Builder::setHadExplicitDefault(bool value) { + _builder.setDataField( + ::capnp::bounded<128>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Field::Group::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Field::Group::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Field::Group::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline bool Field::Ordinal::Reader::isImplicit() const { + return which() == Field::Ordinal::IMPLICIT; +} +inline bool Field::Ordinal::Builder::isImplicit() { + return which() == Field::Ordinal::IMPLICIT; +} +inline ::capnp::Void Field::Ordinal::Reader::getImplicit() const { + KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Field::Ordinal::Builder::getImplicit() { + KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Field::Ordinal::Builder::setImplicit( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Field::Ordinal::IMPLICIT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Field::Ordinal::Reader::isExplicit() const { + return which() == Field::Ordinal::EXPLICIT; +} +inline bool Field::Ordinal::Builder::isExplicit() { + return which() == Field::Ordinal::EXPLICIT; +} +inline ::uint16_t Field::Ordinal::Reader::getExplicit() const { + KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Field::Ordinal::Builder::getExplicit() { + KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<6>() * ::capnp::ELEMENTS); +} +inline void Field::Ordinal::Builder::setExplicit( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Field::Ordinal::EXPLICIT); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<6>() * ::capnp::ELEMENTS, value); +} + +inline bool Enumerant::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Enumerant::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Enumerant::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Enumerant::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Enumerant::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Enumerant::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Enumerant::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Enumerant::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Enumerant::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Enumerant::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Enumerant::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Enumerant::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Enumerant::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader Enumerant::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Enumerant::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Enumerant::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Enumerant::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Enumerant::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> Enumerant::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Superclass::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Superclass::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Superclass::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Superclass::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Superclass::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Superclass::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Superclass::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Superclass::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Superclass::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Superclass::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Superclass::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Superclass::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Method::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Method::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Method::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Method::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Method::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint16_t Method::Reader::getCodeOrder() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Method::Builder::getCodeOrder() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Method::Builder::setCodeOrder( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Method::Reader::getParamStructType() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Method::Builder::getParamStructType() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Method::Builder::setParamStructType( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Method::Reader::getResultStructType() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Method::Builder::getResultStructType() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Method::Builder::setResultStructType( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Method::Reader::hasAnnotations() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasAnnotations() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader Method::Reader::getAnnotations() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Method::Builder::getAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Method::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>::Builder Method::Builder::initAnnotations(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptAnnotations( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>> Method::Builder::disownAnnotations() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasParamBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasParamBrand() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Method::Reader::getParamBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Method::Builder::getParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getParamBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void Method::Builder::setParamBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Method::Builder::initParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void Method::Builder::adoptParamBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownParamBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasResultBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasResultBrand() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Method::Reader::getResultBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Method::Builder::getResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getResultBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(3)); +} +#endif // !CAPNP_LITE +inline void Method::Builder::setResultBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Method::Builder::initResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void Method::Builder::adoptResultBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownResultBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline bool Method::Reader::hasImplicitParameters() const { + return !_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline bool Method::Builder::hasImplicitParameters() { + return !_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader Method::Reader::getImplicitParameters() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder Method::Builder::getImplicitParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} +inline void Method::Builder::setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>::Builder Method::Builder::initImplicitParameters(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), size); +} +inline void Method::Builder::adoptImplicitParameters( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>> Method::Builder::disownImplicitParameters() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<4>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Type::Which Type::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::Which Type::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Type::Reader::isVoid() const { + return which() == Type::VOID; +} +inline bool Type::Builder::isVoid() { + return which() == Type::VOID; +} +inline ::capnp::Void Type::Reader::getVoid() const { + KJ_IREQUIRE((which() == Type::VOID), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getVoid() { + KJ_IREQUIRE((which() == Type::VOID), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setVoid( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::VOID); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isBool() const { + return which() == Type::BOOL; +} +inline bool Type::Builder::isBool() { + return which() == Type::BOOL; +} +inline ::capnp::Void Type::Reader::getBool() const { + KJ_IREQUIRE((which() == Type::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getBool() { + KJ_IREQUIRE((which() == Type::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setBool( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::BOOL); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt8() const { + return which() == Type::INT8; +} +inline bool Type::Builder::isInt8() { + return which() == Type::INT8; +} +inline ::capnp::Void Type::Reader::getInt8() const { + KJ_IREQUIRE((which() == Type::INT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt8() { + KJ_IREQUIRE((which() == Type::INT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt8( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT8); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt16() const { + return which() == Type::INT16; +} +inline bool Type::Builder::isInt16() { + return which() == Type::INT16; +} +inline ::capnp::Void Type::Reader::getInt16() const { + KJ_IREQUIRE((which() == Type::INT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt16() { + KJ_IREQUIRE((which() == Type::INT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt16( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT16); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt32() const { + return which() == Type::INT32; +} +inline bool Type::Builder::isInt32() { + return which() == Type::INT32; +} +inline ::capnp::Void Type::Reader::getInt32() const { + KJ_IREQUIRE((which() == Type::INT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt32() { + KJ_IREQUIRE((which() == Type::INT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt32( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT32); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isInt64() const { + return which() == Type::INT64; +} +inline bool Type::Builder::isInt64() { + return which() == Type::INT64; +} +inline ::capnp::Void Type::Reader::getInt64() const { + KJ_IREQUIRE((which() == Type::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getInt64() { + KJ_IREQUIRE((which() == Type::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setInt64( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT64); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint8() const { + return which() == Type::UINT8; +} +inline bool Type::Builder::isUint8() { + return which() == Type::UINT8; +} +inline ::capnp::Void Type::Reader::getUint8() const { + KJ_IREQUIRE((which() == Type::UINT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint8() { + KJ_IREQUIRE((which() == Type::UINT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint8( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT8); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint16() const { + return which() == Type::UINT16; +} +inline bool Type::Builder::isUint16() { + return which() == Type::UINT16; +} +inline ::capnp::Void Type::Reader::getUint16() const { + KJ_IREQUIRE((which() == Type::UINT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint16() { + KJ_IREQUIRE((which() == Type::UINT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint16( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT16); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint32() const { + return which() == Type::UINT32; +} +inline bool Type::Builder::isUint32() { + return which() == Type::UINT32; +} +inline ::capnp::Void Type::Reader::getUint32() const { + KJ_IREQUIRE((which() == Type::UINT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint32() { + KJ_IREQUIRE((which() == Type::UINT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint32( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT32); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isUint64() const { + return which() == Type::UINT64; +} +inline bool Type::Builder::isUint64() { + return which() == Type::UINT64; +} +inline ::capnp::Void Type::Reader::getUint64() const { + KJ_IREQUIRE((which() == Type::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getUint64() { + KJ_IREQUIRE((which() == Type::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setUint64( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT64); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isFloat32() const { + return which() == Type::FLOAT32; +} +inline bool Type::Builder::isFloat32() { + return which() == Type::FLOAT32; +} +inline ::capnp::Void Type::Reader::getFloat32() const { + KJ_IREQUIRE((which() == Type::FLOAT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getFloat32() { + KJ_IREQUIRE((which() == Type::FLOAT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setFloat32( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::FLOAT32); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isFloat64() const { + return which() == Type::FLOAT64; +} +inline bool Type::Builder::isFloat64() { + return which() == Type::FLOAT64; +} +inline ::capnp::Void Type::Reader::getFloat64() const { + KJ_IREQUIRE((which() == Type::FLOAT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getFloat64() { + KJ_IREQUIRE((which() == Type::FLOAT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setFloat64( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::FLOAT64); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isText() const { + return which() == Type::TEXT; +} +inline bool Type::Builder::isText() { + return which() == Type::TEXT; +} +inline ::capnp::Void Type::Reader::getText() const { + KJ_IREQUIRE((which() == Type::TEXT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getText() { + KJ_IREQUIRE((which() == Type::TEXT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setText( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::TEXT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isData() const { + return which() == Type::DATA; +} +inline bool Type::Builder::isData() { + return which() == Type::DATA; +} +inline ::capnp::Void Type::Reader::getData() const { + KJ_IREQUIRE((which() == Type::DATA), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::Builder::getData() { + KJ_IREQUIRE((which() == Type::DATA), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::Builder::setData( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::DATA); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Reader::isList() const { + return which() == Type::LIST; +} +inline bool Type::Builder::isList() { + return which() == Type::LIST; +} +inline typename Type::List::Reader Type::Reader::getList() const { + KJ_IREQUIRE((which() == Type::LIST), + "Must check which() before get()ing a union member."); + return typename Type::List::Reader(_reader); +} +inline typename Type::List::Builder Type::Builder::getList() { + KJ_IREQUIRE((which() == Type::LIST), + "Must check which() before get()ing a union member."); + return typename Type::List::Builder(_builder); +} +inline typename Type::List::Builder Type::Builder::initList() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::LIST); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::List::Builder(_builder); +} +inline bool Type::Reader::isEnum() const { + return which() == Type::ENUM; +} +inline bool Type::Builder::isEnum() { + return which() == Type::ENUM; +} +inline typename Type::Enum::Reader Type::Reader::getEnum() const { + KJ_IREQUIRE((which() == Type::ENUM), + "Must check which() before get()ing a union member."); + return typename Type::Enum::Reader(_reader); +} +inline typename Type::Enum::Builder Type::Builder::getEnum() { + KJ_IREQUIRE((which() == Type::ENUM), + "Must check which() before get()ing a union member."); + return typename Type::Enum::Builder(_builder); +} +inline typename Type::Enum::Builder Type::Builder::initEnum() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::ENUM); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::Enum::Builder(_builder); +} +inline bool Type::Reader::isStruct() const { + return which() == Type::STRUCT; +} +inline bool Type::Builder::isStruct() { + return which() == Type::STRUCT; +} +inline typename Type::Struct::Reader Type::Reader::getStruct() const { + KJ_IREQUIRE((which() == Type::STRUCT), + "Must check which() before get()ing a union member."); + return typename Type::Struct::Reader(_reader); +} +inline typename Type::Struct::Builder Type::Builder::getStruct() { + KJ_IREQUIRE((which() == Type::STRUCT), + "Must check which() before get()ing a union member."); + return typename Type::Struct::Builder(_builder); +} +inline typename Type::Struct::Builder Type::Builder::initStruct() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::STRUCT); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::Struct::Builder(_builder); +} +inline bool Type::Reader::isInterface() const { + return which() == Type::INTERFACE; +} +inline bool Type::Builder::isInterface() { + return which() == Type::INTERFACE; +} +inline typename Type::Interface::Reader Type::Reader::getInterface() const { + KJ_IREQUIRE((which() == Type::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Type::Interface::Reader(_reader); +} +inline typename Type::Interface::Builder Type::Builder::getInterface() { + KJ_IREQUIRE((which() == Type::INTERFACE), + "Must check which() before get()ing a union member."); + return typename Type::Interface::Builder(_builder); +} +inline typename Type::Interface::Builder Type::Builder::initInterface() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INTERFACE); + _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); + _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); + return typename Type::Interface::Builder(_builder); +} +inline bool Type::Reader::isAnyPointer() const { + return which() == Type::ANY_POINTER; +} +inline bool Type::Builder::isAnyPointer() { + return which() == Type::ANY_POINTER; +} +inline typename Type::AnyPointer::Reader Type::Reader::getAnyPointer() const { + KJ_IREQUIRE((which() == Type::ANY_POINTER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Reader(_reader); +} +inline typename Type::AnyPointer::Builder Type::Builder::getAnyPointer() { + KJ_IREQUIRE((which() == Type::ANY_POINTER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Builder(_builder); +} +inline typename Type::AnyPointer::Builder Type::Builder::initAnyPointer() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::ANY_POINTER); + _builder.setDataField< ::uint16_t>(::capnp::bounded<4>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Builder(_builder); +} +inline bool Type::List::Reader::hasElementType() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::List::Builder::hasElementType() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Type::List::Reader::getElementType() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Type::List::Builder::getElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Type::Pipeline Type::List::Pipeline::getElementType() { + return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::List::Builder::setElementType( ::capnp::schema::Type::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Type::List::Builder::initElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::List::Builder::adoptElementType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Type::List::Builder::disownElementType() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Enum::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Enum::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Type::Enum::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Enum::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::Enum::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Enum::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Enum::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Enum::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Enum::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Enum::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::Enum::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Enum::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Struct::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Struct::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Type::Struct::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Struct::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::Struct::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Struct::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Struct::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Struct::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Struct::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Struct::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::Struct::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Struct::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::uint64_t Type::Interface::Reader::getTypeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::Interface::Builder::getTypeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Type::Interface::Builder::setTypeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::Interface::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Type::Interface::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Type::Interface::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Type::Interface::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Type::Interface::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Type::Interface::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Type::Interface::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Type::Interface::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Interface::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} + +inline bool Type::AnyPointer::Reader::isUnconstrained() const { + return which() == Type::AnyPointer::UNCONSTRAINED; +} +inline bool Type::AnyPointer::Builder::isUnconstrained() { + return which() == Type::AnyPointer::UNCONSTRAINED; +} +inline typename Type::AnyPointer::Unconstrained::Reader Type::AnyPointer::Reader::getUnconstrained() const { + KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Unconstrained::Reader(_reader); +} +inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::getUnconstrained() { + KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Unconstrained::Builder(_builder); +} +inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::initUnconstrained() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::UNCONSTRAINED); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Unconstrained::Builder(_builder); +} +inline bool Type::AnyPointer::Reader::isParameter() const { + return which() == Type::AnyPointer::PARAMETER; +} +inline bool Type::AnyPointer::Builder::isParameter() { + return which() == Type::AnyPointer::PARAMETER; +} +inline typename Type::AnyPointer::Parameter::Reader Type::AnyPointer::Reader::getParameter() const { + KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Parameter::Reader(_reader); +} +inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::getParameter() { + KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::Parameter::Builder(_builder); +} +inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::initParameter() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::PARAMETER); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::Parameter::Builder(_builder); +} +inline bool Type::AnyPointer::Reader::isImplicitMethodParameter() const { + return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; +} +inline bool Type::AnyPointer::Builder::isImplicitMethodParameter() { + return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Reader Type::AnyPointer::Reader::getImplicitMethodParameter() const { + KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::ImplicitMethodParameter::Reader(_reader); +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::getImplicitMethodParameter() { + KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), + "Must check which() before get()ing a union member."); + return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); +} +inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::initImplicitMethodParameter() { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::IMPLICIT_METHOD_PARAMETER); + _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); + return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); +} +inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isAnyKind() const { + return which() == Type::AnyPointer::Unconstrained::ANY_KIND; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isAnyKind() { + return which() == Type::AnyPointer::Unconstrained::ANY_KIND; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getAnyKind() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getAnyKind() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setAnyKind( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::ANY_KIND); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isStruct() const { + return which() == Type::AnyPointer::Unconstrained::STRUCT; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isStruct() { + return which() == Type::AnyPointer::Unconstrained::STRUCT; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getStruct() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getStruct() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setStruct( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::STRUCT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isList() const { + return which() == Type::AnyPointer::Unconstrained::LIST; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isList() { + return which() == Type::AnyPointer::Unconstrained::LIST; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getList() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getList() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setList( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::LIST); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Type::AnyPointer::Unconstrained::Reader::isCapability() const { + return which() == Type::AnyPointer::Unconstrained::CAPABILITY; +} +inline bool Type::AnyPointer::Unconstrained::Builder::isCapability() { + return which() == Type::AnyPointer::Unconstrained::CAPABILITY; +} +inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getCapability() const { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getCapability() { + KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Unconstrained::Builder::setCapability( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::CAPABILITY); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint64_t Type::AnyPointer::Parameter::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Type::AnyPointer::Parameter::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Parameter::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Type::AnyPointer::Parameter::Reader::getParameterIndex() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Type::AnyPointer::Parameter::Builder::getParameterIndex() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::Parameter::Builder::setParameterIndex( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, value); +} + +inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Reader::getParameterIndex() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Builder::getParameterIndex() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS); +} +inline void Type::AnyPointer::ImplicitMethodParameter::Builder::setParameterIndex( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<5>() * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Reader::hasScopes() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Builder::hasScopes() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Reader Brand::Reader::getScopes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Builder Brand::Builder::getScopes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Builder::setScopes( ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>::Builder Brand::Builder::initScopes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Brand::Builder::adoptScopes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>> Brand::Builder::disownScopes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Brand::Scope::Reader::getScopeId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Brand::Scope::Builder::getScopeId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Brand::Scope::Builder::setScopeId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Scope::Reader::isBind() const { + return which() == Brand::Scope::BIND; +} +inline bool Brand::Scope::Builder::isBind() { + return which() == Brand::Scope::BIND; +} +inline bool Brand::Scope::Reader::hasBind() const { + if (which() != Brand::Scope::BIND) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Scope::Builder::hasBind() { + if (which() != Brand::Scope::BIND) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Reader Brand::Scope::Reader::getBind() const { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Builder Brand::Scope::Builder::getBind() { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Scope::Builder::setBind( ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Reader value) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>::Builder Brand::Scope::Builder::initBind(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Brand::Scope::Builder::adoptBind( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>&& value) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>> Brand::Scope::Builder::disownBind() { + KJ_IREQUIRE((which() == Brand::Scope::BIND), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Brand::Scope::Reader::isInherit() const { + return which() == Brand::Scope::INHERIT; +} +inline bool Brand::Scope::Builder::isInherit() { + return which() == Brand::Scope::INHERIT; +} +inline ::capnp::Void Brand::Scope::Reader::getInherit() const { + KJ_IREQUIRE((which() == Brand::Scope::INHERIT), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Brand::Scope::Builder::getInherit() { + KJ_IREQUIRE((which() == Brand::Scope::INHERIT), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Brand::Scope::Builder::setInherit( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::INHERIT); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Brand::Binding::Reader::isUnbound() const { + return which() == Brand::Binding::UNBOUND; +} +inline bool Brand::Binding::Builder::isUnbound() { + return which() == Brand::Binding::UNBOUND; +} +inline ::capnp::Void Brand::Binding::Reader::getUnbound() const { + KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Brand::Binding::Builder::getUnbound() { + KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Brand::Binding::Builder::setUnbound( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::UNBOUND); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Brand::Binding::Reader::isType() const { + return which() == Brand::Binding::TYPE; +} +inline bool Brand::Binding::Builder::isType() { + return which() == Brand::Binding::TYPE; +} +inline bool Brand::Binding::Reader::hasType() const { + if (which() != Brand::Binding::TYPE) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Brand::Binding::Builder::hasType() { + if (which() != Brand::Binding::TYPE) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Type::Reader Brand::Binding::Reader::getType() const { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Type::Builder Brand::Binding::Builder::getType() { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Binding::Builder::setType( ::capnp::schema::Type::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Type::Builder Brand::Binding::Builder::initType() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Brand::Binding::Builder::adoptType( + ::capnp::Orphan< ::capnp::schema::Type>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); + ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Type> Brand::Binding::Builder::disownType() { + KJ_IREQUIRE((which() == Brand::Binding::TYPE), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline ::capnp::schema::Value::Which Value::Reader::which() const { + return _reader.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline ::capnp::schema::Value::Which Value::Builder::which() { + return _builder.getDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline bool Value::Reader::isVoid() const { + return which() == Value::VOID; +} +inline bool Value::Builder::isVoid() { + return which() == Value::VOID; +} +inline ::capnp::Void Value::Reader::getVoid() const { + KJ_IREQUIRE((which() == Value::VOID), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Value::Builder::getVoid() { + KJ_IREQUIRE((which() == Value::VOID), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setVoid( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::VOID); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isBool() const { + return which() == Value::BOOL; +} +inline bool Value::Builder::isBool() { + return which() == Value::BOOL; +} +inline bool Value::Reader::getBool() const { + KJ_IREQUIRE((which() == Value::BOOL), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS); +} + +inline bool Value::Builder::getBool() { + KJ_IREQUIRE((which() == Value::BOOL), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setBool(bool value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::BOOL); + _builder.setDataField( + ::capnp::bounded<16>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt8() const { + return which() == Value::INT8; +} +inline bool Value::Builder::isInt8() { + return which() == Value::INT8; +} +inline ::int8_t Value::Reader::getInt8() const { + KJ_IREQUIRE((which() == Value::INT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::int8_t Value::Builder::getInt8() { + KJ_IREQUIRE((which() == Value::INT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt8( ::int8_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT8); + _builder.setDataField< ::int8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt16() const { + return which() == Value::INT16; +} +inline bool Value::Builder::isInt16() { + return which() == Value::INT16; +} +inline ::int16_t Value::Reader::getInt16() const { + KJ_IREQUIRE((which() == Value::INT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int16_t Value::Builder::getInt16() { + KJ_IREQUIRE((which() == Value::INT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt16( ::int16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT16); + _builder.setDataField< ::int16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt32() const { + return which() == Value::INT32; +} +inline bool Value::Builder::isInt32() { + return which() == Value::INT32; +} +inline ::int32_t Value::Reader::getInt32() const { + KJ_IREQUIRE((which() == Value::INT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int32_t Value::Builder::getInt32() { + KJ_IREQUIRE((which() == Value::INT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt32( ::int32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT32); + _builder.setDataField< ::int32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isInt64() const { + return which() == Value::INT64; +} +inline bool Value::Builder::isInt64() { + return which() == Value::INT64; +} +inline ::int64_t Value::Reader::getInt64() const { + KJ_IREQUIRE((which() == Value::INT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::int64_t Value::Builder::getInt64() { + KJ_IREQUIRE((which() == Value::INT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInt64( ::int64_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT64); + _builder.setDataField< ::int64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint8() const { + return which() == Value::UINT8; +} +inline bool Value::Builder::isUint8() { + return which() == Value::UINT8; +} +inline ::uint8_t Value::Reader::getUint8() const { + KJ_IREQUIRE((which() == Value::UINT8), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint8_t Value::Builder::getUint8() { + KJ_IREQUIRE((which() == Value::UINT8), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint8( ::uint8_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT8); + _builder.setDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint16() const { + return which() == Value::UINT16; +} +inline bool Value::Builder::isUint16() { + return which() == Value::UINT16; +} +inline ::uint16_t Value::Reader::getUint16() const { + KJ_IREQUIRE((which() == Value::UINT16), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Value::Builder::getUint16() { + KJ_IREQUIRE((which() == Value::UINT16), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint16( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT16); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint32() const { + return which() == Value::UINT32; +} +inline bool Value::Builder::isUint32() { + return which() == Value::UINT32; +} +inline ::uint32_t Value::Reader::getUint32() const { + KJ_IREQUIRE((which() == Value::UINT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint32_t Value::Builder::getUint32() { + KJ_IREQUIRE((which() == Value::UINT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint32( ::uint32_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT32); + _builder.setDataField< ::uint32_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isUint64() const { + return which() == Value::UINT64; +} +inline bool Value::Builder::isUint64() { + return which() == Value::UINT64; +} +inline ::uint64_t Value::Reader::getUint64() const { + KJ_IREQUIRE((which() == Value::UINT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Value::Builder::getUint64() { + KJ_IREQUIRE((which() == Value::UINT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setUint64( ::uint64_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT64); + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isFloat32() const { + return which() == Value::FLOAT32; +} +inline bool Value::Builder::isFloat32() { + return which() == Value::FLOAT32; +} +inline float Value::Reader::getFloat32() const { + KJ_IREQUIRE((which() == Value::FLOAT32), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline float Value::Builder::getFloat32() { + KJ_IREQUIRE((which() == Value::FLOAT32), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setFloat32(float value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::FLOAT32); + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isFloat64() const { + return which() == Value::FLOAT64; +} +inline bool Value::Builder::isFloat64() { + return which() == Value::FLOAT64; +} +inline double Value::Reader::getFloat64() const { + KJ_IREQUIRE((which() == Value::FLOAT64), + "Must check which() before get()ing a union member."); + return _reader.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline double Value::Builder::getFloat64() { + KJ_IREQUIRE((which() == Value::FLOAT64), + "Must check which() before get()ing a union member."); + return _builder.getDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setFloat64(double value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::FLOAT64); + _builder.setDataField( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isText() const { + return which() == Value::TEXT; +} +inline bool Value::Builder::isText() { + return which() == Value::TEXT; +} +inline bool Value::Reader::hasText() const { + if (which() != Value::TEXT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasText() { + if (which() != Value::TEXT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader Value::Reader::getText() const { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder Value::Builder::getText() { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Value::Builder::setText( ::capnp::Text::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder Value::Builder::initText(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Value::Builder::adoptText( + ::capnp::Orphan< ::capnp::Text>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> Value::Builder::disownText() { + KJ_IREQUIRE((which() == Value::TEXT), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Value::Reader::isData() const { + return which() == Value::DATA; +} +inline bool Value::Builder::isData() { + return which() == Value::DATA; +} +inline bool Value::Reader::hasData() const { + if (which() != Value::DATA) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasData() { + if (which() != Value::DATA) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Data::Reader Value::Reader::getData() const { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Data::Builder Value::Builder::getData() { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Value::Builder::setData( ::capnp::Data::Reader value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); + ::capnp::_::PointerHelpers< ::capnp::Data>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Data::Builder Value::Builder::initData(unsigned int size) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); + return ::capnp::_::PointerHelpers< ::capnp::Data>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void Value::Builder::adoptData( + ::capnp::Orphan< ::capnp::Data>&& value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); + ::capnp::_::PointerHelpers< ::capnp::Data>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Data> Value::Builder::disownData() { + KJ_IREQUIRE((which() == Value::DATA), + "Must check which() before get()ing a union member."); + return ::capnp::_::PointerHelpers< ::capnp::Data>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Value::Reader::isList() const { + return which() == Value::LIST; +} +inline bool Value::Builder::isList() { + return which() == Value::LIST; +} +inline bool Value::Reader::hasList() const { + if (which() != Value::LIST) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasList() { + if (which() != Value::LIST) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getList() const { + KJ_IREQUIRE((which() == Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getList() { + KJ_IREQUIRE((which() == Value::LIST), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initList() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::LIST); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Value::Reader::isEnum() const { + return which() == Value::ENUM; +} +inline bool Value::Builder::isEnum() { + return which() == Value::ENUM; +} +inline ::uint16_t Value::Reader::getEnum() const { + KJ_IREQUIRE((which() == Value::ENUM), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t Value::Builder::getEnum() { + KJ_IREQUIRE((which() == Value::ENUM), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setEnum( ::uint16_t value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ENUM); + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isStruct() const { + return which() == Value::STRUCT; +} +inline bool Value::Builder::isStruct() { + return which() == Value::STRUCT; +} +inline bool Value::Reader::hasStruct() const { + if (which() != Value::STRUCT) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasStruct() { + if (which() != Value::STRUCT) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getStruct() const { + KJ_IREQUIRE((which() == Value::STRUCT), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getStruct() { + KJ_IREQUIRE((which() == Value::STRUCT), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initStruct() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::STRUCT); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline bool Value::Reader::isInterface() const { + return which() == Value::INTERFACE; +} +inline bool Value::Builder::isInterface() { + return which() == Value::INTERFACE; +} +inline ::capnp::Void Value::Reader::getInterface() const { + KJ_IREQUIRE((which() == Value::INTERFACE), + "Must check which() before get()ing a union member."); + return _reader.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::capnp::Void Value::Builder::getInterface() { + KJ_IREQUIRE((which() == Value::INTERFACE), + "Must check which() before get()ing a union member."); + return _builder.getDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Value::Builder::setInterface( ::capnp::Void value) { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INTERFACE); + _builder.setDataField< ::capnp::Void>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Value::Reader::isAnyPointer() const { + return which() == Value::ANY_POINTER; +} +inline bool Value::Builder::isAnyPointer() { + return which() == Value::ANY_POINTER; +} +inline bool Value::Reader::hasAnyPointer() const { + if (which() != Value::ANY_POINTER) return false; + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Value::Builder::hasAnyPointer() { + if (which() != Value::ANY_POINTER) return false; + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::AnyPointer::Reader Value::Reader::getAnyPointer() const { + KJ_IREQUIRE((which() == Value::ANY_POINTER), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Reader(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::getAnyPointer() { + KJ_IREQUIRE((which() == Value::ANY_POINTER), + "Must check which() before get()ing a union member."); + return ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::AnyPointer::Builder Value::Builder::initAnyPointer() { + _builder.setDataField( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ANY_POINTER); + auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); + result.clear(); + return result; +} + +inline ::uint64_t Annotation::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t Annotation::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void Annotation::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool Annotation::Reader::hasValue() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool Annotation::Builder::hasValue() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Value::Reader Annotation::Reader::getValue() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Value::Builder Annotation::Builder::getValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Value::Pipeline Annotation::Pipeline::getValue() { + return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(0)); +} +#endif // !CAPNP_LITE +inline void Annotation::Builder::setValue( ::capnp::schema::Value::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Value::Builder Annotation::Builder::initValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void Annotation::Builder::adoptValue( + ::capnp::Orphan< ::capnp::schema::Value>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Value> Annotation::Builder::disownValue() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool Annotation::Reader::hasBrand() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool Annotation::Builder::hasBrand() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::Brand::Reader Annotation::Reader::getBrand() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::Brand::Builder Annotation::Builder::getBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::Brand::Pipeline Annotation::Pipeline::getBrand() { + return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(1)); +} +#endif // !CAPNP_LITE +inline void Annotation::Builder::setBrand( ::capnp::schema::Brand::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::Brand::Builder Annotation::Builder::initBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void Annotation::Builder::adoptBrand( + ::capnp::Orphan< ::capnp::schema::Brand>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::Brand> Annotation::Builder::disownBrand() { + return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint16_t CapnpVersion::Reader::getMajor() const { + return _reader.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint16_t CapnpVersion::Builder::getMajor() { + return _builder.getDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CapnpVersion::Builder::setMajor( ::uint16_t value) { + _builder.setDataField< ::uint16_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline ::uint8_t CapnpVersion::Reader::getMinor() const { + return _reader.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} + +inline ::uint8_t CapnpVersion::Builder::getMinor() { + return _builder.getDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS); +} +inline void CapnpVersion::Builder::setMinor( ::uint8_t value) { + _builder.setDataField< ::uint8_t>( + ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); +} + +inline ::uint8_t CapnpVersion::Reader::getMicro() const { + return _reader.getDataField< ::uint8_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} + +inline ::uint8_t CapnpVersion::Builder::getMicro() { + return _builder.getDataField< ::uint8_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS); +} +inline void CapnpVersion::Builder::setMicro( ::uint8_t value) { + _builder.setDataField< ::uint8_t>( + ::capnp::bounded<3>() * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::Reader::hasNodes() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasNodes() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Reader CodeGeneratorRequest::Reader::getNodes() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::Builder::getNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setNodes( ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::Builder::initNodes(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptNodes( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>> CodeGeneratorRequest::Builder::disownNodes() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasRequestedFiles() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasRequestedFiles() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Reader CodeGeneratorRequest::Reader::getRequestedFiles() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::Builder::getRequestedFiles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::Builder::initRequestedFiles(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptRequestedFiles( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>> CodeGeneratorRequest::Builder::disownRequestedFiles() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasCapnpVersion() const { + return !_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasCapnpVersion() { + return !_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::schema::CapnpVersion::Reader CodeGeneratorRequest::Reader::getCapnpVersion() const { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::get(_reader.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline ::capnp::schema::CapnpVersion::Builder CodeGeneratorRequest::Builder::getCapnpVersion() { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::get(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +#if !CAPNP_LITE +inline ::capnp::schema::CapnpVersion::Pipeline CodeGeneratorRequest::Pipeline::getCapnpVersion() { + return ::capnp::schema::CapnpVersion::Pipeline(_typeless.getPointerField(2)); +} +#endif // !CAPNP_LITE +inline void CodeGeneratorRequest::Builder::setCapnpVersion( ::capnp::schema::CapnpVersion::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::set(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), value); +} +inline ::capnp::schema::CapnpVersion::Builder CodeGeneratorRequest::Builder::initCapnpVersion() { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::init(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::adoptCapnpVersion( + ::capnp::Orphan< ::capnp::schema::CapnpVersion>&& value) { + ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::adopt(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::schema::CapnpVersion> CodeGeneratorRequest::Builder::disownCapnpVersion() { + return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::disown(_builder.getPointerField( + ::capnp::bounded<2>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::Reader::hasSourceInfo() const { + return !_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::Builder::hasSourceInfo() { + return !_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Reader CodeGeneratorRequest::Reader::getSourceInfo() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::Builder::getSourceInfo() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::Builder::setSourceInfo( ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::Builder::initSourceInfo(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::Builder::adoptSourceInfo( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>> CodeGeneratorRequest::Builder::disownSourceInfo() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::SourceInfo, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<3>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::RequestedFile::Reader::hasFilename() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Builder::hasFilename() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Reader::getFilename() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::getFilename() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setFilename( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::initFilename(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::adoptFilename( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Builder::disownFilename() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +inline bool CodeGeneratorRequest::RequestedFile::Reader::hasImports() const { + return !_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Builder::hasImports() { + return !_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Reader CodeGeneratorRequest::RequestedFile::Reader::getImports() const { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>::get(_reader.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::RequestedFile::Builder::getImports() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>::get(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>::set(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), value); +} +inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>::Builder CodeGeneratorRequest::RequestedFile::Builder::initImports(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>::init(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Builder::adoptImports( + ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>&& value) { + ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>> CodeGeneratorRequest::RequestedFile::Builder::disownImports() { + return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import, ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField( + ::capnp::bounded<1>() * ::capnp::POINTERS)); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Reader::getId() const { + return _reader.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} + +inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Builder::getId() { + return _builder.getDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setId( ::uint64_t value) { + _builder.setDataField< ::uint64_t>( + ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); +} + +inline bool CodeGeneratorRequest::RequestedFile::Import::Reader::hasName() const { + return !_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline bool CodeGeneratorRequest::RequestedFile::Import::Builder::hasName() { + return !_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); +} +inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Import::Reader::getName() const { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::getName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setName( ::capnp::Text::Reader value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), value); +} +inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::initName(unsigned int size) { + return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), size); +} +inline void CodeGeneratorRequest::RequestedFile::Import::Builder::adoptName( + ::capnp::Orphan< ::capnp::Text>&& value) { + ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); +} +inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Import::Builder::disownName() { + return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( + ::capnp::bounded<0>() * ::capnp::POINTERS)); +} + +} // namespace +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.h new file mode 100644 index 000000000..5eebacba2 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/schema.h @@ -0,0 +1,1019 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#if CAPNP_LITE +#error "Reflection APIs, including this header, are not available in lite mode." +#endif + +#undef CONST +// For some ridiculous reason, Windows defines CONST to const. We have an enum value called CONST +// in schema.capnp.h, so if this is defined, compilation is gonna fail. So we undef it because +// that seems strictly better than failing entirely. But this could cause trouble for people later +// on if they, say, include windows.h, then include schema.h, then include another windows API +// header that uses CONST. I suppose they may have to re-#define CONST in between, or change the +// header ordering. Sorry. +// +// Please don't file a bug report telling us to change our enum naming style. You are at least +// seven years too late. + +#include +#include +#include // work-around macro conflict with `VOID` + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class Schema; +class StructSchema; +class EnumSchema; +class InterfaceSchema; +class ConstSchema; +class ListSchema; +class Type; + +template ()> struct SchemaType_ { typedef Schema Type; }; +template struct SchemaType_ { typedef schema::Type::Which Type; }; +template struct SchemaType_ { typedef schema::Type::Which Type; }; +template struct SchemaType_ { typedef EnumSchema Type; }; +template struct SchemaType_ { typedef StructSchema Type; }; +template struct SchemaType_ { typedef InterfaceSchema Type; }; +template struct SchemaType_ { typedef ListSchema Type; }; + +template +using SchemaType = typename SchemaType_::Type; +// SchemaType is the type of T's schema, e.g. StructSchema if T is a struct. + +namespace _ { // private +extern const RawSchema NULL_SCHEMA; +extern const RawSchema NULL_STRUCT_SCHEMA; +extern const RawSchema NULL_ENUM_SCHEMA; +extern const RawSchema NULL_INTERFACE_SCHEMA; +extern const RawSchema NULL_CONST_SCHEMA; +// The schema types default to these null (empty) schemas in case of error, especially when +// exceptions are disabled. +} // namespace _ (private) + +class Schema { + // Convenience wrapper around capnp::schema::Node. + +public: + inline Schema(): raw(&_::NULL_SCHEMA.defaultBrand) {} + + template + static inline SchemaType from() { return SchemaType::template fromImpl(); } + // Get the Schema for a particular compiled-in type. + + schema::Node::Reader getProto() const; + // Get the underlying Cap'n Proto representation of the schema node. (Note that this accessor + // has performance comparable to accessors of struct-typed fields on Reader classes.) + + kj::ArrayPtr asUncheckedMessage() const; + // Get the encoded schema node content as a single message segment. It is safe to read as an + // unchecked message. + + Schema getDependency(uint64_t id) const CAPNP_DEPRECATED("Does not handle generics correctly."); + // DEPRECATED: This method cannot correctly account for generic type parameter bindings that + // may apply to the dependency. Instead of using this method, use a method of the Schema API + // that corresponds to the exact kind of dependency. For example, to get a field type, use + // StructSchema::Field::getType(). + // + // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a + // struct, you could look up the schema for one of its fields' types. Throws an exception if this + // schema doesn't actually depend on the given id. + // + // Note that not all type IDs found in the schema node are considered "dependencies" -- only the + // ones that are needed to implement the dynamic API are. That includes: + // - Field types. + // - Group types. + // - scopeId for group nodes, but NOT otherwise. + // - Method parameter and return types. + // + // The following are NOT considered dependencies: + // - Nested nodes. + // - scopeId for a non-group node. + // - Annotations. + // + // To obtain schemas for those, you would need a SchemaLoader. + + bool isBranded() const; + // Returns true if this schema represents a non-default parameterization of this type. + + Schema getGeneric() const; + // Get the version of this schema with any brands removed. + + class BrandArgumentList; + BrandArgumentList getBrandArgumentsAtScope(uint64_t scopeId) const; + // Gets the values bound to the brand parameters at the given scope. + + kj::Array getGenericScopeIds() const; + // Returns the type IDs of all parent scopes that have generic parameters, to which this type is + // subject. + + StructSchema asStruct() const; + EnumSchema asEnum() const; + InterfaceSchema asInterface() const; + ConstSchema asConst() const; + // Cast the Schema to a specific type. Throws an exception if the type doesn't match. Use + // getProto() to determine type, e.g. getProto().isStruct(). + + inline bool operator==(const Schema& other) const { return raw == other.raw; } + inline bool operator!=(const Schema& other) const { return raw != other.raw; } + // Determine whether two Schemas are wrapping the exact same underlying data, by identity. If + // you want to check if two Schemas represent the same type (but possibly different versions of + // it), compare their IDs instead. + + inline uint hashCode() const { return kj::hashCode(raw); } + + template + void requireUsableAs() const; + // Throws an exception if a value with this Schema cannot safely be cast to a native value of + // the given type. This passes if either: + // - *this == from() + // - This schema was loaded with SchemaLoader, the type ID matches typeId(), and + // loadCompiledTypeAndDependencies() was called on the SchemaLoader. + + kj::StringPtr getShortDisplayName() const; + // Get the short version of the node's display name. + + const kj::StringPtr getUnqualifiedName() const; + // Get the display name "nickname" of this node minus the prefix + +private: + const _::RawBrandedSchema* raw; + + inline explicit Schema(const _::RawBrandedSchema* raw): raw(raw) { + KJ_IREQUIRE(raw->lazyInitializer == nullptr, + "Must call ensureInitialized() on RawSchema before constructing Schema."); + } + + template static inline Schema fromImpl() { + return Schema(&_::rawSchema()); + } + + void requireUsableAs(const _::RawSchema* expected) const; + + uint32_t getSchemaOffset(const schema::Value::Reader& value) const; + + Type getBrandBinding(uint64_t scopeId, uint index) const; + // Look up the binding for a brand parameter used by this Schema. Returns `AnyPointer` if the + // parameter is not bound. + // + // TODO(someday): Public interface for iterating over all bindings? + + Schema getDependency(uint64_t id, uint location) const; + // Look up schema for a particular dependency of this schema. `location` is the dependency + // location number as defined in _::RawBrandedSchema. + + Type interpretType(schema::Type::Reader proto, uint location) const; + // Interpret a schema::Type in the given location within the schema, compiling it into a + // Type object. + + friend class StructSchema; + friend class EnumSchema; + friend class InterfaceSchema; + friend class ConstSchema; + friend class ListSchema; + friend class SchemaLoader; + friend class Type; + friend kj::StringTree _::structString( + _::StructReader reader, const _::RawBrandedSchema& schema); + friend kj::String _::enumString(uint16_t value, const _::RawBrandedSchema& schema); +}; + +kj::StringPtr KJ_STRINGIFY(const Schema& schema); + +class Schema::BrandArgumentList { + // A list of generic parameter bindings for parameters of some particular type. Note that since + // parameters on an outer type apply to all inner types as well, a deeply-nested type can have + // multiple BrandArgumentLists that apply to it. + // + // A BrandArgumentList only represents the arguments that the client of the type specified. Since + // new parameters can be added over time, this list may not cover all defined parameters for the + // type. Missing parameters should be treated as AnyPointer. This class's implementation of + // operator[] already does this for you; out-of-bounds access will safely return AnyPointer. + +public: + inline BrandArgumentList(): scopeId(0), size_(0), bindings(nullptr) {} + + inline uint size() const { return size_; } + Type operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + uint64_t scopeId; + uint size_; + bool isUnbound; + const _::RawBrandedSchema::Binding* bindings; + + inline BrandArgumentList(uint64_t scopeId, bool isUnbound) + : scopeId(scopeId), size_(0), isUnbound(isUnbound), bindings(nullptr) {} + inline BrandArgumentList(uint64_t scopeId, uint size, + const _::RawBrandedSchema::Binding* bindings) + : scopeId(scopeId), size_(size), isUnbound(false), bindings(bindings) {} + + friend class Schema; +}; + +// ------------------------------------------------------------------- + +class StructSchema: public Schema { +public: + inline StructSchema(): Schema(&_::NULL_STRUCT_SCHEMA.defaultBrand) {} + + class Field; + class FieldList; + class FieldSubset; + + FieldList getFields() const; + // List top-level fields of this struct. This list will contain top-level groups (including + // named unions) but not the members of those groups. The list does, however, contain the + // members of the unnamed union, if there is one. + + FieldSubset getUnionFields() const; + // If the field contains an unnamed union, get a list of fields in the union, ordered by + // ordinal. Since discriminant values are assigned sequentially by ordinal, you may index this + // list by discriminant value. + + FieldSubset getNonUnionFields() const; + // Get the fields of this struct which are not in an unnamed union, ordered by ordinal. + + kj::Maybe findFieldByName(kj::StringPtr name) const; + // Find the field with the given name, or return null if there is no such field. If the struct + // contains an unnamed union, then this will find fields of that union in addition to fields + // of the outer struct, since they exist in the same namespace. It will not, however, find + // members of groups (including named unions) -- you must first look up the group itself, + // then dig into its type. + + Field getFieldByName(kj::StringPtr name) const; + // Like findFieldByName() but throws an exception on failure. + + kj::Maybe getFieldByDiscriminant(uint16_t discriminant) const; + // Finds the field whose `discriminantValue` is equal to the given value, or returns null if + // there is no such field. (If the schema does not represent a union or a struct containing + // an unnamed union, then this always returns null.) + + bool isStreamResult() const; + // Convenience method to check if this is the result type of a streaming RPC method. + + bool mayContainCapabilities() const { return raw->generic->mayContainCapabilities; } + // Returns true if a struct of this type may transitively contain any capabilities. I.e., are + // any of the fields an interface type, or a struct type that may in turn contain capabilities? + // + // This is meant for optimizations where various bookkeeping can possibly be skipped if it is + // known in advance that there are no capabilities. Note that this may conservatively return true + // spuriously, e.g. if it would be inconvenient to compute the correct answer. A false positive + // should never cause incorrect behavior, just potentially hurt performance. + // + // It's important to keep in mind that even if a schema has no capability-typed fields today, + // they could always be added in future versions of the schema. So, just because the schema + // doesn't contain capabilities does NOT necessarily mean that an instance of the struct can't + // contain capabilities. However, it is a pretty good hint that the application won't plan to + // use such capabilities -- for example, if there are no caps in an RPC call's response type + // according to the client's version of the schema, then the client clearly isn't going to try + // to make any pipelined calls. The server could be operating with a new version of the schema + // and could actually return capabilities, but for the client to make a pipelined call, the + // client would have to know in advance that capabilities could be returned. + +private: + StructSchema(Schema base): Schema(base) {} + template static inline StructSchema fromImpl() { + return StructSchema(Schema(&_::rawBrandedSchema())); + } + friend class Schema; + friend class Type; +}; + +class StructSchema::Field { +public: + Field() = default; + + inline schema::Field::Reader getProto() const { return proto; } + inline StructSchema getContainingStruct() const { return parent; } + + inline uint getIndex() const { return index; } + // Get the index of this field within the containing struct or union. + + Type getType() const; + // Get the type of this field. Note that this is preferred over getProto().getType() as this + // method will apply generics. + + uint32_t getDefaultValueSchemaOffset() const; + // For struct, list, and object fields, returns the offset, in words, within the first segment of + // the struct's schema, where this field's default value pointer is located. The schema is + // always stored as a single-segment unchecked message, which in turn means that the default + // value pointer itself can be treated as the root of an unchecked message -- if you know where + // to find it, which is what this method helps you with. + // + // For blobs, returns the offset of the beginning of the blob's content within the first segment + // of the struct's schema. + // + // This is primarily useful for code generators. The C++ code generator, for example, embeds + // the entire schema as a raw word array within the generated code. Of course, to implement + // field accessors, it needs access to those fields' default values. Embedding separate copies + // of those default values would be redundant since they are already included in the schema, but + // seeking through the schema at runtime to find the default values would be ugly. Instead, + // the code generator can use getDefaultValueSchemaOffset() to find the offset of the default + // value within the schema, and can simply apply that offset at runtime. + // + // If the above does not make sense, you probably don't need this method. + + inline bool operator==(const Field& other) const; + inline bool operator!=(const Field& other) const { return !(*this == other); } + inline uint hashCode() const; + +private: + StructSchema parent; + uint index; + schema::Field::Reader proto; + + inline Field(StructSchema parent, uint index, schema::Field::Reader proto) + : parent(parent), index(index), proto(proto) {} + + friend class StructSchema; +}; + +kj::StringPtr KJ_STRINGIFY(const StructSchema::Field& field); + +class StructSchema::FieldList { +public: + FieldList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Field operator[](uint index) const { return Field(parent, index, list[index]); } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + StructSchema parent; + List::Reader list; + + inline FieldList(StructSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class StructSchema; +}; + +class StructSchema::FieldSubset { +public: + FieldSubset() = default; // empty list + + inline uint size() const { return size_; } + inline Field operator[](uint index) const { + return Field(parent, indices[index], list[indices[index]]); + } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + StructSchema parent; + List::Reader list; + const uint16_t* indices; + uint size_; + + inline FieldSubset(StructSchema parent, List::Reader list, + const uint16_t* indices, uint size) + : parent(parent), list(list), indices(indices), size_(size) {} + + friend class StructSchema; +}; + +// ------------------------------------------------------------------- + +class EnumSchema: public Schema { +public: + inline EnumSchema(): Schema(&_::NULL_ENUM_SCHEMA.defaultBrand) {} + + class Enumerant; + class EnumerantList; + + EnumerantList getEnumerants() const; + + kj::Maybe findEnumerantByName(kj::StringPtr name) const; + + Enumerant getEnumerantByName(kj::StringPtr name) const; + // Like findEnumerantByName() but throws an exception on failure. + +private: + EnumSchema(Schema base): Schema(base) {} + template static inline EnumSchema fromImpl() { + return EnumSchema(Schema(&_::rawBrandedSchema())); + } + friend class Schema; + friend class Type; +}; + +class EnumSchema::Enumerant { +public: + Enumerant() = default; + + inline schema::Enumerant::Reader getProto() const { return proto; } + inline EnumSchema getContainingEnum() const { return parent; } + + inline uint16_t getOrdinal() const { return ordinal; } + inline uint getIndex() const { return ordinal; } + + inline bool operator==(const Enumerant& other) const; + inline bool operator!=(const Enumerant& other) const { return !(*this == other); } + inline uint hashCode() const; + +private: + EnumSchema parent; + uint16_t ordinal; + schema::Enumerant::Reader proto; + + inline Enumerant(EnumSchema parent, uint16_t ordinal, schema::Enumerant::Reader proto) + : parent(parent), ordinal(ordinal), proto(proto) {} + + friend class EnumSchema; +}; + +class EnumSchema::EnumerantList { +public: + EnumerantList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Enumerant operator[](uint index) const { return Enumerant(parent, index, list[index]); } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + EnumSchema parent; + List::Reader list; + + inline EnumerantList(EnumSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class EnumSchema; +}; + +// ------------------------------------------------------------------- + +class InterfaceSchema: public Schema { +public: + inline InterfaceSchema(): Schema(&_::NULL_INTERFACE_SCHEMA.defaultBrand) {} + + class Method; + class MethodList; + + MethodList getMethods() const; + + kj::Maybe findMethodByName(kj::StringPtr name) const; + + Method getMethodByName(kj::StringPtr name) const; + // Like findMethodByName() but throws an exception on failure. + + class SuperclassList; + + SuperclassList getSuperclasses() const; + // Get the immediate superclasses of this type, after applying generics. + + bool extends(InterfaceSchema other) const; + // Returns true if `other` is a superclass of this interface (including if `other == *this`). + + kj::Maybe findSuperclass(uint64_t typeId) const; + // Find the superclass of this interface with the given type ID. Returns null if the interface + // extends no such type. + +private: + InterfaceSchema(Schema base): Schema(base) {} + template static inline InterfaceSchema fromImpl() { + return InterfaceSchema(Schema(&_::rawBrandedSchema())); + } + friend class Schema; + friend class Type; + + kj::Maybe findMethodByName(kj::StringPtr name, uint& counter) const; + bool extends(InterfaceSchema other, uint& counter) const; + kj::Maybe findSuperclass(uint64_t typeId, uint& counter) const; + // We protect against malicious schemas with large or cyclic hierarchies by cutting off the + // search when the counter reaches a threshold. +}; + +class InterfaceSchema::Method { +public: + Method() = default; + + inline schema::Method::Reader getProto() const { return proto; } + inline InterfaceSchema getContainingInterface() const { return parent; } + + inline uint16_t getOrdinal() const { return ordinal; } + inline uint getIndex() const { return ordinal; } + + bool isStreaming() const { return getResultType().isStreamResult(); } + // Check if this is a streaming method. + + StructSchema getParamType() const; + StructSchema getResultType() const; + // Get the parameter and result types, including substituting generic parameters. + + inline bool operator==(const Method& other) const; + inline bool operator!=(const Method& other) const { return !(*this == other); } + inline uint hashCode() const; + +private: + InterfaceSchema parent; + uint16_t ordinal; + schema::Method::Reader proto; + + inline Method(InterfaceSchema parent, uint16_t ordinal, + schema::Method::Reader proto) + : parent(parent), ordinal(ordinal), proto(proto) {} + + friend class InterfaceSchema; +}; + +class InterfaceSchema::MethodList { +public: + MethodList() = default; // empty list + + inline uint size() const { return list.size(); } + inline Method operator[](uint index) const { return Method(parent, index, list[index]); } + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + InterfaceSchema parent; + List::Reader list; + + inline MethodList(InterfaceSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class InterfaceSchema; +}; + +class InterfaceSchema::SuperclassList { +public: + SuperclassList() = default; // empty list + + inline uint size() const { return list.size(); } + InterfaceSchema operator[](uint index) const; + + typedef _::IndexingIterator Iterator; + inline Iterator begin() const { return Iterator(this, 0); } + inline Iterator end() const { return Iterator(this, size()); } + +private: + InterfaceSchema parent; + List::Reader list; + + inline SuperclassList(InterfaceSchema parent, List::Reader list) + : parent(parent), list(list) {} + + friend class InterfaceSchema; +}; + +// ------------------------------------------------------------------- + +class ConstSchema: public Schema { + // Represents a constant declaration. + // + // `ConstSchema` can be implicitly cast to DynamicValue to read its value. + +public: + inline ConstSchema(): Schema(&_::NULL_CONST_SCHEMA.defaultBrand) {} + + template + ReaderFor as() const; + // Read the constant's value. This is a convenience method equivalent to casting the ConstSchema + // to a DynamicValue and then calling its `as()` method. For dependency reasons, this method + // is defined in , which you must #include explicitly. + + uint32_t getValueSchemaOffset() const; + // Much like StructSchema::Field::getDefaultValueSchemaOffset(), if the constant has pointer + // type, this gets the offset from the beginning of the constant's schema node to a pointer + // representing the constant value. + + Type getType() const; + +private: + ConstSchema(Schema base): Schema(base) {} + friend class Schema; +}; + +// ------------------------------------------------------------------- + +class Type { +public: + struct BrandParameter { + uint64_t scopeId; + uint index; + }; + struct ImplicitParameter { + uint index; + }; + + inline Type(); + inline Type(schema::Type::Which primitive); + inline Type(StructSchema schema); + inline Type(EnumSchema schema); + inline Type(InterfaceSchema schema); + inline Type(ListSchema schema); + inline Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind); + inline Type(BrandParameter param); + inline Type(ImplicitParameter param); + + template + inline static Type from(); + template + inline static Type from(T&& value); + + inline schema::Type::Which which() const; + + StructSchema asStruct() const; + EnumSchema asEnum() const; + InterfaceSchema asInterface() const; + ListSchema asList() const; + // Each of these methods may only be called if which() returns the corresponding type. + + kj::Maybe getBrandParameter() const; + // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular + // AnyPointer and not a parameter. + + kj::Maybe getImplicitParameter() const; + // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular + // AnyPointer and not a parameter. "Implicit parameters" refer to type parameters on methods. + + inline schema::Type::AnyPointer::Unconstrained::Which whichAnyPointerKind() const; + // Only callable if which() returns ANY_POINTER. + + inline bool isVoid() const; + inline bool isBool() const; + inline bool isInt8() const; + inline bool isInt16() const; + inline bool isInt32() const; + inline bool isInt64() const; + inline bool isUInt8() const; + inline bool isUInt16() const; + inline bool isUInt32() const; + inline bool isUInt64() const; + inline bool isFloat32() const; + inline bool isFloat64() const; + inline bool isText() const; + inline bool isData() const; + inline bool isList() const; + inline bool isEnum() const; + inline bool isStruct() const; + inline bool isInterface() const; + inline bool isAnyPointer() const; + + bool operator==(const Type& other) const; + inline bool operator!=(const Type& other) const { return !(*this == other); } + + uint hashCode() const; + + inline Type wrapInList(uint depth = 1) const; + // Return the Type formed by wrapping this type in List() `depth` times. + + inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema); + // For internal use. + +private: + schema::Type::Which baseType; // type not including applications of List() + uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ... + + bool isImplicitParam; + // If true, this refers to an implicit method parameter. baseType must be ANY_POINTER, scopeId + // must be zero, and paramIndex indicates the parameter index. + + union { + uint16_t paramIndex; + // If baseType is ANY_POINTER but this Type actually refers to a type parameter, this is the + // index of the parameter among the parameters at its scope, and `scopeId` below is the type ID + // of the scope where the parameter was defined. + + schema::Type::AnyPointer::Unconstrained::Which anyPointerKind; + // If scopeId is zero and isImplicitParam is false. + }; + + union { + const _::RawBrandedSchema* schema; // if type is struct, enum, interface... + uint64_t scopeId; // if type is AnyPointer but it's actually a type parameter... + }; + + Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema) + : baseType(baseType), listDepth(listDepth), schema(schema) { + KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER); + } + + void requireUsableAs(Type expected) const; + + template + struct FromValueImpl; + + friend class ListSchema; // only for requireUsableAs() +}; + +// ------------------------------------------------------------------- + +class ListSchema { + // ListSchema is a little different because list types are not described by schema nodes. So, + // ListSchema doesn't subclass Schema. + +public: + ListSchema() = default; + + static ListSchema of(schema::Type::Which primitiveType); + static ListSchema of(StructSchema elementType); + static ListSchema of(EnumSchema elementType); + static ListSchema of(InterfaceSchema elementType); + static ListSchema of(ListSchema elementType); + static ListSchema of(Type elementType); + // Construct the schema for a list of the given type. + + static ListSchema of(schema::Type::Reader elementType, Schema context) + CAPNP_DEPRECATED("Does not handle generics correctly."); + // DEPRECATED: This method cannot correctly account for generic type parameter bindings that + // may apply to the input type. Instead of using this method, use a method of the Schema API + // that corresponds to the exact kind of dependency. For example, to get a field type, use + // StructSchema::Field::getType(). + // + // Construct from an element type schema. Requires a context which can handle getDependency() + // requests for any type ID found in the schema. + + Type getElementType() const; + + inline schema::Type::Which whichElementType() const; + // Get the element type's "which()". ListSchema does not actually store a schema::Type::Reader + // describing the element type, but if it did, this would be equivalent to calling + // .getBody().which() on that type. + + StructSchema getStructElementType() const; + EnumSchema getEnumElementType() const; + InterfaceSchema getInterfaceElementType() const; + ListSchema getListElementType() const; + // Get the schema for complex element types. Each of these throws an exception if the element + // type is not of the requested kind. + + inline bool operator==(const ListSchema& other) const { return elementType == other.elementType; } + inline bool operator!=(const ListSchema& other) const { return elementType != other.elementType; } + + template + void requireUsableAs() const; + +private: + Type elementType; + + inline explicit ListSchema(Type elementType): elementType(elementType) {} + + template + struct FromImpl; + template static inline ListSchema fromImpl() { + return FromImpl::get(); + } + + void requireUsableAs(ListSchema expected) const; + + friend class Schema; +}; + +// ======================================================================================= +// inline implementation + +template <> inline schema::Type::Which Schema::from() { return schema::Type::VOID; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::BOOL; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT8; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT16; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT32; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::INT64; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT8; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT16; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT32; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT64; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT32; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT64; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::TEXT; } +template <> inline schema::Type::Which Schema::from() { return schema::Type::DATA; } + +inline Schema Schema::getDependency(uint64_t id) const { + return getDependency(id, 0); +} + +inline bool Schema::isBranded() const { + return raw != &raw->generic->defaultBrand; +} + +inline Schema Schema::getGeneric() const { + return Schema(&raw->generic->defaultBrand); +} + +template +inline void Schema::requireUsableAs() const { + requireUsableAs(&_::rawSchema()); +} + +inline bool StructSchema::Field::operator==(const Field& other) const { + return parent == other.parent && index == other.index; +} +inline bool EnumSchema::Enumerant::operator==(const Enumerant& other) const { + return parent == other.parent && ordinal == other.ordinal; +} +inline bool InterfaceSchema::Method::operator==(const Method& other) const { + return parent == other.parent && ordinal == other.ordinal; +} + +inline uint StructSchema::Field::hashCode() const { + return kj::hashCode(parent, index); +} +inline uint EnumSchema::Enumerant::hashCode() const { + return kj::hashCode(parent, ordinal); +} +inline uint InterfaceSchema::Method::hashCode() const { + return kj::hashCode(parent, ordinal); +} + +inline ListSchema ListSchema::of(StructSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(EnumSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(InterfaceSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(ListSchema elementType) { + return ListSchema(Type(elementType)); +} +inline ListSchema ListSchema::of(Type elementType) { + return ListSchema(elementType); +} + +inline Type ListSchema::getElementType() const { + return elementType; +} + +inline schema::Type::Which ListSchema::whichElementType() const { + return elementType.which(); +} + +inline StructSchema ListSchema::getStructElementType() const { + return elementType.asStruct(); +} + +inline EnumSchema ListSchema::getEnumElementType() const { + return elementType.asEnum(); +} + +inline InterfaceSchema ListSchema::getInterfaceElementType() const { + return elementType.asInterface(); +} + +inline ListSchema ListSchema::getListElementType() const { + return elementType.asList(); +} + +template +inline void ListSchema::requireUsableAs() const { + static_assert(kind() == Kind::LIST, + "ListSchema::requireUsableAs() requires T is a list type."); + requireUsableAs(Schema::from()); +} + +inline void ListSchema::requireUsableAs(ListSchema expected) const { + elementType.requireUsableAs(expected.elementType); +} + +template +struct ListSchema::FromImpl> { + static inline ListSchema get() { return of(Schema::from()); } +}; + +inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {} +inline Type::Type(schema::Type::Which primitive) + : baseType(primitive), listDepth(0), isImplicitParam(false) { + KJ_IREQUIRE(primitive != schema::Type::STRUCT && + primitive != schema::Type::ENUM && + primitive != schema::Type::INTERFACE && + primitive != schema::Type::LIST); + if (primitive == schema::Type::ANY_POINTER) { + scopeId = 0; + anyPointerKind = schema::Type::AnyPointer::Unconstrained::ANY_KIND; + } else { + schema = nullptr; + } +} +inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema) + : baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) { + KJ_IREQUIRE(derived == schema::Type::STRUCT || + derived == schema::Type::ENUM || + derived == schema::Type::INTERFACE); +} + +inline Type::Type(StructSchema schema) + : baseType(schema::Type::STRUCT), listDepth(0), schema(schema.raw) {} +inline Type::Type(EnumSchema schema) + : baseType(schema::Type::ENUM), listDepth(0), schema(schema.raw) {} +inline Type::Type(InterfaceSchema schema) + : baseType(schema::Type::INTERFACE), listDepth(0), schema(schema.raw) {} +inline Type::Type(ListSchema schema) + : Type(schema.getElementType()) { ++listDepth; } +inline Type::Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), + anyPointerKind(anyPointerKind), scopeId(0) {} +inline Type::Type(BrandParameter param) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), + paramIndex(param.index), scopeId(param.scopeId) {} +inline Type::Type(ImplicitParameter param) + : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(true), + paramIndex(param.index), scopeId(0) {} + +inline schema::Type::Which Type::which() const { + return listDepth > 0 ? schema::Type::LIST : baseType; +} + +inline schema::Type::AnyPointer::Unconstrained::Which Type::whichAnyPointerKind() const { + KJ_IREQUIRE(baseType == schema::Type::ANY_POINTER); + return !isImplicitParam && scopeId == 0 ? anyPointerKind + : schema::Type::AnyPointer::Unconstrained::ANY_KIND; +} + +template +inline Type Type::from() { return Type(Schema::from()); } + +template +struct Type::FromValueImpl { + template + static inline Type type(U&& value) { + return Type::from(); + } +}; + +template +struct Type::FromValueImpl { + template + static inline Type type(U&& value) { + // All dynamic types have getSchema(). + return value.getSchema(); + } +}; + +template +inline Type Type::from(T&& value) { + typedef FromAny> Base; + return Type::FromValueImpl()>::type(kj::fwd(value)); +} + +inline bool Type::isVoid () const { return baseType == schema::Type::VOID && listDepth == 0; } +inline bool Type::isBool () const { return baseType == schema::Type::BOOL && listDepth == 0; } +inline bool Type::isInt8 () const { return baseType == schema::Type::INT8 && listDepth == 0; } +inline bool Type::isInt16 () const { return baseType == schema::Type::INT16 && listDepth == 0; } +inline bool Type::isInt32 () const { return baseType == schema::Type::INT32 && listDepth == 0; } +inline bool Type::isInt64 () const { return baseType == schema::Type::INT64 && listDepth == 0; } +inline bool Type::isUInt8 () const { return baseType == schema::Type::UINT8 && listDepth == 0; } +inline bool Type::isUInt16 () const { return baseType == schema::Type::UINT16 && listDepth == 0; } +inline bool Type::isUInt32 () const { return baseType == schema::Type::UINT32 && listDepth == 0; } +inline bool Type::isUInt64 () const { return baseType == schema::Type::UINT64 && listDepth == 0; } +inline bool Type::isFloat32() const { return baseType == schema::Type::FLOAT32 && listDepth == 0; } +inline bool Type::isFloat64() const { return baseType == schema::Type::FLOAT64 && listDepth == 0; } +inline bool Type::isText () const { return baseType == schema::Type::TEXT && listDepth == 0; } +inline bool Type::isData () const { return baseType == schema::Type::DATA && listDepth == 0; } +inline bool Type::isList () const { return listDepth > 0; } +inline bool Type::isEnum () const { return baseType == schema::Type::ENUM && listDepth == 0; } +inline bool Type::isStruct () const { return baseType == schema::Type::STRUCT && listDepth == 0; } +inline bool Type::isInterface() const { + return baseType == schema::Type::INTERFACE && listDepth == 0; +} +inline bool Type::isAnyPointer() const { + return baseType == schema::Type::ANY_POINTER && listDepth == 0; +} + +inline Type Type::wrapInList(uint depth) const { + Type result = *this; + result.listDepth += depth; + return result; +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-async.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-async.h new file mode 100644 index 000000000..cd661d780 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-async.h @@ -0,0 +1,320 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include +#include "message.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +struct MessageReaderAndFds { + kj::Own reader; + kj::ArrayPtr fds; +}; + +struct MessageAndFds { + kj::ArrayPtr> segments; + kj::ArrayPtr fds; +}; + +class MessageStream { + // Interface over which messages can be sent and received; virtualizes + // the functionality above. +public: + virtual kj::Promise> tryReadMessage( + kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr) = 0; + // Read a message that may also have file descriptors attached, e.g. from a Unix socket with + // SCM_RIGHTS. Returns null on EOF. + // + // `scratchSpace`, if provided, must remain valid until the returned MessageReader is destroyed. + + kj::Promise>> tryReadMessage( + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + // Equivalent to the above with fdSpace = nullptr. + + kj::Promise readMessage( + kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr); + kj::Promise> readMessage( + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + // Like tryReadMessage, but throws an exception on EOF. + + virtual kj::Promise writeMessage( + kj::ArrayPtr fds, + kj::ArrayPtr> segments) + KJ_WARN_UNUSED_RESULT = 0; + kj::Promise writeMessage( + kj::ArrayPtr fds, + MessageBuilder& builder) + KJ_WARN_UNUSED_RESULT; + // Write a message with FDs attached, e.g. to a Unix socket with SCM_RIGHTS. + // The parameters must remain valid until the returned promise resolves. + + kj::Promise writeMessage( + kj::ArrayPtr> segments) + KJ_WARN_UNUSED_RESULT; + kj::Promise writeMessage(MessageBuilder& builder) + KJ_WARN_UNUSED_RESULT; + // Equivalent to the above with fds = nullptr. + + kj::Promise writeMessages( + kj::ArrayPtr messages) + KJ_WARN_UNUSED_RESULT; + virtual kj::Promise writeMessages( + kj::ArrayPtr>> messages) + KJ_WARN_UNUSED_RESULT = 0; + kj::Promise writeMessages(kj::ArrayPtr builders) + KJ_WARN_UNUSED_RESULT; + // Similar to the above, but for writing multiple messages at a time in a batch. + + virtual kj::Maybe getSendBufferSize() = 0; + // Get the size of the underlying send buffer, if applicable. The RPC + // system uses this as a hint for flow control purposes; see: + // + // https://capnproto.org/news/2020-04-23-capnproto-0.8.html#multi-stream-flow-control + // + // ...for a more thorough explanation of how this is used. Implementations + // may return nullptr if they do not have access to this information, or if + // the underlying transport does not use a congestion window. + + virtual kj::Promise end() = 0; + // Cleanly shut down just the write end of the transport, while keeping the read end open. + +}; + +class AsyncIoMessageStream final: public MessageStream { + // A MessageStream that wraps an AsyncIoStream. +public: + explicit AsyncIoMessageStream(kj::AsyncIoStream& stream); + + // Implements MessageStream + kj::Promise> tryReadMessage( + kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr) override; + kj::Promise writeMessage( + kj::ArrayPtr fds, + kj::ArrayPtr> segments) override; + kj::Promise writeMessages( + kj::ArrayPtr>> messages) override; + kj::Maybe getSendBufferSize() override; + + kj::Promise end() override; + + // Make sure the overridden virtual methods don't hide the non-virtual methods. + using MessageStream::tryReadMessage; + using MessageStream::writeMessage; +private: + kj::AsyncIoStream& stream; +}; + +class AsyncCapabilityMessageStream final: public MessageStream { + // A MessageStream that wraps an AsyncCapabilityStream. +public: + explicit AsyncCapabilityMessageStream(kj::AsyncCapabilityStream& stream); + + // Implements MessageStream + kj::Promise> tryReadMessage( + kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr) override; + kj::Promise writeMessage( + kj::ArrayPtr fds, + kj::ArrayPtr> segments) override; + kj::Promise writeMessages( + kj::ArrayPtr>> messages) override; + kj::Maybe getSendBufferSize() override; + kj::Promise end() override; + + // Make sure the overridden virtual methods don't hide the non-virtual methods. + using MessageStream::tryReadMessage; + using MessageStream::writeMessage; +private: + kj::AsyncCapabilityStream& stream; +}; + +class BufferedMessageStream final: public MessageStream { + // A MessageStream that reads into a buffer in the hopes of receiving multiple messages in a + // single system call. Compared to the other implementations, this implementation is expected + // to be faster when reading from an OS stream (but probably not when reading from an in-memory + // async pipe). It has the down sides of using more memory (for the buffer) and requiring extra + // copies. + +public: + using IsShortLivedCallback = kj::Function; + // Callback function which decides whether a message will be "short-lived", meaning that it is + // guaranteed to be dropped before the next message is read. The stream uses this as an + // optimization to decide whether it can return a MessageReader pointing into the buffer, which + // will be reused for future reads. For long-lived messages, the stream must copy the content + // into a separate buffer. + + explicit BufferedMessageStream( + kj::AsyncIoStream& stream, IsShortLivedCallback isShortLivedCallback, + size_t bufferSizeInWords = 8192); + explicit BufferedMessageStream( + kj::AsyncCapabilityStream& stream, IsShortLivedCallback isShortLivedCallback, + size_t bufferSizeInWords = 8192); + + // Implements MessageStream + kj::Promise> tryReadMessage( + kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr) override; + kj::Promise writeMessage( + kj::ArrayPtr fds, + kj::ArrayPtr> segments) override; + kj::Promise writeMessages( + kj::ArrayPtr>> messages) override; + kj::Maybe getSendBufferSize() override; + kj::Promise end() override; + + // Make sure the overridden virtual methods don't hide the non-virtual methods. + using MessageStream::tryReadMessage; + using MessageStream::writeMessage; + +private: + kj::AsyncIoStream& stream; + kj::Maybe capStream; + IsShortLivedCallback isShortLivedCallback; + + kj::Array buffer; + + word* beginData; + // Pointer to location in `buffer` where the next message starts. This is always on a word + // boundray since messages are always a whole number of words. + + kj::byte* beginAvailable; + // Pointer to the location in `buffer` where unused buffer space begins, i.e. immediately after + // the last byte read. + + kj::Vector leftoverFds; + // FDs which were accidentally read too early. These are always connected to the last message + // in the buffer, since the OS would not have allowed us to read past that point. + + bool hasOutstandingShortLivedMessage = false; + + kj::Promise> tryReadMessageImpl( + kj::ArrayPtr fdSpace, size_t fdsSoFar, + ReaderOptions options, kj::ArrayPtr scratchSpace); + + kj::Promise> readEntireMessage( + kj::ArrayPtr prefix, size_t expectedSizeInWords, + kj::ArrayPtr fdSpace, size_t fdsSoFar, + ReaderOptions options); + // Given a message prefix and expected size of the whole message, read the entire message into + // a single array and return it. + + kj::Promise tryReadWithFds( + void* buffer, size_t minBytes, size_t maxBytes, kj::AutoCloseFd* fdBuffer, size_t maxFds); + // Executes AsyncCapabilityStream::tryReadWithFds() on the underlying stream, or falls back to + // AsyncIoStream::tryRead() if it's not a capability stream. + + class MessageReaderImpl; +}; + +// ----------------------------------------------------------------------------- +// Stand-alone functions for reading & writing messages on AsyncInput/AsyncOutputStreams. +// +// In general, foo(stream, ...) is equivalent to +// AsyncIoMessageStream(stream).foo(...), whenever the latter would type check. +// +// The first argument must remain valid until the returned promise resolves +// (or is canceled). + +kj::Promise> readMessage( + kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + +kj::Promise>> tryReadMessage( + kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + +kj::Promise writeMessage(kj::AsyncOutputStream& output, + kj::ArrayPtr> segments) + KJ_WARN_UNUSED_RESULT; + +kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) + KJ_WARN_UNUSED_RESULT; + +// ----------------------------------------------------------------------------- +// Stand-alone versions that support FD passing. +// +// For each of these, `foo(stream, ...)` is equivalent to +// `AsyncCapabilityMessageStream(stream).foo(...)`. + +kj::Promise readMessage( + kj::AsyncCapabilityStream& input, kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr); + +kj::Promise> tryReadMessage( + kj::AsyncCapabilityStream& input, kj::ArrayPtr fdSpace, + ReaderOptions options = ReaderOptions(), kj::ArrayPtr scratchSpace = nullptr); + +kj::Promise writeMessage(kj::AsyncCapabilityStream& output, kj::ArrayPtr fds, + kj::ArrayPtr> segments) + KJ_WARN_UNUSED_RESULT; +kj::Promise writeMessage(kj::AsyncCapabilityStream& output, kj::ArrayPtr fds, + MessageBuilder& builder) + KJ_WARN_UNUSED_RESULT; + + +// ----------------------------------------------------------------------------- +// Stand-alone functions for writing multiple messages at once on AsyncOutputStreams. + +kj::Promise writeMessages(kj::AsyncOutputStream& output, + kj::ArrayPtr>> messages) + KJ_WARN_UNUSED_RESULT; + +kj::Promise writeMessages( + kj::AsyncOutputStream& output, kj::ArrayPtr builders) + KJ_WARN_UNUSED_RESULT; + +// ======================================================================================= +// inline implementation details + +inline kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) { + return writeMessage(output, builder.getSegmentsForOutput()); +} +inline kj::Promise writeMessage( + kj::AsyncCapabilityStream& output, kj::ArrayPtr fds, MessageBuilder& builder) { + return writeMessage(output, fds, builder.getSegmentsForOutput()); +} + +inline kj::Promise MessageStream::writeMessage(kj::ArrayPtr> segments) { + return writeMessage(nullptr, segments); +} + +inline kj::Promise MessageStream::writeMessage(MessageBuilder& builder) { + return writeMessage(builder.getSegmentsForOutput()); +} + +inline kj::Promise MessageStream::writeMessage( + kj::ArrayPtr fds, MessageBuilder& builder) { + return writeMessage(fds, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-packed.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-packed.cc new file mode 100644 index 000000000..04fd42d91 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-packed.cc @@ -0,0 +1,508 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "serialize-packed.h" +#include +#include "layout.h" +#include + +namespace capnp { + +namespace _ { // private + +PackedInputStream::PackedInputStream(kj::BufferedInputStream& inner): inner(inner) {} +PackedInputStream::~PackedInputStream() noexcept(false) {} + +size_t PackedInputStream::tryRead(void* dst, size_t minBytes, size_t maxBytes) { + if (maxBytes == 0) { + return 0; + } + + KJ_DREQUIRE(minBytes % sizeof(word) == 0, "PackedInputStream reads must be word-aligned."); + KJ_DREQUIRE(maxBytes % sizeof(word) == 0, "PackedInputStream reads must be word-aligned."); + + uint8_t* __restrict__ out = reinterpret_cast(dst); + uint8_t* const outEnd = reinterpret_cast(dst) + maxBytes; + uint8_t* const outMin = reinterpret_cast(dst) + minBytes; + + kj::ArrayPtr buffer = inner.tryGetReadBuffer(); + if (buffer.size() == 0) { + return 0; + } + const uint8_t* __restrict__ in = reinterpret_cast(buffer.begin()); + +#define REFRESH_BUFFER() \ + inner.skip(buffer.size()); \ + buffer = inner.getReadBuffer(); \ + KJ_REQUIRE(buffer.size() > 0, "Premature end of packed input.") { \ + return out - reinterpret_cast(dst); \ + } \ + in = reinterpret_cast(buffer.begin()) + +#define BUFFER_END (reinterpret_cast(buffer.end())) +#define BUFFER_REMAINING ((size_t)(BUFFER_END - in)) + + for (;;) { + uint8_t tag; + + KJ_DASSERT((out - reinterpret_cast(dst)) % sizeof(word) == 0, + "Output pointer should always be aligned here."); + + if (BUFFER_REMAINING < 10) { + if (out >= outMin) { + // We read at least the minimum amount, so go ahead and return. + inner.skip(in - reinterpret_cast(buffer.begin())); + return out - reinterpret_cast(dst); + } + + if (BUFFER_REMAINING == 0) { + REFRESH_BUFFER(); + continue; + } + + // We have at least 1, but not 10, bytes available. We need to read slowly, doing a bounds + // check on each byte. + + tag = *in++; + + for (uint i = 0; i < 8; i++) { + if (tag & (1u << i)) { + if (BUFFER_REMAINING == 0) { + REFRESH_BUFFER(); + } + *out++ = *in++; + } else { + *out++ = 0; + } + } + + if (BUFFER_REMAINING == 0 && (tag == 0 || tag == 0xffu)) { + REFRESH_BUFFER(); + } + } else { + tag = *in++; + +#define HANDLE_BYTE(n) \ + { \ + bool isNonzero = (tag & (1u << n)) != 0; \ + *out++ = *in & (-(int8_t)isNonzero); \ + in += isNonzero; \ + } + + HANDLE_BYTE(0); + HANDLE_BYTE(1); + HANDLE_BYTE(2); + HANDLE_BYTE(3); + HANDLE_BYTE(4); + HANDLE_BYTE(5); + HANDLE_BYTE(6); + HANDLE_BYTE(7); +#undef HANDLE_BYTE + } + + if (tag == 0) { + KJ_DASSERT(BUFFER_REMAINING > 0, "Should always have non-empty buffer here."); + + uint runLength = *in++ * sizeof(word); + + KJ_REQUIRE(runLength <= outEnd - out, + "Packed input did not end cleanly on a segment boundary.") { + return out - reinterpret_cast(dst); + } + memset(out, 0, runLength); + out += runLength; + + } else if (tag == 0xffu) { + KJ_DASSERT(BUFFER_REMAINING > 0, "Should always have non-empty buffer here."); + + uint runLength = *in++ * sizeof(word); + + KJ_REQUIRE(runLength <= outEnd - out, + "Packed input did not end cleanly on a segment boundary.") { + return out - reinterpret_cast(dst); + } + + size_t inRemaining = BUFFER_REMAINING; + if (inRemaining >= runLength) { + // Fast path. + memcpy(out, in, runLength); + out += runLength; + in += runLength; + } else { + // Copy over the first buffer, then do one big read for the rest. + memcpy(out, in, inRemaining); + out += inRemaining; + runLength -= inRemaining; + + inner.skip(buffer.size()); + inner.read(out, runLength); + out += runLength; + + if (out == outEnd) { + return maxBytes; + } else { + buffer = inner.getReadBuffer(); + in = reinterpret_cast(buffer.begin()); + + // Skip the bounds check below since we just did the same check above. + continue; + } + } + } + + if (out == outEnd) { + inner.skip(in - reinterpret_cast(buffer.begin())); + return maxBytes; + } + } + + KJ_FAIL_ASSERT("Can't get here."); + return 0; // GCC knows KJ_FAIL_ASSERT doesn't return, but Eclipse CDT still warns... + +#undef REFRESH_BUFFER +} + +void PackedInputStream::skip(size_t bytes) { + // We can't just read into buffers because buffers must end on block boundaries. + + if (bytes == 0) { + return; + } + + KJ_DREQUIRE(bytes % sizeof(word) == 0, "PackedInputStream reads must be word-aligned."); + + kj::ArrayPtr buffer = inner.getReadBuffer(); + const uint8_t* __restrict__ in = reinterpret_cast(buffer.begin()); + +#define REFRESH_BUFFER() \ + inner.skip(buffer.size()); \ + buffer = inner.getReadBuffer(); \ + KJ_REQUIRE(buffer.size() > 0, "Premature end of packed input.") { return; } \ + in = reinterpret_cast(buffer.begin()) + + for (;;) { + uint8_t tag; + + if (BUFFER_REMAINING < 10) { + if (BUFFER_REMAINING == 0) { + REFRESH_BUFFER(); + continue; + } + + // We have at least 1, but not 10, bytes available. We need to read slowly, doing a bounds + // check on each byte. + + tag = *in++; + + for (uint i = 0; i < 8; i++) { + if (tag & (1u << i)) { + if (BUFFER_REMAINING == 0) { + REFRESH_BUFFER(); + } + in++; + } + } + bytes -= 8; + + if (BUFFER_REMAINING == 0 && (tag == 0 || tag == 0xffu)) { + REFRESH_BUFFER(); + } + } else { + tag = *in++; + +#define HANDLE_BYTE(n) \ + in += (tag & (1u << n)) != 0 + + HANDLE_BYTE(0); + HANDLE_BYTE(1); + HANDLE_BYTE(2); + HANDLE_BYTE(3); + HANDLE_BYTE(4); + HANDLE_BYTE(5); + HANDLE_BYTE(6); + HANDLE_BYTE(7); +#undef HANDLE_BYTE + + bytes -= 8; + } + + if (tag == 0) { + KJ_DASSERT(BUFFER_REMAINING > 0, "Should always have non-empty buffer here."); + + uint runLength = *in++ * sizeof(word); + + KJ_REQUIRE(runLength <= bytes, "Packed input did not end cleanly on a segment boundary.") { + return; + } + + bytes -= runLength; + + } else if (tag == 0xffu) { + KJ_DASSERT(BUFFER_REMAINING > 0, "Should always have non-empty buffer here."); + + uint runLength = *in++ * sizeof(word); + + KJ_REQUIRE(runLength <= bytes, "Packed input did not end cleanly on a segment boundary.") { + return; + } + + bytes -= runLength; + + size_t inRemaining = BUFFER_REMAINING; + if (inRemaining > runLength) { + // Fast path. + in += runLength; + } else { + // Forward skip to the underlying stream. + runLength -= inRemaining; + inner.skip(buffer.size() + runLength); + + if (bytes == 0) { + return; + } else { + buffer = inner.getReadBuffer(); + in = reinterpret_cast(buffer.begin()); + + // Skip the bounds check below since we just did the same check above. + continue; + } + } + } + + if (bytes == 0) { + inner.skip(in - reinterpret_cast(buffer.begin())); + return; + } + } + + KJ_FAIL_ASSERT("Can't get here."); +} + +// ------------------------------------------------------------------- + +PackedOutputStream::PackedOutputStream(kj::BufferedOutputStream& inner) + : inner(inner) {} +PackedOutputStream::~PackedOutputStream() noexcept(false) {} + +void PackedOutputStream::write(const void* src, size_t size) { + kj::ArrayPtr buffer = inner.getWriteBuffer(); + byte slowBuffer[20]; + + uint8_t* __restrict__ out = reinterpret_cast(buffer.begin()); + + const uint8_t* __restrict__ in = reinterpret_cast(src); + const uint8_t* const inEnd = reinterpret_cast(src) + size; + + while (in < inEnd) { + if (reinterpret_cast(buffer.end()) - out < 10) { + // Oops, we're out of space. We need at least 10 bytes for the fast path, since we don't + // bounds-check on every byte. + + // Write what we have so far. + inner.write(buffer.begin(), out - reinterpret_cast(buffer.begin())); + + // Use a slow buffer into which we'll encode 10 to 20 bytes. This should get us past the + // output stream's buffer boundary. + buffer = kj::arrayPtr(slowBuffer, sizeof(slowBuffer)); + out = reinterpret_cast(buffer.begin()); + } + + uint8_t* tagPos = out++; + +#define HANDLE_BYTE(n) \ + uint8_t bit##n = *in != 0; \ + *out = *in; \ + out += bit##n; /* out only advances if the byte was non-zero */ \ + ++in + + HANDLE_BYTE(0); + HANDLE_BYTE(1); + HANDLE_BYTE(2); + HANDLE_BYTE(3); + HANDLE_BYTE(4); + HANDLE_BYTE(5); + HANDLE_BYTE(6); + HANDLE_BYTE(7); +#undef HANDLE_BYTE + + uint8_t tag = (bit0 << 0) | (bit1 << 1) | (bit2 << 2) | (bit3 << 3) + | (bit4 << 4) | (bit5 << 5) | (bit6 << 6) | (bit7 << 7); + *tagPos = tag; + + if (tag == 0) { + // An all-zero word is followed by a count of consecutive zero words (not including the + // first one). + + // We can check a whole word at a time. (Here is where we use the assumption that + // `src` is word-aligned.) + const uint64_t* inWord = reinterpret_cast(in); + + // The count must fit it 1 byte, so limit to 255 words. + const uint64_t* limit = reinterpret_cast(inEnd); + if (limit - inWord > 255) { + limit = inWord + 255; + } + + while (inWord < limit && *inWord == 0) { + ++inWord; + } + + // Write the count. + *out++ = inWord - reinterpret_cast(in); + + // Advance input. + in = reinterpret_cast(inWord); + + } else if (tag == 0xffu) { + // An all-nonzero word is followed by a count of consecutive uncompressed words, followed + // by the uncompressed words themselves. + + // Count the number of consecutive words in the input which have no more than a single + // zero-byte. We look for at least two zeros because that's the point where our compression + // scheme becomes a net win. + // TODO(perf): Maybe look for three zeros? Compressing a two-zero word is a loss if the + // following word has no zeros. + const uint8_t* runStart = in; + + const uint8_t* limit = inEnd; + if ((size_t)(limit - in) > 255 * sizeof(word)) { + limit = in + 255 * sizeof(word); + } + + while (in < limit) { + // Check eight input bytes for zeros. + uint c = *in++ == 0; + c += *in++ == 0; + c += *in++ == 0; + c += *in++ == 0; + c += *in++ == 0; + c += *in++ == 0; + c += *in++ == 0; + c += *in++ == 0; + + if (c >= 2) { + // Un-read the word with multiple zeros, since we'll want to compress that one. + in -= 8; + break; + } + } + + // Write the count. + uint count = in - runStart; + *out++ = count / sizeof(word); + + if (count <= reinterpret_cast(buffer.end()) - out) { + // There's enough space to memcpy. + memcpy(out, runStart, count); + out += count; + } else { + // Input overruns the output buffer. We'll give it to the output stream in one chunk + // and let it decide what to do. + inner.write(buffer.begin(), reinterpret_cast(out) - buffer.begin()); + inner.write(runStart, in - runStart); + buffer = inner.getWriteBuffer(); + out = reinterpret_cast(buffer.begin()); + } + } + } + + // Write whatever is left. + inner.write(buffer.begin(), reinterpret_cast(out) - buffer.begin()); +} + +} // namespace _ (private) + +// ======================================================================================= + +PackedMessageReader::PackedMessageReader( + kj::BufferedInputStream& inputStream, ReaderOptions options, kj::ArrayPtr scratchSpace) + : PackedInputStream(inputStream), + InputStreamMessageReader(static_cast(*this), options, scratchSpace) {} + +PackedMessageReader::~PackedMessageReader() noexcept(false) {} + +PackedFdMessageReader::PackedFdMessageReader( + int fd, ReaderOptions options, kj::ArrayPtr scratchSpace) + : FdInputStream(fd), + BufferedInputStreamWrapper(static_cast(*this)), + PackedMessageReader(static_cast(*this), + options, scratchSpace) {} + +PackedFdMessageReader::PackedFdMessageReader( + kj::AutoCloseFd fd, ReaderOptions options, kj::ArrayPtr scratchSpace) + : FdInputStream(kj::mv(fd)), + BufferedInputStreamWrapper(static_cast(*this)), + PackedMessageReader(static_cast(*this), + options, scratchSpace) {} + +PackedFdMessageReader::~PackedFdMessageReader() noexcept(false) {} + +void writePackedMessage(kj::BufferedOutputStream& output, + kj::ArrayPtr> segments) { + _::PackedOutputStream packedOutput(output); + writeMessage(packedOutput, segments); +} + +void writePackedMessage(kj::OutputStream& output, + kj::ArrayPtr> segments) { + KJ_IF_MAYBE(bufferedOutputPtr, kj::dynamicDowncastIfAvailable(output)) { + writePackedMessage(*bufferedOutputPtr, segments); + } else { + byte buffer[8192]; + kj::BufferedOutputStreamWrapper bufferedOutput(output, kj::arrayPtr(buffer, sizeof(buffer))); + writePackedMessage(bufferedOutput, segments); + } +} + +void writePackedMessageToFd(int fd, kj::ArrayPtr> segments) { + kj::FdOutputStream output(fd); + writePackedMessage(output, segments); +} + +size_t computeUnpackedSizeInWords(kj::ArrayPtr packedBytes) { + const byte* ptr = packedBytes.begin(); + const byte* end = packedBytes.end(); + + size_t total = 0; + while (ptr < end) { + uint tag = *ptr; + size_t count = kj::popCount(tag); + total += 1; + KJ_REQUIRE(end - ptr >= count, "invalid packed data"); + ptr += count + 1; + + if (tag == 0) { + KJ_REQUIRE(ptr < end, "invalid packed data"); + total += *ptr++; + } else if (tag == 0xff) { + KJ_REQUIRE(ptr < end, "invalid packed data"); + size_t words = *ptr++; + total += words; + size_t bytes = words * sizeof(word); + KJ_REQUIRE(end - ptr >= bytes, "invalid packed data"); + ptr += bytes; + } + } + + return total; +} + +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-packed.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-packed.h new file mode 100644 index 000000000..a0329b130 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-packed.h @@ -0,0 +1,128 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "serialize.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +namespace _ { // private + +class PackedInputStream: public kj::InputStream { + // An input stream that unpacks packed data with a picky constraint: The caller must read data + // in the exact same size and sequence as the data was written to PackedOutputStream. + +public: + explicit PackedInputStream(kj::BufferedInputStream& inner); + KJ_DISALLOW_COPY_AND_MOVE(PackedInputStream); + ~PackedInputStream() noexcept(false); + + // implements InputStream ------------------------------------------ + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + kj::BufferedInputStream& inner; +}; + +class PackedOutputStream: public kj::OutputStream { + // An output stream that packs data. Buffers passed to `write()` must be word-aligned. +public: + explicit PackedOutputStream(kj::BufferedOutputStream& inner); + KJ_DISALLOW_COPY_AND_MOVE(PackedOutputStream); + ~PackedOutputStream() noexcept(false); + + // implements OutputStream ----------------------------------------- + void write(const void* buffer, size_t bytes) override; + +private: + kj::BufferedOutputStream& inner; +}; + +} // namespace _ (private) + +class PackedMessageReader: private _::PackedInputStream, public InputStreamMessageReader { +public: + PackedMessageReader(kj::BufferedInputStream& inputStream, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + KJ_DISALLOW_COPY_AND_MOVE(PackedMessageReader); + ~PackedMessageReader() noexcept(false); +}; + +class PackedFdMessageReader: private kj::FdInputStream, private kj::BufferedInputStreamWrapper, + public PackedMessageReader { +public: + PackedFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + // Read message from a file descriptor, without taking ownership of the descriptor. + // Note that if you want to reuse the descriptor after the reader is destroyed, you'll need to + // seek it, since otherwise the position is unspecified. + + PackedFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + // Read a message from a file descriptor, taking ownership of the descriptor. + + KJ_DISALLOW_COPY_AND_MOVE(PackedFdMessageReader); + + ~PackedFdMessageReader() noexcept(false); +}; + +void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder); +void writePackedMessage(kj::BufferedOutputStream& output, + kj::ArrayPtr> segments); +// Write a packed message to a buffered output stream. + +void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder); +void writePackedMessage(kj::OutputStream& output, + kj::ArrayPtr> segments); +// Write a packed message to an unbuffered output stream. If you intend to write multiple messages +// in succession, consider wrapping your output in a buffered stream in order to reduce system +// call overhead. + +void writePackedMessageToFd(int fd, MessageBuilder& builder); +void writePackedMessageToFd(int fd, kj::ArrayPtr> segments); +// Write a single packed message to the file descriptor. + +size_t computeUnpackedSizeInWords(kj::ArrayPtr packedBytes); +// Computes the number of words to which the given packed bytes will unpack. Not intended for use +// in performance-sensitive situations. + +// ======================================================================================= +// inline stuff + +inline void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder) { + writePackedMessage(output, builder.getSegmentsForOutput()); +} + +inline void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder) { + writePackedMessage(output, builder.getSegmentsForOutput()); +} + +inline void writePackedMessageToFd(int fd, MessageBuilder& builder) { + writePackedMessageToFd(fd, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-text.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-text.h new file mode 100644 index 000000000..8acd9be84 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize-text.h @@ -0,0 +1,93 @@ +// Copyright (c) 2015 Philip Quinn. +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include "dynamic.h" +#include "orphan.h" +#include "schema.h" + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class TextCodec { + // Reads and writes Cap'n Proto objects in a plain text format (as used in the schema + // language for constants, and read/written by the 'decode' and 'encode' commands of + // the capnp tool). + // + // This format is useful for debugging or human input, but it is not a robust alternative + // to the binary format. Changes to a schema's types or names that are permitted in a + // schema's binary evolution will likely break messages stored in this format. + // + // Note that definitions or references (to constants, other fields, or files) are not + // permitted in this format. To evaluate declarations with the full expressiveness of the + // schema language, see `capnp::SchemaParser`. + // + // Requires linking with the capnpc library. + +public: + TextCodec(); + ~TextCodec() noexcept(true); + + void setPrettyPrint(bool enabled); + // If enabled, pads the output of `encode()` with spaces and newlines to make it more + // human-readable. + + template + kj::String encode(T&& value) const; + kj::String encode(DynamicValue::Reader value) const; + // Encode any Cap'n Proto value. + + template + Orphan decode(kj::StringPtr input, Orphanage orphanage) const; + // Decode a text message into a Cap'n Proto object of type T, allocated in the given + // orphanage. Any errors parsing the input or assigning the fields of T are thrown as + // exceptions. + + void decode(kj::StringPtr input, DynamicStruct::Builder output) const; + // Decode a text message for a struct into the given builder. Any errors parsing the + // input or assigning the fields of the output are thrown as exceptions. + + // TODO(someday): expose some control over the error handling? +private: + Orphan decode(kj::StringPtr input, Type type, Orphanage orphanage) const; + + bool prettyPrint; +}; + +// ======================================================================================= +// inline stuff + +template +inline kj::String TextCodec::encode(T&& value) const { + return encode(DynamicValue::Reader(ReaderFor>(kj::fwd(value)))); +} + +template +inline Orphan TextCodec::decode(kj::StringPtr input, Orphanage orphanage) const { + return decode(input, Type::from(), orphanage).template releaseAs(); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize.cc new file mode 100644 index 000000000..abb34f799 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize.cc @@ -0,0 +1,327 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "serialize.h" +#include "layout.h" +#include +#include +#ifdef _WIN32 +#include +#include +#endif + +namespace capnp { + +FlatArrayMessageReader::FlatArrayMessageReader( + kj::ArrayPtr array, ReaderOptions options) + : MessageReader(options), end(array.end()) { + if (array.size() < 1) { + // Assume empty message. + return; + } + + const _::WireValue* table = + reinterpret_cast*>(array.begin()); + + uint segmentCount = table[0].get() + 1; + size_t offset = segmentCount / 2u + 1u; + + KJ_REQUIRE(array.size() >= offset, "Message ends prematurely in segment table.") { + return; + } + + { + uint segmentSize = table[1].get(); + + KJ_REQUIRE(array.size() >= offset + segmentSize, + "Message ends prematurely in first segment.") { + return; + } + + segment0 = array.slice(offset, offset + segmentSize); + offset += segmentSize; + } + + if (segmentCount > 1) { + moreSegments = kj::heapArray>(segmentCount - 1); + + for (uint i = 1; i < segmentCount; i++) { + uint segmentSize = table[i + 1].get(); + + KJ_REQUIRE(array.size() >= offset + segmentSize, "Message ends prematurely.") { + moreSegments = nullptr; + return; + } + + moreSegments[i - 1] = array.slice(offset, offset + segmentSize); + offset += segmentSize; + } + } + + end = array.begin() + offset; +} + +size_t expectedSizeInWordsFromPrefix(kj::ArrayPtr array) { + if (array.size() < 1) { + // All messages are at least one word. + return 1; + } + + const _::WireValue* table = + reinterpret_cast*>(array.begin()); + + uint segmentCount = table[0].get() + 1; + size_t offset = segmentCount / 2u + 1u; + + // If the array is too small to contain the full segment table, truncate segmentCount to just + // what is available. + segmentCount = kj::min(segmentCount, array.size() * 2 - 1u); + + size_t totalSize = offset; + for (uint i = 0; i < segmentCount; i++) { + totalSize += table[i + 1].get(); + } + return totalSize; +} + +kj::ArrayPtr FlatArrayMessageReader::getSegment(uint id) { + if (id == 0) { + return segment0; + } else if (id <= moreSegments.size()) { + return moreSegments[id - 1]; + } else { + return nullptr; + } +} + +kj::ArrayPtr initMessageBuilderFromFlatArrayCopy( + kj::ArrayPtr array, MessageBuilder& target, ReaderOptions options) { + FlatArrayMessageReader reader(array, options); + target.setRoot(reader.getRoot()); + return kj::arrayPtr(reader.getEnd(), array.end()); +} + +kj::Array messageToFlatArray(kj::ArrayPtr> segments) { + kj::Array result = kj::heapArray(computeSerializedSizeInWords(segments)); + + _::WireValue* table = + reinterpret_cast<_::WireValue*>(result.begin()); + + // We write the segment count - 1 because this makes the first word zero for single-segment + // messages, improving compression. We don't bother doing this with segment sizes because + // one-word segments are rare anyway. + table[0].set(segments.size() - 1); + + for (uint i = 0; i < segments.size(); i++) { + table[i + 1].set(segments[i].size()); + } + + if (segments.size() % 2 == 0) { + // Set padding byte. + table[segments.size() + 1].set(0); + } + + word* dst = result.begin() + segments.size() / 2 + 1; + + for (auto& segment: segments) { + memcpy(dst, segment.begin(), segment.size() * sizeof(word)); + dst += segment.size(); + } + + KJ_DASSERT(dst == result.end(), "Buffer overrun/underrun bug in code above."); + + return kj::mv(result); +} + +size_t computeSerializedSizeInWords(kj::ArrayPtr> segments) { + KJ_REQUIRE(segments.size() > 0, "Tried to serialize uninitialized message."); + + size_t totalSize = segments.size() / 2 + 1; + + for (auto& segment: segments) { + totalSize += segment.size(); + } + + return totalSize; +} + +// ======================================================================================= + +InputStreamMessageReader::InputStreamMessageReader( + kj::InputStream& inputStream, ReaderOptions options, kj::ArrayPtr scratchSpace) + : MessageReader(options), inputStream(inputStream), readPos(nullptr) { + _::WireValue firstWord[2]; + + inputStream.read(firstWord, sizeof(firstWord)); + + uint segmentCount = firstWord[0].get() + 1; + uint segment0Size = segmentCount == 0 ? 0 : firstWord[1].get(); + + size_t totalWords = segment0Size; + + // Reject messages with too many segments for security reasons. + KJ_REQUIRE(segmentCount < 512, "Message has too many segments.") { + segmentCount = 1; + segment0Size = 1; + break; + } + + // Read sizes for all segments except the first. Include padding if necessary. + KJ_STACK_ARRAY(_::WireValue, moreSizes, segmentCount & ~1, 16, 64); + if (segmentCount > 1) { + inputStream.read(moreSizes.begin(), moreSizes.size() * sizeof(moreSizes[0])); + for (uint i = 0; i < segmentCount - 1; i++) { + totalWords += moreSizes[i].get(); + } + } + + // Don't accept a message which the receiver couldn't possibly traverse without hitting the + // traversal limit. Without this check, a malicious client could transmit a very large segment + // size to make the receiver allocate excessive space and possibly crash. + KJ_REQUIRE(totalWords <= options.traversalLimitInWords, + "Message is too large. To increase the limit on the receiving end, see " + "capnp::ReaderOptions.") { + segmentCount = 1; + segment0Size = kj::min(segment0Size, options.traversalLimitInWords); + totalWords = segment0Size; + break; + } + + if (scratchSpace.size() < totalWords) { + // TODO(perf): Consider allocating each segment as a separate chunk to reduce memory + // fragmentation. + ownedSpace = kj::heapArray(totalWords); + scratchSpace = ownedSpace; + } + + segment0 = scratchSpace.slice(0, segment0Size); + + if (segmentCount > 1) { + moreSegments = kj::heapArray>(segmentCount - 1); + size_t offset = segment0Size; + + for (uint i = 0; i < segmentCount - 1; i++) { + uint segmentSize = moreSizes[i].get(); + moreSegments[i] = scratchSpace.slice(offset, offset + segmentSize); + offset += segmentSize; + } + } + + if (segmentCount == 1) { + inputStream.read(scratchSpace.begin(), totalWords * sizeof(word)); + } else if (segmentCount > 1) { + readPos = scratchSpace.asBytes().begin(); + readPos += inputStream.read(readPos, segment0Size * sizeof(word), totalWords * sizeof(word)); + } +} + +InputStreamMessageReader::~InputStreamMessageReader() noexcept(false) { + if (readPos != nullptr) { + unwindDetector.catchExceptionsIfUnwinding([&]() { + // Note that lazy reads only happen when we have multiple segments, so moreSegments.back() is + // valid. + const byte* allEnd = reinterpret_cast(moreSegments.back().end()); + inputStream.skip(allEnd - readPos); + }); + } +} + +kj::ArrayPtr InputStreamMessageReader::getSegment(uint id) { + if (id > moreSegments.size()) { + return nullptr; + } + + kj::ArrayPtr segment = id == 0 ? segment0 : moreSegments[id - 1]; + + if (readPos != nullptr) { + // May need to lazily read more data. + const byte* segmentEnd = reinterpret_cast(segment.end()); + if (readPos < segmentEnd) { + // Note that lazy reads only happen when we have multiple segments, so moreSegments.back() is + // valid. + const byte* allEnd = reinterpret_cast(moreSegments.back().end()); + readPos += inputStream.read(readPos, segmentEnd - readPos, allEnd - readPos); + } + } + + return segment; +} + +void readMessageCopy(kj::InputStream& input, MessageBuilder& target, + ReaderOptions options, kj::ArrayPtr scratchSpace) { + InputStreamMessageReader message(input, options, scratchSpace); + target.setRoot(message.getRoot()); +} + +// ------------------------------------------------------------------- + +void writeMessage(kj::OutputStream& output, kj::ArrayPtr> segments) { + KJ_REQUIRE(segments.size() > 0, "Tried to serialize uninitialized message."); + + KJ_STACK_ARRAY(_::WireValue, table, (segments.size() + 2) & ~size_t(1), 16, 64); + + // We write the segment count - 1 because this makes the first word zero for single-segment + // messages, improving compression. We don't bother doing this with segment sizes because + // one-word segments are rare anyway. + table[0].set(segments.size() - 1); + for (uint i = 0; i < segments.size(); i++) { + table[i + 1].set(segments[i].size()); + } + if (segments.size() % 2 == 0) { + // Set padding byte. + table[segments.size() + 1].set(0); + } + + KJ_STACK_ARRAY(kj::ArrayPtr, pieces, segments.size() + 1, 4, 32); + pieces[0] = table.asBytes(); + + for (uint i = 0; i < segments.size(); i++) { + pieces[i + 1] = segments[i].asBytes(); + } + + output.write(pieces); +} + +// ======================================================================================= + +StreamFdMessageReader::~StreamFdMessageReader() noexcept(false) {} + +void writeMessageToFd(int fd, kj::ArrayPtr> segments) { +#ifdef _WIN32 + auto oldMode = _setmode(fd, _O_BINARY); + if (oldMode != _O_BINARY) { + _setmode(fd, oldMode); + KJ_FAIL_REQUIRE("Tried to write a message to a file descriptor that is in text mode. Set the " + "file descriptor to binary mode by calling the _setmode Windows CRT function, or passing " + "_O_BINARY to _open()."); + } +#endif + kj::FdOutputStream stream(fd); + writeMessage(stream, segments); +} + +void readMessageCopyFromFd(int fd, MessageBuilder& target, + ReaderOptions options, kj::ArrayPtr scratchSpace) { + kj::FdInputStream stream(fd); + readMessageCopy(stream, target, options, scratchSpace); +} + +} // namespace capnp diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize.h new file mode 100644 index 000000000..b79dae935 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/serialize.h @@ -0,0 +1,234 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file implements a simple serialization format for Cap'n Proto messages. The format +// is as follows: +// +// * 32-bit little-endian segment count (4 bytes). +// * 32-bit little-endian size of each segment (4*(segment count) bytes). +// * Padding so that subsequent data is 64-bit-aligned (0 or 4 bytes). (I.e., if there are an even +// number of segments, there are 4 bytes of zeros here, otherwise there is no padding.) +// * Data from each segment, in order (8*sum(segment sizes) bytes) +// +// This format has some important properties: +// - It is self-delimiting, so multiple messages may be written to a stream without any external +// delimiter. +// - The total size and position of each segment can be determined by reading only the first part +// of the message, allowing lazy and random-access reading of the segment data. +// - A message is always at least 8 bytes. +// - A single-segment message can be read entirely in two system calls with no buffering. +// - A multi-segment message can be read entirely in three system calls with no buffering. +// - The format is appropriate for mmap()ing since all data is aligned. + +#pragma once + +#include "message.h" +#include + +CAPNP_BEGIN_HEADER + +namespace capnp { + +class FlatArrayMessageReader: public MessageReader { + // Parses a message from a flat array. Note that it makes sense to use this together with mmap() + // for extremely fast parsing. + +public: + FlatArrayMessageReader(kj::ArrayPtr array, ReaderOptions options = ReaderOptions()); + // The array must remain valid until the MessageReader is destroyed. + + kj::ArrayPtr getSegment(uint id) override; + + const word* getEnd() const { return end; } + // Get a pointer just past the end of the message as determined by reading the message header. + // This could actually be before the end of the input array. This pointer is useful e.g. if + // you know that the input array has extra stuff appended after the message and you want to + // get at it. + +private: + // Optimize for single-segment case. + kj::ArrayPtr segment0; + kj::Array> moreSegments; + const word* end; +}; + +kj::ArrayPtr initMessageBuilderFromFlatArrayCopy( + kj::ArrayPtr array, MessageBuilder& target, + ReaderOptions options = ReaderOptions()); +// Convenience function which reads a message using `FlatArrayMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// Returns an ArrayPtr containing any words left over in the array after consuming the whole +// message. This is useful when reading multiple messages that have been concatenated. See also +// FlatArrayMessageReader::getEnd(). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +kj::Array messageToFlatArray(MessageBuilder& builder); +// Constructs a flat array containing the entire content of the given message. +// +// To output the message as bytes, use `.asBytes()` on the returned word array. Keep in mind that +// `asBytes()` returns an ArrayPtr, so you have to save the Array as well to prevent it from being +// deleted. For example: +// +// kj::Array words = messageToFlatArray(myMessage); +// kj::ArrayPtr bytes = words.asBytes(); +// write(fd, bytes.begin(), bytes.size()); + +kj::Array messageToFlatArray(kj::ArrayPtr> segments); +// Version of messageToFlatArray that takes a raw segment array. + +size_t computeSerializedSizeInWords(MessageBuilder& builder); +// Returns the size, in words, that will be needed to serialize the message, including the header. + +size_t computeSerializedSizeInWords(kj::ArrayPtr> segments); +// Version of computeSerializedSizeInWords that takes a raw segment array. + +size_t expectedSizeInWordsFromPrefix(kj::ArrayPtr messagePrefix); +// Given a prefix of a serialized message, try to determine the expected total size of the message, +// in words. The returned size is based on the information known so far; it may be an underestimate +// if the prefix doesn't contain the full segment table. +// +// If the returned value is greater than `messagePrefix.size()`, then the message is not yet +// complete and the app cannot parse it yet. If the returned value is less than or equal to +// `messagePrefix.size()`, then the returned value is the exact total size of the message; any +// remaining bytes are part of the next message. +// +// This function is useful when reading messages from a stream in an asynchronous way, but when +// using the full KJ async infrastructure would be too difficult. Each time bytes are received, +// use this function to determine if an entire message is ready to be parsed. + +// ======================================================================================= + +class InputStreamMessageReader: public MessageReader { + // A MessageReader that reads from an abstract kj::InputStream. See also StreamFdMessageReader + // for a subclass specific to file descriptors. + +public: + InputStreamMessageReader(kj::InputStream& inputStream, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); + ~InputStreamMessageReader() noexcept(false); + + // implements MessageReader ---------------------------------------- + kj::ArrayPtr getSegment(uint id) override; + +private: + kj::InputStream& inputStream; + byte* readPos; + + // Optimize for single-segment case. + kj::ArrayPtr segment0; + kj::Array> moreSegments; + + kj::Array ownedSpace; + // Only if scratchSpace wasn't big enough. + + kj::UnwindDetector unwindDetector; +}; + +void readMessageCopy(kj::InputStream& input, MessageBuilder& target, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); +// Convenience function which reads a message using `InputStreamMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +void writeMessage(kj::OutputStream& output, MessageBuilder& builder); +// Write the message to the given output stream. + +void writeMessage(kj::OutputStream& output, kj::ArrayPtr> segments); +// Write the segment array to the given output stream. + +// ======================================================================================= +// Specializations for reading from / writing to file descriptors. + +class StreamFdMessageReader: private kj::FdInputStream, public InputStreamMessageReader { + // A MessageReader that reads from a stream-based file descriptor. + +public: + StreamFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr) + : FdInputStream(fd), InputStreamMessageReader(*this, options, scratchSpace) {} + // Read message from a file descriptor, without taking ownership of the descriptor. + + StreamFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr) + : FdInputStream(kj::mv(fd)), InputStreamMessageReader(*this, options, scratchSpace) {} + // Read a message from a file descriptor, taking ownership of the descriptor. + + ~StreamFdMessageReader() noexcept(false); +}; + +void readMessageCopyFromFd(int fd, MessageBuilder& target, + ReaderOptions options = ReaderOptions(), + kj::ArrayPtr scratchSpace = nullptr); +// Convenience function which reads a message using `StreamFdMessageReader` then copies the +// content into the target `MessageBuilder`, verifying that the message structure is valid +// (although not necessarily that it matches the desired schema). +// +// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one +// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not +// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) + +void writeMessageToFd(int fd, MessageBuilder& builder); +// Write the message to the given file descriptor. +// +// This function throws an exception on any I/O error. If your code is not exception-safe, be sure +// you catch this exception at the call site. If throwing an exception is not acceptable, you +// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). + +void writeMessageToFd(int fd, kj::ArrayPtr> segments); +// Write the segment array to the given file descriptor. +// +// This function throws an exception on any I/O error. If your code is not exception-safe, be sure +// you catch this exception at the call site. If throwing an exception is not acceptable, you +// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). + +// ======================================================================================= +// inline stuff + +inline kj::Array messageToFlatArray(MessageBuilder& builder) { + return messageToFlatArray(builder.getSegmentsForOutput()); +} + +inline size_t computeSerializedSizeInWords(MessageBuilder& builder) { + return computeSerializedSizeInWords(builder.getSegmentsForOutput()); +} + +inline void writeMessage(kj::OutputStream& output, MessageBuilder& builder) { + writeMessage(output, builder.getSegmentsForOutput()); +} + +inline void writeMessageToFd(int fd, MessageBuilder& builder) { + writeMessageToFd(fd, builder.getSegmentsForOutput()); +} + +} // namespace capnp + +CAPNP_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/stream.capnp.cc b/src/plugins/streamers/lstream/runtime/capnp/capnp/stream.capnp.cc new file mode 100644 index 000000000..098f26a5b --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/stream.capnp.cc @@ -0,0 +1,55 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: stream.capnp + +#include "stream.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<17> b_995f9a3377c0b16e = { + { 0, 0, 0, 0, 5, 0, 6, 0, + 110, 177, 192, 119, 51, 154, 95, 153, + 19, 0, 0, 0, 1, 0, 0, 0, + 248, 243, 147, 19, 169, 102, 195, 134, + 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 0, 0, 2, 1, 0, 0, + 33, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 112, 110, 112, 47, 115, 116, + 114, 101, 97, 109, 46, 99, 97, 112, + 110, 112, 58, 83, 116, 114, 101, 97, + 109, 82, 101, 115, 117, 108, 116, 0, + 0, 0, 0, 0, 1, 0, 1, 0, } +}; +::capnp::word const* const bp_995f9a3377c0b16e = b_995f9a3377c0b16e.words; +#if !CAPNP_LITE +const ::capnp::_::RawSchema s_995f9a3377c0b16e = { + 0x995f9a3377c0b16e, b_995f9a3377c0b16e.words, 17, nullptr, nullptr, + 0, 0, nullptr, nullptr, nullptr, { &s_995f9a3377c0b16e, nullptr, nullptr, 0, 0, nullptr }, false +}; +#endif // !CAPNP_LITE +} // namespace schemas +} // namespace capnp + +// ======================================================================================= + +namespace capnp { + +// StreamResult +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr uint16_t StreamResult::_capnpPrivate::dataWordSize; +constexpr uint16_t StreamResult::_capnpPrivate::pointerCount; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#if !CAPNP_LITE +#if CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +constexpr ::capnp::Kind StreamResult::_capnpPrivate::kind; +constexpr ::capnp::_::RawSchema const* StreamResult::_capnpPrivate::schema; +#endif // !CAPNP_NEED_REDUNDANT_CONSTEXPR_DECL +#endif // !CAPNP_LITE + + +} // namespace + diff --git a/src/plugins/streamers/lstream/runtime/capnp/capnp/stream.capnp.h b/src/plugins/streamers/lstream/runtime/capnp/capnp/stream.capnp.h new file mode 100644 index 000000000..447ffa407 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/capnp/capnp/stream.capnp.h @@ -0,0 +1,121 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: stream.capnp + +#pragma once + +#include +#include + +#ifndef CAPNP_VERSION +#error "CAPNP_VERSION is not defined, is capnp/generated-header-support.h missing?" +#elif CAPNP_VERSION != 1000001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + +CAPNP_BEGIN_HEADER + +namespace capnp { +namespace schemas { + +CAPNP_DECLARE_SCHEMA(995f9a3377c0b16e); + +} // namespace schemas +} // namespace capnp + +namespace capnp { + +struct StreamResult { + StreamResult() = delete; + + class Reader; + class Builder; + class Pipeline; + + struct _capnpPrivate { + CAPNP_DECLARE_STRUCT_HEADER(995f9a3377c0b16e, 0, 0) + #if !CAPNP_LITE + static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } + #endif // !CAPNP_LITE + }; +}; + +// ======================================================================================= + +class StreamResult::Reader { +public: + typedef StreamResult Reads; + + Reader() = default; + inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} + + inline ::capnp::MessageSize totalSize() const { + return _reader.totalSize().asPublic(); + } + +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { + return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); + } +#endif // !CAPNP_LITE + +private: + ::capnp::_::StructReader _reader; + template + friend struct ::capnp::ToDynamic_; + template + friend struct ::capnp::_::PointerHelpers; + template + friend struct ::capnp::List; + friend class ::capnp::MessageBuilder; + friend class ::capnp::Orphanage; +}; + +class StreamResult::Builder { +public: + typedef StreamResult Builds; + + Builder() = delete; // Deleted to discourage incorrect usage. + // You can explicitly initialize to nullptr instead. + inline Builder(decltype(nullptr)) {} + inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} + inline operator Reader() const { return Reader(_builder.asReader()); } + inline Reader asReader() const { return *this; } + + inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } +#if !CAPNP_LITE + inline ::kj::StringTree toString() const { return asReader().toString(); } +#endif // !CAPNP_LITE + +private: + ::capnp::_::StructBuilder _builder; + template + friend struct ::capnp::ToDynamic_; + friend class ::capnp::Orphanage; + template + friend struct ::capnp::_::PointerHelpers; +}; + +#if !CAPNP_LITE +class StreamResult::Pipeline { +public: + typedef StreamResult Pipelines; + + inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} + inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) + : _typeless(kj::mv(typeless)) {} + +private: + ::capnp::AnyPointer::Pipeline _typeless; + friend class ::capnp::PipelineHook; + template + friend struct ::capnp::ToDynamic_; +}; +#endif // !CAPNP_LITE + +// ======================================================================================= + +} // namespace + +CAPNP_END_HEADER + diff --git a/src/plugins/streamers/lstream/runtime/fetch.sh b/src/plugins/streamers/lstream/runtime/fetch.sh new file mode 100755 index 000000000..c4e9ced80 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/fetch.sh @@ -0,0 +1,208 @@ +#!/bin/bash -e + +tmp=.tmp + +rm -rf $tmp +mkdir $tmp +cd $tmp +git clone https://github.com/capnproto/capnproto.git -b v1.0.1 . +cd .. + +rm -rf kj capnp + +# NOTE: putting the original sources in a folder below the .pro file +# avoids issues with the include path that Qt imposes and which creates +# a name clash with standard headers like "string.h" + +mkdir kj +mkdir kj/kj +mkdir kj/kj/parse +mkdir kj/kj/std +mkdir capnp +mkdir capnp/capnp +mkdir capnp/capnp/compat + +cp $tmp/{LICENSE,CONTRIBUTORS} kj +cp $tmp/{LICENSE,CONTRIBUTORS} capnp + +echo "# DO NOT EDIT!" >kj/kj.pro +echo "# (SEE ../kj.pro)" >>kj/kj.pro +echo "" >>kj/kj.pro +cat kj.pro >>kj/kj.pro + +echo "# DO NOT EDIT!" >capnp/capnp.pro +echo "# (SEE ../capnp.pro)" >>capnp/capnp.pro +echo "" >>capnp/capnp.pro +cat capnp.pro >>capnp/capnp.pro + +capnp_sources_lite=( + c++.capnp.c++ + blob.c++ + arena.c++ + layout.c++ + list.c++ + any.c++ + message.c++ + schema.capnp.c++ + stream.capnp.c++ + serialize.c++ + serialize-packed.c++ +) + +capnp_headers=( + arena.h + c++.capnp.h + common.h + blob.h + endian.h + layout.h + orphan.h + list.h + any.h + message.h + capability.h + membrane.h + dynamic.h + schema.h + schema.capnp.h + stream.capnp.h + schema-lite.h + schema-loader.h + schema-parser.h + pretty-print.h + serialize.h + serialize-async.h + serialize-packed.h + serialize-text.h + pointer-helpers.h + generated-header-support.h + raw-schema.h +) + +capnp_compat_headers=( + std-iterator.h +) + +kj_sources_lite=( + array.c++ + list.c++ + common.c++ + debug.c++ + exception.c++ + io.c++ + memory.c++ + mutex.c++ + string.c++ + source-location.c++ + hash.c++ + table.c++ + thread.c++ + main.c++ + arena.c++ + units.c++ + encoding.c++ + time.c++ +) + +kj_headers=( + common.h + units.h + memory.h + refcount.h + array.h + list.h + vector.h + string.h + string-tree.h + source-location.h + hash.h + table.h + map.h + encoding.h + exception.h + debug.h + arena.h + io.h + tuple.h + one-of.h + function.h + mutex.h + thread.h + threadlocal.h + filesystem.h + time.h + main.h + win32-api-version.h + windows-sanity.h + miniposix.h +) + +kj_parse_headers=( + common.h + char.h +) +kj_std_headers=( + iostream.h +) + +for f in ${capnp_sources_lite[@]}; do + ftarget=${f/.c++/.cc} + cp $tmp/c++/src/capnp/$f capnp/capnp/$ftarget +done +for f in ${capnp_headers[@]}; do + cp $tmp/c++/src/capnp/$f capnp/capnp +done +for f in ${capnp_compat_headers[@]}; do + cp $tmp/c++/src/capnp/compat/$f capnp/capnp/compat +done + +pri=capnp/capnp.pri +echo "" >$pri +echo "CAPNP_SOURCES=\\" >>$pri +for f in ${capnp_sources_lite[@]}; do + ftarget=${f/.c++/.cc} + echo " capnp/$ftarget \\" >>$pri +done +echo "" >>$pri +echo "CAPNP_HEADERS=\\" >>$pri +for f in ${capnp_headers[@]}; do + echo " capnp/$f \\" >>$pri +done +for f in ${capnp_compat_headers[@]}; do + echo " capnp/compat/$f \\" >>$pri +done + +for f in ${kj_sources_lite[@]}; do + ftarget=${f/.c++/.cc} + cp $tmp/c++/src/kj/$f kj/kj/$ftarget +done +for f in ${kj_headers[@]}; do + cp $tmp/c++/src/kj/$f kj/kj +done +for f in ${kj_parse_headers[@]}; do + cp $tmp/c++/src/kj/parse/$f kj/kj/parse +done +for f in ${kj_std_headers[@]}; do + cp $tmp/c++/src/kj/std/$f kj/kj/std +done + +pri=kj/kj.pri +echo "" >$pri +echo "KJ_SOURCES=\\" >>$pri +for f in ${kj_sources_lite[@]}; do + ftarget=${f/.c++/.cc} + echo " kj/$ftarget \\" >>$pri +done +echo "" >>$pri +echo "KJ_HEADERS=\\" >>$pri +for f in ${kj_headers[@]}; do + echo " kj/$f \\" >>$pri +done +for f in ${kj_parse_headers[@]}; do + echo " kj/parse/$f \\" >>$pri +done +for f in ${kj_std_headers[@]}; do + echo " kj/std/$f \\" >>$pri +done + + diff --git a/src/plugins/streamers/lstream/runtime/kj.pro b/src/plugins/streamers/lstream/runtime/kj.pro new file mode 100644 index 000000000..cf4070edc --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj.pro @@ -0,0 +1,17 @@ + +TEMPLATE = lib +DESTDIR = $$OUT_PWD/../../../../.. +INCLUDEPATH = + +include($$PWD/../../lstream.pri) +include($$PWD/kj.pri) + +TARGET = xkj +CONFIG += staticlib +SOURCES = $$KJ_SOURCES +HEADERS = $$KJ_HEADERS + +DEFINES = CAPNP_LITE +LIBS = +QT = + diff --git a/src/plugins/streamers/lstream/runtime/kj/CONTRIBUTORS b/src/plugins/streamers/lstream/runtime/kj/CONTRIBUTORS new file mode 100644 index 000000000..24902a940 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/CONTRIBUTORS @@ -0,0 +1,23 @@ +The following people have made large code contributions to this repository. +Those contributions are copyright the respective authors and licensed by them +under the same MIT license terms as the rest of the library. + +Kenton Varda : Primary Author +Jason Choy : kj/threadlocal.h and other iOS tweaks, `name` annotation in C++ code generator +Remy Blank (contributions copyright Google Inc.): KJ Timers +Joshua Warner : cmake build, AnyStruct/AnyList, other stuff +Scott Purdy : kj/std iostream interface +Bryan Borham : Initial MSVC support +Philip Quinn : cmake build and other assorted bits +Brian Taylor : emacs syntax highlighting +Ben Laurie : discovered and responsibly disclosed security bugs +Kamal Marhubi : JSON parser +Oliver Kuckertz : FdObserver POLLPRI support +Harris Hancock : MSVC support +Branislav Katreniak : JSON decode +Matthew Maurer : Canonicalization Support +David Renshaw : bugfixes and miscellaneous maintenance +Ingvar Stepanyan : Custom handlers for JSON decode + +This file does not list people who maintain their own Cap'n Proto +implementations as separate projects. Those people are awesome too! :) diff --git a/src/plugins/streamers/lstream/runtime/kj/LICENSE b/src/plugins/streamers/lstream/runtime/kj/LICENSE new file mode 100644 index 000000000..1eabc941f --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013-2017 Sandstorm Development Group, Inc.; Cloudflare, Inc.; +and other contributors. Each commit is copyright by its respective author or +author's employer. + +Licensed under the MIT License: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/src/plugins/streamers/lstream/runtime/kj/kj.pri b/src/plugins/streamers/lstream/runtime/kj/kj.pri new file mode 100644 index 000000000..85613cd74 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj.pri @@ -0,0 +1,55 @@ + +KJ_SOURCES=\ + kj/array.cc \ + kj/list.cc \ + kj/common.cc \ + kj/debug.cc \ + kj/exception.cc \ + kj/io.cc \ + kj/memory.cc \ + kj/mutex.cc \ + kj/string.cc \ + kj/source-location.cc \ + kj/hash.cc \ + kj/table.cc \ + kj/thread.cc \ + kj/main.cc \ + kj/arena.cc \ + kj/units.cc \ + kj/encoding.cc \ + kj/time.cc \ + +KJ_HEADERS=\ + kj/common.h \ + kj/units.h \ + kj/memory.h \ + kj/refcount.h \ + kj/array.h \ + kj/list.h \ + kj/vector.h \ + kj/string.h \ + kj/string-tree.h \ + kj/source-location.h \ + kj/hash.h \ + kj/table.h \ + kj/map.h \ + kj/encoding.h \ + kj/exception.h \ + kj/debug.h \ + kj/arena.h \ + kj/io.h \ + kj/tuple.h \ + kj/one-of.h \ + kj/function.h \ + kj/mutex.h \ + kj/thread.h \ + kj/threadlocal.h \ + kj/filesystem.h \ + kj/time.h \ + kj/main.h \ + kj/win32-api-version.h \ + kj/windows-sanity.h \ + kj/miniposix.h \ + kj/parse/common.h \ + kj/parse/char.h \ + kj/std/iostream.h \ diff --git a/src/plugins/streamers/lstream/runtime/kj/kj.pro b/src/plugins/streamers/lstream/runtime/kj/kj.pro new file mode 100644 index 000000000..fbecaa238 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj.pro @@ -0,0 +1,20 @@ +# DO NOT EDIT! +# (SEE ../kj.pro) + + +TEMPLATE = lib +DESTDIR = $$OUT_PWD/../../../../.. +INCLUDEPATH = + +include($$PWD/../../lstream.pri) +include($$PWD/kj.pri) + +TARGET = xkj +CONFIG += staticlib +SOURCES = $$KJ_SOURCES +HEADERS = $$KJ_HEADERS + +DEFINES = CAPNP_LITE +LIBS = +QT = + diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/arena.cc b/src/plugins/streamers/lstream/runtime/kj/kj/arena.cc new file mode 100644 index 000000000..06dc0605a --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/arena.cc @@ -0,0 +1,167 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "arena.h" +#include "debug.h" +#include + +namespace kj { + +Arena::Arena(size_t chunkSizeHint): nextChunkSize(kj::max(sizeof(ChunkHeader), chunkSizeHint)) {} + +Arena::Arena(ArrayPtr scratch) + : nextChunkSize(kj::max(sizeof(ChunkHeader), scratch.size())) { + if (scratch.size() > sizeof(ChunkHeader)) { + ChunkHeader* chunk = reinterpret_cast(scratch.begin()); + chunk->end = scratch.end(); + chunk->pos = reinterpret_cast(chunk + 1); + chunk->next = nullptr; // Never actually observed. + + // Don't place the chunk in the chunk list because it's not ours to delete. Just make it the + // current chunk so that we'll allocate from it until it is empty. + currentChunk = chunk; + } +} + +Arena::~Arena() noexcept(false) { + // Run cleanup() explicitly, but if it throws an exception, make sure to run it again as part of + // unwind. The second call will not throw because destructors are required to guard against + // exceptions when already unwinding. + KJ_ON_SCOPE_FAILURE(cleanup()); + cleanup(); +} + +void Arena::cleanup() { + while (objectList != nullptr) { + void* ptr = objectList + 1; + auto destructor = objectList->destructor; + objectList = objectList->next; + destructor(ptr); + } + + while (chunkList != nullptr) { + void* ptr = chunkList; + chunkList = chunkList->next; + operator delete(ptr); + } +} + +namespace { + +constexpr bool KJ_UNUSED isPowerOfTwo(size_t value) { + return (value & (value - 1)) == 0; +} + +inline byte* alignTo(byte* p, uint alignment) { + // Round the pointer up to the next aligned value. + + KJ_DASSERT(isPowerOfTwo(alignment), alignment); + uintptr_t mask = alignment - 1; + uintptr_t i = reinterpret_cast(p); + return reinterpret_cast((i + mask) & ~mask); +} + +inline size_t alignTo(size_t s, uint alignment) { + // Round the pointer up to the next aligned value. + + KJ_DASSERT(isPowerOfTwo(alignment), alignment); + size_t mask = alignment - 1; + return (s + mask) & ~mask; +} + +} // namespace + +void* Arena::allocateBytes(size_t amount, uint alignment, bool hasDisposer) { + if (hasDisposer) { + alignment = kj::max(alignment, alignof(ObjectHeader)); + amount += alignTo(sizeof(ObjectHeader), alignment); + } + + void* result = allocateBytesInternal(amount, alignment); + + if (hasDisposer) { + // Reserve space for the ObjectHeader, but don't add it to the object list yet. + result = alignTo(reinterpret_cast(result) + sizeof(ObjectHeader), alignment); + } + + KJ_DASSERT(reinterpret_cast(result) % alignment == 0); + return result; +} + +void* Arena::allocateBytesInternal(size_t amount, uint alignment) { + if (currentChunk != nullptr) { + ChunkHeader* chunk = currentChunk; + byte* alignedPos = alignTo(chunk->pos, alignment); + + // Careful about overflow here. + if (amount + (alignedPos - chunk->pos) <= chunk->end - chunk->pos) { + // There's enough space in this chunk. + chunk->pos = alignedPos + amount; + return alignedPos; + } + } + + // Not enough space in the current chunk. Allocate a new one. + + // We need to allocate at least enough space for the ChunkHeader and the requested allocation. + + // If the alignment is less than that of the chunk header, we'll need to increase it. + alignment = kj::max(alignment, alignof(ChunkHeader)); + + // If the ChunkHeader size does not match the alignment, we'll need to pad it up. + amount += alignTo(sizeof(ChunkHeader), alignment); + + // Make sure we're going to allocate enough space. + while (nextChunkSize < amount) { + nextChunkSize *= 2; + } + + // Allocate. + byte* bytes = reinterpret_cast(operator new(nextChunkSize)); + + // Set up the ChunkHeader at the beginning of the allocation. + ChunkHeader* newChunk = reinterpret_cast(bytes); + newChunk->next = chunkList; + newChunk->pos = bytes + amount; + newChunk->end = bytes + nextChunkSize; + currentChunk = newChunk; + chunkList = newChunk; + nextChunkSize *= 2; + + // Move past the ChunkHeader to find the position of the allocated object. + return alignTo(bytes + sizeof(ChunkHeader), alignment); +} + +StringPtr Arena::copyString(StringPtr content) { + char* data = reinterpret_cast(allocateBytes(content.size() + 1, 1, false)); + memcpy(data, content.cStr(), content.size() + 1); + return StringPtr(data, content.size()); +} + +void Arena::setDestructor(void* ptr, void (*destructor)(void*)) { + ObjectHeader* header = reinterpret_cast(ptr) - 1; + KJ_DASSERT(reinterpret_cast(header) % alignof(ObjectHeader) == 0); + header->destructor = destructor; + header->next = objectList; + objectList = header; +} + +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/arena.h b/src/plugins/streamers/lstream/runtime/kj/kj/arena.h new file mode 100644 index 000000000..a16b29112 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/arena.h @@ -0,0 +1,210 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "memory.h" +#include "array.h" +#include "string.h" + +KJ_BEGIN_HEADER + +namespace kj { + +class Arena { + // A class which allows several objects to be allocated in contiguous chunks of memory, then + // frees them all at once. + // + // Allocating from the same Arena in multiple threads concurrently is NOT safe, because making + // it safe would require atomic operations that would slow down allocation even when + // single-threaded. If you need to use arena allocation in a multithreaded context, consider + // allocating thread-local arenas. + +public: + explicit Arena(size_t chunkSizeHint = 1024); + // Create an Arena. `chunkSizeHint` hints at where to start when allocating chunks, but is only + // a hint -- the Arena will, for example, allocate progressively larger chunks as time goes on, + // in order to reduce overall allocation overhead. + + explicit Arena(ArrayPtr scratch); + // Allocates from the given scratch space first, only resorting to the heap when it runs out. + + KJ_DISALLOW_COPY_AND_MOVE(Arena); + ~Arena() noexcept(false); + + template + T& allocate(Params&&... params); + template + ArrayPtr allocateArray(size_t size); + // Allocate an object or array of type T. If T has a non-trivial destructor, that destructor + // will be run during the Arena's destructor. Such destructors are run in opposite order of + // allocation. Note that these methods must maintain a list of destructors to call, which has + // overhead, but this overhead only applies if T has a non-trivial destructor. + + template + Own allocateOwn(Params&&... params); + template + Array allocateOwnArray(size_t size); + template + ArrayBuilder allocateOwnArrayBuilder(size_t capacity); + // Allocate an object or array of type T. Destructors are executed when the returned Own + // or Array goes out-of-scope, which must happen before the Arena is destroyed. This variant + // is useful when you need to control when the destructor is called. This variant also avoids + // the need for the Arena itself to keep track of destructors to call later, which may make it + // slightly more efficient. + + template + inline T& copy(T&& value) { return allocate>(kj::fwd(value)); } + // Allocate a copy of the given value in the arena. This is just a shortcut for calling the + // type's copy (or move) constructor. + + StringPtr copyString(StringPtr content); + // Make a copy of the given string inside the arena, and return a pointer to the copy. + +private: + struct ChunkHeader { + ChunkHeader* next; + byte* pos; // first unallocated byte in this chunk + byte* end; // end of this chunk + }; + struct ObjectHeader { + void (*destructor)(void*); + ObjectHeader* next; + }; + + size_t nextChunkSize; + ChunkHeader* chunkList = nullptr; + ObjectHeader* objectList = nullptr; + + ChunkHeader* currentChunk = nullptr; + + void cleanup(); + // Run all destructors, leaving the above pointers null. If a destructor throws, the State is + // left in a consistent state, such that if cleanup() is called again, it will pick up where + // it left off. + + void* allocateBytes(size_t amount, uint alignment, bool hasDisposer); + // Allocate the given number of bytes. `hasDisposer` must be true if `setDisposer()` may be + // called on this pointer later. + + void* allocateBytesInternal(size_t amount, uint alignment); + // Try to allocate the given number of bytes without taking a lock. Fails if and only if there + // is no space left in the current chunk. + + void setDestructor(void* ptr, void (*destructor)(void*)); + // Schedule the given destructor to be executed when the Arena is destroyed. `ptr` must be a + // pointer previously returned by an `allocateBytes()` call for which `hasDisposer` was true. + + template + static void destroyArray(void* pointer) { + size_t elementCount = *reinterpret_cast(pointer); + constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); + DestructorOnlyArrayDisposer::instance.disposeImpl( + reinterpret_cast(pointer) + prefixSize, + sizeof(T), elementCount, elementCount, &destroyObject); + } + + template + static void destroyObject(void* pointer) { + dtor(*reinterpret_cast(pointer)); + } +}; + +// ======================================================================================= +// Inline implementation details + +template +T& Arena::allocate(Params&&... params) { + T& result = *reinterpret_cast(allocateBytes( + sizeof(T), alignof(T), !KJ_HAS_TRIVIAL_DESTRUCTOR(T))); + if (!KJ_HAS_TRIVIAL_CONSTRUCTOR(T) || sizeof...(Params) > 0) { + ctor(result, kj::fwd(params)...); + } + if (!KJ_HAS_TRIVIAL_DESTRUCTOR(T)) { + setDestructor(&result, &destroyObject); + } + return result; +} + +template +ArrayPtr Arena::allocateArray(size_t size) { + if (KJ_HAS_TRIVIAL_DESTRUCTOR(T)) { + ArrayPtr result = + arrayPtr(reinterpret_cast(allocateBytes( + sizeof(T) * size, alignof(T), false)), size); + if (!KJ_HAS_TRIVIAL_CONSTRUCTOR(T)) { + for (size_t i = 0; i < size; i++) { + ctor(result[i]); + } + } + return result; + } else { + // Allocate with a 64-bit prefix in which we store the array size. + constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); + void* base = allocateBytes(sizeof(T) * size + prefixSize, alignof(T), true); + size_t& tag = *reinterpret_cast(base); + ArrayPtr result = + arrayPtr(reinterpret_cast(reinterpret_cast(base) + prefixSize), size); + setDestructor(base, &destroyArray); + + if (KJ_HAS_TRIVIAL_CONSTRUCTOR(T)) { + tag = size; + } else { + // In case of constructor exceptions, we need the tag to end up storing the number of objects + // that were successfully constructed, so that they'll be properly destroyed. + tag = 0; + for (size_t i = 0; i < size; i++) { + ctor(result[i]); + tag = i + 1; + } + } + return result; + } +} + +template +Own Arena::allocateOwn(Params&&... params) { + T& result = *reinterpret_cast(allocateBytes(sizeof(T), alignof(T), false)); + if (!KJ_HAS_TRIVIAL_CONSTRUCTOR(T) || sizeof...(Params) > 0) { + ctor(result, kj::fwd(params)...); + } + return Own(&result, DestructorOnlyDisposer::instance); +} + +template +Array Arena::allocateOwnArray(size_t size) { + ArrayBuilder result = allocateOwnArrayBuilder(size); + for (size_t i = 0; i < size; i++) { + result.add(); + } + return result.finish(); +} + +template +ArrayBuilder Arena::allocateOwnArrayBuilder(size_t capacity) { + return ArrayBuilder( + reinterpret_cast(allocateBytes(sizeof(T) * capacity, alignof(T), false)), + capacity, DestructorOnlyArrayDisposer::instance); +} + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/array.cc b/src/plugins/streamers/lstream/runtime/kj/kj/array.cc new file mode 100644 index 000000000..3ac3d489c --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/array.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "array.h" +#include "exception.h" + +namespace kj { + +void ExceptionSafeArrayUtil::construct(size_t count, void (*constructElement)(void*)) { + while (count > 0) { + constructElement(pos); + pos += elementSize; + ++constructedElementCount; + --count; + } +} + +void ExceptionSafeArrayUtil::destroyAll() { + while (constructedElementCount > 0) { + pos -= elementSize; + --constructedElementCount; + destroyElement(pos); + } +} + +const DestructorOnlyArrayDisposer DestructorOnlyArrayDisposer::instance = + DestructorOnlyArrayDisposer(); + +void DestructorOnlyArrayDisposer::disposeImpl( + void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const { + if (destroyElement != nullptr) { + ExceptionSafeArrayUtil guard(firstElement, elementSize, elementCount, destroyElement); + guard.destroyAll(); + } +} + +const NullArrayDisposer NullArrayDisposer::instance = NullArrayDisposer(); + +void NullArrayDisposer::disposeImpl( + void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const {} + +namespace _ { // private + +struct AutoDeleter { + void* ptr; + inline void* release() { void* result = ptr; ptr = nullptr; return result; } + inline AutoDeleter(void* ptr): ptr(ptr) {} + inline ~AutoDeleter() { operator delete(ptr); } +}; + +void* HeapArrayDisposer::allocateImpl(size_t elementSize, size_t elementCount, size_t capacity, + void (*constructElement)(void*), + void (*destroyElement)(void*)) { + AutoDeleter result(operator new(elementSize * capacity)); + + if (constructElement == nullptr) { + // Nothing to do. + } else if (destroyElement == nullptr) { + byte* pos = reinterpret_cast(result.ptr); + while (elementCount > 0) { + constructElement(pos); + pos += elementSize; + --elementCount; + } + } else { + ExceptionSafeArrayUtil guard(result.ptr, elementSize, 0, destroyElement); + guard.construct(elementCount, constructElement); + guard.release(); + } + + return result.release(); +} + +void HeapArrayDisposer::disposeImpl( + void* firstElement, size_t elementSize, size_t elementCount, size_t capacity, + void (*destroyElement)(void*)) const { + // Note that capacity is ignored since operator delete() doesn't care about it. + AutoDeleter deleter(firstElement); + + if (destroyElement != nullptr) { + ExceptionSafeArrayUtil guard(firstElement, elementSize, elementCount, destroyElement); + guard.destroyAll(); + } +} + +const HeapArrayDisposer HeapArrayDisposer::instance = HeapArrayDisposer(); + +} // namespace _ (private) +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/array.h b/src/plugins/streamers/lstream/runtime/kj/kj/array.h new file mode 100644 index 000000000..55f7ace8e --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/array.h @@ -0,0 +1,913 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "memory.h" +#include +#include + +KJ_BEGIN_HEADER + +namespace kj { + +// ======================================================================================= +// ArrayDisposer -- Implementation details. + +class ArrayDisposer { + // Much like Disposer from memory.h. + +protected: + // Do not declare a destructor, as doing so will force a global initializer for + // HeapArrayDisposer::instance. + + virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const = 0; + // Disposes of the array. `destroyElement` invokes the destructor of each element, or is nullptr + // if the elements have trivial destructors. `capacity` is the amount of space that was + // allocated while `elementCount` is the number of elements that were actually constructed; + // these are always the same number for Array but may be different when using ArrayBuilder. + +public: + + template + void dispose(T* firstElement, size_t elementCount, size_t capacity) const; + // Helper wrapper around disposeImpl(). + // + // Callers must not call dispose() on the same array twice, even if the first call throws + // an exception. + +private: + template + struct Dispose_; +}; + +class ExceptionSafeArrayUtil { + // Utility class that assists in constructing or destroying elements of an array, where the + // constructor or destructor could throw exceptions. In case of an exception, + // ExceptionSafeArrayUtil's destructor will call destructors on all elements that have been + // constructed but not destroyed. Remember that destructors that throw exceptions are required + // to use UnwindDetector to detect unwind and avoid exceptions in this case. Therefore, no more + // than one exception will be thrown (and the program will not terminate). + +public: + inline ExceptionSafeArrayUtil(void* ptr, size_t elementSize, size_t constructedElementCount, + void (*destroyElement)(void*)) + : pos(reinterpret_cast(ptr) + elementSize * constructedElementCount), + elementSize(elementSize), constructedElementCount(constructedElementCount), + destroyElement(destroyElement) {} + KJ_DISALLOW_COPY_AND_MOVE(ExceptionSafeArrayUtil); + + inline ~ExceptionSafeArrayUtil() noexcept(false) { + if (constructedElementCount > 0) destroyAll(); + } + + void construct(size_t count, void (*constructElement)(void*)); + // Construct the given number of elements. + + void destroyAll(); + // Destroy all elements. Call this immediately before ExceptionSafeArrayUtil goes out-of-scope + // to ensure that one element throwing an exception does not prevent the others from being + // destroyed. + + void release() { constructedElementCount = 0; } + // Prevent ExceptionSafeArrayUtil's destructor from destroying the constructed elements. + // Call this after you've successfully finished constructing. + +private: + byte* pos; + size_t elementSize; + size_t constructedElementCount; + void (*destroyElement)(void*); +}; + +class DestructorOnlyArrayDisposer: public ArrayDisposer { +public: + static const DestructorOnlyArrayDisposer instance; + + void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; +}; + +class NullArrayDisposer: public ArrayDisposer { + // An ArrayDisposer that does nothing. Can be used to construct a fake Arrays that doesn't + // actually own its content. + +public: + static const NullArrayDisposer instance; + + void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; +}; + +// ======================================================================================= +// Array + +template +class Array { + // An owned array which will automatically be disposed of (using an ArrayDisposer) in the + // destructor. Can be moved, but not copied. Much like Own, but for arrays rather than + // single objects. + +public: + inline Array(): ptr(nullptr), size_(0), disposer(nullptr) {} + inline Array(decltype(nullptr)): ptr(nullptr), size_(0), disposer(nullptr) {} + inline Array(Array&& other) noexcept + : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { + other.ptr = nullptr; + other.size_ = 0; + } + inline Array(Array>&& other) noexcept + : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { + other.ptr = nullptr; + other.size_ = 0; + } + inline Array(T* firstElement KJ_LIFETIMEBOUND, size_t size, const ArrayDisposer& disposer) + : ptr(firstElement), size_(size), disposer(&disposer) {} + + KJ_DISALLOW_COPY(Array); + inline ~Array() noexcept { dispose(); } + + inline operator ArrayPtr() KJ_LIFETIMEBOUND { + return ArrayPtr(ptr, size_); + } + inline operator ArrayPtr() const KJ_LIFETIMEBOUND { + return ArrayPtr(ptr, size_); + } + inline ArrayPtr asPtr() KJ_LIFETIMEBOUND { + return ArrayPtr(ptr, size_); + } + inline ArrayPtr asPtr() const KJ_LIFETIMEBOUND { + return ArrayPtr(ptr, size_); + } + + inline size_t size() const { return size_; } + inline T& operator[](size_t index) KJ_LIFETIMEBOUND { + KJ_IREQUIRE(index < size_, "Out-of-bounds Array access."); + return ptr[index]; + } + inline const T& operator[](size_t index) const KJ_LIFETIMEBOUND { + KJ_IREQUIRE(index < size_, "Out-of-bounds Array access."); + return ptr[index]; + } + + inline const T* begin() const KJ_LIFETIMEBOUND { return ptr; } + inline const T* end() const KJ_LIFETIMEBOUND { return ptr + size_; } + inline const T& front() const KJ_LIFETIMEBOUND { return *ptr; } + inline const T& back() const KJ_LIFETIMEBOUND { return *(ptr + size_ - 1); } + inline T* begin() KJ_LIFETIMEBOUND { return ptr; } + inline T* end() KJ_LIFETIMEBOUND { return ptr + size_; } + inline T& front() KJ_LIFETIMEBOUND { return *ptr; } + inline T& back() KJ_LIFETIMEBOUND { return *(ptr + size_ - 1); } + + template + inline bool operator==(const U& other) const { return asPtr() == other; } + template + inline bool operator!=(const U& other) const { return asPtr() != other; } + + inline ArrayPtr slice(size_t start, size_t end) KJ_LIFETIMEBOUND { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); + return ArrayPtr(ptr + start, end - start); + } + inline ArrayPtr slice(size_t start, size_t end) const KJ_LIFETIMEBOUND { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); + return ArrayPtr(ptr + start, end - start); + } + + inline ArrayPtr asBytes() const KJ_LIFETIMEBOUND { return asPtr().asBytes(); } + inline ArrayPtr> asBytes() KJ_LIFETIMEBOUND { return asPtr().asBytes(); } + inline ArrayPtr asChars() const KJ_LIFETIMEBOUND { return asPtr().asChars(); } + inline ArrayPtr> asChars() KJ_LIFETIMEBOUND { return asPtr().asChars(); } + + inline Array> releaseAsBytes() { + // Like asBytes() but transfers ownership. + static_assert(sizeof(T) == sizeof(byte), + "releaseAsBytes() only possible on arrays with byte-size elements (e.g. chars)."); + Array> result( + reinterpret_cast*>(ptr), size_, *disposer); + ptr = nullptr; + size_ = 0; + return result; + } + inline Array> releaseAsChars() { + // Like asChars() but transfers ownership. + static_assert(sizeof(T) == sizeof(PropagateConst), + "releaseAsChars() only possible on arrays with char-size elements (e.g. bytes)."); + Array> result( + reinterpret_cast*>(ptr), size_, *disposer); + ptr = nullptr; + size_ = 0; + return result; + } + + inline bool operator==(decltype(nullptr)) const { return size_ == 0; } + inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } + + inline Array& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + inline Array& operator=(Array&& other) { + dispose(); + ptr = other.ptr; + size_ = other.size_; + disposer = other.disposer; + other.ptr = nullptr; + other.size_ = 0; + return *this; + } + + template + Array attach(Attachments&&... attachments) KJ_WARN_UNUSED_RESULT; + // Like Own::attach(), but attaches to an Array. + +private: + T* ptr; + size_t size_; + const ArrayDisposer* disposer; + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + size_t sizeCopy = size_; + if (ptrCopy != nullptr) { + ptr = nullptr; + size_ = 0; + disposer->dispose(ptrCopy, sizeCopy, sizeCopy); + } + } + + template + friend class Array; + template + friend class ArrayBuilder; +}; + +static_assert(!canMemcpy>(), "canMemcpy<>() is broken"); + +namespace _ { // private + +class HeapArrayDisposer final: public ArrayDisposer { +public: + template + static T* allocate(size_t count); + template + static T* allocateUninitialized(size_t count); + + static const HeapArrayDisposer instance; + +private: + static void* allocateImpl(size_t elementSize, size_t elementCount, size_t capacity, + void (*constructElement)(void*), void (*destroyElement)(void*)); + // Allocates and constructs the array. Both function pointers are null if the constructor is + // trivial, otherwise destroyElement is null if the constructor doesn't throw. + + virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, + size_t capacity, void (*destroyElement)(void*)) const override; + + template + struct Allocate_; +}; + +} // namespace _ (private) + +template +inline Array heapArray(size_t size) { + // Much like `heap()` from memory.h, allocates a new array on the heap. + + return Array(_::HeapArrayDisposer::allocate(size), size, + _::HeapArrayDisposer::instance); +} + +template Array heapArray(const T* content, size_t size); +template Array heapArray(ArrayPtr content); +template Array heapArray(ArrayPtr content); +template Array heapArray(Iterator begin, Iterator end); +template Array heapArray(std::initializer_list init); +// Allocate a heap array containing a copy of the given content. + +template +Array heapArrayFromIterable(Container&& a) { return heapArray(a.begin(), a.end()); } +template +Array heapArrayFromIterable(Array&& a) { return mv(a); } + +// ======================================================================================= +// ArrayBuilder + +template +class ArrayBuilder { + // Class which lets you build an Array specifying the exact constructor arguments for each + // element, rather than starting by default-constructing them. + +public: + ArrayBuilder(): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} + ArrayBuilder(decltype(nullptr)): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} + explicit ArrayBuilder(RemoveConst* firstElement, size_t capacity, + const ArrayDisposer& disposer) + : ptr(firstElement), pos(firstElement), endPtr(firstElement + capacity), + disposer(&disposer) {} + ArrayBuilder(ArrayBuilder&& other) + : ptr(other.ptr), pos(other.pos), endPtr(other.endPtr), disposer(other.disposer) { + other.ptr = nullptr; + other.pos = nullptr; + other.endPtr = nullptr; + } + ArrayBuilder(Array&& other) + : ptr(other.ptr), pos(other.ptr + other.size_), endPtr(pos), disposer(other.disposer) { + // Create an already-full ArrayBuilder from an Array of the same type. This constructor + // primarily exists to enable Vector to be constructed from Array. + other.ptr = nullptr; + other.size_ = 0; + } + KJ_DISALLOW_COPY(ArrayBuilder); + inline ~ArrayBuilder() noexcept(false) { dispose(); } + + inline operator ArrayPtr() KJ_LIFETIMEBOUND { + return arrayPtr(ptr, pos); + } + inline operator ArrayPtr() const KJ_LIFETIMEBOUND { + return arrayPtr(ptr, pos); + } + inline ArrayPtr asPtr() KJ_LIFETIMEBOUND { + return arrayPtr(ptr, pos); + } + inline ArrayPtr asPtr() const KJ_LIFETIMEBOUND { + return arrayPtr(ptr, pos); + } + + inline size_t size() const { return pos - ptr; } + inline size_t capacity() const { return endPtr - ptr; } + inline T& operator[](size_t index) KJ_LIFETIMEBOUND { + KJ_IREQUIRE(index < implicitCast(pos - ptr), "Out-of-bounds Array access."); + return ptr[index]; + } + inline const T& operator[](size_t index) const KJ_LIFETIMEBOUND { + KJ_IREQUIRE(index < implicitCast(pos - ptr), "Out-of-bounds Array access."); + return ptr[index]; + } + + inline const T* begin() const KJ_LIFETIMEBOUND { return ptr; } + inline const T* end() const KJ_LIFETIMEBOUND { return pos; } + inline const T& front() const KJ_LIFETIMEBOUND { return *ptr; } + inline const T& back() const KJ_LIFETIMEBOUND { return *(pos - 1); } + inline T* begin() KJ_LIFETIMEBOUND { return ptr; } + inline T* end() KJ_LIFETIMEBOUND { return pos; } + inline T& front() KJ_LIFETIMEBOUND { return *ptr; } + inline T& back() KJ_LIFETIMEBOUND { return *(pos - 1); } + + ArrayBuilder& operator=(ArrayBuilder&& other) { + dispose(); + ptr = other.ptr; + pos = other.pos; + endPtr = other.endPtr; + disposer = other.disposer; + other.ptr = nullptr; + other.pos = nullptr; + other.endPtr = nullptr; + return *this; + } + ArrayBuilder& operator=(decltype(nullptr)) { + dispose(); + return *this; + } + + template + T& add(Params&&... params) KJ_LIFETIMEBOUND { + KJ_IREQUIRE(pos < endPtr, "Added too many elements to ArrayBuilder."); + ctor(*pos, kj::fwd(params)...); + return *pos++; + } + + template + void addAll(Container&& container) { + addAll()>( + container.begin(), container.end()); + } + + template + void addAll(Iterator start, Iterator end); + + void removeLast() { + KJ_IREQUIRE(pos > ptr, "No elements present to remove."); + kj::dtor(*--pos); + } + + void truncate(size_t size) { + KJ_IREQUIRE(size <= this->size(), "can't use truncate() to expand"); + + T* target = ptr + size; + if (KJ_HAS_TRIVIAL_DESTRUCTOR(T)) { + pos = target; + } else { + while (pos > target) { + kj::dtor(*--pos); + } + } + } + + void clear() { + if (KJ_HAS_TRIVIAL_DESTRUCTOR(T)) { + pos = ptr; + } else { + while (pos > ptr) { + kj::dtor(*--pos); + } + } + } + + void resize(size_t size) { + KJ_IREQUIRE(size <= capacity(), "can't resize past capacity"); + + T* target = ptr + size; + if (target > pos) { + // expand + if (KJ_HAS_TRIVIAL_CONSTRUCTOR(T)) { + pos = target; + } else { + while (pos < target) { + kj::ctor(*pos++); + } + } + } else { + // truncate + if (KJ_HAS_TRIVIAL_DESTRUCTOR(T)) { + pos = target; + } else { + while (pos > target) { + kj::dtor(*--pos); + } + } + } + } + + Array finish() { + // We could safely remove this check if we assume that the disposer implementation doesn't + // need to know the original capacity, as is the case with HeapArrayDisposer since it uses + // operator new() or if we created a custom disposer for ArrayBuilder which stores the capacity + // in a prefix. But that would make it hard to write cleverer heap allocators, and anyway this + // check might catch bugs. Probably people should use Vector if they want to build arrays + // without knowing the final size in advance. + KJ_IREQUIRE(pos == endPtr, "ArrayBuilder::finish() called prematurely."); + Array result(reinterpret_cast(ptr), pos - ptr, *disposer); + ptr = nullptr; + pos = nullptr; + endPtr = nullptr; + return result; + } + + inline bool isFull() const { + return pos == endPtr; + } + +private: + T* ptr; + RemoveConst* pos; + T* endPtr; + const ArrayDisposer* disposer = &NullArrayDisposer::instance; + + inline void dispose() { + // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly + // dispose again. + T* ptrCopy = ptr; + T* posCopy = pos; + T* endCopy = endPtr; + if (ptrCopy != nullptr) { + ptr = nullptr; + pos = nullptr; + endPtr = nullptr; + disposer->dispose(ptrCopy, posCopy - ptrCopy, endCopy - ptrCopy); + } + } +}; + +template +inline ArrayBuilder heapArrayBuilder(size_t size) { + // Like `heapArray()` but does not default-construct the elements. You must construct them + // manually by calling `add()`. + + return ArrayBuilder(_::HeapArrayDisposer::allocateUninitialized>(size), + size, _::HeapArrayDisposer::instance); +} + +// ======================================================================================= +// Inline Arrays + +template +class FixedArray { + // A fixed-width array whose storage is allocated inline rather than on the heap. + +public: + inline constexpr size_t size() const { return fixedSize; } + inline constexpr T* begin() KJ_LIFETIMEBOUND { return content; } + inline constexpr T* end() KJ_LIFETIMEBOUND { return content + fixedSize; } + inline constexpr const T* begin() const KJ_LIFETIMEBOUND { return content; } + inline constexpr const T* end() const KJ_LIFETIMEBOUND { return content + fixedSize; } + + inline constexpr operator ArrayPtr() KJ_LIFETIMEBOUND { + return arrayPtr(content, fixedSize); + } + inline constexpr operator ArrayPtr() const KJ_LIFETIMEBOUND { + return arrayPtr(content, fixedSize); + } + + inline constexpr T& operator[](size_t index) KJ_LIFETIMEBOUND { return content[index]; } + inline constexpr const T& operator[](size_t index) const KJ_LIFETIMEBOUND { + return content[index]; + } + +private: + T content[fixedSize]; +}; + +template +class CappedArray { + // Like `FixedArray` but can be dynamically resized as long as the size does not exceed the limit + // specified by the template parameter. + // + // TODO(someday): Don't construct elements past currentSize? + +public: + inline KJ_CONSTEXPR() CappedArray(): currentSize(fixedSize) {} + inline explicit constexpr CappedArray(size_t s): currentSize(s) {} + + inline size_t size() const { return currentSize; } + inline void setSize(size_t s) { KJ_IREQUIRE(s <= fixedSize); currentSize = s; } + inline T* begin() KJ_LIFETIMEBOUND { return content; } + inline T* end() KJ_LIFETIMEBOUND { return content + currentSize; } + inline const T* begin() const KJ_LIFETIMEBOUND { return content; } + inline const T* end() const KJ_LIFETIMEBOUND { return content + currentSize; } + + inline operator ArrayPtr() KJ_LIFETIMEBOUND { + return arrayPtr(content, currentSize); + } + inline operator ArrayPtr() const KJ_LIFETIMEBOUND { + return arrayPtr(content, currentSize); + } + + inline T& operator[](size_t index) KJ_LIFETIMEBOUND { return content[index]; } + inline const T& operator[](size_t index) const KJ_LIFETIMEBOUND { return content[index]; } + +private: + size_t currentSize; + T content[fixedSize]; +}; + +// ======================================================================================= +// KJ_MAP + +#define KJ_MAP(elementName, array) \ + ::kj::_::Mapper(array) * \ + [&](typename ::kj::_::Mapper::Element elementName) +// Applies some function to every element of an array, returning an Array of the results, with +// nice syntax. Example: +// +// StringPtr foo = "abcd"; +// Array bar = KJ_MAP(c, foo) -> char { return c + 1; }; +// KJ_ASSERT(str(bar) == "bcde"); + +namespace _ { // private + +template +struct Mapper { + T array; + Mapper(T&& array): array(kj::fwd(array)) {} + template + auto operator*(Func&& func) -> Array { + auto builder = heapArrayBuilder(array.size()); + for (auto iter = array.begin(); iter != array.end(); ++iter) { + builder.add(func(*iter)); + } + return builder.finish(); + } + typedef decltype(*kj::instance().begin()) Element; +}; + +template +struct Mapper { + T* array; + Mapper(T* array): array(array) {} + template + auto operator*(Func&& func) -> Array { + auto builder = heapArrayBuilder(s); + for (size_t i = 0; i < s; i++) { + builder.add(func(array[i])); + } + return builder.finish(); + } + typedef decltype(*array)& Element; +}; + +} // namespace _ (private) + +// ======================================================================================= +// Inline implementation details + +template +struct ArrayDisposer::Dispose_ { + static void dispose(T* firstElement, size_t elementCount, size_t capacity, + const ArrayDisposer& disposer) { + disposer.disposeImpl(const_cast*>(firstElement), + sizeof(T), elementCount, capacity, nullptr); + } +}; +template +struct ArrayDisposer::Dispose_ { + static void destruct(void* ptr) { + kj::dtor(*reinterpret_cast(ptr)); + } + + static void dispose(T* firstElement, size_t elementCount, size_t capacity, + const ArrayDisposer& disposer) { + disposer.disposeImpl(const_cast*>(firstElement), + sizeof(T), elementCount, capacity, &destruct); + } +}; + +template +void ArrayDisposer::dispose(T* firstElement, size_t elementCount, size_t capacity) const { + Dispose_::dispose(firstElement, elementCount, capacity, *this); +} + +namespace _ { // private + +template +struct HeapArrayDisposer::Allocate_ { + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast(allocateImpl( + sizeof(T), elementCount, capacity, nullptr, nullptr)); + } +}; +template +struct HeapArrayDisposer::Allocate_ { + static void construct(void* ptr) { + kj::ctor(*reinterpret_cast(ptr)); + } + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast(allocateImpl( + sizeof(T), elementCount, capacity, &construct, nullptr)); + } +}; +template +struct HeapArrayDisposer::Allocate_ { + static void construct(void* ptr) { + kj::ctor(*reinterpret_cast(ptr)); + } + static void destruct(void* ptr) { + kj::dtor(*reinterpret_cast(ptr)); + } + static T* allocate(size_t elementCount, size_t capacity) { + return reinterpret_cast(allocateImpl( + sizeof(T), elementCount, capacity, &construct, &destruct)); + } +}; + +template +T* HeapArrayDisposer::allocate(size_t count) { + return Allocate_::allocate(count, count); +} + +template +T* HeapArrayDisposer::allocateUninitialized(size_t count) { + return Allocate_::allocate(0, count); +} + +template ()> +struct CopyConstructArray_; + +template +struct CopyConstructArray_ { + static inline T* apply(T* __restrict__ pos, T* start, T* end) { + if (end != start) { + memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); + } + return pos + (end - start); + } +}; + +template +struct CopyConstructArray_ { + static inline T* apply(T* __restrict__ pos, const T* start, const T* end) { + if (end != start) { + memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); + } + return pos + (end - start); + } +}; + +template +struct CopyConstructArray_ { + static inline T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Since both the copy constructor and assignment operator are trivial, we know that assignment + // is equivalent to copy-constructing. So we can make this case somewhat easier for the + // compiler to optimize. + while (start != end) { + *pos++ = *start++; + } + return pos; + } +}; + +template +struct CopyConstructArray_ { + struct ExceptionGuard { + T* start; + T* pos; + inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} + ~ExceptionGuard() noexcept(false) { + while (pos > start) { + dtor(*--pos); + } + } + }; + + static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Verify that T can be *implicitly* constructed from the source values. + if (false) implicitCast(*start); + + if (noexcept(T(*start))) { + while (start != end) { + ctor(*pos++, *start++); + } + return pos; + } else { + // Crap. This is complicated. + ExceptionGuard guard(pos); + while (start != end) { + ctor(*guard.pos, *start++); + ++guard.pos; + } + guard.start = guard.pos; + return guard.pos; + } + } +}; + +template +struct CopyConstructArray_ { + // Actually move-construct. + + struct ExceptionGuard { + T* start; + T* pos; + inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} + ~ExceptionGuard() noexcept(false) { + while (pos > start) { + dtor(*--pos); + } + } + }; + + static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Verify that T can be *implicitly* constructed from the source values. + if (false) implicitCast(kj::mv(*start)); + + if (noexcept(T(kj::mv(*start)))) { + while (start != end) { + ctor(*pos++, kj::mv(*start++)); + } + return pos; + } else { + // Crap. This is complicated. + ExceptionGuard guard(pos); + while (start != end) { + ctor(*guard.pos, kj::mv(*start++)); + ++guard.pos; + } + guard.start = guard.pos; + return guard.pos; + } + } +}; + +} // namespace _ (private) + +template +template +void ArrayBuilder::addAll(Iterator start, Iterator end) { + pos = _::CopyConstructArray_, Decay, move>::apply(pos, start, end); +} + +template +Array heapArray(const T* content, size_t size) { + ArrayBuilder builder = heapArrayBuilder(size); + builder.addAll(content, content + size); + return builder.finish(); +} + +template +Array heapArray(T* content, size_t size) { + ArrayBuilder builder = heapArrayBuilder(size); + builder.addAll(content, content + size); + return builder.finish(); +} + +template +Array heapArray(ArrayPtr content) { + ArrayBuilder builder = heapArrayBuilder(content.size()); + builder.addAll(content); + return builder.finish(); +} + +template +Array heapArray(ArrayPtr content) { + ArrayBuilder builder = heapArrayBuilder(content.size()); + builder.addAll(content); + return builder.finish(); +} + +template Array +heapArray(Iterator begin, Iterator end) { + ArrayBuilder builder = heapArrayBuilder(end - begin); + builder.addAll(begin, end); + return builder.finish(); +} + +template +inline Array heapArray(std::initializer_list init) { + return heapArray(init.begin(), init.end()); +} + +#if __cplusplus > 201402L +template +inline Array> arr(T&& param1, Params&&... params) { + ArrayBuilder> builder = heapArrayBuilder>(sizeof...(params) + 1); + (builder.add(kj::fwd(param1)), ... , builder.add(kj::fwd(params))); + return builder.finish(); +} +template +inline Array> arrOf(Params&&... params) { + ArrayBuilder> builder = heapArrayBuilder>(sizeof...(params)); + (... , builder.add(kj::fwd(params))); + return builder.finish(); +} +#endif + +namespace _ { // private + +template +struct ArrayDisposableOwnedBundle final: public ArrayDisposer, public OwnedBundle { + ArrayDisposableOwnedBundle(T&&... values): OwnedBundle(kj::fwd(values)...) {} + void disposeImpl(void*, size_t, size_t, size_t, void (*)(void*)) const override { delete this; } +}; + +} // namespace _ (private) + +template +template +Array Array::attach(Attachments&&... attachments) { + T* ptrCopy = ptr; + auto sizeCopy = size_; + + KJ_IREQUIRE(ptrCopy != nullptr, "cannot attach to null pointer"); + + // HACK: If someone accidentally calls .attach() on a null pointer in opt mode, try our best to + // accomplish reasonable behavior: We turn the pointer non-null but still invalid, so that the + // disposer will still be called when the pointer goes out of scope. + if (ptrCopy == nullptr) ptrCopy = reinterpret_cast(1); + + auto bundle = new _::ArrayDisposableOwnedBundle, Attachments...>( + kj::mv(*this), kj::fwd(attachments)...); + return Array(ptrCopy, sizeCopy, *bundle); +} + +template +template +Array ArrayPtr::attach(Attachments&&... attachments) const { + T* ptrCopy = ptr; + + KJ_IREQUIRE(ptrCopy != nullptr, "cannot attach to null pointer"); + + // HACK: If someone accidentally calls .attach() on a null pointer in opt mode, try our best to + // accomplish reasonable behavior: We turn the pointer non-null but still invalid, so that the + // disposer will still be called when the pointer goes out of scope. + if (ptrCopy == nullptr) ptrCopy = reinterpret_cast(1); + + auto bundle = new _::ArrayDisposableOwnedBundle( + kj::fwd(attachments)...); + return Array(ptrCopy, size_, *bundle); +} + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/common.cc b/src/plugins/streamers/lstream/runtime/kj/kj/common.cc new file mode 100644 index 000000000..8960b2316 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/common.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "common.h" +#include "debug.h" +#include + +namespace kj { +namespace _ { // private + +void inlineRequireFailure(const char* file, int line, const char* expectation, + const char* macroArgs, const char* message) { + if (message == nullptr) { + Debug::Fault f(file, line, kj::Exception::Type::FAILED, expectation, macroArgs); + f.fatal(); + } else { + Debug::Fault f(file, line, kj::Exception::Type::FAILED, expectation, macroArgs, message); + f.fatal(); + } +} + +void unreachable() { + KJ_FAIL_ASSERT("Supposedly-unreachable branch executed."); + + // Really make sure we abort. + KJ_KNOWN_UNREACHABLE(abort()); +} + +} // namespace _ (private) + +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/common.h b/src/plugins/streamers/lstream/runtime/kj/kj/common.h new file mode 100644 index 000000000..c5a1c102a --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/common.h @@ -0,0 +1,2039 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Header that should be #included by everyone. +// +// This defines very simple utilities that are widely applicable. + +#pragma once + +#if defined(__GNUC__) || defined(__clang__) +#define KJ_BEGIN_SYSTEM_HEADER _Pragma("GCC system_header") +#elif defined(_MSC_VER) +#define KJ_BEGIN_SYSTEM_HEADER __pragma(warning(push, 0)) +#define KJ_END_SYSTEM_HEADER __pragma(warning(pop)) +#endif + +#ifndef KJ_BEGIN_SYSTEM_HEADER +#define KJ_BEGIN_SYSTEM_HEADER +#endif + +#ifndef KJ_END_SYSTEM_HEADER +#define KJ_END_SYSTEM_HEADER +#endif + +#if !defined(KJ_HEADER_WARNINGS) || !KJ_HEADER_WARNINGS +#define KJ_BEGIN_HEADER KJ_BEGIN_SYSTEM_HEADER +#define KJ_END_HEADER KJ_END_SYSTEM_HEADER +#else +#define KJ_BEGIN_HEADER +#define KJ_END_HEADER +#endif + +#ifdef __has_cpp_attribute +#define KJ_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define KJ_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +#ifdef __has_feature +#define KJ_HAS_COMPILER_FEATURE(x) __has_feature(x) +#else +#define KJ_HAS_COMPILER_FEATURE(x) 0 +#endif + +KJ_BEGIN_HEADER + +#ifndef KJ_NO_COMPILER_CHECK +// Technically, __cplusplus should be 201402L for C++14, but GCC 4.9 -- which is supported -- still +// had it defined to 201300L even with -std=c++14. +#if __cplusplus < 201300L && !__CDT_PARSER__ && !_MSC_VER + #error "This code requires C++14. Either your compiler does not support it or it is not enabled." + #ifdef __GNUC__ + // Compiler claims compatibility with GCC, so presumably supports -std. + #error "Pass -std=c++14 on the compiler command line to enable C++14." + #endif +#endif + +#ifdef __GNUC__ + #if __clang__ + #if __clang_major__ < 5 + #warning "This library requires at least Clang 5.0." + #elif __cplusplus >= 201402L && !__has_include() + #warning "Your compiler supports C++14 but your C++ standard library does not. If your "\ + "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ + "-stdlib=libc++ to your CXXFLAGS." + #endif + #else + #if __GNUC__ < 5 + #warning "This library requires at least GCC 5.0." + #endif + #endif +#elif defined(_MSC_VER) + #if _MSC_VER < 1910 && !defined(__clang__) + #error "You need Visual Studio 2017 or better to compile this code." + #endif +#else + #warning "I don't recognize your compiler. As of this writing, Clang, GCC, and Visual Studio "\ + "are the only known compilers with enough C++14 support for this library. "\ + "#define KJ_NO_COMPILER_CHECK to make this warning go away." +#endif +#endif + +#include +#include +#include +#include + +#if __linux__ && __cplusplus > 201200L +// Hack around stdlib bug with C++14 that exists on some Linux systems. +// Apparently in this mode the C library decides not to define gets() but the C++ library still +// tries to import it into the std namespace. This bug has been fixed at the source but is still +// widely present in the wild e.g. on Ubuntu 14.04. +#undef _GLIBCXX_HAVE_GETS +#endif + +#if _WIN32 +// Windows likes to define macros for min() and max(). We just can't deal with this. +// If windows.h was included already, undef these. +#undef min +#undef max +// If windows.h was not included yet, define the macro that prevents min() and max() from being +// defined. +#ifndef NOMINMAX +#define NOMINMAX 1 +#endif +#endif + +#if defined(_MSC_VER) +#include // __popcnt +#endif + +// ======================================================================================= + +namespace kj { + +typedef unsigned int uint; +typedef unsigned char byte; + +// ======================================================================================= +// Common macros, especially for common yet compiler-specific features. + +// Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific +// evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly +// to override these checks. + +// TODO: Ideally we'd use __cpp_exceptions/__cpp_rtti not being defined as the first pass since +// that is the standard compliant way. However, it's unclear how to use those macros (or any +// others) to distinguish between the compiler supporting feature detection and the feature being +// disabled vs the compiler not supporting feature detection at all. +#if defined(__has_feature) + #if !defined(KJ_NO_RTTI) && !__has_feature(cxx_rtti) + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !__has_feature(cxx_exceptions) + #define KJ_NO_EXCEPTIONS 1 + #endif +#elif defined(__GNUC__) + #if !defined(KJ_NO_RTTI) && !__GXX_RTTI + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS + #define KJ_NO_EXCEPTIONS 1 + #endif +#elif defined(_MSC_VER) + #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) + #define KJ_NO_RTTI 1 + #endif + #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) + #define KJ_NO_EXCEPTIONS 1 + #endif +#endif + +#if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) +// Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. +// Otherwise, fall back to checking whether optimization is enabled. +#if defined(DEBUG) || defined(_DEBUG) +#define KJ_DEBUG +#elif defined(NDEBUG) +#define KJ_NDEBUG +#elif __OPTIMIZE__ +#define KJ_NDEBUG +#else +#define KJ_DEBUG +#endif +#endif + +#define KJ_DISALLOW_COPY(classname) \ + classname(const classname&) = delete; \ + classname& operator=(const classname&) = delete +// Deletes the implicit copy constructor and assignment operator. This inhibits the compiler from +// generating the implicit move constructor and assignment operator for this class, but allows the +// code author to supply them, if they make sense to implement. +// +// This macro should not be your first choice. Instead, prefer using KJ_DISALLOW_COPY_AND_MOVE, and only use +// this macro when you have determined that you must implement move semantics for your type. + +#define KJ_DISALLOW_COPY_AND_MOVE(classname) \ + classname(const classname&) = delete; \ + classname& operator=(const classname&) = delete; \ + classname(classname&&) = delete; \ + classname& operator=(classname&&) = delete +// Deletes the implicit copy and move constructors and assignment operators. This is useful in cases +// where the code author wants to provide an additional compile-time guard against subsequent +// maintainers casually adding move operations. This is particularly useful when implementing RAII +// classes that are intended to be completely immobile. + +#ifdef __GNUC__ +#define KJ_LIKELY(condition) __builtin_expect(condition, true) +#define KJ_UNLIKELY(condition) __builtin_expect(condition, false) +// Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we +// expect the condition to be true/false enough of the time that it's worth hard-coding branch +// prediction. +#else +#define KJ_LIKELY(condition) (condition) +#define KJ_UNLIKELY(condition) (condition) +#endif + +#if defined(KJ_DEBUG) || __NO_INLINE__ +#define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ +// Don't force inline in debug mode. +#else +#if defined(_MSC_VER) && !defined(__clang__) +#define KJ_ALWAYS_INLINE(...) __forceinline __VA_ARGS__ +#else +#define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ __attribute__((always_inline)) +#endif +// Force a function to always be inlined. Apply only to the prototype, not to the definition. +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define KJ_NOINLINE __declspec(noinline) +#else +#define KJ_NOINLINE __attribute__((noinline)) +#endif + +#if defined(_MSC_VER) && !__clang__ +#define KJ_NORETURN(prototype) __declspec(noreturn) prototype +#define KJ_UNUSED +#define KJ_WARN_UNUSED_RESULT +// TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so +// wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx +// Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. +#else +#define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) +#define KJ_UNUSED __attribute__((unused)) +#define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#endif + +#if KJ_HAS_CPP_ATTRIBUTE(clang::lifetimebound) +// If this is generating too many false-positives, the user is responsible for disabling the +// problematic warning at the compiler switch level or by suppressing the place where the +// false-positive is reported through compiler-specific pragmas if available. +#define KJ_LIFETIMEBOUND [[clang::lifetimebound]] +#else +#define KJ_LIFETIMEBOUND +#endif +// Annotation that indicates the returned value is referencing a resource owned by this type (e.g. +// cStr() on a std::string). Unfortunately this lifetime can only be superficial currently & cannot +// track further. For example, there's no way to get `array.asPtr().slice(5, 6))` to warn if the +// last slice exceeds the lifetime of `array`. That's because in the general case `ArrayPtr::slice` +// can't have the lifetime bound annotation since it's not wrong to do something like: +// ArrayPtr doSomething(ArrayPtr foo) { +// ... +// return foo.slice(5, 6); +// } +// If `ArrayPtr::slice` had a lifetime bound then the compiler would warn about this perfectly +// legitimate method. Really there needs to be 2 more annotations. One to inherit the lifetime bound +// and another to inherit the lifetime bound from a parameter (which really could be the same thing +// by allowing a syntax like `[[clang::lifetimebound(*this)]]`. +// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound + +#if __clang__ +#define KJ_UNUSED_MEMBER __attribute__((unused)) +// Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC +// complains if the attribute is set on members. +#else +#define KJ_UNUSED_MEMBER +#endif + +#if __cplusplus > 201703L || (__clang__ && __clang_major__ >= 9 && __cplusplus >= 201103L) +// Technically this was only added to C++20 but Clang allows it for >= C++11 and spelunking the +// attributes manual indicates it first came in with Clang 9. +#define KJ_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else +#define KJ_NO_UNIQUE_ADDRESS +#endif + +#if KJ_HAS_COMPILER_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) +#define KJ_DISABLE_TSAN __attribute__((no_sanitize("thread"), noinline)) +#else +#define KJ_DISABLE_TSAN +#endif + +#if __clang__ +#define KJ_DEPRECATED(reason) \ + __attribute__((deprecated(reason))) +#define KJ_UNAVAILABLE(reason) \ + __attribute__((unavailable(reason))) +#elif __GNUC__ +#define KJ_DEPRECATED(reason) \ + __attribute__((deprecated)) +#define KJ_UNAVAILABLE(reason) = delete +// If the `unavailable` attribute is not supproted, just mark the method deleted, which at least +// makes it a compile-time error to try to call it. Note that on Clang, marking a method deleted +// *and* unavailable unfortunately defeats the purpose of the unavailable annotation, as the +// generic "deleted" error is reported instead. +#else +#define KJ_DEPRECATED(reason) +#define KJ_UNAVAILABLE(reason) = delete +// TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). +#endif + +#if KJ_TESTING_KJ // defined in KJ's own unit tests; others should not define this +#undef KJ_DEPRECATED +#define KJ_DEPRECATED(reason) +#endif + +namespace _ { // private + +KJ_NORETURN(void inlineRequireFailure( + const char* file, int line, const char* expectation, const char* macroArgs, + const char* message = nullptr)); + +KJ_NORETURN(void unreachable()); + +} // namespace _ (private) + +#if _MSC_VER && !defined(__clang__) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) +#define KJ_MSVC_TRADITIONAL_CPP 1 +#endif + +#ifdef KJ_DEBUG +#if KJ_MSVC_TRADITIONAL_CPP +#define KJ_IREQUIRE(condition, ...) \ + if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ + __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) +// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to +// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that +// it will be enabled depending on whether the application is compiled in debug mode rather than +// whether libkj is. +#else +#define KJ_IREQUIRE(condition, ...) \ + if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ + __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) +// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to +// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that +// it will be enabled depending on whether the application is compiled in debug mode rather than +// whether libkj is. +#endif +#else +#define KJ_IREQUIRE(condition, ...) +#endif + +#define KJ_IASSERT KJ_IREQUIRE + +#define KJ_UNREACHABLE ::kj::_::unreachable(); +// Put this on code paths that cannot be reached to suppress compiler warnings about missing +// returns. + +#if __clang__ +#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT +#else +#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE +#endif + +#if __clang__ +#define KJ_KNOWN_UNREACHABLE(code) \ + do { \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wunreachable-code\"") \ + code; \ + _Pragma("clang diagnostic pop") \ + } while (false) +// Suppress "unreachable code" warnings on intentionally unreachable code. +#else +// TODO(someday): Add support for non-clang compilers. +#define KJ_KNOWN_UNREACHABLE(code) do {code;} while(false) +#endif + +#if KJ_HAS_CPP_ATTRIBUTE(fallthrough) +#define KJ_FALLTHROUGH [[fallthrough]] +#else +#define KJ_FALLTHROUGH +#endif + +// #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) +// +// Allocate an array, preferably on the stack, unless it is too big. On GCC this will use +// variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` +// is the stack array size to use if variable-width arrays are not supported. `maxStack` is the +// maximum stack array size if variable-width arrays *are* supported. +#if __GNUC__ && !__clang__ +#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ + size_t name##_size = (size); \ + bool name##_isOnStack = name##_size <= (maxStack); \ + type name##_stack[kj::max(1, name##_isOnStack ? name##_size : 0)]; \ + ::kj::Array name##_heap = name##_isOnStack ? \ + nullptr : kj::heapArray(name##_size); \ + ::kj::ArrayPtr name = name##_isOnStack ? \ + kj::arrayPtr(name##_stack, name##_size) : name##_heap +#else +#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ + size_t name##_size = (size); \ + bool name##_isOnStack = name##_size <= (minStack); \ + type name##_stack[minStack]; \ + ::kj::Array name##_heap = name##_isOnStack ? \ + nullptr : kj::heapArray(name##_size); \ + ::kj::ArrayPtr name = name##_isOnStack ? \ + kj::arrayPtr(name##_stack, name##_size) : name##_heap +#endif + +#define KJ_CONCAT_(x, y) x##y +#define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) +#define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) +// Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that +// the name can be used multiple times in the same macro. + +#if _MSC_VER && !defined(__clang__) + +#define KJ_CONSTEXPR(...) __VA_ARGS__ +// Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be +// provided, or just leave blank to remove the keyword entirely. +// +// TODO(msvc): Remove this hack once MSVC fully supports constexpr. + +#ifndef __restrict__ +#define __restrict__ __restrict +// TODO(msvc): Would it be better to define a KJ_RESTRICT macro? +#endif + +#pragma warning(disable: 4521 4522) +// This warning complains when there are two copy constructors, one for a const reference and +// one for a non-const reference. It is often quite necessary to do this in wrapper templates, +// therefore this warning is dumb and we disable it. + +#pragma warning(disable: 4458) +// Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, +// since I don't use a special name format for members. + +#else // _MSC_VER +#define KJ_CONSTEXPR(...) constexpr +#endif + +// ======================================================================================= +// Template metaprogramming helpers. + +#define KJ_HAS_TRIVIAL_CONSTRUCTOR __is_trivially_constructible +#if __GNUC__ && !__clang__ +#define KJ_HAS_NOTHROW_CONSTRUCTOR __has_nothrow_constructor +#define KJ_HAS_TRIVIAL_DESTRUCTOR __has_trivial_destructor +#else +#define KJ_HAS_NOTHROW_CONSTRUCTOR __is_nothrow_constructible +#define KJ_HAS_TRIVIAL_DESTRUCTOR __is_trivially_destructible +#endif + +template struct NoInfer_ { typedef T Type; }; +template using NoInfer = typename NoInfer_::Type; +// Use NoInfer::Type in place of T for a template function parameter to prevent inference of +// the type based on the parameter value. + +template struct RemoveConst_ { typedef T Type; }; +template struct RemoveConst_ { typedef T Type; }; +template using RemoveConst = typename RemoveConst_::Type; + +template struct IsLvalueReference_ { static constexpr bool value = false; }; +template struct IsLvalueReference_ { static constexpr bool value = true; }; +template +inline constexpr bool isLvalueReference() { return IsLvalueReference_::value; } + +template struct Decay_ { typedef T Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template struct Decay_ { typedef typename Decay_::Type Type; }; +template using Decay = typename Decay_::Type; + +template struct EnableIf_; +template <> struct EnableIf_ { typedef void Type; }; +template using EnableIf = typename EnableIf_::Type; +// Use like: +// +// template ()>> +// void func(T&& t); + +template struct VoidSfinae_ { using Type = void; }; +template using VoidSfinae = typename VoidSfinae_::Type; +// Note: VoidSfinae is std::void_t from C++17. + +template +T instance() noexcept; +// Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify +// instance(). + +struct DisallowConstCopy { + // Inherit from this, or declare a member variable of this type, to prevent the class from being + // copyable from a const reference -- instead, it will only be copyable from non-const references. + // This is useful for enforcing transitive constness of contained pointers. + // + // For example, say you have a type T which contains a pointer. T has non-const methods which + // modify the value at that pointer, but T's const methods are designed to allow reading only. + // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and + // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then + // callers will only be able to copy non-const instances of T. Ideally, there is some + // parallel type ImmutableT which is like a version of T that only has const methods, and can + // be copied from a const T. + // + // Note that due to C++ rules about implicit copy constructors and assignment operators, any + // type that contains or inherits from a type that disallows const copies will also automatically + // disallow const copies. Hey, cool, that's exactly what we want. + +#if CAPNP_DEBUG_TYPES + // Alas! Declaring a defaulted non-const copy constructor tickles a bug which causes GCC and + // Clang to disagree on ABI, using different calling conventions to pass this type, leading to + // immediate segfaults. See: + // https://bugs.llvm.org/show_bug.cgi?id=23764 + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58074 + // + // Because of this, we can't use this technique. We guard it by CAPNP_DEBUG_TYPES so that it + // still applies to the Cap'n Proto developers during internal testing. + + DisallowConstCopy() = default; + DisallowConstCopy(DisallowConstCopy&) = default; + DisallowConstCopy(DisallowConstCopy&&) = default; + DisallowConstCopy& operator=(DisallowConstCopy&) = default; + DisallowConstCopy& operator=(DisallowConstCopy&&) = default; +#endif +}; + +#if _MSC_VER && !defined(__clang__) + +#define KJ_CPCAP(obj) obj=::kj::cp(obj) +// TODO(msvc): MSVC refuses to invoke non-const versions of copy constructors in by-value lambda +// captures. Wrap your captured object in this macro to force the compiler to perform a copy. +// Example: +// +// struct Foo: DisallowConstCopy {}; +// Foo foo; +// auto lambda = [KJ_CPCAP(foo)] {}; + +#else + +#define KJ_CPCAP(obj) obj +// Clang and gcc both already perform copy capturing correctly with non-const copy constructors. + +#endif + +template +struct DisallowConstCopyIfNotConst: public DisallowConstCopy { + // Inherit from this when implementing a template that contains a pointer to T and which should + // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is + // an alias for DisallowConstCopy. +}; + +template +struct DisallowConstCopyIfNotConst {}; + +template struct IsConst_ { static constexpr bool value = false; }; +template struct IsConst_ { static constexpr bool value = true; }; +template constexpr bool isConst() { return IsConst_::value; } + +template struct EnableIfNotConst_ { typedef T Type; }; +template struct EnableIfNotConst_; +template using EnableIfNotConst = typename EnableIfNotConst_::Type; + +template struct EnableIfConst_; +template struct EnableIfConst_ { typedef T Type; }; +template using EnableIfConst = typename EnableIfConst_::Type; + +template struct RemoveConstOrDisable_ { struct Type; }; +template struct RemoveConstOrDisable_ { typedef T Type; }; +template using RemoveConstOrDisable = typename RemoveConstOrDisable_::Type; + +template struct IsReference_ { static constexpr bool value = false; }; +template struct IsReference_ { static constexpr bool value = true; }; +template constexpr bool isReference() { return IsReference_::value; } + +template +struct PropagateConst_ { typedef To Type; }; +template +struct PropagateConst_ { typedef const To Type; }; +template +using PropagateConst = typename PropagateConst_::Type; + +namespace _ { // private + +template +T refIfLvalue(T&&); + +} // namespace _ (private) + +#define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) +// Like decltype(exp), but if exp is an lvalue, produces a reference type. +// +// int i; +// decltype(i) i1(i); // i1 has type int. +// KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. +// KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. +// KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. + +template struct IsSameType_ { static constexpr bool value = false; }; +template struct IsSameType_ { static constexpr bool value = true; }; +template constexpr bool isSameType() { return IsSameType_::value; } + +template constexpr bool isIntegral() { return false; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } +template <> constexpr bool isIntegral() { return true; } + +template +struct CanConvert_ { + static int sfinae(T); + static bool sfinae(...); +}; + +template +constexpr bool canConvert() { + return sizeof(CanConvert_::sfinae(instance())) == sizeof(int); +} + +#if __GNUC__ && !__clang__ && __GNUC__ < 5 +template +constexpr bool canMemcpy() { + // Returns true if T can be copied using memcpy instead of using the copy constructor or + // assignment operator. + + // GCC 4 does not have __is_trivially_constructible and friends, and there doesn't seem to be + // any reliable alternative. __has_trivial_copy() and __has_trivial_assign() return the right + // thing at one point but later on they changed such that a deleted copy constructor was + // considered "trivial" (apparently technically correct, though useless). So, on GCC 4 we give up + // and assume we can't memcpy() at all, and must explicitly copy-construct everything. + return false; +} +#define KJ_ASSERT_CAN_MEMCPY(T) +#else +template +constexpr bool canMemcpy() { + // Returns true if T can be copied using memcpy instead of using the copy constructor or + // assignment operator. + + return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); +} +#define KJ_ASSERT_CAN_MEMCPY(T) \ + static_assert(kj::canMemcpy(), "this code expects this type to be memcpy()-able"); +#endif + +template +class Badge { + // A pattern for marking individual methods such that they can only be called from a specific + // caller class: Make the method public but give it a parameter of type `Badge`. Only + // `Caller` can construct one, so only `Caller` can call the method. + // + // // We only allow calls from the class `Bar`. + // void foo(Badge) + // + // The call site looks like: + // + // foo({}); + // + // This pattern also works well for declaring private constructors, but still being able to use + // them with `kj::heap()`, etc. + // + // Idea from: https://awesomekling.github.io/Serenity-C++-patterns-The-Badge/ + // + // Note that some forms of this idea make the copy constructor private as well, in order to + // prohibit `Badge(*(Badge*)nullptr)`. However, that would prevent badges from + // being passed through forwarding functions like `kj::heap()`, which would ruin one of the main + // use cases for this pattern in KJ. In any case, dereferencing a null pointer is UB; there are + // plenty of other ways to get access to private members if you're willing to go UB. For one-off + // debugging purposes, you might as well use `#define private public` at the top of the file. +private: + Badge() {} + friend T; +}; + +// ======================================================================================= +// Equivalents to std::move() and std::forward(), since these are very commonly needed and the +// std header pulls in lots of other stuff. +// +// We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used +// that the cost of typing more letters outweighs the cost of being slightly harder to understand +// when first encountered. + +template constexpr T&& mv(T& t) noexcept { return static_cast(t); } +template constexpr T&& fwd(NoInfer& t) noexcept { return static_cast(t); } + +template constexpr T cp(T& t) noexcept { return t; } +template constexpr T cp(const T& t) noexcept { return t; } +// Useful to force a copy, particularly to pass into a function that expects T&&. + +template struct ChooseType_; +template struct ChooseType_ { typedef T Type; }; +template struct ChooseType_ { typedef T Type; }; +template struct ChooseType_ { typedef U Type; }; + +template +using WiderType = typename ChooseType_= sizeof(U)>::Type; + +template +inline constexpr auto min(T&& a, U&& b) -> WiderType, Decay> { + return a < b ? WiderType, Decay>(a) : WiderType, Decay>(b); +} + +template +inline constexpr auto max(T&& a, U&& b) -> WiderType, Decay> { + return a > b ? WiderType, Decay>(a) : WiderType, Decay>(b); +} + +template +inline constexpr size_t size(T (&arr)[s]) { return s; } +template +inline constexpr size_t size(T&& arr) { return arr.size(); } +// Returns the size of the parameter, whether the parameter is a regular C array or a container +// with a `.size()` method. + +class MaxValue_ { +private: + template + inline constexpr T maxSigned() const { + return (1ull << (sizeof(T) * 8 - 1)) - 1; + } + template + inline constexpr T maxUnsigned() const { + return ~static_cast(0u); + } + +public: +#define _kJ_HANDLE_TYPE(T) \ + inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ + inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned(); } + _kJ_HANDLE_TYPE(char) + _kJ_HANDLE_TYPE(short) + _kJ_HANDLE_TYPE(int) + _kJ_HANDLE_TYPE(long) + _kJ_HANDLE_TYPE(long long) +#undef _kJ_HANDLE_TYPE + + inline constexpr operator char() const { + // `char` is different from both `signed char` and `unsigned char`, and may be signed or + // unsigned on different platforms. Ugh. + return char(-1) < 0 ? MaxValue_::maxSigned() + : MaxValue_::maxUnsigned(); + } +}; + +class MinValue_ { +private: + template + inline constexpr T minSigned() const { + return 1ull << (sizeof(T) * 8 - 1); + } + template + inline constexpr T minUnsigned() const { + return 0u; + } + +public: +#define _kJ_HANDLE_TYPE(T) \ + inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ + inline constexpr operator unsigned T() const { return MinValue_::minUnsigned(); } + _kJ_HANDLE_TYPE(char) + _kJ_HANDLE_TYPE(short) + _kJ_HANDLE_TYPE(int) + _kJ_HANDLE_TYPE(long) + _kJ_HANDLE_TYPE(long long) +#undef _kJ_HANDLE_TYPE + + inline constexpr operator char() const { + // `char` is different from both `signed char` and `unsigned char`, and may be signed or + // unsigned on different platforms. Ugh. + return char(-1) < 0 ? MinValue_::minSigned() + : MinValue_::minUnsigned(); + } +}; + +static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); +// A special constant which, when cast to an integer type, takes on the maximum possible value of +// that type. This is useful to use as e.g. a parameter to a function because it will be robust +// in the face of changes to the parameter's type. +// +// `char` is not supported, but `signed char` and `unsigned char` are. + +static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); +// A special constant which, when cast to an integer type, takes on the minimum possible value +// of that type. This is useful to use as e.g. a parameter to a function because it will be robust +// in the face of changes to the parameter's type. +// +// `char` is not supported, but `signed char` and `unsigned char` are. + +template +inline bool operator==(T t, MaxValue_) { return t == Decay(maxValue); } +template +inline bool operator==(T t, MinValue_) { return t == Decay(minValue); } + +template +inline constexpr unsigned long long maxValueForBits() { + // Get the maximum integer representable in the given number of bits. + + // 1ull << 64 is unfortunately undefined. + return (bits == 64 ? 0 : (1ull << bits)) - 1; +} + +struct ThrowOverflow { + // Functor which throws an exception complaining about integer overflow. Usually this is used + // with the interfaces in units.h, but is defined here because Cap'n Proto wants to avoid + // including units.h when not using CAPNP_DEBUG_TYPES. + [[noreturn]] void operator()() const; +}; + +#if __GNUC__ || __clang__ || _MSC_VER +inline constexpr float inf() { return __builtin_huge_valf(); } +inline constexpr float nan() { return __builtin_nanf(""); } + +#else +#error "Not sure how to support your compiler." +#endif + +inline constexpr bool isNaN(float f) { return f != f; } +inline constexpr bool isNaN(double f) { return f != f; } + +inline int popCount(unsigned int x) { +#if defined(_MSC_VER) && !defined(__clang__) + return __popcnt(x); + // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int +#else + return __builtin_popcount(x); +#endif +} + +// ======================================================================================= +// Useful fake containers + +template +class Range { +public: + inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} + inline explicit constexpr Range(const T& end): begin_(0), end_(end) {} + + class Iterator { + public: + Iterator() = default; + inline Iterator(const T& value): value(value) {} + + inline const T& operator* () const { return value; } + inline const T& operator[](size_t index) const { return value + index; } + inline Iterator& operator++() { ++value; return *this; } + inline Iterator operator++(int) { return Iterator(value++); } + inline Iterator& operator--() { --value; return *this; } + inline Iterator operator--(int) { return Iterator(value--); } + inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } + inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } + inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } + inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } + inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } + + inline bool operator==(const Iterator& other) const { return value == other.value; } + inline bool operator!=(const Iterator& other) const { return value != other.value; } + inline bool operator<=(const Iterator& other) const { return value <= other.value; } + inline bool operator>=(const Iterator& other) const { return value >= other.value; } + inline bool operator< (const Iterator& other) const { return value < other.value; } + inline bool operator> (const Iterator& other) const { return value > other.value; } + + private: + T value; + }; + + inline Iterator begin() const { return Iterator(begin_); } + inline Iterator end() const { return Iterator(end_); } + + inline auto size() const -> decltype(instance() - instance()) { return end_ - begin_; } + +private: + T begin_; + T end_; +}; + +template +inline constexpr Range, Decay>> range(T begin, U end) { + return Range, Decay>>(begin, end); +} + +template +inline constexpr Range> range(T begin, T end) { return Range>(begin, end); } +// Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` +// (exclusive). Example: +// +// // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. +// for (int i: kj::range(1, 10)) { print(i); } + +template +inline constexpr Range> zeroTo(T end) { return Range>(end); } +// Returns a fake iterable container containing all values of T from zero (inclusive) to `end` +// (exclusive). Example: +// +// // Prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. +// for (int i: kj::zeroTo(10)) { print(i); } + +template +inline constexpr Range indices(T&& container) { + // Shortcut for iterating over the indices of a container: + // + // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } + + return range(0, kj::size(container)); +} + +template +class Repeat { +public: + inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} + + class Iterator { + public: + Iterator() = default; + inline Iterator(const T& value, size_t index): value(value), index(index) {} + + inline const T& operator* () const { return value; } + inline const T& operator[](ptrdiff_t index) const { return value; } + inline Iterator& operator++() { ++index; return *this; } + inline Iterator operator++(int) { return Iterator(value, index++); } + inline Iterator& operator--() { --index; return *this; } + inline Iterator operator--(int) { return Iterator(value, index--); } + inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } + inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } + inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } + inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } + inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } + + inline bool operator==(const Iterator& other) const { return index == other.index; } + inline bool operator!=(const Iterator& other) const { return index != other.index; } + inline bool operator<=(const Iterator& other) const { return index <= other.index; } + inline bool operator>=(const Iterator& other) const { return index >= other.index; } + inline bool operator< (const Iterator& other) const { return index < other.index; } + inline bool operator> (const Iterator& other) const { return index > other.index; } + + private: + T value; + size_t index; + }; + + inline Iterator begin() const { return Iterator(value, 0); } + inline Iterator end() const { return Iterator(value, count); } + + inline size_t size() const { return count; } + inline const T& operator[](ptrdiff_t) const { return value; } + +private: + T value; + size_t count; +}; + +template +inline constexpr Repeat> repeat(T&& value, size_t count) { + // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating + // a bunch of spaces: `kj::repeat(' ', indent * 2)` + + return Repeat>(value, count); +} + +template +class MappedIterator: private Mapping { + // An iterator that wraps some other iterator and maps the values through a mapping function. + // The type `Mapping` must define a method `map()` which performs this mapping. + +public: + template + MappedIterator(Inner inner, Params&&... params) + : Mapping(kj::fwd(params)...), inner(inner) {} + + inline auto operator->() const { return &Mapping::map(*inner); } + inline decltype(auto) operator* () const { return Mapping::map(*inner); } + inline decltype(auto) operator[](size_t index) const { return Mapping::map(inner[index]); } + inline MappedIterator& operator++() { ++inner; return *this; } + inline MappedIterator operator++(int) { return MappedIterator(inner++, *this); } + inline MappedIterator& operator--() { --inner; return *this; } + inline MappedIterator operator--(int) { return MappedIterator(inner--, *this); } + inline MappedIterator& operator+=(ptrdiff_t amount) { inner += amount; return *this; } + inline MappedIterator& operator-=(ptrdiff_t amount) { inner -= amount; return *this; } + inline MappedIterator operator+ (ptrdiff_t amount) const { + return MappedIterator(inner + amount, *this); + } + inline MappedIterator operator- (ptrdiff_t amount) const { + return MappedIterator(inner - amount, *this); + } + inline ptrdiff_t operator- (const MappedIterator& other) const { return inner - other.inner; } + + inline bool operator==(const MappedIterator& other) const { return inner == other.inner; } + inline bool operator!=(const MappedIterator& other) const { return inner != other.inner; } + inline bool operator<=(const MappedIterator& other) const { return inner <= other.inner; } + inline bool operator>=(const MappedIterator& other) const { return inner >= other.inner; } + inline bool operator< (const MappedIterator& other) const { return inner < other.inner; } + inline bool operator> (const MappedIterator& other) const { return inner > other.inner; } + +private: + Inner inner; +}; + +template +class MappedIterable: private Mapping { + // An iterable that wraps some other iterable and maps the values through a mapping function. + // The type `Mapping` must define a method `map()` which performs this mapping. + +public: + template + MappedIterable(Inner inner, Params&&... params) + : Mapping(kj::fwd(params)...), inner(inner) {} + + typedef Decay().begin())> InnerIterator; + typedef MappedIterator Iterator; + typedef Decay().begin())> InnerConstIterator; + typedef MappedIterator ConstIterator; + + inline Iterator begin() { return { inner.begin(), (Mapping&)*this }; } + inline Iterator end() { return { inner.end(), (Mapping&)*this }; } + inline ConstIterator begin() const { return { inner.begin(), (const Mapping&)*this }; } + inline ConstIterator end() const { return { inner.end(), (const Mapping&)*this }; } + +private: + Inner inner; +}; + +// ======================================================================================= +// Manually invoking constructors and destructors +// +// ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. + +// We want placement new, but we don't want to #include . operator new cannot be defined in +// a namespace, and defining it globally conflicts with the definition in . So we have to +// define a dummy type and an operator new that uses it. + +namespace _ { // private +struct PlacementNew {}; +} // namespace _ (private) +} // namespace kj + +inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { + return __p; +} + +inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} + +namespace kj { + +template +inline void ctor(T& location, Params&&... params) { + new (_::PlacementNew(), &location) T(kj::fwd(params)...); +} + +template +inline void dtor(T& location) { + location.~T(); +} + +// ======================================================================================= +// Maybe +// +// Use in cases where you want to indicate that a value may be null. Using Maybe instead of T* +// forces the caller to handle the null case in order to satisfy the compiler, thus reliably +// preventing null pointer dereferences at runtime. +// +// Maybe can be implicitly constructed from T and from nullptr. +// To read the value of a Maybe, do: +// +// KJ_IF_MAYBE(value, someFuncReturningMaybe()) { +// doSomething(*value); +// } else { +// maybeWasNull(); +// } +// +// KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following +// block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, +// though it may or may not actually be a pointer. +// +// Note that Maybe actually just wraps a pointer, whereas Maybe wraps a T and a boolean +// indicating nullness. + +template +class Maybe; + +namespace _ { // private + +template +class NullableValue { + // Class whose interface behaves much like T*, but actually contains an instance of T and a + // boolean flag indicating nullness. + +public: + inline NullableValue(NullableValue&& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, kj::mv(other.value)); + } + } + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + inline NullableValue(NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + inline ~NullableValue() +#if _MSC_VER && !defined(__clang__) + // TODO(msvc): MSVC has a hard time with noexcept specifier expressions that are more complex + // than `true` or `false`. We had a workaround for VS2015, but VS2017 regressed. + noexcept(false) +#else + noexcept(noexcept(instance().~T())) +#endif + { + if (isSet) { + dtor(value); + } + } + + inline T& operator*() & { return value; } + inline const T& operator*() const & { return value; } + inline T&& operator*() && { return kj::mv(value); } + inline const T&& operator*() const && { return kj::mv(value); } + inline T* operator->() { return &value; } + inline const T* operator->() const { return &value; } + inline operator T*() { return isSet ? &value : nullptr; } + inline operator const T*() const { return isSet ? &value : nullptr; } + + template + inline T& emplace(Params&&... params) { + if (isSet) { + isSet = false; + dtor(value); + } + ctor(value, kj::fwd(params)...); + isSet = true; + return value; + } + + inline NullableValue(): isSet(false) {} + inline NullableValue(T&& t) + : isSet(true) { + ctor(value, kj::mv(t)); + } + inline NullableValue(T& t) + : isSet(true) { + ctor(value, t); + } + inline NullableValue(const T& t) + : isSet(true) { + ctor(value, t); + } + template + inline NullableValue(NullableValue&& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, kj::mv(other.value)); + } + } + template + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, other.value); + } + } + template + inline NullableValue(const NullableValue& other) + : isSet(other.isSet) { + if (isSet) { + ctor(value, *other.ptr); + } + } + inline NullableValue(decltype(nullptr)): isSet(false) {} + + inline NullableValue& operator=(NullableValue&& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, kj::mv(other.value)); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(NullableValue& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, other.value); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(const NullableValue& other) { + if (&other != this) { + // Careful about throwing destructors/constructors here. + if (isSet) { + isSet = false; + dtor(value); + } + if (other.isSet) { + ctor(value, other.value); + isSet = true; + } + } + return *this; + } + + inline NullableValue& operator=(T&& other) { emplace(kj::mv(other)); return *this; } + inline NullableValue& operator=(T& other) { emplace(other); return *this; } + inline NullableValue& operator=(const T& other) { emplace(other); return *this; } + template + inline NullableValue& operator=(NullableValue&& other) { + if (other.isSet) { + emplace(kj::mv(other.value)); + } else { + *this = nullptr; + } + return *this; + } + template + inline NullableValue& operator=(const NullableValue& other) { + if (other.isSet) { + emplace(other.value); + } else { + *this = nullptr; + } + return *this; + } + template + inline NullableValue& operator=(const NullableValue& other) { + if (other.isSet) { + emplace(other.value); + } else { + *this = nullptr; + } + return *this; + } + inline NullableValue& operator=(decltype(nullptr)) { + if (isSet) { + isSet = false; + dtor(value); + } + return *this; + } + + inline bool operator==(decltype(nullptr)) const { return !isSet; } + inline bool operator!=(decltype(nullptr)) const { return isSet; } + + NullableValue(const T* t) = delete; + NullableValue& operator=(const T* other) = delete; + // We used to permit assigning a Maybe directly from a T*, and the assignment would check for + // nullness. This turned out never to be useful, and sometimes to be dangerous. + +private: + bool isSet; + +#if _MSC_VER && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable: 4624) +// Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning +// seems broken. +#endif + + union { + T value; + }; + +#if _MSC_VER && !defined(__clang__) +#pragma warning(pop) +#endif + + friend class kj::Maybe; + template + friend NullableValue&& readMaybe(Maybe&& maybe); +}; + +template +inline NullableValue&& readMaybe(Maybe&& maybe) { return kj::mv(maybe.ptr); } +template +inline T* readMaybe(Maybe& maybe) { return maybe.ptr; } +template +inline const T* readMaybe(const Maybe& maybe) { return maybe.ptr; } +template +inline T* readMaybe(Maybe&& maybe) { return maybe.ptr; } +template +inline T* readMaybe(const Maybe& maybe) { return maybe.ptr; } + +template +inline T* readMaybe(T* ptr) { return ptr; } +// Allow KJ_IF_MAYBE to work on regular pointers. + +} // namespace _ (private) + +#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) + +#if __GNUC__ || __clang__ +// These two macros provide a friendly syntax to extract the value of a Maybe or return early. +// +// Use KJ_UNWRAP_OR_RETURN if you just want to return a simple value when the Maybe is null: +// +// int foo(Maybe maybe) { +// int value = KJ_UNWRAP_OR_RETURN(maybe, -1); +// // ... use value ... +// } +// +// For functions returning void, omit the second parameter to KJ_UNWRAP_OR_RETURN: +// +// void foo(Maybe maybe) { +// int value = KJ_UNWRAP_OR_RETURN(maybe); +// // ... use value ... +// } +// +// Use KJ_UNWRAP_OR if you want to execute a block with multiple statements. +// +// int foo(Maybe maybe) { +// int value = KJ_UNWRAP_OR(maybe, { +// KJ_LOG(ERROR, "problem!!!"); +// return -1; +// }); +// // ... use value ... +// } +// +// The block MUST return at the end or you will get a compiler error +// +// Unfortunately, these macros seem impossible to express without using GCC's non-standard +// "statement expressions" extension. IIFEs don't do the trick here because a lambda cannot +// return out of the parent scope. These macros should therefore only be used in projects that +// target GCC or GCC-compatible compilers. +// +// `__GNUC__` is not defined when using LLVM's MSVC-compatible compiler driver `clang-cl` (even +// though clang supports the required extension), hence the additional `|| __clang__`. + +#define KJ_UNWRAP_OR_RETURN(value, ...) \ + (*({ \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (!_kj_result) { \ + return __VA_ARGS__; \ + } \ + kj::mv(_kj_result); \ + })) + +#define KJ_UNWRAP_OR(value, block) \ + (*({ \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (!_kj_result) { \ + block; \ + asm("KJ_UNWRAP_OR_block_is_missing_return_statement\n"); \ + } \ + kj::mv(_kj_result); \ + })) +#endif + +template +class Maybe { + // A T, or nullptr. + + // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. + +public: + Maybe(): ptr(nullptr) {} + Maybe(T&& t): ptr(kj::mv(t)) {} + Maybe(T& t): ptr(t) {} + Maybe(const T& t): ptr(t) {} + Maybe(Maybe&& other): ptr(kj::mv(other.ptr)) { other = nullptr; } + Maybe(const Maybe& other): ptr(other.ptr) {} + Maybe(Maybe& other): ptr(other.ptr) {} + + template + Maybe(Maybe&& other) { + KJ_IF_MAYBE(val, kj::mv(other)) { + ptr.emplace(kj::mv(*val)); + other = nullptr; + } + } + template + Maybe(Maybe&& other) { + KJ_IF_MAYBE(val, other) { + ptr.emplace(*val); + other = nullptr; + } + } + template + Maybe(const Maybe& other) { + KJ_IF_MAYBE(val, other) { + ptr.emplace(*val); + } + } + + Maybe(decltype(nullptr)): ptr(nullptr) {} + + template + inline T& emplace(Params&&... params) { + // Replace this Maybe's content with a new value constructed by passing the given parameters to + // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. + // Returns a reference to the newly-constructed value. + + return ptr.emplace(kj::fwd(params)...); + } + + inline Maybe& operator=(T&& other) { ptr = kj::mv(other); return *this; } + inline Maybe& operator=(T& other) { ptr = other; return *this; } + inline Maybe& operator=(const T& other) { ptr = other; return *this; } + + inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); other = nullptr; return *this; } + inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } + inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } + + template + Maybe& operator=(Maybe&& other) { + KJ_IF_MAYBE(val, kj::mv(other)) { + ptr.emplace(kj::mv(*val)); + other = nullptr; + } else { + ptr = nullptr; + } + return *this; + } + template + Maybe& operator=(const Maybe& other) { + KJ_IF_MAYBE(val, other) { + ptr.emplace(*val); + } else { + ptr = nullptr; + } + return *this; + } + + inline Maybe& operator=(decltype(nullptr)) { ptr = nullptr; return *this; } + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + inline bool operator==(const Maybe& other) const { + if (ptr == nullptr) { + return other == nullptr; + } else { + return other.ptr != nullptr && *ptr == *other.ptr; + } + } + inline bool operator!=(const Maybe& other) const { return !(*this == other); } + + Maybe(const T* t) = delete; + Maybe& operator=(const T* other) = delete; + // We used to permit assigning a Maybe directly from a T*, and the assignment would check for + // nullness. This turned out never to be useful, and sometimes to be dangerous. + + T& orDefault(T& defaultValue) & { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + const T& orDefault(const T& defaultValue) const & { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + T&& orDefault(T&& defaultValue) && { + if (ptr == nullptr) { + return kj::mv(defaultValue); + } else { + return kj::mv(*ptr); + } + } + const T&& orDefault(const T&& defaultValue) const && { + if (ptr == nullptr) { + return kj::mv(defaultValue); + } else { + return kj::mv(*ptr); + } + } + + template () ? instance() : instance()())> + Result orDefault(F&& lazyDefaultValue) & { + if (ptr == nullptr) { + return lazyDefaultValue(); + } else { + return *ptr; + } + } + + template () ? instance() : instance()())> + Result orDefault(F&& lazyDefaultValue) const & { + if (ptr == nullptr) { + return lazyDefaultValue(); + } else { + return *ptr; + } + } + + template () ? instance() : instance()())> + Result orDefault(F&& lazyDefaultValue) && { + if (ptr == nullptr) { + return lazyDefaultValue(); + } else { + return kj::mv(*ptr); + } + } + + template () ? instance() : instance()())> + Result orDefault(F&& lazyDefaultValue) const && { + if (ptr == nullptr) { + return lazyDefaultValue(); + } else { + return kj::mv(*ptr); + } + } + + template + auto map(Func&& f) & -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template + auto map(Func&& f) const & -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template + auto map(Func&& f) && -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(*ptr)); + } + } + + template + auto map(Func&& f) const && -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(kj::mv(*ptr)); + } + } + +private: + _::NullableValue ptr; + + template + friend class Maybe; + template + friend _::NullableValue&& _::readMaybe(Maybe&& maybe); + template + friend U* _::readMaybe(Maybe& maybe); + template + friend const U* _::readMaybe(const Maybe& maybe); +}; + +template +class Maybe { +public: + constexpr Maybe(): ptr(nullptr) {} + constexpr Maybe(T& t): ptr(&t) {} + constexpr Maybe(T* t): ptr(t) {} + + inline constexpr Maybe(PropagateConst& other): ptr(other.ptr) {} + // Allow const copy only if `T` itself is const. Otherwise allow only non-const copy, to + // protect transitive constness. Clang is happy for this constructor to be declared `= default` + // since, after evaluation of `PropagateConst`, it does end up being a default-able constructor. + // But, GCC and MSVC both complain about that, claiming this constructor cannot be declared + // default. I don't know who is correct, but whatever, we'll write out an implementation, fine. + // + // Note that we can't solve this by inheriting DisallowConstCopyIfNotConst because we want + // to override the move constructor, and if we override the move constructor then we must define + // the copy constructor here. + + inline constexpr Maybe(Maybe&& other): ptr(other.ptr) { other.ptr = nullptr; } + + template + inline constexpr Maybe(Maybe& other): ptr(other.ptr) {} + template + inline constexpr Maybe(const Maybe& other): ptr(const_cast(other.ptr)) {} + template + inline constexpr Maybe(Maybe&& other): ptr(other.ptr) { other.ptr = nullptr; } + template + inline constexpr Maybe(const Maybe&& other) = delete; + template ()>> + constexpr Maybe(Maybe& other): ptr(other.ptr.operator U*()) {} + template ()>> + constexpr Maybe(const Maybe& other): ptr(other.ptr.operator const U*()) {} + inline constexpr Maybe(decltype(nullptr)): ptr(nullptr) {} + + inline Maybe& operator=(T& other) { ptr = &other; return *this; } + inline Maybe& operator=(T* other) { ptr = other; return *this; } + inline Maybe& operator=(PropagateConst& other) { ptr = other.ptr; return *this; } + inline Maybe& operator=(Maybe&& other) { ptr = other.ptr; other.ptr = nullptr; return *this; } + template + inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } + template + inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } + template + inline Maybe& operator=(Maybe&& other) { ptr = other.ptr; other.ptr = nullptr; return *this; } + template + inline Maybe& operator=(const Maybe&& other) = delete; + + inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } + inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } + + T& orDefault(T& defaultValue) { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + const T& orDefault(const T& defaultValue) const { + if (ptr == nullptr) { + return defaultValue; + } else { + return *ptr; + } + } + + template + auto map(Func&& f) -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + return f(*ptr); + } + } + + template + auto map(Func&& f) const -> Maybe()))> { + if (ptr == nullptr) { + return nullptr; + } else { + const T& ref = *ptr; + return f(ref); + } + } + +private: + T* ptr; + + template + friend class Maybe; + template + friend U* _::readMaybe(Maybe&& maybe); + template + friend U* _::readMaybe(const Maybe& maybe); +}; + +// ======================================================================================= +// ArrayPtr +// +// So common that we put it in common.h rather than array.h. + +template +class Array; + +template +class ArrayPtr: public DisallowConstCopyIfNotConst { + // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, + // and passing by value only copies the pointer, not the target. + +public: + inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} + inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} + inline constexpr ArrayPtr(T* ptr KJ_LIFETIMEBOUND, size_t size): ptr(ptr), size_(size) {} + inline constexpr ArrayPtr(T* begin KJ_LIFETIMEBOUND, T* end KJ_LIFETIMEBOUND) + : ptr(begin), size_(end - begin) {} + ArrayPtr& operator=(Array&&) = delete; + ArrayPtr& operator=(decltype(nullptr)) { + ptr = nullptr; + size_ = 0; + return *this; + } + +#if __GNUC__ && !__clang__ && __GNUC__ >= 9 +// GCC 9 added a warning when we take an initializer_list as a constructor parameter and save a +// pointer to its content in a class member. GCC apparently imagines we're going to do something +// dumb like this: +// ArrayPtr ptr = { 1, 2, 3 }; +// foo(ptr[1]); // undefined behavior! +// Any KJ programmer should be able to recognize that this is UB, because an ArrayPtr does not own +// its content. That's not what this constructor is for, tohugh. This constructor is meant to allow +// code like this: +// int foo(ArrayPtr p); +// // ... later ... +// foo({1, 2, 3}); +// In this case, the initializer_list's backing array, like any temporary, lives until the end of +// the statement `foo({1, 2, 3});`. Therefore, it lives at least until the call to foo() has +// returned, which is exactly what we care about. This usage is fine! GCC is wrong to warn. +// +// Amusingly, Clang's implementation has a similar type that they call ArrayRef which apparently +// triggers this same GCC warning. My guess is that Clang will not introduce a similar warning +// given that it triggers on their own, legitimate code. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-list-lifetime" +#endif + inline KJ_CONSTEXPR() ArrayPtr( + ::std::initializer_list> init KJ_LIFETIMEBOUND) + : ptr(init.begin()), size_(init.size()) {} +#if __GNUC__ && !__clang__ && __GNUC__ >= 9 +#pragma GCC diagnostic pop +#endif + + template + inline constexpr ArrayPtr(KJ_LIFETIMEBOUND T (&native)[size]): ptr(native), size_(size) { + // Construct an ArrayPtr from a native C-style array. + // + // We disable this constructor for const char arrays because otherwise you would be able to + // implicitly convert a character literal to ArrayPtr, which sounds really great, + // except that the NUL terminator would be included, which probably isn't what you intended. + // + // TODO(someday): Maybe we should support character literals but explicitly chop off the NUL + // terminator. This could do the wrong thing if someone tries to construct an + // ArrayPtr from a non-NUL-terminated char array, but evidence suggests that all + // real use cases are in fact intending to remove the NUL terminator. It's convenient to be + // able to specify ArrayPtr as a parameter type and be able to accept strings + // as input in addition to arrays. Currently, you'll need overloading to support string + // literals in this case, but if you overload StringPtr, then you'll find that several + // conversions (e.g. from String and from a literal char array) become ambiguous! You end up + // having to overload for literal char arrays specifically which is cumbersome. + + static_assert(!isSameType(), + "Can't implicitly convert literal char array to ArrayPtr because we don't know if " + "you meant to include the NUL terminator. We may change this in the future to " + "automatically drop the NUL terminator. For now, try explicitly converting to StringPtr, " + "which can in turn implicitly convert to ArrayPtr."); + static_assert(!isSameType(), "see above"); + static_assert(!isSameType(), "see above"); + } + + inline operator ArrayPtr() const { + return ArrayPtr(ptr, size_); + } + inline ArrayPtr asConst() const { + return ArrayPtr(ptr, size_); + } + + inline constexpr size_t size() const { return size_; } + inline const T& operator[](size_t index) const { + KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); + return ptr[index]; + } + inline T& operator[](size_t index) { + KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); + return ptr[index]; + } + + inline T* begin() { return ptr; } + inline T* end() { return ptr + size_; } + inline T& front() { return *ptr; } + inline T& back() { return *(ptr + size_ - 1); } + inline constexpr const T* begin() const { return ptr; } + inline constexpr const T* end() const { return ptr + size_; } + inline const T& front() const { return *ptr; } + inline const T& back() const { return *(ptr + size_ - 1); } + + inline ArrayPtr slice(size_t start, size_t end) const { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); + return ArrayPtr(ptr + start, end - start); + } + inline ArrayPtr slice(size_t start, size_t end) { + KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); + return ArrayPtr(ptr + start, end - start); + } + inline bool startsWith(const ArrayPtr& other) const { + return other.size() <= size_ && slice(0, other.size()) == other; + } + inline bool endsWith(const ArrayPtr& other) const { + return other.size() <= size_ && slice(size_ - other.size(), size_) == other; + } + + inline Maybe findFirst(const T& match) const { + for (size_t i = 0; i < size_; i++) { + if (ptr[i] == match) { + return i; + } + } + return nullptr; + } + inline Maybe findLast(const T& match) const { + for (size_t i = size_; i--;) { + if (ptr[i] == match) { + return i; + } + } + return nullptr; + } + + inline ArrayPtr> asBytes() const { + // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing + // rules. + return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; + } + inline ArrayPtr> asChars() const { + // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing + // rules. + return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; + } + + inline bool operator==(decltype(nullptr)) const { return size_ == 0; } + inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } + + inline bool operator==(const ArrayPtr& other) const { + if (size_ != other.size_) return false; + if (isIntegral>()) { + if (size_ == 0) return true; + return memcmp(ptr, other.ptr, size_ * sizeof(T)) == 0; + } + for (size_t i = 0; i < size_; i++) { + if (ptr[i] != other[i]) return false; + } + return true; + } +#if !__cpp_impl_three_way_comparison + inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } +#endif + + template + inline bool operator==(const ArrayPtr& other) const { + if (size_ != other.size()) return false; + for (size_t i = 0; i < size_; i++) { + if (ptr[i] != other[i]) return false; + } + return true; + } +#if !__cpp_impl_three_way_comparison + template + inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } +#endif + + template + Array attach(Attachments&&... attachments) const KJ_WARN_UNUSED_RESULT; + // Like Array::attach(), but also promotes an ArrayPtr to an Array. Generally the attachment + // should be an object that actually owns the array that the ArrayPtr is pointing at. + // + // You must include kj/array.h to call this. + +private: + T* ptr; + size_t size_; +}; + +template <> +inline Maybe ArrayPtr::findFirst(const char& c) const { + const char* pos = reinterpret_cast(memchr(ptr, c, size_)); + if (pos == nullptr) { + return nullptr; + } else { + return pos - ptr; + } +} + +template <> +inline Maybe ArrayPtr::findFirst(const char& c) const { + char* pos = reinterpret_cast(memchr(ptr, c, size_)); + if (pos == nullptr) { + return nullptr; + } else { + return pos - ptr; + } +} + +template <> +inline Maybe ArrayPtr::findFirst(const byte& c) const { + const byte* pos = reinterpret_cast(memchr(ptr, c, size_)); + if (pos == nullptr) { + return nullptr; + } else { + return pos - ptr; + } +} + +template <> +inline Maybe ArrayPtr::findFirst(const byte& c) const { + byte* pos = reinterpret_cast(memchr(ptr, c, size_)); + if (pos == nullptr) { + return nullptr; + } else { + return pos - ptr; + } +} + +// glibc has a memrchr() for reverse search but it's non-standard, so we don't bother optimizing +// findLast(), which isn't used much anyway. + +template +inline constexpr ArrayPtr arrayPtr(T* ptr KJ_LIFETIMEBOUND, size_t size) { + // Use this function to construct ArrayPtrs without writing out the type name. + return ArrayPtr(ptr, size); +} + +template +inline constexpr ArrayPtr arrayPtr(T* begin KJ_LIFETIMEBOUND, T* end KJ_LIFETIMEBOUND) { + // Use this function to construct ArrayPtrs without writing out the type name. + return ArrayPtr(begin, end); +} + +// ======================================================================================= +// Casts + +template +To implicitCast(From&& from) { + // `implicitCast(value)` casts `value` to type `T` only if the conversion is implicit. Useful + // for e.g. resolving ambiguous overloads without sacrificing type-safety. + return kj::fwd(from); +} + +template +Maybe dynamicDowncastIfAvailable(From& from) { + // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful + // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary + // for correctness. It is highly recommended that you try to arrange all your dynamic_casts + // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface + // design. + + // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed + // we should have a separate cast function like dynamicCrosscastIfAvailable(). + if (false) { + kj::implicitCast(kj::implicitCast(nullptr)); + } + +#if KJ_NO_RTTI + return nullptr; +#else + return dynamic_cast(&from); +#endif +} + +template +To& downcast(From& from) { + // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a + // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify + // that the value really has the requested type. + + // Force a compile error if To is not a subtype of From. + if (false) { + kj::implicitCast(kj::implicitCast(nullptr)); + } + +#if !KJ_NO_RTTI + KJ_IREQUIRE(dynamic_cast(&from) != nullptr, "Value cannot be downcast() to requested type."); +#endif + + return static_cast(from); +} + +// ======================================================================================= +// Defer + +namespace _ { // private + +template +class Deferred { +public: + Deferred(Func&& func): maybeFunc(kj::fwd(func)) {} + ~Deferred() noexcept(false) { + run(); + } + KJ_DISALLOW_COPY(Deferred); + + Deferred(Deferred&&) = default; + // Since we use a kj::Maybe, the default move constructor does exactly what we want it to do. + + void run() { + // Move `maybeFunc` to the local scope so that even if we throw, we destroy the functor we had. + auto maybeLocalFunc = kj::mv(maybeFunc); + KJ_IF_MAYBE(func, maybeLocalFunc) { + (*func)(); + } + } + + void cancel() { + maybeFunc = nullptr; + } + +private: + kj::Maybe maybeFunc; + // Note that `Func` may actually be an lvalue reference because `kj::defer` takes its argument via + // universal reference. `kj::Maybe` has specializations for lvalue reference types, so this works + // out. +}; + +} // namespace _ (private) + +template +_::Deferred defer(Func&& func) { + // Returns an object which will invoke the given functor in its destructor. The object is not + // copyable but is move-constructable with the semantics you'd expect. Since the return type is + // private, you need to assign to an `auto` variable. + // + // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you + // want some code to run at current scope exit. + // + // KJ_DEFER does not support move-assignment for its returned objects. If you need to reuse the + // variable for your deferred function object, then you will want to write your own class for that + // purpose. + + return _::Deferred(kj::fwd(func)); +} + +#define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) +// Run the given code when the function exits, whether by return or exception. + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/debug.cc b/src/plugins/streamers/lstream/runtime/kj/kj/debug.cc new file mode 100644 index 000000000..f685e3162 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/debug.cc @@ -0,0 +1,477 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if _WIN32 || __CYGWIN__ +#include "win32-api-version.h" +#endif + +#include "debug.h" +#include +#include +#include +#include + +#if _WIN32 || __CYGWIN__ +#if !__CYGWIN__ +#define strerror_r(errno,buf,len) strerror_s(buf,len,errno) +#endif +#include +#include "windows-sanity.h" +#include "encoding.h" +#include +#endif + +namespace kj { +namespace _ { // private + +LogSeverity Debug::minSeverity = LogSeverity::WARNING; + +namespace { + +Exception::Type typeOfErrno(int error) { + switch (error) { +#ifdef EDQUOT + case EDQUOT: +#endif +#ifdef EMFILE + case EMFILE: +#endif +#ifdef ENFILE + case ENFILE: +#endif +#ifdef ENOBUFS + case ENOBUFS: +#endif +#ifdef ENOLCK + case ENOLCK: +#endif +#ifdef ENOMEM + case ENOMEM: +#endif +#ifdef ENOSPC + case ENOSPC: +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: +#endif +#ifdef EUSERS + case EUSERS: +#endif + return Exception::Type::OVERLOADED; + +#ifdef ENOTCONN + case ENOTCONN: +#endif +#ifdef ECONNABORTED + case ECONNABORTED: +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: +#endif +#ifdef ECONNRESET + case ECONNRESET: +#endif +#ifdef EHOSTDOWN + case EHOSTDOWN: +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: +#endif +#ifdef ENETDOWN + case ENETDOWN: +#endif +#ifdef ENETRESET + case ENETRESET: +#endif +#ifdef ENETUNREACH + case ENETUNREACH: +#endif +#ifdef ENONET + case ENONET: +#endif +#ifdef EPIPE + case EPIPE: +#endif + return Exception::Type::DISCONNECTED; + +#ifdef ENOSYS + case ENOSYS: +#endif +#ifdef ENOTSUP + case ENOTSUP: +#endif +#if defined(EOPNOTSUPP) && EOPNOTSUPP != ENOTSUP + case EOPNOTSUPP: +#endif +#ifdef ENOPROTOOPT + case ENOPROTOOPT: +#endif +#ifdef ENOTSOCK + // This is really saying "syscall not implemented for non-sockets". + case ENOTSOCK: +#endif + return Exception::Type::UNIMPLEMENTED; + + default: + return Exception::Type::FAILED; + } +} + +#if _WIN32 || __CYGWIN__ + +Exception::Type typeOfWin32Error(DWORD error) { + switch (error) { + // TODO(someday): This needs more work. + + case WSAETIMEDOUT: + return Exception::Type::OVERLOADED; + + case WSAENOTCONN: + case WSAECONNABORTED: + case WSAECONNREFUSED: + case WSAECONNRESET: + case WSAEHOSTDOWN: + case WSAEHOSTUNREACH: + case WSAENETDOWN: + case WSAENETRESET: + case WSAENETUNREACH: + case WSAESHUTDOWN: + return Exception::Type::DISCONNECTED; + + case WSAEOPNOTSUPP: + case WSAENOPROTOOPT: + case WSAENOTSOCK: // This is really saying "syscall not implemented for non-sockets". + return Exception::Type::UNIMPLEMENTED; + + default: + return Exception::Type::FAILED; + } +} + +#endif // _WIN32 + +enum DescriptionStyle { + LOG, + ASSERTION, + SYSCALL +}; + +static String makeDescriptionImpl(DescriptionStyle style, const char* code, int errorNumber, + const char* sysErrorString, const char* macroArgs, + ArrayPtr argValues) { + KJ_STACK_ARRAY(ArrayPtr, argNames, argValues.size(), 8, 64); + + if (argValues.size() > 0) { + size_t index = 0; + const char* start = macroArgs; + while (isspace(*start)) ++start; + const char* pos = start; + uint depth = 0; + bool quoted = false; + while (char c = *pos++) { + if (quoted) { + if (c == '\\' && *pos != '\0') { + ++pos; + } else if (c == '\"') { + quoted = false; + } + } else { + if (c == '(') { + ++depth; + } else if (c == ')') { + --depth; + } else if (c == '\"') { + quoted = true; + } else if (c == ',' && depth == 0) { + if (index < argValues.size()) { + argNames[index++] = arrayPtr(start, pos - 1); + } + while (isspace(*pos)) ++pos; + start = pos; + if (*pos == '\0') { + // ignore trailing comma + break; + } + } + } + } + if (index < argValues.size()) { + argNames[index++] = arrayPtr(start, pos - 1); + } + + if (index != argValues.size()) { + getExceptionCallback().logMessage(LogSeverity::ERROR, __FILE__, __LINE__, 0, + str("Failed to parse logging macro args into ", + argValues.size(), " names: ", macroArgs, '\n')); + } + } + + if (style == SYSCALL) { + // Strip off leading "foo = " from code, since callers will sometimes write things like: + // ssize_t n; + // RECOVERABLE_SYSCALL(n = read(fd, buffer, sizeof(buffer))) { return ""; } + // return std::string(buffer, n); + const char* equalsPos = strchr(code, '='); + if (equalsPos != nullptr && equalsPos[1] != '=') { + code = equalsPos + 1; + while (isspace(*code)) ++code; + } + } + + if (style == ASSERTION && code == nullptr) { + style = LOG; + } + + { + StringPtr expected = "expected "; + StringPtr codeArray = style == LOG ? nullptr : StringPtr(code); + StringPtr sep = " = "; + StringPtr delim = "; "; + StringPtr colon = ": "; + StringPtr openBracket = " ["; + StringPtr closeBracket = "]"; + + StringPtr sysErrorArray; +// On android before marshmallow only the posix version of stderror_r was +// available, even with __USE_GNU. +#if __USE_GNU && !(defined(__ANDROID_API__) && __ANDROID_API__ < 23) + char buffer[256]; + if (style == SYSCALL) { + if (sysErrorString == nullptr) { + sysErrorArray = strerror_r(errorNumber, buffer, sizeof(buffer)); + } else { + sysErrorArray = sysErrorString; + } + } +#else + char buffer[256]; + if (style == SYSCALL) { + if (sysErrorString == nullptr) { + strerror_r(errorNumber, buffer, sizeof(buffer)); + sysErrorArray = buffer; + } else { + sysErrorArray = sysErrorString; + } + } +#endif + + size_t totalSize = 0; + switch (style) { + case LOG: + break; + case ASSERTION: + totalSize += expected.size() + codeArray.size(); + break; + case SYSCALL: + totalSize += codeArray.size() + colon.size() + sysErrorArray.size(); + break; + } + + auto needsLabel = [](ArrayPtr &argName) -> bool { + return (argName.size() > 0 && argName[0] != '\"' && + !(argName.size() >= 8 && memcmp(argName.begin(), "kj::str(", 8) == 0)); + }; + + for (size_t i = 0; i < argValues.size(); i++) { + if (argNames[i] == "_kjCondition"_kj) { + // Special handling: don't output delimiter, we want to append this to the previous item, + // in brackets. Also, if it's just "[false]" (meaning we didn't manage to extract a + // comparison), don't add it at all. + if (argValues[i] != "false") { + totalSize += openBracket.size() + argValues[i].size() + closeBracket.size(); + } + continue; + } + + if (i > 0 || style != LOG) { + totalSize += delim.size(); + } + if (needsLabel(argNames[i])) { + totalSize += argNames[i].size() + sep.size(); + } + totalSize += argValues[i].size(); + } + + String result = heapString(totalSize); + char* pos = result.begin(); + + switch (style) { + case LOG: + break; + case ASSERTION: + pos = _::fill(pos, expected, codeArray); + break; + case SYSCALL: + pos = _::fill(pos, codeArray, colon, sysErrorArray); + break; + } + + for (size_t i = 0; i < argValues.size(); i++) { + if (argNames[i] == "_kjCondition"_kj) { + // Special handling: don't output delimiter, we want to append this to the previous item, + // in brackets. Also, if it's just "[false]" (meaning we didn't manage to extract a + // comparison), don't add it at all. + if (argValues[i] != "false") { + pos = _::fill(pos, openBracket, argValues[i], closeBracket); + } + continue; + } + + if (i > 0 || style != LOG) { + pos = _::fill(pos, delim); + } + if (needsLabel(argNames[i])) { + pos = _::fill(pos, argNames[i], sep); + } + pos = _::fill(pos, argValues[i]); + } + + return result; + } +} + +} // namespace + +void Debug::logInternal(const char* file, int line, LogSeverity severity, const char* macroArgs, + ArrayPtr argValues) { + getExceptionCallback().logMessage(severity, trimSourceFilename(file).cStr(), line, 0, + makeDescriptionImpl(LOG, nullptr, 0, nullptr, macroArgs, argValues)); +} + +Debug::Fault::~Fault() noexcept(false) { + if (exception != nullptr) { + Exception copy = mv(*exception); + delete exception; + throwRecoverableException(mv(copy), 1); + } +} + +void Debug::Fault::fatal() { + Exception copy = mv(*exception); + delete exception; + exception = nullptr; + throwFatalException(mv(copy), 1); + KJ_KNOWN_UNREACHABLE(abort()); +} + +void Debug::Fault::init( + const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs, ArrayPtr argValues) { + exception = new Exception(type, file, line, + makeDescriptionImpl(ASSERTION, condition, 0, nullptr, macroArgs, argValues)); +} + +void Debug::Fault::init( + const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr argValues) { + exception = new Exception(typeOfErrno(osErrorNumber), file, line, + makeDescriptionImpl(SYSCALL, condition, osErrorNumber, nullptr, macroArgs, argValues)); +} + +#if _WIN32 || __CYGWIN__ +void Debug::Fault::init( + const char* file, int line, Win32Result osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr argValues) { + LPVOID ptr; + // TODO(someday): Why doesn't this work for winsock errors? + DWORD result = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, osErrorNumber.number, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &ptr, 0, NULL); + + String message; + if (result > 0) { + KJ_DEFER(LocalFree(ptr)); + const wchar_t* desc = reinterpret_cast(ptr); + size_t len = wcslen(desc); + if (len > 0 && desc[len-1] == '\n') --len; + if (len > 0 && desc[len-1] == '\r') --len; + message = kj::str('#', osErrorNumber.number, ' ', + decodeWideString(arrayPtr(desc, len))); + } else { + message = kj::str("win32 error code: ", osErrorNumber.number); + } + + exception = new Exception(typeOfWin32Error(osErrorNumber.number), file, line, + makeDescriptionImpl(SYSCALL, condition, 0, message.cStr(), + macroArgs, argValues)); +} +#endif + +String Debug::makeDescriptionInternal(const char* macroArgs, ArrayPtr argValues) { + return makeDescriptionImpl(LOG, nullptr, 0, nullptr, macroArgs, argValues); +} + +int Debug::getOsErrorNumber(bool nonblocking) { + int result = errno; + + // On many systems, EAGAIN and EWOULDBLOCK have the same value, but this is not strictly required + // by POSIX, so we need to check both. + return result == EINTR ? -1 + : nonblocking && (result == EAGAIN || result == EWOULDBLOCK) ? 0 + : result; +} + +#if _WIN32 || __CYGWIN__ +uint Debug::getWin32ErrorCode() { + return ::GetLastError(); +} +#endif + +Debug::Context::Context(): logged(false) {} +Debug::Context::~Context() noexcept(false) {} + +Debug::Context::Value Debug::Context::ensureInitialized() { + KJ_IF_MAYBE(v, value) { + return Value(v->file, v->line, heapString(v->description)); + } else { + Value result = evaluate(); + value = Value(result.file, result.line, heapString(result.description)); + return result; + } +} + +void Debug::Context::onRecoverableException(Exception&& exception) { + Value v = ensureInitialized(); + exception.wrapContext(v.file, v.line, mv(v.description)); + next.onRecoverableException(kj::mv(exception)); +} +void Debug::Context::onFatalException(Exception&& exception) { + Value v = ensureInitialized(); + exception.wrapContext(v.file, v.line, mv(v.description)); + next.onFatalException(kj::mv(exception)); +} +void Debug::Context::logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) { + if (!logged) { + Value v = ensureInitialized(); + next.logMessage(LogSeverity::INFO, trimSourceFilename(v.file).cStr(), v.line, 0, + str("context: ", mv(v.description), '\n')); + logged = true; + } + + next.logMessage(severity, file, line, contextDepth + 1, mv(text)); +} + +} // namespace _ (private) +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/debug.h b/src/plugins/streamers/lstream/runtime/kj/kj/debug.h new file mode 100644 index 000000000..9f8459b1c --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/debug.h @@ -0,0 +1,737 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// This file declares convenient macros for debug logging and error handling. The macros make +// it excessively easy to extract useful context information from code. Example: +// +// KJ_ASSERT(a == b, a, b, "a and b must be the same."); +// +// On failure, this will throw an exception whose description looks like: +// +// myfile.c++:43: bug in code: expected a == b; a = 14; b = 72; a and b must be the same. +// +// As you can see, all arguments after the first provide additional context. +// +// The macros available are: +// +// * `KJ_LOG(severity, ...)`: Just writes a log message, to stderr by default (but you can +// intercept messages by implementing an ExceptionCallback). `severity` is `INFO`, `WARNING`, +// `ERROR`, or `FATAL`. By default, `INFO` logs are not written, but for command-line apps the +// user should be able to pass a flag like `--verbose` to enable them. Other log levels are +// enabled by default. Log messages -- like exceptions -- can be intercepted by registering an +// ExceptionCallback. +// +// * `KJ_DBG(...)`: Like `KJ_LOG`, but intended specifically for temporary log lines added while +// debugging a particular problem. Calls to `KJ_DBG` should always be deleted before committing +// code. It is suggested that you set up a pre-commit hook that checks for this. +// +// * `KJ_ASSERT(condition, ...)`: Throws an exception if `condition` is false, or aborts if +// exceptions are disabled. This macro should be used to check for bugs in the surrounding code +// and its dependencies, but NOT to check for invalid input. The macro may be followed by a +// brace-delimited code block; if so, the block will be executed in the case where the assertion +// fails, before throwing the exception. If control jumps out of the block (e.g. with "break", +// "return", or "goto"), then the error is considered "recoverable" -- in this case, if +// exceptions are disabled, execution will continue normally rather than aborting (but if +// exceptions are enabled, an exception will still be thrown on exiting the block). A "break" +// statement in particular will jump to the code immediately after the block (it does not break +// any surrounding loop or switch). Example: +// +// KJ_ASSERT(value >= 0, "Value cannot be negative.", value) { +// // Assertion failed. Set value to zero to "recover". +// value = 0; +// // Don't abort if exceptions are disabled. Continue normally. +// // (Still throw an exception if they are enabled, though.) +// break; +// } +// // When exceptions are disabled, we'll get here even if the assertion fails. +// // Otherwise, we get here only if the assertion passes. +// +// * `KJ_REQUIRE(condition, ...)`: Like `KJ_ASSERT` but used to check preconditions -- e.g. to +// validate parameters passed from a caller. A failure indicates that the caller is buggy. +// +// * `KJ_ASSUME(condition, ...)`: Like `KJ_ASSERT`, but in release mode (if KJ_DEBUG is not +// defined; see below) instead warrants to the compiler that the condition can be assumed to +// hold, allowing it to optimize accordingly. This can result in undefined behavior, so use +// this macro *only* if you can prove to your satisfaction that the condition is guaranteed by +// surrounding code, and if the condition failing to hold would in any case result in undefined +// behavior in its dependencies. +// +// * `KJ_SYSCALL(code, ...)`: Executes `code` assuming it makes a system call. A negative result +// is considered an error, with error code reported via `errno`. EINTR is handled by retrying. +// Other errors are handled by throwing an exception. If you need to examine the return code, +// assign it to a variable like so: +// +// int fd; +// KJ_SYSCALL(fd = open(filename, O_RDONLY), filename); +// +// `KJ_SYSCALL` can be followed by a recovery block, just like `KJ_ASSERT`. +// +// * `KJ_NONBLOCKING_SYSCALL(code, ...)`: Like KJ_SYSCALL, but will not throw an exception on +// EAGAIN/EWOULDBLOCK. The calling code should check the syscall's return value to see if it +// indicates an error; in this case, it can assume the error was EAGAIN because any other error +// would have caused an exception to be thrown. +// +// * `KJ_CONTEXT(...)`: Notes additional contextual information relevant to any exceptions thrown +// from within the current scope. That is, until control exits the block in which KJ_CONTEXT() +// is used, if any exception is generated, it will contain the given information in its context +// chain. This is helpful because it can otherwise be very difficult to come up with error +// messages that make sense within low-level helper code. Note that the parameters to +// KJ_CONTEXT() are only evaluated if an exception is thrown. This implies that any variables +// used must remain valid until the end of the scope. +// +// Notes: +// * Do not write expressions with side-effects in the message content part of the macro, as the +// message will not necessarily be evaluated. +// * For every macro `FOO` above except `LOG`, there is also a `FAIL_FOO` macro used to report +// failures that already happened. For the macros that check a boolean condition, `FAIL_FOO` +// omits the first parameter and behaves like it was `false`. `FAIL_SYSCALL` and +// `FAIL_RECOVERABLE_SYSCALL` take a string and an OS error number as the first two parameters. +// The string should be the name of the failed system call. +// * For every macro `FOO` above except `ASSUME`, there is a `DFOO` version (or +// `RECOVERABLE_DFOO`) which is only executed in debug mode, i.e. when KJ_DEBUG is defined. +// KJ_DEBUG is defined automatically by common.h when compiling without optimization (unless +// NDEBUG is defined), but you can also define it explicitly (e.g. -DKJ_DEBUG). Generally, +// production builds should NOT use KJ_DEBUG as it may enable expensive checks that are unlikely +// to fail. + +#pragma once + +#include "string.h" +#include "exception.h" +#include "windows-sanity.h" // work-around macro conflict with `ERROR` + +KJ_BEGIN_HEADER + +namespace kj { + +#if KJ_MSVC_TRADITIONAL_CPP +// MSVC does __VA_ARGS__ differently from GCC: +// - A trailing comma before an empty __VA_ARGS__ is removed automatically, whereas GCC wants +// you to request this behavior with "##__VA_ARGS__". +// - If __VA_ARGS__ is passed directly as an argument to another macro, it will be treated as a +// *single* argument rather than an argument list. This can be worked around by wrapping the +// outer macro call in KJ_EXPAND(), which apparently forces __VA_ARGS__ to be expanded before +// the macro is evaluated. I don't understand the C preprocessor. +// - Using "#__VA_ARGS__" to stringify __VA_ARGS__ expands to zero tokens when __VA_ARGS__ is +// empty, rather than expanding to an empty string literal. We can work around by concatenating +// with an empty string literal. + +#define KJ_EXPAND(X) X + +#define KJ_LOG(severity, ...) \ + for (bool _kj_shouldLog = ::kj::_::Debug::shouldLog(::kj::LogSeverity::severity); \ + _kj_shouldLog; _kj_shouldLog = false) \ + ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ + "" #__VA_ARGS__, __VA_ARGS__) + +#define KJ_DBG(...) KJ_EXPAND(KJ_LOG(DBG, __VA_ARGS__)) + +#define KJ_REQUIRE(cond, ...) \ + if (auto _kjCondition = ::kj::_::MAGIC_ASSERT << cond) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #cond, "_kjCondition," #__VA_ARGS__, _kjCondition, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_REQUIRE(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_NONBLOCKING_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#if _WIN32 || __CYGWIN__ + +#define KJ_WIN32(call, ...) \ + if (auto _kjWin32Result = ::kj::_::Debug::win32Call(call)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjWin32Result, #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_WINSOCK(call, ...) \ + if (auto _kjWin32Result = ::kj::_::Debug::winsockCall(call)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjWin32Result, #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_WIN32(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::Win32Result(errorNumber), code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +#endif + +#define KJ_UNIMPLEMENTED(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ + nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) + +// TODO(msvc): MSVC mis-deduces `ContextImpl` as `ContextImpl` in some edge +// cases, such as inside nested lambdas inside member functions. Wrapping the type in +// `decltype(instance<...>())` helps it deduce the context function's type correctly. +#define KJ_CONTEXT(...) \ + auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ + return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)); \ + }; \ + decltype(::kj::instance<::kj::_::Debug::ContextImpl>()) \ + KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*[&] { \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", "" #__VA_ARGS__, __VA_ARGS__).fatal(); \ + } \ + return _kj_result; \ + }()) + +#define KJ_EXCEPTION(type, ...) \ + ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)) + +#else + +#define KJ_LOG(severity, ...) \ + for (bool _kj_shouldLog = ::kj::_::Debug::shouldLog(::kj::LogSeverity::severity); \ + _kj_shouldLog; _kj_shouldLog = false) \ + ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ + #__VA_ARGS__, ##__VA_ARGS__) + +#define KJ_DBG(...) KJ_LOG(DBG, ##__VA_ARGS__) + +#define KJ_REQUIRE(cond, ...) \ + if (auto _kjCondition = ::kj::_::MAGIC_ASSERT << cond) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #cond, "_kjCondition," #__VA_ARGS__, _kjCondition, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_REQUIRE(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_NONBLOCKING_SYSCALL(call, ...) \ + if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#if _WIN32 || __CYGWIN__ + +#define KJ_WIN32(call, ...) \ + if (auto _kjWin32Result = ::kj::_::Debug::win32Call(call)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjWin32Result, #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) +// Invoke a Win32 syscall that returns either BOOL or HANDLE, and throw an exception if it fails. + +#define KJ_WINSOCK(call, ...) \ + if (auto _kjWin32Result = ::kj::_::Debug::winsockCall(call)) {} else \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + _kjWin32Result, #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) +// Like KJ_WIN32 but for winsock calls which return `int` with SOCKET_ERROR indicating failure. +// +// Unfortunately, it's impossible to distinguish these from BOOL-returning Win32 calls by type, +// since BOOL is in fact an alias for `int`. :( + +#define KJ_FAIL_WIN32(code, errorNumber, ...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ + ::kj::_::Debug::Win32Result(errorNumber), code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#endif + +#define KJ_UNIMPLEMENTED(...) \ + for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ + nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) + +#define KJ_CONTEXT(...) \ + auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ + return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)); \ + }; \ + ::kj::_::Debug::ContextImpl \ + KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) + +#if _MSC_VER && !defined(__clang__) + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*([&] { \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \ + } \ + return _kj_result; \ + }())) + +#else + +#define KJ_REQUIRE_NONNULL(value, ...) \ + (*({ \ + auto _kj_result = ::kj::_::readMaybe(value); \ + if (KJ_UNLIKELY(!_kj_result)) { \ + ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ + #value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \ + } \ + kj::mv(_kj_result); \ + })) + +#endif + +#define KJ_EXCEPTION(type, ...) \ + ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ + ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)) + +#endif + +#define KJ_SYSCALL_HANDLE_ERRORS(call) \ + if (int _kjSyscallError = ::kj::_::Debug::syscallError([&](){return (call);}, false)) \ + switch (int error KJ_UNUSED = _kjSyscallError) +// Like KJ_SYSCALL, but doesn't throw. Instead, the block after the macro is a switch block on the +// error. Additionally, the int value `error` is defined within the block. So you can do: +// +// KJ_SYSCALL_HANDLE_ERRORS(foo()) { +// case ENOENT: +// handleNoSuchFile(); +// break; +// case EEXIST: +// handleExists(); +// break; +// default: +// KJ_FAIL_SYSCALL("foo()", error); +// } else { +// handleSuccessCase(); +// } + +#if _WIN32 || __CYGWIN__ + +#define KJ_WIN32_HANDLE_ERRORS(call) \ + if (uint _kjWin32Error = ::kj::_::Debug::win32Call(call).number) \ + switch (uint error KJ_UNUSED = _kjWin32Error) +// Like KJ_WIN32, but doesn't throw. Instead, the block after the macro is a switch block on the +// error. Additionally, the int value `error` is defined within the block. So you can do: +// +// KJ_SYSCALL_HANDLE_ERRORS(foo()) { +// case ERROR_FILE_NOT_FOUND: +// handleNoSuchFile(); +// break; +// case ERROR_FILE_EXISTS: +// handleExists(); +// break; +// default: +// KJ_FAIL_WIN32("foo()", error); +// } else { +// handleSuccessCase(); +// } + +#endif + +#define KJ_ASSERT KJ_REQUIRE +#define KJ_FAIL_ASSERT KJ_FAIL_REQUIRE +#define KJ_ASSERT_NONNULL KJ_REQUIRE_NONNULL +// Use "ASSERT" in place of "REQUIRE" when the problem is local to the immediate surrounding code. +// That is, if the assert ever fails, it indicates that the immediate surrounding code is broken. + +#ifdef KJ_DEBUG +#define KJ_DLOG KJ_LOG +#define KJ_DASSERT KJ_ASSERT +#define KJ_DREQUIRE KJ_REQUIRE +#define KJ_ASSUME KJ_ASSERT +#else +#define KJ_DLOG(...) do {} while (false) +#define KJ_DASSERT(...) do {} while (false) +#define KJ_DREQUIRE(...) do {} while (false) +#if defined(__GNUC__) +#define KJ_ASSUME(cond, ...) do { if (cond) {} else __builtin_unreachable(); } while (false) +#elif defined(__clang__) +#define KJ_ASSUME(cond, ...) __builtin_assume(cond) +#elif defined(_MSC_VER) +#define KJ_ASSUME(cond, ...) __assume(cond) +#else +#define KJ_ASSUME(...) do {} while (false) +#endif + +#endif + +namespace _ { // private + +class Debug { +public: + Debug() = delete; + + typedef LogSeverity Severity; // backwards-compatibility + +#if _WIN32 || __CYGWIN__ + struct Win32Result { + uint number; + inline explicit Win32Result(uint number): number(number) {} + operator bool() const { return number == 0; } + }; +#endif + + static inline bool shouldLog(LogSeverity severity) { return severity >= minSeverity; } + // Returns whether messages of the given severity should be logged. + + static inline void setLogLevel(LogSeverity severity) { minSeverity = severity; } + // Set the minimum message severity which will be logged. + // + // TODO(someday): Expose publicly. + + template + static void log(const char* file, int line, LogSeverity severity, const char* macroArgs, + Params&&... params); + + class Fault { + public: + template + Fault(const char* file, int line, Code code, + const char* condition, const char* macroArgs, Params&&... params); + Fault(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs); + Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs); +#if _WIN32 || __CYGWIN__ + Fault(const char* file, int line, Win32Result osErrorNumber, + const char* condition, const char* macroArgs); +#endif + ~Fault() noexcept(false); + + KJ_NOINLINE KJ_NORETURN(void fatal()); + // Throw the exception. + + private: + void init(const char* file, int line, Exception::Type type, + const char* condition, const char* macroArgs, ArrayPtr argValues); + void init(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr argValues); +#if _WIN32 || __CYGWIN__ + void init(const char* file, int line, Win32Result osErrorNumber, + const char* condition, const char* macroArgs, ArrayPtr argValues); +#endif + + Exception* exception; + }; + + class SyscallResult { + public: + inline SyscallResult(int errorNumber): errorNumber(errorNumber) {} + inline operator void*() { return errorNumber == 0 ? this : nullptr; } + inline int getErrorNumber() { return errorNumber; } + + private: + int errorNumber; + }; + + template + static SyscallResult syscall(Call&& call, bool nonblocking); + template + static int syscallError(Call&& call, bool nonblocking); + +#if _WIN32 || __CYGWIN__ + static Win32Result win32Call(int boolean); + static Win32Result win32Call(void* handle); + static Win32Result winsockCall(int result); + static uint getWin32ErrorCode(); +#endif + + class Context: public ExceptionCallback { + public: + Context(); + KJ_DISALLOW_COPY_AND_MOVE(Context); + virtual ~Context() noexcept(false); + + struct Value { + const char* file; + int line; + String description; + + inline Value(const char* file, int line, String&& description) + : file(file), line(line), description(mv(description)) {} + }; + + virtual Value evaluate() = 0; + + virtual void onRecoverableException(Exception&& exception) override; + virtual void onFatalException(Exception&& exception) override; + virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) override; + + private: + bool logged; + Maybe value; + + Value ensureInitialized(); + }; + + template + class ContextImpl: public Context { + public: + inline ContextImpl(Func& func): func(func) {} + KJ_DISALLOW_COPY_AND_MOVE(ContextImpl); + + Value evaluate() override { + return func(); + } + private: + Func& func; + }; + + template + static String makeDescription(const char* macroArgs, Params&&... params); + +private: + static LogSeverity minSeverity; + + static void logInternal(const char* file, int line, LogSeverity severity, const char* macroArgs, + ArrayPtr argValues); + static String makeDescriptionInternal(const char* macroArgs, ArrayPtr argValues); + + static int getOsErrorNumber(bool nonblocking); + // Get the error code of the last error (e.g. from errno). Returns -1 on EINTR. +}; + +template +void Debug::log(const char* file, int line, LogSeverity severity, const char* macroArgs, + Params&&... params) { + String argValues[sizeof...(Params)] = {str(params)...}; + logInternal(file, line, severity, macroArgs, arrayPtr(argValues, sizeof...(Params))); +} + +template <> +inline void Debug::log<>(const char* file, int line, LogSeverity severity, const char* macroArgs) { + logInternal(file, line, severity, macroArgs, nullptr); +} + +template +Debug::Fault::Fault(const char* file, int line, Code code, + const char* condition, const char* macroArgs, Params&&... params) + : exception(nullptr) { + String argValues[sizeof...(Params)] = {str(params)...}; + init(file, line, code, condition, macroArgs, + arrayPtr(argValues, sizeof...(Params))); +} + +inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, osErrorNumber, condition, macroArgs, nullptr); +} + +inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, type, condition, macroArgs, nullptr); +} + +#if _WIN32 || __CYGWIN__ +inline Debug::Fault::Fault(const char* file, int line, Win32Result osErrorNumber, + const char* condition, const char* macroArgs) + : exception(nullptr) { + init(file, line, osErrorNumber, condition, macroArgs, nullptr); +} + +inline Debug::Win32Result Debug::win32Call(int boolean) { + return boolean ? Win32Result(0) : Win32Result(getWin32ErrorCode()); +} +inline Debug::Win32Result Debug::win32Call(void* handle) { + // Assume null and INVALID_HANDLE_VALUE mean failure. + return win32Call(handle != nullptr && handle != (void*)-1); +} +inline Debug::Win32Result Debug::winsockCall(int result) { + // Expect a return value of SOCKET_ERROR means failure. + return win32Call(result != -1); +} +#endif + +template +Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) { + while (call() < 0) { + int errorNum = getOsErrorNumber(nonblocking); + // getOsErrorNumber() returns -1 to indicate EINTR. + // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a + // non-error. + if (errorNum != -1) { + return SyscallResult(errorNum); + } + } + return SyscallResult(0); +} + +template +int Debug::syscallError(Call&& call, bool nonblocking) { + while (call() < 0) { + int errorNum = getOsErrorNumber(nonblocking); + // getOsErrorNumber() returns -1 to indicate EINTR. + // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a + // non-error. + if (errorNum != -1) { + return errorNum; + } + } + return 0; +} + +template +String Debug::makeDescription(const char* macroArgs, Params&&... params) { + String argValues[sizeof...(Params)] = {str(params)...}; + return makeDescriptionInternal(macroArgs, arrayPtr(argValues, sizeof...(Params))); +} + +template <> +inline String Debug::makeDescription<>(const char* macroArgs) { + return makeDescriptionInternal(macroArgs, nullptr); +} + +// ======================================================================================= +// Magic Asserts! +// +// When KJ_ASSERT(foo == bar) fails, `foo` and `bar`'s actual values will be stringified in the +// error message. How does it work? We use template magic and operator precedence. The assertion +// actually evaluates something like this: +// +// if (auto _kjCondition = kj::_::MAGIC_ASSERT << foo == bar) +// +// `<<` has operator precedence slightly above `==`, so `kj::_::MAGIC_ASSERT << foo` gets evaluated +// first. This wraps `foo` in a little wrapper that captures the comparison operators and keeps +// enough information around to be able to stringify the left and right sides of the comparison +// independently. As always, the stringification only actually occurs if the assert fails. +// +// You might ask why we use operator `<<` and not e.g. operator `<=`, since operators of the same +// precedence are evaluated left-to-right. The answer is that some compilers trigger all sorts of +// warnings when you seem to be using a comparison as the input to another comparison. The +// particular warning GCC produces is its general "-Wparentheses" warning which is broadly useful, +// so we don't want to disable it. `<<` also produces some warnings, but only on Clang and the +// specific warning is one we're comfortable disabling (see below). This does mean that we have to +// explicitly overload `operator<<` ourselves to make sure using it in an assert still works. +// +// You might also ask, if we're using operator `<<` anyway, why not start it from the right, in +// which case it would bind after computing any `<<` operators that were actually in the user's +// code? I tried this, but it resulted in a somewhat broader warning from clang that I felt worse +// about disabling (a warning about `<<` precedence not applying specifically to overloads) and +// also created ambiguous overload errors in the KJ units code. + +#if __clang__ +// We intentionally overload operator << for the specific purpose of evaluating it before +// evaluating comparison expressions, so stop Clang from warning about it. Unfortunately this means +// eliminating a warning that would otherwise be useful for people using iostreams... sorry. +#pragma GCC diagnostic ignored "-Woverloaded-shift-op-parentheses" +#endif + +template +struct DebugExpression; + +template ()))> +inline auto tryToCharSequence(T* value) { return kj::toCharSequence(*value); } +inline StringPtr tryToCharSequence(...) { return "(can't stringify)"_kj; } +// SFINAE to stringify a value if and only if it can be stringified. + +template +struct DebugComparison { + Left left; + Right right; + StringPtr op; + bool result; + + inline operator bool() const { return KJ_LIKELY(result); } + + template inline void operator&(T&& other) = delete; + template inline void operator^(T&& other) = delete; + template inline void operator|(T&& other) = delete; +}; + +template +String KJ_STRINGIFY(DebugComparison& cmp) { + return _::concat(tryToCharSequence(&cmp.left), cmp.op, tryToCharSequence(&cmp.right)); +} + +template +struct DebugExpression { + DebugExpression(T&& value): value(kj::fwd(value)) {} + T value; + + // Handle comparison operations by constructing a DebugComparison value. +#define DEFINE_OPERATOR(OP) \ + template \ + DebugComparison operator OP(U&& other) { \ + bool result = value OP other; \ + return { kj::fwd(value), kj::fwd(other), " " #OP " "_kj, result }; \ + } + DEFINE_OPERATOR(==); + DEFINE_OPERATOR(!=); + DEFINE_OPERATOR(<=); + DEFINE_OPERATOR(>=); + DEFINE_OPERATOR(< ); + DEFINE_OPERATOR(> ); +#undef DEFINE_OPERATOR + + // Handle binary operators that have equal or lower precedence than comparisons by performing + // the operation and wrapping the result. +#define DEFINE_OPERATOR(OP) \ + template inline auto operator OP(U&& other) { \ + return DebugExpression(value) OP kj::fwd(other))>(\ + kj::fwd(value) OP kj::fwd(other)); \ + } + DEFINE_OPERATOR(<<); + DEFINE_OPERATOR(>>); + DEFINE_OPERATOR(&); + DEFINE_OPERATOR(^); + DEFINE_OPERATOR(|); +#undef DEFINE_OPERATOR + + inline operator bool() { + // No comparison performed, we're just asserting the expression is truthy. This also covers + // the case of the logic operators && and || -- we cannot overload those because doing so would + // break short-circuiting behavior. + return value; + } +}; + +template +StringPtr KJ_STRINGIFY(const DebugExpression& exp) { + // Hack: This will only ever be called in cases where the expression's truthiness was asserted + // directly, and was determined to be falsy. + return "false"_kj; +} + +struct DebugExpressionStart { + template + DebugExpression operator<<(T&& value) const { + return DebugExpression(kj::fwd(value)); + } +}; +static constexpr DebugExpressionStart MAGIC_ASSERT; + +} // namespace _ (private) +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/encoding.cc b/src/plugins/streamers/lstream/runtime/kj/kj/encoding.cc new file mode 100644 index 000000000..06ef3ab78 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/encoding.cc @@ -0,0 +1,1030 @@ +// Copyright (c) 2017 Cloudflare, Inc.; Sandstorm Development Group, Inc.; and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "encoding.h" +#include "vector.h" +#include "debug.h" + +namespace kj { + +namespace { + +#define GOTO_ERROR_IF(cond) if (KJ_UNLIKELY(cond)) goto error + +inline void addChar32(Vector& vec, char32_t u) { + // Encode as surrogate pair. + u -= 0x10000; + vec.add(0xd800 | (u >> 10)); + vec.add(0xdc00 | (u & 0x03ff)); +} + +inline void addChar32(Vector& vec, char32_t u) { + vec.add(u); +} + +template +EncodingResult> encodeUtf(ArrayPtr text, bool nulTerminate) { + Vector result(text.size() + nulTerminate); + bool hadErrors = false; + + size_t i = 0; + while (i < text.size()) { + byte c = text[i++]; + if (c < 0x80) { + // 0xxxxxxx -- ASCII + result.add(c); + continue; + } else if (KJ_UNLIKELY(c < 0xc0)) { + // 10xxxxxx -- malformed continuation byte + goto error; + } else if (c < 0xe0) { + // 110xxxxx -- 2-byte + byte c2; + GOTO_ERROR_IF(i == text.size() || ((c2 = text[i]) & 0xc0) != 0x80); ++i; + char16_t u = (static_cast(c & 0x1f) << 6) + | (static_cast(c2 & 0x3f) ); + + // Disallow overlong sequence. + GOTO_ERROR_IF(u < 0x80); + + result.add(u); + continue; + } else if (c < 0xf0) { + // 1110xxxx -- 3-byte + byte c2, c3; + GOTO_ERROR_IF(i == text.size() || ((c2 = text[i]) & 0xc0) != 0x80); ++i; + GOTO_ERROR_IF(i == text.size() || ((c3 = text[i]) & 0xc0) != 0x80); ++i; + char16_t u = (static_cast(c & 0x0f) << 12) + | (static_cast(c2 & 0x3f) << 6) + | (static_cast(c3 & 0x3f) ); + + // Disallow overlong sequence. + GOTO_ERROR_IF(u < 0x0800); + + // Flag surrogate pair code points as errors, but allow them through. + if (KJ_UNLIKELY((u & 0xf800) == 0xd800)) { + if (result.size() > 0 && + (u & 0xfc00) == 0xdc00 && + (result.back() & 0xfc00) == 0xd800) { + // Whoops, the *previous* character was also an invalid surrogate, and if we add this + // one too, they'll form a valid surrogate pair. If we allowed this, then it would mean + // invalid UTF-8 round-tripped to UTF-16 and back could actually change meaning entirely. + // OTOH, the reason we allow dangling surrogates is to allow invalid UTF-16 to round-trip + // to UTF-8 without loss, but if the original UTF-16 had a valid surrogate pair, it would + // have been encoded as a valid single UTF-8 codepoint, not as separate UTF-8 codepoints + // for each surrogate. + goto error; + } + + hadErrors = true; + } + + result.add(u); + continue; + } else if (c < 0xf8) { + // 11110xxx -- 4-byte + byte c2, c3, c4; + GOTO_ERROR_IF(i == text.size() || ((c2 = text[i]) & 0xc0) != 0x80); ++i; + GOTO_ERROR_IF(i == text.size() || ((c3 = text[i]) & 0xc0) != 0x80); ++i; + GOTO_ERROR_IF(i == text.size() || ((c4 = text[i]) & 0xc0) != 0x80); ++i; + char32_t u = (static_cast(c & 0x07) << 18) + | (static_cast(c2 & 0x3f) << 12) + | (static_cast(c3 & 0x3f) << 6) + | (static_cast(c4 & 0x3f) ); + + // Disallow overlong sequence. + GOTO_ERROR_IF(u < 0x10000); + + // Unicode ends at U+10FFFF + GOTO_ERROR_IF(u >= 0x110000); + + addChar32(result, u); + continue; + } else { + // 5-byte and 6-byte sequences are not legal as they'd result in codepoints outside the + // range of Unicode. + goto error; + } + + error: + result.add(0xfffd); + hadErrors = true; + // Ignore all continuation bytes. + while (i < text.size() && (text[i] & 0xc0) == 0x80) { + ++i; + } + } + + if (nulTerminate) result.add(0); + + return { result.releaseAsArray(), hadErrors }; +} + +} // namespace + +EncodingResult> encodeUtf16(ArrayPtr text, bool nulTerminate) { + return encodeUtf(text, nulTerminate); +} + +EncodingResult> encodeUtf32(ArrayPtr text, bool nulTerminate) { + return encodeUtf(text, nulTerminate); +} + +EncodingResult decodeUtf16(ArrayPtr utf16) { + Vector result(utf16.size() + 1); + bool hadErrors = false; + + size_t i = 0; + while (i < utf16.size()) { + char16_t u = utf16[i++]; + + if (u < 0x80) { + result.add(u); + continue; + } else if (u < 0x0800) { + result.addAll>({ + static_cast(((u >> 6) ) | 0xc0), + static_cast(((u ) & 0x3f) | 0x80) + }); + continue; + } else if ((u & 0xf800) == 0xd800) { + // surrogate pair + char16_t u2; + if (KJ_UNLIKELY(i == utf16.size() // missing second half + || (u & 0x0400) != 0 // first half in wrong range + || ((u2 = utf16[i]) & 0xfc00) != 0xdc00)) { // second half in wrong range + hadErrors = true; + goto threeByte; + } + ++i; + + char32_t u32 = (((u & 0x03ff) << 10) | (u2 & 0x03ff)) + 0x10000; + result.addAll>({ + static_cast(((u32 >> 18) ) | 0xf0), + static_cast(((u32 >> 12) & 0x3f) | 0x80), + static_cast(((u32 >> 6) & 0x3f) | 0x80), + static_cast(((u32 ) & 0x3f) | 0x80) + }); + continue; + } else { + threeByte: + result.addAll>({ + static_cast(((u >> 12) ) | 0xe0), + static_cast(((u >> 6) & 0x3f) | 0x80), + static_cast(((u ) & 0x3f) | 0x80) + }); + continue; + } + } + + result.add(0); + return { String(result.releaseAsArray()), hadErrors }; +} + +EncodingResult decodeUtf32(ArrayPtr utf16) { + Vector result(utf16.size() + 1); + bool hadErrors = false; + + size_t i = 0; + while (i < utf16.size()) { + char32_t u = utf16[i++]; + + if (u < 0x80) { + result.add(u); + continue; + } else if (u < 0x0800) { + result.addAll>({ + static_cast(((u >> 6) ) | 0xc0), + static_cast(((u ) & 0x3f) | 0x80) + }); + continue; + } else if (u < 0x10000) { + if (KJ_UNLIKELY((u & 0xfffff800) == 0xd800)) { + // no surrogates allowed in utf-32 + hadErrors = true; + } + result.addAll>({ + static_cast(((u >> 12) ) | 0xe0), + static_cast(((u >> 6) & 0x3f) | 0x80), + static_cast(((u ) & 0x3f) | 0x80) + }); + continue; + } else { + GOTO_ERROR_IF(u >= 0x110000); // outside Unicode range + result.addAll>({ + static_cast(((u >> 18) ) | 0xf0), + static_cast(((u >> 12) & 0x3f) | 0x80), + static_cast(((u >> 6) & 0x3f) | 0x80), + static_cast(((u ) & 0x3f) | 0x80) + }); + continue; + } + + error: + result.addAll(StringPtr(u8"\ufffd")); + hadErrors = true; + } + + result.add(0); + return { String(result.releaseAsArray()), hadErrors }; +} + +namespace { + +#if __GNUC__ >= 8 && !__clang__ +// GCC 8's new class-memaccess warning rightly dislikes the following hacks, but we're really sure +// we want to allow them so disable the warning. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + +template +Array coerceTo(Array&& array) { + static_assert(sizeof(To) == sizeof(From), "incompatible coercion"); + Array result; + memcpy(&result, &array, sizeof(array)); + memset(&array, 0, sizeof(array)); + return result; +} + +template +ArrayPtr coerceTo(ArrayPtr array) { + static_assert(sizeof(To) == sizeof(From), "incompatible coercion"); + return arrayPtr(reinterpret_cast(array.begin()), array.size()); +} + +template +EncodingResult> coerceTo(EncodingResult>&& result) { + return { coerceTo(Array(kj::mv(result))), result.hadErrors }; +} + +#if __GNUC__ >= 8 && !__clang__ +#pragma GCC diagnostic pop +#endif + +template +struct WideConverter; + +template <> +struct WideConverter { + typedef char Type; + + static EncodingResult> encode(ArrayPtr text, bool nulTerminate) { + auto result = heapArray(text.size() + nulTerminate); + memcpy(result.begin(), text.begin(), text.size()); + if (nulTerminate) result.back() = 0; + return { kj::mv(result), false }; + } + + static EncodingResult decode(ArrayPtr text) { + return { kj::heapString(text), false }; + } +}; + +template <> +struct WideConverter { + typedef char16_t Type; + + static inline EncodingResult> encode( + ArrayPtr text, bool nulTerminate) { + return encodeUtf16(text, nulTerminate); + } + + static inline EncodingResult decode(ArrayPtr text) { + return decodeUtf16(text); + } +}; + +template <> +struct WideConverter { + typedef char32_t Type; + + static inline EncodingResult> encode( + ArrayPtr text, bool nulTerminate) { + return encodeUtf32(text, nulTerminate); + } + + static inline EncodingResult decode(ArrayPtr text) { + return decodeUtf32(text); + } +}; + +} // namespace + +EncodingResult> encodeWideString(ArrayPtr text, bool nulTerminate) { + return coerceTo(WideConverter::encode(text, nulTerminate)); +} +EncodingResult decodeWideString(ArrayPtr wide) { + using Converter = WideConverter; + return Converter::decode(coerceTo(wide)); +} + +// ======================================================================================= + +namespace { + +const char HEX_DIGITS[] = "0123456789abcdef"; +// Maps integer in the range [0,16) to a hex digit. + +const char HEX_DIGITS_URI[] = "0123456789ABCDEF"; +// RFC 3986 section 2.1 says "For consistency, URI producers and normalizers should use uppercase +// hexadecimal digits for all percent-encodings. + +static Maybe tryFromHexDigit(char c) { + if ('0' <= c && c <= '9') { + return c - '0'; + } else if ('a' <= c && c <= 'f') { + return c - ('a' - 10); + } else if ('A' <= c && c <= 'F') { + return c - ('A' - 10); + } else { + return nullptr; + } +} + +static Maybe tryFromOctDigit(char c) { + if ('0' <= c && c <= '7') { + return c - '0'; + } else { + return nullptr; + } +} + +} // namespace + +String encodeHex(ArrayPtr input) { + return strArray(KJ_MAP(b, input) { + return heapArray({HEX_DIGITS[b/16], HEX_DIGITS[b%16]}); + }, ""); +} + +EncodingResult> decodeHex(ArrayPtr text) { + auto result = heapArray(text.size() / 2); + bool hadErrors = text.size() % 2; + + for (auto i: kj::indices(result)) { + byte b = 0; + KJ_IF_MAYBE(d1, tryFromHexDigit(text[i*2])) { + b = *d1 << 4; + } else { + hadErrors = true; + } + KJ_IF_MAYBE(d2, tryFromHexDigit(text[i*2+1])) { + b |= *d2; + } else { + hadErrors = true; + } + result[i] = b; + } + + return { kj::mv(result), hadErrors }; +} + +String encodeUriComponent(ArrayPtr bytes) { + Vector result(bytes.size() + 1); + for (byte b: bytes) { + if (('A' <= b && b <= 'Z') || + ('a' <= b && b <= 'z') || + ('0' <= b && b <= '9') || + b == '-' || b == '_' || b == '.' || b == '!' || b == '~' || b == '*' || b == '\'' || + b == '(' || b == ')') { + result.add(b); + } else { + result.add('%'); + result.add(HEX_DIGITS_URI[b/16]); + result.add(HEX_DIGITS_URI[b%16]); + } + } + result.add('\0'); + return String(result.releaseAsArray()); +} + +String encodeUriFragment(ArrayPtr bytes) { + Vector result(bytes.size() + 1); + for (byte b: bytes) { + if (('?' <= b && b <= '_') || // covers A-Z + ('a' <= b && b <= '~') || // covers a-z + ('&' <= b && b <= ';') || // covers 0-9 + b == '!' || b == '=' || b == '#' || b == '$') { + result.add(b); + } else { + result.add('%'); + result.add(HEX_DIGITS_URI[b/16]); + result.add(HEX_DIGITS_URI[b%16]); + } + } + result.add('\0'); + return String(result.releaseAsArray()); +} + +String encodeUriPath(ArrayPtr bytes) { + Vector result(bytes.size() + 1); + for (byte b: bytes) { + if (('@' <= b && b <= '[') || // covers A-Z + ('a' <= b && b <= 'z') || + ('0' <= b && b <= ';') || // covers 0-9 + ('&' <= b && b <= '.') || + b == '_' || b == '!' || b == '=' || b == ']' || + b == '^' || b == '|' || b == '~' || b == '$') { + result.add(b); + } else { + result.add('%'); + result.add(HEX_DIGITS_URI[b/16]); + result.add(HEX_DIGITS_URI[b%16]); + } + } + result.add('\0'); + return String(result.releaseAsArray()); +} + +String encodeUriUserInfo(ArrayPtr bytes) { + Vector result(bytes.size() + 1); + for (byte b: bytes) { + if (('A' <= b && b <= 'Z') || + ('a' <= b && b <= 'z') || + ('0' <= b && b <= '9') || + ('&' <= b && b <= '.') || + b == '_' || b == '!' || b == '~' || b == '$') { + result.add(b); + } else { + result.add('%'); + result.add(HEX_DIGITS_URI[b/16]); + result.add(HEX_DIGITS_URI[b%16]); + } + } + result.add('\0'); + return String(result.releaseAsArray()); +} + +String encodeWwwForm(ArrayPtr bytes) { + Vector result(bytes.size() + 1); + for (byte b: bytes) { + if (('A' <= b && b <= 'Z') || + ('a' <= b && b <= 'z') || + ('0' <= b && b <= '9') || + b == '-' || b == '_' || b == '.' || b == '*') { + result.add(b); + } else if (b == ' ') { + result.add('+'); + } else { + result.add('%'); + result.add(HEX_DIGITS_URI[b/16]); + result.add(HEX_DIGITS_URI[b%16]); + } + } + result.add('\0'); + return String(result.releaseAsArray()); +} + +EncodingResult> decodeBinaryUriComponent( + ArrayPtr text, DecodeUriOptions options) { + Vector result(text.size() + options.nulTerminate); + bool hadErrors = false; + + const char* ptr = text.begin(); + const char* end = text.end(); + while (ptr < end) { + if (*ptr == '%') { + ++ptr; + + if (ptr == end) { + hadErrors = true; + } else KJ_IF_MAYBE(d1, tryFromHexDigit(*ptr)) { + byte b = *d1; + ++ptr; + if (ptr == end) { + hadErrors = true; + } else KJ_IF_MAYBE(d2, tryFromHexDigit(*ptr)) { + b = (b << 4) | *d2; + ++ptr; + } else { + hadErrors = true; + } + result.add(b); + } else { + hadErrors = true; + } + } else if (options.plusToSpace && *ptr == '+') { + ++ptr; + result.add(' '); + } else { + result.add(*ptr++); + } + } + + if (options.nulTerminate) result.add(0); + return { result.releaseAsArray(), hadErrors }; +} + +// ======================================================================================= + +namespace _ { // private + +String encodeCEscapeImpl(ArrayPtr bytes, bool isBinary) { + Vector escaped(bytes.size()); + + for (byte b: bytes) { + switch (b) { + case '\a': escaped.addAll(StringPtr("\\a")); break; + case '\b': escaped.addAll(StringPtr("\\b")); break; + case '\f': escaped.addAll(StringPtr("\\f")); break; + case '\n': escaped.addAll(StringPtr("\\n")); break; + case '\r': escaped.addAll(StringPtr("\\r")); break; + case '\t': escaped.addAll(StringPtr("\\t")); break; + case '\v': escaped.addAll(StringPtr("\\v")); break; + case '\'': escaped.addAll(StringPtr("\\\'")); break; + case '\"': escaped.addAll(StringPtr("\\\"")); break; + case '\\': escaped.addAll(StringPtr("\\\\")); break; + default: + if (b < 0x20 || b == 0x7f || (isBinary && b > 0x7f)) { + // Use octal escape, not hex, because hex escapes technically have no length limit and + // so can create ambiguity with subsequent characters. + escaped.add('\\'); + escaped.add(HEX_DIGITS[b / 64]); + escaped.add(HEX_DIGITS[(b / 8) % 8]); + escaped.add(HEX_DIGITS[b % 8]); + } else { + escaped.add(b); + } + break; + } + } + + escaped.add(0); + return String(escaped.releaseAsArray()); +} + +} // namespace + +EncodingResult> decodeBinaryCEscape(ArrayPtr text, bool nulTerminate) { + Vector result(text.size() + nulTerminate); + bool hadErrors = false; + + size_t i = 0; + while (i < text.size()) { + char c = text[i++]; + if (c == '\\') { + if (i == text.size()) { + hadErrors = true; + continue; + } + char c2 = text[i++]; + switch (c2) { + case 'a' : result.add('\a'); break; + case 'b' : result.add('\b'); break; + case 'f' : result.add('\f'); break; + case 'n' : result.add('\n'); break; + case 'r' : result.add('\r'); break; + case 't' : result.add('\t'); break; + case 'v' : result.add('\v'); break; + case '\'': result.add('\''); break; + case '\"': result.add('\"'); break; + case '\\': result.add('\\'); break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + uint value = c2 - '0'; + for (uint j = 0; j < 2 && i < text.size(); j++) { + KJ_IF_MAYBE(d, tryFromOctDigit(text[i])) { + ++i; + value = (value << 3) | *d; + } else { + break; + } + } + if (value >= 0x100) hadErrors = true; + result.add(value); + break; + } + + case 'x': { + uint value = 0; + while (i < text.size()) { + KJ_IF_MAYBE(d, tryFromHexDigit(text[i])) { + ++i; + value = (value << 4) | *d; + } else { + break; + } + } + if (value >= 0x100) hadErrors = true; + result.add(value); + break; + } + + case 'u': { + char16_t value = 0; + for (uint j = 0; j < 4; j++) { + if (i == text.size()) { + hadErrors = true; + break; + } else KJ_IF_MAYBE(d, tryFromHexDigit(text[i])) { + ++i; + value = (value << 4) | *d; + } else { + hadErrors = true; + break; + } + } + auto utf = decodeUtf16(arrayPtr(&value, 1)); + if (utf.hadErrors) hadErrors = true; + result.addAll(utf.asBytes()); + break; + } + + case 'U': { + char32_t value = 0; + for (uint j = 0; j < 8; j++) { + if (i == text.size()) { + hadErrors = true; + break; + } else KJ_IF_MAYBE(d, tryFromHexDigit(text[i])) { + ++i; + value = (value << 4) | *d; + } else { + hadErrors = true; + break; + } + } + auto utf = decodeUtf32(arrayPtr(&value, 1)); + if (utf.hadErrors) hadErrors = true; + result.addAll(utf.asBytes()); + break; + } + + default: + result.add(c2); + } + } else { + result.add(c); + } + } + + if (nulTerminate) result.add(0); + return { result.releaseAsArray(), hadErrors }; +} + +// ======================================================================================= +// This code is derived from libb64 which has been placed in the public domain. +// For details, see http://sourceforge.net/projects/libb64 + +// ------------------------------------------------------------------- +// Encoder + +namespace { + +typedef enum { + step_A, step_B, step_C +} base64_encodestep; + +typedef struct { + base64_encodestep step; + char result; + int stepcount; +} base64_encodestate; + +const int CHARS_PER_LINE = 72; + +void base64_init_encodestate(base64_encodestate* state_in) { + state_in->step = step_A; + state_in->result = 0; + state_in->stepcount = 0; +} + +char base64_encode_value(char value_in) { + static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + if (value_in > 63) return '='; + return encoding[(int)value_in]; +} + +int base64_encode_block(const char* plaintext_in, int length_in, + char* code_out, base64_encodestate* state_in, bool breakLines) { + const char* plainchar = plaintext_in; + const char* const plaintextend = plaintext_in + length_in; + char* codechar = code_out; + char result; + char fragment; + + result = state_in->result; + + switch (state_in->step) { + while (1) { + KJ_FALLTHROUGH; + case step_A: + if (plainchar == plaintextend) { + state_in->result = result; + state_in->step = step_A; + return codechar - code_out; + } + fragment = *plainchar++; + result = (fragment & 0x0fc) >> 2; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x003) << 4; + KJ_FALLTHROUGH; + case step_B: + if (plainchar == plaintextend) { + state_in->result = result; + state_in->step = step_B; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0f0) >> 4; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x00f) << 2; + KJ_FALLTHROUGH; + case step_C: + if (plainchar == plaintextend) { + state_in->result = result; + state_in->step = step_C; + return codechar - code_out; + } + fragment = *plainchar++; + result |= (fragment & 0x0c0) >> 6; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x03f) >> 0; + *codechar++ = base64_encode_value(result); + + ++(state_in->stepcount); + if (breakLines && state_in->stepcount == CHARS_PER_LINE/4) { + *codechar++ = '\n'; + state_in->stepcount = 0; + } + } + } + /* control should not reach here */ + return codechar - code_out; +} + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in, bool breakLines) { + char* codechar = code_out; + + switch (state_in->step) { + case step_B: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + *codechar++ = '='; + ++state_in->stepcount; + break; + case step_C: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + ++state_in->stepcount; + break; + case step_A: + break; + } + if (breakLines && state_in->stepcount > 0) { + *codechar++ = '\n'; + } + + return codechar - code_out; +} + +} // namespace + +String encodeBase64(ArrayPtr input, bool breakLines) { + /* set up a destination buffer large enough to hold the encoded data */ + // equivalent to ceil(input.size() / 3) * 4 + auto numChars = (input.size() + 2) / 3 * 4; + if (breakLines) { + // Add space for newline characters. + uint lineCount = numChars / CHARS_PER_LINE; + if (numChars % CHARS_PER_LINE > 0) { + // Partial line. + ++lineCount; + } + numChars = numChars + lineCount; + } + auto output = heapString(numChars); + /* keep track of our encoded position */ + char* c = output.begin(); + /* store the number of bytes encoded by a single call */ + int cnt = 0; + size_t total = 0; + /* we need an encoder state */ + base64_encodestate s; + + /*---------- START ENCODING ----------*/ + /* initialise the encoder state */ + base64_init_encodestate(&s); + /* gather data from the input and send it to the output */ + cnt = base64_encode_block((const char *)input.begin(), input.size(), c, &s, breakLines); + c += cnt; + total += cnt; + + /* since we have encoded the entire input string, we know that + there is no more input data; finalise the encoding */ + cnt = base64_encode_blockend(c, &s, breakLines); + c += cnt; + total += cnt; + /*---------- STOP ENCODING ----------*/ + + KJ_ASSERT(total == output.size(), total, output.size()); + + return output; +} + +// ------------------------------------------------------------------- +// Decoder + +namespace { + +typedef enum { + step_a, step_b, step_c, step_d +} base64_decodestep; + +struct base64_decodestate { + bool hadErrors = false; + size_t nPaddingBytesSeen = 0; + // Output state. `nPaddingBytesSeen` is not guaranteed to be correct if `hadErrors` is true. It is + // included in the state purely to preserve the streaming capability of the algorithm while still + // checking for errors correctly (consider chunk 1 = "abc=", chunk 2 = "d"). + + base64_decodestep step = step_a; + char plainchar = 0; +}; + +int base64_decode_value(char value_in) { + // Returns either the fragment value or: -1 on whitespace, -2 on padding, -3 on invalid input. + // + // Note that the original libb64 implementation used -1 for invalid input, -2 on padding -- this + // new scheme allows for some simpler error checks in steps A and B. + + static const signed char decoding[] = { + -3,-3,-3,-3,-3,-3,-3,-3, -3,-1,-1,-3,-1,-1,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -1,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,62,-3,-3,-3,63, + 52,53,54,55,56,57,58,59, 60,61,-3,-3,-3,-2,-3,-3, + -3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22, 23,24,25,-3,-3,-3,-3,-3, + -3,26,27,28,29,30,31,32, 33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48, 49,50,51,-3,-3,-3,-3,-3, + + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + -3,-3,-3,-3,-3,-3,-3,-3, -3,-3,-3,-3,-3,-3,-3,-3, + }; + static_assert(sizeof(decoding) == 256, "base64 decoding table size error"); + return decoding[(unsigned char)value_in]; +} + +int base64_decode_block(const char* code_in, const int length_in, + char* plaintext_out, base64_decodestate* state_in) { + const char* codechar = code_in; + char* plainchar = plaintext_out; + signed char fragment; + + if (state_in->step != step_a) { + *plainchar = state_in->plainchar; + } + +#define ERROR_IF(predicate) state_in->hadErrors = state_in->hadErrors || (predicate) + + switch (state_in->step) + { + while (1) + { + KJ_FALLTHROUGH; + case step_a: + do { + if (codechar == code_in+length_in) { + state_in->step = step_a; + state_in->plainchar = '\0'; + return plainchar - plaintext_out; + } + fragment = (signed char)base64_decode_value(*codechar++); + // It is an error to see invalid or padding bytes in step A. + ERROR_IF(fragment < -1); + } while (fragment < 0); + *plainchar = (fragment & 0x03f) << 2; + KJ_FALLTHROUGH; + case step_b: + do { + if (codechar == code_in+length_in) { + state_in->step = step_b; + state_in->plainchar = *plainchar; + // It is always an error to suspend from step B, because we don't have enough bits yet. + // TODO(someday): This actually breaks the streaming use case, if base64_decode_block() is + // to be called multiple times. We'll fix it if we ever care to support streaming. + state_in->hadErrors = true; + return plainchar - plaintext_out; + } + fragment = (signed char)base64_decode_value(*codechar++); + // It is an error to see invalid or padding bytes in step B. + ERROR_IF(fragment < -1); + } while (fragment < 0); + *plainchar++ |= (fragment & 0x030) >> 4; + *plainchar = (fragment & 0x00f) << 4; + KJ_FALLTHROUGH; + case step_c: + do { + if (codechar == code_in+length_in) { + state_in->step = step_c; + state_in->plainchar = *plainchar; + // It is an error to complete from step C if we have seen incomplete padding. + // TODO(someday): This actually breaks the streaming use case, if base64_decode_block() is + // to be called multiple times. We'll fix it if we ever care to support streaming. + ERROR_IF(state_in->nPaddingBytesSeen == 1); + return plainchar - plaintext_out; + } + fragment = (signed char)base64_decode_value(*codechar++); + // It is an error to see invalid bytes or more than two padding bytes in step C. + ERROR_IF(fragment < -2 || (fragment == -2 && ++state_in->nPaddingBytesSeen > 2)); + } while (fragment < 0); + // It is an error to continue from step C after having seen any padding. + ERROR_IF(state_in->nPaddingBytesSeen > 0); + *plainchar++ |= (fragment & 0x03c) >> 2; + *plainchar = (fragment & 0x003) << 6; + KJ_FALLTHROUGH; + case step_d: + do { + if (codechar == code_in+length_in) { + state_in->step = step_d; + state_in->plainchar = *plainchar; + return plainchar - plaintext_out; + } + fragment = (signed char)base64_decode_value(*codechar++); + // It is an error to see invalid bytes or more than one padding byte in step D. + ERROR_IF(fragment < -2 || (fragment == -2 && ++state_in->nPaddingBytesSeen > 1)); + } while (fragment < 0); + // It is an error to continue from step D after having seen padding bytes. + ERROR_IF(state_in->nPaddingBytesSeen > 0); + *plainchar++ |= (fragment & 0x03f); + } + } + +#undef ERROR_IF + + /* control should not reach here */ + return plainchar - plaintext_out; +} + +} // namespace + +EncodingResult> decodeBase64(ArrayPtr input) { + base64_decodestate state; + + auto output = heapArray((input.size() * 6 + 7) / 8); + + size_t n = base64_decode_block(input.begin(), input.size(), + reinterpret_cast(output.begin()), &state); + + if (n < output.size()) { + auto copy = heapArray(n); + memcpy(copy.begin(), output.begin(), n); + output = kj::mv(copy); + } + + return EncodingResult>(kj::mv(output), state.hadErrors); +} + +String encodeBase64Url(ArrayPtr bytes) { + // TODO(perf): Rewrite as single pass? + // TODO(someday): Write decoder? + + auto base64 = kj::encodeBase64(bytes); + + for (char& c: base64) { + if (c == '+') c = '-'; + if (c == '/') c = '_'; + } + + // Remove trailing '='s. + kj::ArrayPtr slice = base64; + while (slice.size() > 0 && slice.back() == '=') { + slice = slice.slice(0, slice.size() - 1); + } + + return kj::str(slice); +} + +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/encoding.h b/src/plugins/streamers/lstream/runtime/kj/kj/encoding.h new file mode 100644 index 000000000..d61ee473b --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/encoding.h @@ -0,0 +1,445 @@ +// Copyright (c) 2017 Cloudflare, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +// Functions for encoding/decoding bytes and text in common formats, including: +// - UTF-{8,16,32} +// - Hex +// - URI encoding +// - Base64 + +#include "string.h" + +KJ_BEGIN_HEADER + +namespace kj { + +template +struct EncodingResult: public ResultType { + // Equivalent to ResultType (a String or wide-char array) for all intents and purposes, except + // that the bool `hadErrors` can be inspected to see if any errors were encountered in the input. + // Each encoding/decoding function that returns this type will "work around" errors in some way, + // so an application doesn't strictly have to check for errors. E.g. the Unicode functions + // replace errors with U+FFFD in the output. + // + // Through magic, KJ_IF_MAYBE() and KJ_{REQUIRE,ASSERT}_NONNULL() work on EncodingResult + // exactly if it were a Maybe that is null in case of errors. + + inline EncodingResult(ResultType&& result, bool hadErrors) + : ResultType(kj::mv(result)), hadErrors(hadErrors) {} + + const bool hadErrors; +}; + +template +inline auto KJ_STRINGIFY(const EncodingResult& value) + -> decltype(toCharSequence(implicitCast(value))) { + return toCharSequence(implicitCast(value)); +} + +EncodingResult> encodeUtf16(ArrayPtr text, bool nulTerminate = false); +EncodingResult> encodeUtf32(ArrayPtr text, bool nulTerminate = false); +// Convert UTF-8 text (which KJ strings use) to UTF-16 or UTF-32. +// +// If `nulTerminate` is true, an extra NUL character will be added to the end of the output. +// +// The returned arrays are in platform-native endianness (otherwise they wouldn't really be +// char16_t / char32_t). +// +// Note that the KJ Unicode encoding and decoding functions actually implement +// [WTF-8 encoding](http://simonsapin.github.io/wtf-8/), which affects how invalid input is +// handled. See comments on decodeUtf16() for more info. + +EncodingResult decodeUtf16(ArrayPtr utf16); +EncodingResult decodeUtf32(ArrayPtr utf32); +// Convert UTF-16 or UTF-32 to UTF-8 (which KJ strings use). +// +// The input should NOT include a NUL terminator; any NUL characters in the input array will be +// preserved in the output. +// +// The input must be in platform-native endianness. BOMs are NOT recognized by these functions. +// +// Note that the KJ Unicode encoding and decoding functions actually implement +// [WTF-8 encoding](http://simonsapin.github.io/wtf-8/). This means that if you start with an array +// of char16_t and you pass it through any number of conversions to other Unicode encodings, +// eventually returning it to UTF-16, all the while ignoring `hadErrors`, you will end up with +// exactly the same char16_t array you started with, *even if* the array is not valid UTF-16. This +// is useful because many real-world systems that were designed for UCS-2 (plain 16-bit Unicode) +// and later "upgraded" to UTF-16 do not enforce that their UTF-16 is well-formed. For example, +// file names on Windows NT are encoded using 16-bit characters, without enforcing that the +// character sequence is valid UTF-16. It is important that programs on Windows be able to handle +// such filenames, even if they choose to convert the name to UTF-8 for internal processing. +// +// Specifically, KJ's Unicode handling allows unpaired surrogate code points to round-trip through +// UTF-8 and UTF-32. Unpaired surrogates will be flagged as an error (setting `hadErrors` in the +// result), but will NOT be replaced with the Unicode replacement character as other erroneous +// sequences would be, but rather encoded as an invalid surrogate codepoint in the target encoding. +// +// KJ makes the following guarantees about invalid input: +// - A round trip from UTF-16 to other encodings and back will produce exactly the original input, +// with every leg of the trip raising the `hadErrors` flag if the original input was not valid. +// - A round trip from UTF-8 or UTF-32 to other encodings and back will either produce exactly +// the original input, or will have replaced some invalid sequences with the Unicode replacement +// character, U+FFFD. No code units will ever be removed unless they are replaced with U+FFFD, +// and no code units will ever be added except to encode U+FFFD. If the original input was not +// valid, the `hadErrors` flag will be raised on the first leg of the trip, and will also be +// raised on subsequent legs unless all invalid sequences were replaced with U+FFFD (which, after +// all, is a valid code point). + +EncodingResult> encodeWideString( + ArrayPtr text, bool nulTerminate = false); +EncodingResult decodeWideString(ArrayPtr wide); +// Encode / decode strings of wchar_t, aka "wide strings". Unfortunately, different platforms have +// different definitions for wchar_t. For example, on Windows they are 16-bit and encode UTF-16, +// but on Linux they are 32-bit and encode UTF-32. Some platforms even define wchar_t as 8-bit, +// encoding UTF-8 (e.g. BeOS did this). +// +// KJ assumes that wide strings use the UTF encoding that corresponds to the size of wchar_t on +// the target platform. So, these functions are simple aliases for encodeUtf*/decodeUtf*, above +// (or simply make a copy if wchar_t is 8 bits). + +String encodeHex(ArrayPtr bytes); +EncodingResult> decodeHex(ArrayPtr text); +// Encode/decode bytes as hex strings. + +String encodeUriComponent(ArrayPtr bytes); +String encodeUriComponent(ArrayPtr bytes); +EncodingResult decodeUriComponent(ArrayPtr text); +// Encode/decode URI components using % escapes for characters listed as "reserved" in RFC 2396. +// This is the same behavior as JavaScript's `encodeURIComponent()`. +// +// See https://tools.ietf.org/html/rfc2396#section-2.3 + +String encodeUriFragment(ArrayPtr bytes); +String encodeUriFragment(ArrayPtr bytes); +// Encode URL fragment components using the fragment percent encode set defined by the WHATWG URL +// specification. Use decodeUriComponent() to decode. +// +// Quirk: We also percent-encode the '%' sign itself, because we expect to be called on percent- +// decoded data. In other words, this function is not idempotent, in contrast to the URL spec. +// +// See https://url.spec.whatwg.org/#fragment-percent-encode-set + +String encodeUriPath(ArrayPtr bytes); +String encodeUriPath(ArrayPtr bytes); +// Encode URL path components (not entire paths!) using the path percent encode set defined by the +// WHATWG URL specification. Use decodeUriComponent() to decode. +// +// Quirk: We also percent-encode the '%' sign itself, because we expect to be called on percent- +// decoded data. In other words, this function is not idempotent, in contrast to the URL spec. +// +// Quirk: This percent-encodes '/' and '\' characters as well, which are not actually in the set +// defined by the WHATWG URL spec. Since a conforming URL implementation will only ever call this +// function on individual path components, and never entire paths, augmenting the character set to +// include these separators allows this function to be used to implement a URL class that stores +// its path components in percent-decoded form. +// +// See https://url.spec.whatwg.org/#path-percent-encode-set + +String encodeUriUserInfo(ArrayPtr bytes); +String encodeUriUserInfo(ArrayPtr bytes); +// Encode URL userinfo components using the userinfo percent encode set defined by the WHATWG URL +// specification. Use decodeUriComponent() to decode. +// +// Quirk: We also percent-encode the '%' sign itself, because we expect to be called on percent- +// decoded data. In other words, this function is not idempotent, in contrast to the URL spec. +// +// See https://url.spec.whatwg.org/#userinfo-percent-encode-set + +String encodeWwwForm(ArrayPtr bytes); +String encodeWwwForm(ArrayPtr bytes); +EncodingResult decodeWwwForm(ArrayPtr text); +// Encode/decode URI components using % escapes and '+' (for spaces) according to the +// application/x-www-form-urlencoded format defined by the WHATWG URL specification. +// +// Note: Like the fragment, path, and userinfo percent-encoding functions above, this function is +// not idempotent: we percent-encode '%' signs. However, in this particular case the spec happens +// to agree with us! +// +// See https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer + +struct DecodeUriOptions { + // Parameter to `decodeBinaryUriComponent()`. + + // This struct is intentionally convertible from bool, in order to maintain backwards + // compatibility with code written when `decodeBinaryUriComponent()` took a boolean second + // parameter. + DecodeUriOptions(bool nulTerminate = false, bool plusToSpace = false) + : nulTerminate(nulTerminate), plusToSpace(plusToSpace) {} + + bool nulTerminate; + // Append a terminal NUL byte. + + bool plusToSpace; + // Convert '+' to ' ' characters before percent decoding. Used to decode + // application/x-www-form-urlencoded text, such as query strings. +}; +EncodingResult> decodeBinaryUriComponent( + ArrayPtr text, DecodeUriOptions options = DecodeUriOptions()); +// Decode URI components using % escapes. This is a lower-level interface used to implement both +// `decodeUriComponent()` and `decodeWwwForm()` + +String encodeCEscape(ArrayPtr bytes); +String encodeCEscape(ArrayPtr bytes); +EncodingResult> decodeBinaryCEscape( + ArrayPtr text, bool nulTerminate = false); +EncodingResult decodeCEscape(ArrayPtr text); + +String encodeBase64(ArrayPtr bytes, bool breakLines = false); +// Encode the given bytes as base64 text. If `breakLines` is true, line breaks will be inserted +// into the output every 72 characters (e.g. for encoding e-mail bodies). + +EncodingResult> decodeBase64(ArrayPtr text); +// Decode base64 text. This function reports errors required by the WHATWG HTML/Infra specs: see +// https://html.spec.whatwg.org/multipage/webappapis.html#atob for details. + +String encodeBase64Url(ArrayPtr bytes); +// Encode the given bytes as URL-safe base64 text. (RFC 4648, section 5) + +// ======================================================================================= +// inline implementation details + +namespace _ { // private + +template +NullableValue readMaybe(EncodingResult&& value) { + if (value.hadErrors) { + return nullptr; + } else { + return kj::mv(value); + } +} + +template +T* readMaybe(EncodingResult& value) { + if (value.hadErrors) { + return nullptr; + } else { + return &value; + } +} + +template +const T* readMaybe(const EncodingResult& value) { + if (value.hadErrors) { + return nullptr; + } else { + return &value; + } +} + +String encodeCEscapeImpl(ArrayPtr bytes, bool isBinary); + +} // namespace _ (private) + +inline String encodeUriComponent(ArrayPtr text) { + return encodeUriComponent(text.asBytes()); +} +inline EncodingResult decodeUriComponent(ArrayPtr text) { + auto result = decodeBinaryUriComponent(text, DecodeUriOptions { /*.nulTerminate=*/true }); + return { String(result.releaseAsChars()), result.hadErrors }; +} + +inline String encodeUriFragment(ArrayPtr text) { + return encodeUriFragment(text.asBytes()); +} +inline String encodeUriPath(ArrayPtr text) { + return encodeUriPath(text.asBytes()); +} +inline String encodeUriUserInfo(ArrayPtr text) { + return encodeUriUserInfo(text.asBytes()); +} + +inline String encodeWwwForm(ArrayPtr text) { + return encodeWwwForm(text.asBytes()); +} +inline EncodingResult decodeWwwForm(ArrayPtr text) { + auto result = decodeBinaryUriComponent(text, DecodeUriOptions { /*.nulTerminate=*/true, + /*.plusToSpace=*/true }); + return { String(result.releaseAsChars()), result.hadErrors }; +} + +inline String encodeCEscape(ArrayPtr text) { + return _::encodeCEscapeImpl(text.asBytes(), false); +} + +inline String encodeCEscape(ArrayPtr bytes) { + return _::encodeCEscapeImpl(bytes, true); +} + +inline EncodingResult decodeCEscape(ArrayPtr text) { + auto result = decodeBinaryCEscape(text, true); + return { String(result.releaseAsChars()), result.hadErrors }; +} + +// If you pass a string literal to a function taking ArrayPtr, it'll include the NUL +// termintator, which is surprising. Let's add overloads that avoid that. In practice this probably +// only even matters for encoding-test.c++. + +template +inline EncodingResult> encodeUtf16(const char (&text)[s], bool nulTerminate=false) { + return encodeUtf16(arrayPtr(text, s - 1), nulTerminate); +} +template +inline EncodingResult> encodeUtf32(const char (&text)[s], bool nulTerminate=false) { + return encodeUtf32(arrayPtr(text, s - 1), nulTerminate); +} +template +inline EncodingResult> encodeWideString( + const char (&text)[s], bool nulTerminate=false) { + return encodeWideString(arrayPtr(text, s - 1), nulTerminate); +} +template +inline EncodingResult decodeUtf16(const char16_t (&utf16)[s]) { + return decodeUtf16(arrayPtr(utf16, s - 1)); +} +template +inline EncodingResult decodeUtf32(const char32_t (&utf32)[s]) { + return decodeUtf32(arrayPtr(utf32, s - 1)); +} +template +inline EncodingResult decodeWideString(const wchar_t (&utf32)[s]) { + return decodeWideString(arrayPtr(utf32, s - 1)); +} +template +inline EncodingResult> decodeHex(const char (&text)[s]) { + return decodeHex(arrayPtr(text, s - 1)); +} +template +inline String encodeUriComponent(const char (&text)[s]) { + return encodeUriComponent(arrayPtr(text, s - 1)); +} +template +inline Array decodeBinaryUriComponent(const char (&text)[s]) { + return decodeBinaryUriComponent(arrayPtr(text, s - 1)); +} +template +inline EncodingResult decodeUriComponent(const char (&text)[s]) { + return decodeUriComponent(arrayPtr(text, s-1)); +} +template +inline String encodeUriFragment(const char (&text)[s]) { + return encodeUriFragment(arrayPtr(text, s - 1)); +} +template +inline String encodeUriPath(const char (&text)[s]) { + return encodeUriPath(arrayPtr(text, s - 1)); +} +template +inline String encodeUriUserInfo(const char (&text)[s]) { + return encodeUriUserInfo(arrayPtr(text, s - 1)); +} +template +inline String encodeWwwForm(const char (&text)[s]) { + return encodeWwwForm(arrayPtr(text, s - 1)); +} +template +inline EncodingResult decodeWwwForm(const char (&text)[s]) { + return decodeWwwForm(arrayPtr(text, s-1)); +} +template +inline String encodeCEscape(const char (&text)[s]) { + return encodeCEscape(arrayPtr(text, s - 1)); +} +template +inline EncodingResult> decodeBinaryCEscape(const char (&text)[s]) { + return decodeBinaryCEscape(arrayPtr(text, s - 1)); +} +template +inline EncodingResult decodeCEscape(const char (&text)[s]) { + return decodeCEscape(arrayPtr(text, s-1)); +} +template +EncodingResult> decodeBase64(const char (&text)[s]) { + return decodeBase64(arrayPtr(text, s - 1)); +} + +#if __cplusplus >= 202000L +template +inline EncodingResult> encodeUtf16(const char8_t (&text)[s], bool nulTerminate=false) { + return encodeUtf16(arrayPtr(reinterpret_cast(text), s - 1), nulTerminate); +} +template +inline EncodingResult> encodeUtf32(const char8_t (&text)[s], bool nulTerminate=false) { + return encodeUtf32(arrayPtr(reinterpret_cast(text), s - 1), nulTerminate); +} +template +inline EncodingResult> encodeWideString( + const char8_t (&text)[s], bool nulTerminate=false) { + return encodeWideString(arrayPtr(reinterpret_cast(text), s - 1), nulTerminate); +} +template +inline EncodingResult> decodeHex(const char8_t (&text)[s]) { + return decodeHex(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline String encodeUriComponent(const char8_t (&text)[s]) { + return encodeUriComponent(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline Array decodeBinaryUriComponent(const char8_t (&text)[s]) { + return decodeBinaryUriComponent(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline EncodingResult decodeUriComponent(const char8_t (&text)[s]) { + return decodeUriComponent(arrayPtr(reinterpret_cast(text), s-1)); +} +template +inline String encodeUriFragment(const char8_t (&text)[s]) { + return encodeUriFragment(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline String encodeUriPath(const char8_t (&text)[s]) { + return encodeUriPath(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline String encodeUriUserInfo(const char8_t (&text)[s]) { + return encodeUriUserInfo(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline String encodeWwwForm(const char8_t (&text)[s]) { + return encodeWwwForm(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline EncodingResult decodeWwwForm(const char8_t (&text)[s]) { + return decodeWwwForm(arrayPtr(reinterpret_cast(text), s-1)); +} +template +inline String encodeCEscape(const char8_t (&text)[s]) { + return encodeCEscape(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline EncodingResult> decodeBinaryCEscape(const char8_t (&text)[s]) { + return decodeBinaryCEscape(arrayPtr(reinterpret_cast(text), s - 1)); +} +template +inline EncodingResult decodeCEscape(const char8_t (&text)[s]) { + return decodeCEscape(arrayPtr(reinterpret_cast(text), s-1)); +} +template +EncodingResult> decodeBase64(const char8_t (&text)[s]) { + return decodeBase64(arrayPtr(reinterpret_cast(text), s - 1)); +} +#endif + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/exception.cc b/src/plugins/streamers/lstream/runtime/kj/kj/exception.cc new file mode 100644 index 000000000..246830dea --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/exception.cc @@ -0,0 +1,1427 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#if _WIN32 || __CYGWIN__ +#include "win32-api-version.h" +#endif + +#if (_WIN32 && _M_X64) || (__CYGWIN__ && __x86_64__) +// Currently the Win32 stack-trace code only supports x86_64. We could easily extend it to support +// i386 as well but it requires some code changes around how we read the context to start the +// trace. +#define KJ_USE_WIN32_DBGHELP 1 +#endif + +#include "exception.h" +#include "string.h" +#include "debug.h" +#include "threadlocal.h" +#include "miniposix.h" +#include "function.h" +#include "main.h" +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#endif +#include "io.h" + +#if !KJ_NO_RTTI +#include +#endif +#if __GNUC__ +#include +#endif + +#if (__linux__ && __GLIBC__ && !__UCLIBC__) || __APPLE__ +#define KJ_HAS_BACKTRACE 1 +#include +#endif + +#if _WIN32 || __CYGWIN__ +#include +#include "windows-sanity.h" +#include +#endif + +#if (__linux__ || __APPLE__ || __CYGWIN__) +#include +#include +#endif + +#if __CYGWIN__ +#include +#include +#endif + +#if KJ_HAS_LIBDL +#include "dlfcn.h" +#endif + +#if _MSC_VER +#include +#endif + +#if KJ_HAS_COMPILER_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#include +#else +static void __lsan_ignore_object(const void* p) {} +#endif +// TODO(cleanup): Remove the LSAN stuff per https://github.com/capnproto/capnproto/pull/1255 +// feedback. + +namespace { +template +inline T* lsanIgnoreObjectAndReturn(T* ptr) { + // Defensively lsan_ignore_object since the documentation doesn't explicitly specify what happens + // if you call this multiple times on the same object. + // TODO(cleanup): Remove this per https://github.com/capnproto/capnproto/pull/1255. + __lsan_ignore_object(ptr); + return ptr; +} +} + +namespace kj { + +StringPtr KJ_STRINGIFY(LogSeverity severity) { + static const char* SEVERITY_STRINGS[] = { + "info", + "warning", + "error", + "fatal", + "debug" + }; + + return SEVERITY_STRINGS[static_cast(severity)]; +} + +#if KJ_USE_WIN32_DBGHELP + +namespace { + +struct Dbghelp { + // Load dbghelp.dll dynamically since we don't really need it, it's just for debugging. + + HINSTANCE lib; + + BOOL (WINAPI *symInitialize)(HANDLE hProcess,PCSTR UserSearchPath,BOOL fInvadeProcess); + BOOL (WINAPI *stackWalk64)( + DWORD MachineType,HANDLE hProcess,HANDLE hThread, + LPSTACKFRAME64 StackFrame,PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); + PVOID (WINAPI *symFunctionTableAccess64)(HANDLE hProcess,DWORD64 AddrBase); + DWORD64 (WINAPI *symGetModuleBase64)(HANDLE hProcess,DWORD64 qwAddr); + BOOL (WINAPI *symGetLineFromAddr64)( + HANDLE hProcess,DWORD64 qwAddr,PDWORD pdwDisplacement,PIMAGEHLP_LINE64 Line64); + +#if __GNUC__ && !__clang__ && __GNUC__ >= 8 +// GCC 8 warns that our reinterpret_casts of function pointers below are casting between +// incompatible types. Yes, GCC, we know that. This is the nature of GetProcAddress(); it returns +// everything as `long long int (*)()` and we have to cast to the actual type. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + Dbghelp() + : lib(LoadLibraryA("dbghelp.dll")), + symInitialize(lib == nullptr ? nullptr : + reinterpret_cast( + GetProcAddress(lib, "SymInitialize"))), + stackWalk64(symInitialize == nullptr ? nullptr : + reinterpret_cast( + GetProcAddress(lib, "StackWalk64"))), + symFunctionTableAccess64(symInitialize == nullptr ? nullptr : + reinterpret_cast( + GetProcAddress(lib, "SymFunctionTableAccess64"))), + symGetModuleBase64(symInitialize == nullptr ? nullptr : + reinterpret_cast( + GetProcAddress(lib, "SymGetModuleBase64"))), + symGetLineFromAddr64(symInitialize == nullptr ? nullptr : + reinterpret_cast( + GetProcAddress(lib, "SymGetLineFromAddr64"))) { + if (symInitialize != nullptr) { + symInitialize(GetCurrentProcess(), NULL, TRUE); + } + } +#if __GNUC__ && !__clang__ && __GNUC__ >= 9 +#pragma GCC diagnostic pop +#endif +}; + +const Dbghelp& getDbghelp() { + static Dbghelp dbghelp; + return dbghelp; +} + +ArrayPtr getStackTrace(ArrayPtr space, uint ignoreCount, + HANDLE thread, CONTEXT& context) { + // NOTE: Apparently there is a function CaptureStackBackTrace() that is equivalent to glibc's + // backtrace(). Somehow I missed that when I originally wrote this. However, + // CaptureStackBackTrace() does not accept a CONTEXT parameter; it can only trace the caller. + // That's more problematic on Windows where breakHandler(), sehHandler(), and Cygwin signal + // handlers all depend on the ability to pass a CONTEXT. So we'll keep this code, which works + // after all. + + const Dbghelp& dbghelp = getDbghelp(); + if (dbghelp.stackWalk64 == nullptr || + dbghelp.symFunctionTableAccess64 == nullptr || + dbghelp.symGetModuleBase64 == nullptr) { + return nullptr; + } + + STACKFRAME64 frame; + memset(&frame, 0, sizeof(frame)); + + frame.AddrPC.Offset = context.Rip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Rsp; + frame.AddrStack.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Rbp; + frame.AddrFrame.Mode = AddrModeFlat; + + HANDLE process = GetCurrentProcess(); + + uint count = 0; + for (; count < space.size(); count++) { + if (!dbghelp.stackWalk64(IMAGE_FILE_MACHINE_AMD64, process, thread, + &frame, &context, NULL, dbghelp.symFunctionTableAccess64, + dbghelp.symGetModuleBase64, NULL)){ + break; + } + + // Subtract 1 from each address so that we identify the calling instructions, rather than the + // return addresses (which are typically the instruction after the call). + space[count] = reinterpret_cast(frame.AddrPC.Offset - 1); + } + + return space.slice(kj::min(ignoreCount, count), count); +} + +} // namespace +#endif + +ArrayPtr getStackTrace(ArrayPtr space, uint ignoreCount) { + if (getExceptionCallback().stackTraceMode() == ExceptionCallback::StackTraceMode::NONE) { + return nullptr; + } + +#if KJ_USE_WIN32_DBGHELP + CONTEXT context; + RtlCaptureContext(&context); + return getStackTrace(space, ignoreCount, GetCurrentThread(), context); +#elif KJ_HAS_BACKTRACE + size_t size = backtrace(space.begin(), space.size()); + for (auto& addr: space.slice(0, size)) { + // The addresses produced by backtrace() are return addresses, which means they point to the + // instruction immediately after the call. Invoking addr2line on these can be confusing because + // it often points to the next line. If the next instruction is inlined from another function, + // the trace can be extra-confusing, since now it claims to be in a function that was not + // actually on the call stack. If we subtract 1 from each address, though, we get a much more + // reasonable trace. This may cause the addresses to be invalid instruction pointers if the + // instructions were multi-byte, but it appears addr2line is able to cope with this. + addr = reinterpret_cast(reinterpret_cast(addr) - 1); + } + return space.slice(kj::min(ignoreCount + 1, size), size); +#else + return nullptr; +#endif +} + +#if (__GNUC__ && !_WIN32) || __clang__ +// Allow dependents to override the implementation of stack symbolication by making it a weak +// symbol. We prefer weak symbols over some sort of callback registration mechanism becasue this +// allows an alternate symbolication library to be easily linked into tests without changing the +// code of the test. +__attribute__((weak)) +#endif +String stringifyStackTrace(ArrayPtr trace) { + if (trace.size() == 0) return nullptr; + if (getExceptionCallback().stackTraceMode() != ExceptionCallback::StackTraceMode::FULL) { + return nullptr; + } + +#if KJ_USE_WIN32_DBGHELP && _MSC_VER + + // Try to get file/line using SymGetLineFromAddr64(). We don't bother if we aren't on MSVC since + // this requires MSVC debug info. + // + // TODO(someday): We could perhaps shell out to addr2line on MinGW. + + const Dbghelp& dbghelp = getDbghelp(); + if (dbghelp.symGetLineFromAddr64 == nullptr) return nullptr; + + HANDLE process = GetCurrentProcess(); + + KJ_STACK_ARRAY(String, lines, trace.size(), 32, 32); + + for (auto i: kj::indices(trace)) { + IMAGEHLP_LINE64 lineInfo; + memset(&lineInfo, 0, sizeof(lineInfo)); + lineInfo.SizeOfStruct = sizeof(lineInfo); + DWORD displacement; + if (dbghelp.symGetLineFromAddr64(process, reinterpret_cast(trace[i]), &displacement, &lineInfo)) { + lines[i] = kj::str('\n', lineInfo.FileName, ':', lineInfo.LineNumber); + } + } + + return strArray(lines, ""); + +#elif (__linux__ || __APPLE__ || __CYGWIN__) && !__ANDROID__ + // We want to generate a human-readable stack trace. + + // TODO(someday): It would be really great if we could avoid farming out to another process + // and do this all in-process, but that may involve onerous requirements like large library + // dependencies or using -rdynamic. + + // The environment manipulation is not thread-safe, so lock a mutex. This could still be + // problematic if another thread is manipulating the environment in unrelated code, but there's + // not much we can do about that. This is debug-only anyway and only an issue when LD_PRELOAD + // is in use. + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&mutex); + KJ_DEFER(pthread_mutex_unlock(&mutex)); + + // Don't heapcheck / intercept syscalls. + const char* preload = getenv("LD_PRELOAD"); + String oldPreload; + if (preload != nullptr) { + oldPreload = heapString(preload); + unsetenv("LD_PRELOAD"); + } + KJ_DEFER(if (oldPreload != nullptr) { setenv("LD_PRELOAD", oldPreload.cStr(), true); }); + + String lines[32]; + FILE* p = nullptr; + auto strTrace = strArray(trace, " "); + +#if __linux__ + if (access("/proc/self/exe", R_OK) < 0) { + // Apparently /proc is not available? + return nullptr; + } + + // Obtain symbolic stack trace using addr2line. + // TODO(cleanup): Use fork() and exec() or maybe our own Subprocess API (once it exists), to + // avoid depending on a shell. + p = popen(str("addr2line -e /proc/", getpid(), "/exe ", strTrace).cStr(), "r"); +#elif __APPLE__ + // The Mac OS X equivalent of addr2line is atos. + // (Internally, it uses the private CoreSymbolication.framework library.) + p = popen(str("xcrun atos -p ", getpid(), ' ', strTrace).cStr(), "r"); +#elif __CYGWIN__ + wchar_t exeWinPath[MAX_PATH]; + if (GetModuleFileNameW(nullptr, exeWinPath, sizeof(exeWinPath)) == 0) { + return nullptr; + } + char exePosixPath[MAX_PATH * 2]; + if (cygwin_conv_path(CCP_WIN_W_TO_POSIX, exeWinPath, exePosixPath, sizeof(exePosixPath)) < 0) { + return nullptr; + } + p = popen(str("addr2line -e '", exePosixPath, "' ", strTrace).cStr(), "r"); +#endif + + if (p == nullptr) { + return nullptr; + } + + char line[512]; + size_t i = 0; + while (i < kj::size(lines) && fgets(line, sizeof(line), p) != nullptr) { + // Don't include exception-handling infrastructure or promise infrastructure in stack trace. + // addr2line output matches file names; atos output matches symbol names. + if (strstr(line, "kj/common.c++") != nullptr || + strstr(line, "kj/exception.") != nullptr || + strstr(line, "kj/debug.") != nullptr || + strstr(line, "kj/async.") != nullptr || + strstr(line, "kj/async-prelude.h") != nullptr || + strstr(line, "kj/async-inl.h") != nullptr || + strstr(line, "kj::Exception") != nullptr || + strstr(line, "kj::_::Debug") != nullptr) { + continue; + } + + size_t len = strlen(line); + if (len > 0 && line[len-1] == '\n') line[len-1] = '\0'; + lines[i++] = str("\n ", trimSourceFilename(line), ": returning here"); + } + + // Skip remaining input. + while (fgets(line, sizeof(line), p) != nullptr) {} + + pclose(p); + + return strArray(arrayPtr(lines, i), ""); + +#else + return nullptr; +#endif +} + +String stringifyStackTraceAddresses(ArrayPtr trace) { +#if KJ_HAS_LIBDL + return strArray(KJ_MAP(addr, trace) { + Dl_info info; + // Shared libraries are mapped near the end of the address space while the executable is mapped + // near the beginning. We want to print addresses in the executable as raw addresses, not + // offsets, since that's what addr2line expects for executables. For shared libraries it + // expects offsets. In any case, most frames are likely to be in the main executable so it + // makes the output cleaner if we don't repeatedly write its name. + if (reinterpret_cast(addr) >= 0x400000000000ull && dladdr(addr, &info)) { + uintptr_t offset = reinterpret_cast(addr) - + reinterpret_cast(info.dli_fbase); + return kj::str(info.dli_fname, '@', reinterpret_cast(offset)); + } else { + return kj::str(addr); + } + }, " "); +#else + // TODO(someday): Support other platforms. + return kj::strArray(trace, " "); +#endif +} + +StringPtr stringifyStackTraceAddresses(ArrayPtr trace, ArrayPtr scratch) { + // Version which writes into a pre-allocated buffer. This is safe for signal handlers to the + // extent that dladdr() is safe. + // + // TODO(cleanup): We should improve the KJ stringification framework so that there's a way to + // write this string directly into a larger message buffer with strPreallocated(). + +#if KJ_HAS_LIBDL + char* ptr = scratch.begin(); + char* limit = scratch.end() - 1; + + for (auto addr: trace) { + Dl_info info; + // Shared libraries are mapped near the end of the address space while the executable is mapped + // near the beginning. We want to print addresses in the executable as raw addresses, not + // offsets, since that's what addr2line expects for executables. For shared libraries it + // expects offsets. In any case, most frames are likely to be in the main executable so it + // makes the output cleaner if we don't repeatedly write its name. + if (reinterpret_cast(addr) >= 0x400000000000ull && dladdr(addr, &info)) { + uintptr_t offset = reinterpret_cast(addr) - + reinterpret_cast(info.dli_fbase); + ptr = _::fillLimited(ptr, limit, kj::StringPtr(info.dli_fname), "@0x"_kj, hex(offset)); + } else { + ptr = _::fillLimited(ptr, limit, toCharSequence(addr)); + } + + ptr = _::fillLimited(ptr, limit, " "_kj); + } + *ptr = '\0'; + return StringPtr(scratch.begin(), ptr); +#else + // TODO(someday): Support other platforms. + return kj::strPreallocated(scratch, kj::delimited(trace, " ")); +#endif +} + +String getStackTrace() { + void* space[32]; + auto trace = getStackTrace(space, 2); + return kj::str(stringifyStackTraceAddresses(trace), stringifyStackTrace(trace)); +} + +namespace { + +#if !KJ_NO_EXCEPTIONS + +[[noreturn]] void terminateHandler() { + void* traceSpace[32]; + + // ignoreCount = 3 to ignore std::terminate entry. + auto trace = kj::getStackTrace(traceSpace, 3); + + kj::String message; + + auto eptr = std::current_exception(); + if (eptr != nullptr) { + try { + std::rethrow_exception(eptr); + } catch (const kj::Exception& exception) { + message = kj::str("*** Fatal uncaught kj::Exception: ", exception, '\n'); + } catch (const std::exception& exception) { + message = kj::str("*** Fatal uncaught std::exception: ", exception.what(), + "\nstack: ", stringifyStackTraceAddresses(trace), + stringifyStackTrace(trace), '\n'); + } catch (...) { + message = kj::str("*** Fatal uncaught exception of type: ", kj::getCaughtExceptionType(), + "\nstack: ", stringifyStackTraceAddresses(trace), + stringifyStackTrace(trace), '\n'); + } + } else { + message = kj::str("*** std::terminate() called with no exception" + "\nstack: ", stringifyStackTraceAddresses(trace), + stringifyStackTrace(trace), '\n'); + } + + kj::FdOutputStream(STDERR_FILENO).write(message.begin(), message.size()); + _exit(1); +} + +#endif + +} // namespace + +#if KJ_USE_WIN32_DBGHELP && !__CYGWIN__ +namespace { + +DWORD mainThreadId = 0; + +BOOL WINAPI breakHandler(DWORD type) { + switch (type) { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: { + HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, mainThreadId); + if (thread != NULL) { + if (SuspendThread(thread) != (DWORD)-1) { + CONTEXT context; + memset(&context, 0, sizeof(context)); + context.ContextFlags = CONTEXT_FULL; + if (GetThreadContext(thread, &context)) { + void* traceSpace[32]; + auto trace = getStackTrace(traceSpace, 0, thread, context); + ResumeThread(thread); + auto message = kj::str("*** Received CTRL+C. stack: ", + stringifyStackTraceAddresses(trace), + stringifyStackTrace(trace), '\n'); + FdOutputStream(STDERR_FILENO).write(message.begin(), message.size()); + } else { + ResumeThread(thread); + } + } + CloseHandle(thread); + } + break; + } + default: + break; + } + + return FALSE; // still crash +} + +kj::StringPtr exceptionDescription(DWORD code) { + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: return "access violation"; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "array bounds exceeded"; + case EXCEPTION_BREAKPOINT: return "breakpoint"; + case EXCEPTION_DATATYPE_MISALIGNMENT: return "datatype misalignment"; + case EXCEPTION_FLT_DENORMAL_OPERAND: return "denormal floating point operand"; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "floating point division by zero"; + case EXCEPTION_FLT_INEXACT_RESULT: return "inexact floating point result"; + case EXCEPTION_FLT_INVALID_OPERATION: return "invalid floating point operation"; + case EXCEPTION_FLT_OVERFLOW: return "floating point overflow"; + case EXCEPTION_FLT_STACK_CHECK: return "floating point stack overflow"; + case EXCEPTION_FLT_UNDERFLOW: return "floating point underflow"; + case EXCEPTION_ILLEGAL_INSTRUCTION: return "illegal instruction"; + case EXCEPTION_IN_PAGE_ERROR: return "page error"; + case EXCEPTION_INT_DIVIDE_BY_ZERO: return "integer divided by zero"; + case EXCEPTION_INT_OVERFLOW: return "integer overflow"; + case EXCEPTION_INVALID_DISPOSITION: return "invalid disposition"; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "noncontinuable exception"; + case EXCEPTION_PRIV_INSTRUCTION: return "privileged instruction"; + case EXCEPTION_SINGLE_STEP: return "single step"; + case EXCEPTION_STACK_OVERFLOW: return "stack overflow"; + default: return "(unknown exception code)"; + } +} + +LONG WINAPI sehHandler(EXCEPTION_POINTERS* info) { + void* traceSpace[32]; + auto trace = getStackTrace(traceSpace, 0, GetCurrentThread(), *info->ContextRecord); + auto message = kj::str("*** Received structured exception #0x", + hex(info->ExceptionRecord->ExceptionCode), ": ", + exceptionDescription(info->ExceptionRecord->ExceptionCode), + "; stack: ", + stringifyStackTraceAddresses(trace), + stringifyStackTrace(trace), '\n'); + FdOutputStream(STDERR_FILENO).write(message.begin(), message.size()); + return EXCEPTION_EXECUTE_HANDLER; // still crash +} + +} // namespace + +void printStackTraceOnCrash() { + mainThreadId = GetCurrentThreadId(); + KJ_WIN32(SetConsoleCtrlHandler(breakHandler, TRUE)); + SetUnhandledExceptionFilter(&sehHandler); + +#if !KJ_NO_EXCEPTIONS + // Also override std::terminate() handler with something nicer for KJ. + std::set_terminate(&terminateHandler); +#endif +} + +#elif _WIN32 +// Windows, but KJ_USE_WIN32_DBGHELP is not enabled. We can't print useful stack traces, so don't +// try to catch SEH nor ctrl+C. + +void printStackTraceOnCrash() { +#if !KJ_NO_EXCEPTIONS + std::set_terminate(&terminateHandler); +#endif +} + +#else +namespace { + +[[noreturn]] void crashHandler(int signo, siginfo_t* info, void* context) { + void* traceSpace[32]; + +#if KJ_USE_WIN32_DBGHELP + // Win32 backtracing can't trace its way out of a Cygwin signal handler. However, Cygwin gives + // us direct access to the CONTEXT, which we can pass to the Win32 tracing functions. + ucontext_t* ucontext = reinterpret_cast(context); + // Cygwin's mcontext_t has the same layout as CONTEXT. + // TODO(someday): Figure out why this produces garbage for SIGINT from ctrl+C. It seems to work + // correctly for SIGSEGV. + CONTEXT win32Context; + static_assert(sizeof(ucontext->uc_mcontext) >= sizeof(win32Context), + "mcontext_t should be an extension of CONTEXT"); + memcpy(&win32Context, &ucontext->uc_mcontext, sizeof(win32Context)); + auto trace = getStackTrace(traceSpace, 0, GetCurrentThread(), win32Context); +#else + // ignoreCount = 2 to ignore crashHandler() and signal trampoline. + auto trace = getStackTrace(traceSpace, 2); +#endif + + auto message = kj::str("*** Received signal #", signo, ": ", strsignal(signo), + "\nstack: ", stringifyStackTraceAddresses(trace), + stringifyStackTrace(trace), '\n'); + + FdOutputStream(STDERR_FILENO).write(message.begin(), message.size()); + _exit(1); +} + +} // namespace + +void printStackTraceOnCrash() { + // Set up alternate signal stack so that stack overflows can be handled. + stack_t stack; + memset(&stack, 0, sizeof(stack)); + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif +#ifndef MAP_GROWSDOWN +#define MAP_GROWSDOWN 0 +#endif + + stack.ss_size = 65536; + // Note: ss_sp is char* on FreeBSD, void* on Linux and OSX. + stack.ss_sp = reinterpret_cast(mmap( + nullptr, stack.ss_size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, -1, 0)); + KJ_SYSCALL(sigaltstack(&stack, nullptr)); + + // Catch all relevant signals. + struct sigaction action; + memset(&action, 0, sizeof(action)); + + action.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER | SA_RESETHAND; + action.sa_sigaction = &crashHandler; + + // Dump stack on common "crash" signals. + KJ_SYSCALL(sigaction(SIGSEGV, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGBUS, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGFPE, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGABRT, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGILL, &action, nullptr)); + + // Dump stack on unimplemented syscalls -- useful in seccomp sandboxes. + KJ_SYSCALL(sigaction(SIGSYS, &action, nullptr)); + +#ifdef KJ_DEBUG + // Dump stack on keyboard interrupt -- useful for infinite loops. Only in debug mode, though, + // because stack traces on ctrl+c can be obnoxious for, say, command-line tools. + KJ_SYSCALL(sigaction(SIGINT, &action, nullptr)); +#endif + +#if !KJ_NO_EXCEPTIONS + // Also override std::terminate() handler with something nicer for KJ. + std::set_terminate(&terminateHandler); +#endif +} +#endif + +kj::StringPtr trimSourceFilename(kj::StringPtr filename) { + // Removes noisy prefixes from source code file name. + // + // The goal here is to produce the "canonical" filename given the filename returned by e.g. + // addr2line. addr2line gives us the full path of the file as passed on the compiler + // command-line, which in turn is affected by build system and by whether and where we're + // performing an out-of-tree build. + // + // To deal with all this, we look for directory names in the path which we recognize to be + // locations that represent roots of the source tree. We strip said root and everything before + // it. + // + // On Windows, we often get filenames containing backslashes. Since we aren't allowed to allocate + // a new string here, we can't do much about this, so our returned "canonical" name will + // unfortunately end up with backslashes. + + static constexpr const char* ROOTS[] = { + "ekam-provider/canonical/", // Ekam source file. + "ekam-provider/c++header/", // Ekam include file. + "src/", // Non-Ekam source root. + "tmp/", // Non-Ekam generated code. +#if _WIN32 + "src\\", // Win32 source root. + "tmp\\", // Win32 generated code. +#endif + }; + +retry: + for (size_t i: kj::indices(filename)) { + if (i == 0 || filename[i-1] == '/' +#if _WIN32 + || filename[i-1] == '\\' +#endif + ) { + // We're at the start of a directory name. Check for valid prefixes. + for (kj::StringPtr root: ROOTS) { + if (filename.slice(i).startsWith(root)) { + filename = filename.slice(i + root.size()); + + // We should keep searching to find the last instance of a root name. `i` is no longer + // a valid index for `filename` so start the loop over. + goto retry; + } + } + } + } + + return filename; +} + +void resetCrashHandlers() { +#ifndef _WIN32 + struct sigaction action; + memset(&action, 0, sizeof(action)); + + action.sa_handler = SIG_DFL; + KJ_SYSCALL(sigaction(SIGSEGV, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGBUS, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGFPE, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGABRT, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGILL, &action, nullptr)); + KJ_SYSCALL(sigaction(SIGSYS, &action, nullptr)); + +#ifdef KJ_DEBUG + KJ_SYSCALL(sigaction(SIGINT, &action, nullptr)); +#endif +#endif + +#if !KJ_NO_EXCEPTIONS + std::set_terminate(nullptr); +#endif +} + +StringPtr KJ_STRINGIFY(Exception::Type type) { + static const char* TYPE_STRINGS[] = { + "failed", + "overloaded", + "disconnected", + "unimplemented" + }; + + return TYPE_STRINGS[static_cast(type)]; +} + +String KJ_STRINGIFY(const Exception& e) { + uint contextDepth = 0; + + Maybe contextPtr = e.getContext(); + for (;;) { + KJ_IF_MAYBE(c, contextPtr) { + ++contextDepth; + contextPtr = c->next; + } else { + break; + } + } + + Array contextText = heapArray(contextDepth); + + contextDepth = 0; + contextPtr = e.getContext(); + for (;;) { + KJ_IF_MAYBE(c, contextPtr) { + contextText[contextDepth++] = + str(trimSourceFilename(c->file), ":", c->line, ": context: ", c->description, "\n"); + contextPtr = c->next; + } else { + break; + } + } + + // Note that we put "remote" before "stack" because trace frames are ordered callee before + // caller, so this is the most natural presentation ordering. + return str(strArray(contextText, ""), + e.getFile(), ":", e.getLine(), ": ", e.getType(), + e.getDescription() == nullptr ? "" : ": ", e.getDescription(), + e.getRemoteTrace().size() > 0 ? "\nremote: " : "", + e.getRemoteTrace(), + e.getStackTrace().size() > 0 ? "\nstack: " : "", + stringifyStackTraceAddresses(e.getStackTrace()), + stringifyStackTrace(e.getStackTrace())); +} + +Exception::Exception(Type type, const char* file, int line, String description) noexcept + : file(trimSourceFilename(file).cStr()), line(line), type(type), description(mv(description)), + traceCount(0) {} + +Exception::Exception(Type type, String file, int line, String description) noexcept + : ownFile(kj::mv(file)), file(trimSourceFilename(ownFile).cStr()), line(line), type(type), + description(mv(description)), traceCount(0) {} + +Exception::Exception(const Exception& other) noexcept + : file(other.file), line(other.line), type(other.type), + description(heapString(other.description)), traceCount(other.traceCount) { + if (file == other.ownFile.cStr()) { + ownFile = heapString(other.ownFile); + file = ownFile.cStr(); + } + + if (other.remoteTrace != nullptr) { + remoteTrace = kj::str(other.remoteTrace); + } + + memcpy(trace, other.trace, sizeof(trace[0]) * traceCount); + + KJ_IF_MAYBE(c, other.context) { + context = heap(**c); + } +} + +Exception::~Exception() noexcept {} + +Exception::Context::Context(const Context& other) noexcept + : file(other.file), line(other.line), description(str(other.description)) { + KJ_IF_MAYBE(n, other.next) { + next = heap(**n); + } +} + +void Exception::wrapContext(const char* file, int line, String&& description) { + context = heap(file, line, mv(description), mv(context)); +} + +void Exception::extendTrace(uint ignoreCount, uint limit) { + if (isFullTrace) { + // Awkward: extendTrace() was called twice without truncating in between. This should probably + // be an error, but historically we didn't check for this so I'm hesitant to make it an error + // now. We shouldn't actually extend the trace, though, as our current trace is presumably + // rooted in main() and it'd be weird to append frames "above" that. + // TODO(cleanup): Abort here and see what breaks? + return; + } + + KJ_STACK_ARRAY(void*, newTraceSpace, kj::min(kj::size(trace), limit) + ignoreCount + 1, + sizeof(trace)/sizeof(trace[0]) + 8, 128); + + auto newTrace = kj::getStackTrace(newTraceSpace, ignoreCount + 1); + if (newTrace.size() > ignoreCount + 2) { + // Remove suffix that won't fit into our static-sized trace. + newTrace = newTrace.slice(0, kj::min(kj::size(trace) - traceCount, newTrace.size())); + + // Copy the rest into our trace. + memcpy(trace + traceCount, newTrace.begin(), newTrace.asBytes().size()); + traceCount += newTrace.size(); + isFullTrace = true; + } +} + +void Exception::truncateCommonTrace() { + if (isFullTrace) { + // We're truncating the common portion of the full trace, turning it back into a limited + // trace. + isFullTrace = false; + } else { + // If the trace was never extended in the first place, trying to truncate it is at best a waste + // of time and at worst might remove information for no reason. So, don't. + // + // This comes up in particular in coroutines, when the exception originated from a co_awaited + // promise. In that case we manually add the one relevant frame to the trace, rather than + // call extendTrace() just to have to truncate most of it again a moment later in the + // unhandled_exception() callback. + return; + } + + if (traceCount > 0) { + // Create a "reference" stack trace that is a little bit deeper than the one in the exception. + void* refTraceSpace[sizeof(this->trace) / sizeof(this->trace[0]) + 4]; + auto refTrace = kj::getStackTrace(refTraceSpace, 0); + + // We expect that the deepest frame in the exception's stack trace should be somewhere in our + // own trace, since our own trace has a deeper limit. Search for it. + for (uint i = refTrace.size(); i > 0; i--) { + if (refTrace[i-1] == trace[traceCount-1]) { + // See how many frames match. + for (uint j = 0; j < i; j++) { + if (j >= traceCount) { + // We matched the whole trace, apparently? + traceCount = 0; + return; + } else if (refTrace[i-j-1] != trace[traceCount-j-1]) { + // Found mismatching entry. + + // If we matched more than half of the reference trace, guess that this is in fact + // the prefix we're looking for. + if (j > refTrace.size() / 2) { + // Delete the matching suffix. Also delete one non-matched entry on the assumption + // that both traces contain that stack frame but are simply at different points in + // the function. + traceCount -= j + 1; + return; + } + } + } + } + } + + // No match. Ignore. + } +} + +void Exception::addTrace(void* ptr) { + // TODO(cleanup): Abort here if isFullTrace is true, and see what breaks. This method only makes + // sense to call on partial traces. + + if (traceCount < kj::size(trace)) { + trace[traceCount++] = ptr; + } +} + +void Exception::addTraceHere() { +#if __GNUC__ + addTrace(__builtin_return_address(0)); +#elif _MSC_VER + addTrace(_ReturnAddress()); +#else + #error "please implement for your compiler" +#endif +} + +#if !KJ_NO_EXCEPTIONS + +namespace { + +KJ_THREADLOCAL_PTR(ExceptionImpl) currentException = nullptr; + +} // namespace + +class ExceptionImpl: public Exception, public std::exception { +public: + inline ExceptionImpl(Exception&& other): Exception(mv(other)) { + insertIntoCurrentExceptions(); + } + ExceptionImpl(const ExceptionImpl& other): Exception(other) { + // No need to copy whatBuffer since it's just to hold the return value of what(). + insertIntoCurrentExceptions(); + } + ~ExceptionImpl() { + // Look for ourselves in the list. + for (auto* ptr = ¤tException; *ptr != nullptr; ptr = &(*ptr)->nextCurrentException) { + if (*ptr == this) { + *ptr = nextCurrentException; + return; + } + } + + // Possibly the ExceptionImpl was destroyed on a different thread than created it? That's + // pretty bad, we'd better abort. + abort(); + } + + const char* what() const noexcept override; + +private: + mutable String whatBuffer; + ExceptionImpl* nextCurrentException = nullptr; + + void insertIntoCurrentExceptions() { + nextCurrentException = currentException; + currentException = this; + } + + friend class InFlightExceptionIterator; +}; + +const char* ExceptionImpl::what() const noexcept { + whatBuffer = str(*this); + return whatBuffer.begin(); +} + +InFlightExceptionIterator::InFlightExceptionIterator() + : ptr(currentException) {} + +Maybe InFlightExceptionIterator::next() { + if (ptr == nullptr) return nullptr; + + const ExceptionImpl& result = *static_cast(ptr); + ptr = result.nextCurrentException; + return result; +} + +#endif // !KJ_NO_EXCEPTIONS + +kj::Exception getDestructionReason(void* traceSeparator, kj::Exception::Type defaultType, + const char* defaultFile, int defaultLine, kj::StringPtr defaultDescription) { +#if !KJ_NO_EXCEPTIONS + InFlightExceptionIterator iter; + KJ_IF_MAYBE(e, iter.next()) { + auto copy = kj::cp(*e); + copy.truncateCommonTrace(); + return copy; + } else { +#endif + // Darn, use a generic exception. + kj::Exception exception(defaultType, defaultFile, defaultLine, + kj::heapString(defaultDescription)); + + // Let's give some context on where the PromiseFulfiller was destroyed. + exception.extendTrace(2, 16); + + // Add a separator that hopefully makes this understandable... + exception.addTrace(traceSeparator); + + return exception; +#if !KJ_NO_EXCEPTIONS + } +#endif +} + +// ======================================================================================= + +namespace { + +KJ_THREADLOCAL_PTR(ExceptionCallback) threadLocalCallback = nullptr; + +} // namespace + +void requireOnStack(void* ptr, kj::StringPtr description) { +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || \ + KJ_HAS_COMPILER_FEATURE(address_sanitizer) || \ + defined(__SANITIZE_ADDRESS__) + // When using libfuzzer or ASAN, this sanity check may spurriously fail, so skip it. +#else + char stackVar; + ptrdiff_t offset = reinterpret_cast(ptr) - &stackVar; + KJ_REQUIRE(offset < 65536 && offset > -65536, + kj::str(description)); +#endif +} + +ExceptionCallback::ExceptionCallback(): next(getExceptionCallback()) { + requireOnStack(this, "ExceptionCallback must be allocated on the stack."); + threadLocalCallback = this; +} + +ExceptionCallback::ExceptionCallback(ExceptionCallback& next): next(next) {} + +ExceptionCallback::~ExceptionCallback() noexcept(false) { + if (&next != this) { + threadLocalCallback = &next; + } +} + +void ExceptionCallback::onRecoverableException(Exception&& exception) { + next.onRecoverableException(mv(exception)); +} + +void ExceptionCallback::onFatalException(Exception&& exception) { + next.onFatalException(mv(exception)); +} + +void ExceptionCallback::logMessage( + LogSeverity severity, const char* file, int line, int contextDepth, String&& text) { + next.logMessage(severity, file, line, contextDepth, mv(text)); +} + +ExceptionCallback::StackTraceMode ExceptionCallback::stackTraceMode() { + return next.stackTraceMode(); +} + +Function)> ExceptionCallback::getThreadInitializer() { + return next.getThreadInitializer(); +} + +namespace _ { // private + uint uncaughtExceptionCount(); // defined later in this file +} + +class ExceptionCallback::RootExceptionCallback: public ExceptionCallback { +public: + RootExceptionCallback(): ExceptionCallback(*this) {} + + void onRecoverableException(Exception&& exception) override { +#if KJ_NO_EXCEPTIONS + logException(LogSeverity::ERROR, mv(exception)); +#else + if (_::uncaughtExceptionCount() > 0) { + // Bad time to throw an exception. Just log instead. + // + // TODO(someday): We should really compare uncaughtExceptionCount() against the count at + // the innermost runCatchingExceptions() frame in this thread to tell if exceptions are + // being caught correctly. + logException(LogSeverity::ERROR, mv(exception)); + } else { + throw ExceptionImpl(mv(exception)); + } +#endif + } + + void onFatalException(Exception&& exception) override { +#if KJ_NO_EXCEPTIONS + logException(LogSeverity::FATAL, mv(exception)); +#else + throw ExceptionImpl(mv(exception)); +#endif + } + + void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text) override { + text = str(kj::repeat('_', contextDepth), file, ":", line, ": ", severity, ": ", + mv(text), '\n'); + + StringPtr textPtr = text; + + while (textPtr != nullptr) { + miniposix::ssize_t n = miniposix::write(STDERR_FILENO, textPtr.begin(), textPtr.size()); + if (n <= 0) { + // stderr is broken. Give up. + return; + } + textPtr = textPtr.slice(n); + } + } + + StackTraceMode stackTraceMode() override { +#ifdef KJ_DEBUG + return StackTraceMode::FULL; +#else + return StackTraceMode::ADDRESS_ONLY; +#endif + } + + Function)> getThreadInitializer() override { + return [](Function func) { + // No initialization needed since RootExceptionCallback is automatically the root callback + // for new threads. + func(); + }; + } + +private: + void logException(LogSeverity severity, Exception&& e) { + // We intentionally go back to the top exception callback on the stack because we don't want to + // bypass whatever log processing is in effect. + // + // We intentionally don't log the context since it should get re-added by the exception callback + // anyway. + getExceptionCallback().logMessage(severity, e.getFile(), e.getLine(), 0, str( + e.getType(), e.getDescription() == nullptr ? "" : ": ", e.getDescription(), + e.getRemoteTrace().size() > 0 ? "\nremote: " : "", + e.getRemoteTrace(), + e.getStackTrace().size() > 0 ? "\nstack: " : "", + stringifyStackTraceAddresses(e.getStackTrace()), + stringifyStackTrace(e.getStackTrace()), "\n")); + } +}; + +ExceptionCallback& getExceptionCallback() { + static auto defaultCallback = lsanIgnoreObjectAndReturn( + new ExceptionCallback::RootExceptionCallback()); + // We allocate on the heap because some objects may throw in their destructors. If those objects + // had static storage, they might get fully constructed before the root callback. If they however + // then throw an exception during destruction, there would be a lifetime issue because their + // destructor would end up getting registered after the root callback's destructor. One solution + // is to just leak this pointer & allocate on first-use. The cost is that the initialization is + // mildly more expensive (+ we need to annotate sanitizers to ignore the problem). A great + // compiler annotation that would simply things would be one that allowed static variables to have + // their destruction omitted wholesale. That would allow us to avoid the heap but still have the + // same robust safety semantics leaking would give us. A practical alternative that could be + // implemented without new compilers would be to define another static root callback in + // RootExceptionCallback's destructor (+ a separate pointer to share its value with this + // function). Since this would end up getting constructed during exit unwind, it would have the + // nice property of effectively being guaranteed to be evicted last. + // + // All this being said, I came back to leaking the object is the easiest tweak here: + // * Can't go wrong + // * Easy to maintain + // * Throwing exceptions is bound to do be expensive and malloc-happy anyway, so the incremental + // cost of 1 heap allocation is minimal. + // + // TODO(cleanup): Harris has an excellent suggestion in + // https://github.com/capnproto/capnproto/pull/1255 that should ensure we initialize the root + // callback once on first use as a global & never destroy it. + + ExceptionCallback* scoped = threadLocalCallback; + return scoped != nullptr ? *scoped : *defaultCallback; +} + +void throwFatalException(kj::Exception&& exception, uint ignoreCount) { + if (ignoreCount != (uint)kj::maxValue) exception.extendTrace(ignoreCount + 1); + getExceptionCallback().onFatalException(kj::mv(exception)); + abort(); +} + +void throwRecoverableException(kj::Exception&& exception, uint ignoreCount) { + if (ignoreCount != (uint)kj::maxValue) exception.extendTrace(ignoreCount + 1); + getExceptionCallback().onRecoverableException(kj::mv(exception)); +} + +// ======================================================================================= + +namespace _ { // private + +#if __cplusplus >= 201703L + +uint uncaughtExceptionCount() { + return std::uncaught_exceptions(); +} + +#elif __GNUC__ + +// Horrible -- but working -- hack: We can dig into __cxa_get_globals() in order to extract the +// count of uncaught exceptions. This function is part of the C++ ABI implementation used on Linux, +// OSX, and probably other platforms that use GCC. Unfortunately, __cxa_get_globals() is only +// actually defined in cxxabi.h on some platforms (e.g. Linux, but not OSX), and even where it is +// defined, it returns an incomplete type. Here we use the same hack used by Evgeny Panasyuk: +// https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp +// +// Notice that a similar hack is possible on MSVC -- if its C++11 support ever gets to the point of +// supporting KJ in the first place. +// +// It appears likely that a future version of the C++ standard may include an +// uncaught_exception_count() function in the standard library, or an equivalent language feature. +// Some discussion: +// https://groups.google.com/a/isocpp.org/d/msg/std-proposals/HglEslyZFYs/kKdu5jJw5AgJ + +struct FakeEhGlobals { + // Fake + + void* caughtExceptions; + uint uncaughtExceptions; +}; + +// LLVM's libstdc++ doesn't declare __cxa_get_globals in its cxxabi.h. GNU does. Because it is +// extern "C", the compiler wills get upset if we re-declare it even in a different namespace. +#if _LIBCPPABI_VERSION +extern "C" void* __cxa_get_globals(); +#else +using abi::__cxa_get_globals; +#endif + +uint uncaughtExceptionCount() { + return reinterpret_cast(__cxa_get_globals())->uncaughtExceptions; +} + +#elif _MSC_VER + +#if _MSC_VER >= 1900 +// MSVC14 has a refactored CRT which now provides a direct accessor for this value. +// See https://svn.boost.org/trac/boost/ticket/10158 for a brief discussion. +extern "C" int *__cdecl __processing_throw(); + +uint uncaughtExceptionCount() { + return static_cast(*__processing_throw()); +} + +#elif _MSC_VER >= 1400 +// The below was copied from: +// https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp + +extern "C" char *__cdecl _getptd(); + +uint uncaughtExceptionCount() { + return *reinterpret_cast(_getptd() + (sizeof(void*) == 8 ? 0x100 : 0x90)); +} +#else +uint uncaughtExceptionCount() { + // Since the above doesn't work, fall back to uncaught_exception(). This will produce incorrect + // results in very obscure cases that Cap'n Proto doesn't really rely on anyway. + return std::uncaught_exception(); +} +#endif + +#else +#error "This needs to be ported to your compiler / C++ ABI." +#endif + +} // namespace _ (private) + +UnwindDetector::UnwindDetector(): uncaughtCount(_::uncaughtExceptionCount()) {} + +bool UnwindDetector::isUnwinding() const { + return _::uncaughtExceptionCount() > uncaughtCount; +} + +#if !KJ_NO_EXCEPTIONS +void UnwindDetector::catchThrownExceptionAsSecondaryFault() const { + // TODO(someday): Attach the secondary exception to whatever primary exception is causing + // the unwind. For now we just drop it on the floor as this is probably fine most of the + // time. + getCaughtExceptionAsKj(); +} +#endif + +#if __GNUC__ && !KJ_NO_RTTI +static kj::String demangleTypeName(const char* name) { + if (name == nullptr) return kj::heapString("(nil)"); + + int status; + char* buf = abi::__cxa_demangle(name, nullptr, nullptr, &status); + kj::String result = kj::heapString(buf == nullptr ? name : buf); + free(buf); + return kj::mv(result); +} + +kj::String getCaughtExceptionType() { + return demangleTypeName(abi::__cxa_current_exception_type()->name()); +} +#else +kj::String getCaughtExceptionType() { + return kj::heapString("(unknown)"); +} +#endif + +namespace { + +size_t sharedSuffixLength(kj::ArrayPtr a, kj::ArrayPtr b) { + size_t result = 0; + while (a.size() > 0 && b.size() > 0 && a.back() == b.back()) { + ++result; + a = a.slice(0, a.size() - 1); + b = b.slice(0, b.size() - 1); + } + return result; +} + +} // namespace + +kj::ArrayPtr computeRelativeTrace( + kj::ArrayPtr trace, kj::ArrayPtr relativeTo) { + using miniposix::ssize_t; + + static constexpr size_t MIN_MATCH_LEN = 4; + if (trace.size() < MIN_MATCH_LEN || relativeTo.size() < MIN_MATCH_LEN) { + return trace; + } + + kj::ArrayPtr bestMatch = trace; + uint bestMatchLen = MIN_MATCH_LEN - 1; // must beat this to choose something else + + // `trace` and `relativeTrace` may have been truncated at different points. We iterate through + // truncating various suffixes from one of the two and then seeing if the remaining suffixes + // match. + for (ssize_t i = -(ssize_t)(trace.size() - MIN_MATCH_LEN); + i <= (ssize_t)(relativeTo.size() - MIN_MATCH_LEN); + i++) { + // Negative values truncate `trace`, positive values truncate `relativeTo`. + kj::ArrayPtr subtrace = trace.slice(0, trace.size() - kj::max(0, -i)); + kj::ArrayPtr subrt = relativeTo + .slice(0, relativeTo.size() - kj::max(0, i)); + + uint matchLen = sharedSuffixLength(subtrace, subrt); + if (matchLen > bestMatchLen) { + bestMatchLen = matchLen; + bestMatch = subtrace.slice(0, subtrace.size() - matchLen + 1); + } + } + + return bestMatch; +} + +#if KJ_NO_EXCEPTIONS + +namespace _ { // private + +class RecoverableExceptionCatcher: public ExceptionCallback { + // Catches a recoverable exception without using try/catch. Used when compiled with + // -fno-exceptions. + +public: + virtual ~RecoverableExceptionCatcher() noexcept(false) {} + + void onRecoverableException(Exception&& exception) override { + if (caught == nullptr) { + caught = mv(exception); + } else { + // TODO(someday): Consider it a secondary fault? + } + } + + Maybe caught; +}; + +Maybe runCatchingExceptions(Runnable& runnable) { + RecoverableExceptionCatcher catcher; + runnable.run(); + KJ_IF_MAYBE(e, catcher.caught) { + e->truncateCommonTrace(); + } + return mv(catcher.caught); +} + +} // namespace _ (private) + +#else // KJ_NO_EXCEPTIONS + +kj::Exception getCaughtExceptionAsKj() { + try { + throw; + } catch (Exception& e) { + e.truncateCommonTrace(); + return kj::mv(e); + } catch (CanceledException) { + throw; + } catch (std::bad_alloc& e) { + return Exception(Exception::Type::OVERLOADED, + "(unknown)", -1, str("std::bad_alloc: ", e.what())); + } catch (std::exception& e) { + return Exception(Exception::Type::FAILED, + "(unknown)", -1, str("std::exception: ", e.what())); + } catch (TopLevelProcessContext::CleanShutdownException) { + throw; + } catch (...) { +#if __GNUC__ && !KJ_NO_RTTI + return Exception(Exception::Type::FAILED, "(unknown)", -1, str( + "unknown non-KJ exception of type: ", getCaughtExceptionType())); +#else + return Exception(Exception::Type::FAILED, "(unknown)", -1, str("unknown non-KJ exception")); +#endif + } +} +#endif // !KJ_NO_EXCEPTIONS + +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/exception.h b/src/plugins/streamers/lstream/runtime/kj/kj/exception.h new file mode 100644 index 000000000..be90163f9 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/exception.h @@ -0,0 +1,504 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "memory.h" +#include "array.h" +#include "string.h" +#include "windows-sanity.h" // work-around macro conflict with `ERROR` + +KJ_BEGIN_HEADER + +namespace kj { + +class ExceptionImpl; +template class Function; + +class Exception { + // Exception thrown in case of fatal errors. + // + // Actually, a subclass of this which also implements std::exception will be thrown, but we hide + // that fact from the interface to avoid #including . + +public: + enum class Type { + // What kind of failure? + + FAILED = 0, + // Something went wrong. This is the usual error type. KJ_ASSERT and KJ_REQUIRE throw this + // error type. + + OVERLOADED = 1, + // The call failed because of a temporary lack of resources. This could be space resources + // (out of memory, out of disk space) or time resources (request queue overflow, operation + // timed out). + // + // The operation might work if tried again, but it should NOT be repeated immediately as this + // may simply exacerbate the problem. + + DISCONNECTED = 2, + // The call required communication over a connection that has been lost. The callee will need + // to re-establish connections and try again. + + UNIMPLEMENTED = 3 + // The requested method is not implemented. The caller may wish to revert to a fallback + // approach based on other methods. + + // IF YOU ADD A NEW VALUE: + // - Update the stringifier. + // - Update Cap'n Proto's RPC protocol's Exception.Type enum. + }; + + Exception(Type type, const char* file, int line, String description = nullptr) noexcept; + Exception(Type type, String file, int line, String description = nullptr) noexcept; + Exception(const Exception& other) noexcept; + Exception(Exception&& other) = default; + ~Exception() noexcept; + + const char* getFile() const { return file; } + int getLine() const { return line; } + Type getType() const { return type; } + StringPtr getDescription() const { return description; } + ArrayPtr getStackTrace() const { return arrayPtr(trace, traceCount); } + + void setDescription(kj::String&& desc) { description = kj::mv(desc); } + + StringPtr getRemoteTrace() const { return remoteTrace; } + void setRemoteTrace(kj::String&& value) { remoteTrace = kj::mv(value); } + // Additional stack trace data originating from a remote server. If present, then + // `getStackTrace()` only traces up until entry into the RPC system, and the remote trace + // contains any trace information returned over the wire. This string is human-readable but the + // format is otherwise unspecified. + + struct Context { + // Describes a bit about what was going on when the exception was thrown. + + const char* file; + int line; + String description; + Maybe> next; + + Context(const char* file, int line, String&& description, Maybe>&& next) + : file(file), line(line), description(mv(description)), next(mv(next)) {} + Context(const Context& other) noexcept; + }; + + inline Maybe getContext() const { + KJ_IF_MAYBE(c, context) { + return **c; + } else { + return nullptr; + } + } + + void wrapContext(const char* file, int line, String&& description); + // Wraps the context in a new node. This becomes the head node returned by getContext() -- it + // is expected that contexts will be added in reverse order as the exception passes up the + // callback stack. + + KJ_NOINLINE void extendTrace(uint ignoreCount, uint limit = kj::maxValue); + // Append the current stack trace to the exception's trace, ignoring the first `ignoreCount` + // frames (see `getStackTrace()` for discussion of `ignoreCount`). + // + // If `limit` is set, limit the number of frames added to the given number. + + KJ_NOINLINE void truncateCommonTrace(); + // Remove the part of the stack trace which the exception shares with the caller of this method. + // This is used by the async library to remove the async infrastructure from the stack trace + // before replacing it with the async trace. + + void addTrace(void* ptr); + // Append the given pointer to the backtrace, if it is not already full. This is used by the + // async library to trace through the promise chain that led to the exception. + + KJ_NOINLINE void addTraceHere(); + // Adds the location that called this method to the stack trace. + +private: + String ownFile; + const char* file; + int line; + Type type; + String description; + Maybe> context; + String remoteTrace; + void* trace[32]; + uint traceCount; + + bool isFullTrace = false; + // Is `trace` a full trace to the top of the stack (or as close as we could get before we ran + // out of space)? If this is false, then `trace` is instead a partial trace covering just the + // frames between where the exception was thrown and where it was caught. + // + // extendTrace() transitions this to true, and truncateCommonTrace() changes it back to false. + // + // In theory, an exception should only hold a full trace when it is in the process of being + // thrown via the C++ exception handling mechanism -- extendTrace() is called before the throw + // and truncateCommonTrace() after it is caught. Note that when exceptions propagate through + // async promises, the trace is extended one frame at a time instead, so isFullTrace should + // remain false. + + friend class ExceptionImpl; +}; + +struct CanceledException { }; +// This exception is thrown to force-unwind a stack in order to immediately cancel whatever that +// stack was doing. It is used in the implementation of fibers in particular. Application code +// should almost never catch this exception, unless you need to modify stack unwinding for some +// reason. kj::runCatchingExceptions() does not catch it. + +StringPtr KJ_STRINGIFY(Exception::Type type); +String KJ_STRINGIFY(const Exception& e); + +// ======================================================================================= + +enum class LogSeverity { + INFO, // Information describing what the code is up to, which users may request to see + // with a flag like `--verbose`. Does not indicate a problem. Not printed by + // default; you must call setLogLevel(INFO) to enable. + WARNING, // A problem was detected but execution can continue with correct output. + ERROR, // Something is wrong, but execution can continue with garbage output. + FATAL, // Something went wrong, and execution cannot continue. + DBG // Temporary debug logging. See KJ_DBG. + + // Make sure to update the stringifier if you add a new severity level. +}; + +StringPtr KJ_STRINGIFY(LogSeverity severity); + +class ExceptionCallback { + // If you don't like C++ exceptions, you may implement and register an ExceptionCallback in order + // to perform your own exception handling. For example, a reasonable thing to do is to have + // onRecoverableException() set a flag indicating that an error occurred, and then check for that + // flag just before writing to storage and/or returning results to the user. If the flag is set, + // discard whatever you have and return an error instead. + // + // ExceptionCallbacks must always be allocated on the stack. When an exception is thrown, the + // newest ExceptionCallback on the calling thread's stack is called. The default implementation + // of each method calls the next-oldest ExceptionCallback for that thread. Thus the callbacks + // behave a lot like try/catch blocks, except that they are called before any stack unwinding + // occurs. + +public: + ExceptionCallback(); + KJ_DISALLOW_COPY_AND_MOVE(ExceptionCallback); + virtual ~ExceptionCallback() noexcept(false); + + virtual void onRecoverableException(Exception&& exception); + // Called when an exception has been raised, but the calling code has the ability to continue by + // producing garbage output. This method _should_ throw the exception, but is allowed to simply + // return if garbage output is acceptable. + // + // The global default implementation throws an exception unless the library was compiled with + // -fno-exceptions, in which case it logs an error and returns. + + virtual void onFatalException(Exception&& exception); + // Called when an exception has been raised and the calling code cannot continue. If this method + // returns normally, abort() will be called. The method must throw the exception to avoid + // aborting. + // + // The global default implementation throws an exception unless the library was compiled with + // -fno-exceptions, in which case it logs an error and returns. + + virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, + String&& text); + // Called when something wants to log some debug text. `contextDepth` indicates how many levels + // of context the message passed through; it may make sense to indent the message accordingly. + // + // The global default implementation writes the text to stderr. + + enum class StackTraceMode { + FULL, + // Stringifying a stack trace will attempt to determine source file and line numbers. This may + // be expensive. For example, on Linux, this shells out to `addr2line`. + // + // This is the default in debug builds. + + ADDRESS_ONLY, + // Stringifying a stack trace will only generate a list of code addresses. + // + // This is the default in release builds. + + NONE + // Generating a stack trace will always return an empty array. + // + // This avoids ever unwinding the stack. On Windows in particular, the stack unwinding library + // has been observed to be pretty slow, so exception-heavy code might benefit significantly + // from this setting. (But exceptions should be rare...) + }; + + virtual StackTraceMode stackTraceMode(); + // Returns the current preferred stack trace mode. + + virtual Function)> getThreadInitializer(); + // Called just before a new thread is spawned using kj::Thread. Returns a function which should + // be invoked inside the new thread to initialize the thread's ExceptionCallback. The initializer + // function itself receives, as its parameter, the thread's main function, which it must call. + +protected: + ExceptionCallback& next; + +private: + ExceptionCallback(ExceptionCallback& next); + + class RootExceptionCallback; + friend ExceptionCallback& getExceptionCallback(); + + friend class Thread; +}; + +ExceptionCallback& getExceptionCallback(); +// Returns the current exception callback. + +KJ_NOINLINE KJ_NORETURN(void throwFatalException(kj::Exception&& exception, uint ignoreCount = 0)); +// Invoke the exception callback to throw the given fatal exception. If the exception callback +// returns, abort. + +KJ_NOINLINE void throwRecoverableException(kj::Exception&& exception, uint ignoreCount = 0); +// Invoke the exception callback to throw the given recoverable exception. If the exception +// callback returns, return normally. + +// ======================================================================================= + +namespace _ { class Runnable; } + +template +Maybe runCatchingExceptions(Func&& func); +// Executes the given function (usually, a lambda returning nothing) catching any exceptions that +// are thrown. Returns the Exception if there was one, or null if the operation completed normally. +// Non-KJ exceptions will be wrapped. +// +// If exception are disabled (e.g. with -fno-exceptions), this will still detect whether any +// recoverable exceptions occurred while running the function and will return those. + +#if !KJ_NO_EXCEPTIONS + +kj::Exception getCaughtExceptionAsKj(); +// Call from the catch block of a try/catch to get a `kj::Exception` representing the exception +// that was caught, the same way that `kj::runCatchingExceptions` would when catching an exception. +// This is sometimes useful if `runCatchingExceptions()` doesn't quite fit your use case. You can +// call this from any catch block, including `catch (...)`. +// +// Some exception types will actually be rethrown by this function, rather than returned. The most +// common example is `CanceledException`, whose purpose is to unwind the stack and is not meant to +// be caught. + +#endif // !KJ_NO_EXCEPTIONS + +class UnwindDetector { + // Utility for detecting when a destructor is called due to unwind. Useful for: + // - Avoiding throwing exceptions in this case, which would terminate the program. + // - Detecting whether to commit or roll back a transaction. + // + // To use this class, either inherit privately from it or declare it as a member. The detector + // works by comparing the exception state against that when the constructor was called, so for + // an object that was actually constructed during exception unwind, it will behave as if no + // unwind is taking place. This is usually the desired behavior. + +public: + UnwindDetector(); + + bool isUnwinding() const; + // Returns true if the current thread is in a stack unwind that it wasn't in at the time the + // object was constructed. + + template + void catchExceptionsIfUnwinding(Func&& func) const; + // Runs the given function (e.g., a lambda). If isUnwinding() is true, any exceptions are + // caught and treated as secondary faults, meaning they are considered to be side-effects of the + // exception that is unwinding the stack. Otherwise, exceptions are passed through normally. + +private: + uint uncaughtCount; + +#if !KJ_NO_EXCEPTIONS + void catchThrownExceptionAsSecondaryFault() const; +#endif +}; + +#if KJ_NO_EXCEPTIONS + +namespace _ { // private + +class Runnable { +public: + virtual void run() = 0; +}; + +template +class RunnableImpl: public Runnable { +public: + RunnableImpl(Func&& func): func(kj::fwd(func)) {} + void run() override { + func(); + } +private: + Func func; +}; + +Maybe runCatchingExceptions(Runnable& runnable); + +} // namespace _ (private) + +#endif // KJ_NO_EXCEPTIONS + +template +Maybe runCatchingExceptions(Func&& func) { +#if KJ_NO_EXCEPTIONS + _::RunnableImpl runnable(kj::fwd(func)); + return _::runCatchingExceptions(runnable); +#else + try { + func(); + return nullptr; + } catch (...) { + return getCaughtExceptionAsKj(); + } +#endif +} + +template +void UnwindDetector::catchExceptionsIfUnwinding(Func&& func) const { +#if KJ_NO_EXCEPTIONS + // Can't possibly be unwinding... + func(); +#else + if (isUnwinding()) { + try { + func(); + } catch (...) { + catchThrownExceptionAsSecondaryFault(); + } + } else { + func(); + } +#endif +} + +#define KJ_ON_SCOPE_SUCCESS(code) \ + ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ + KJ_DEFER(if (!KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) +// Runs `code` if the current scope is exited normally (not due to an exception). + +#define KJ_ON_SCOPE_FAILURE(code) \ + ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ + KJ_DEFER(if (KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) +// Runs `code` if the current scope is exited due to an exception. + +// ======================================================================================= + +KJ_NOINLINE ArrayPtr getStackTrace(ArrayPtr space, uint ignoreCount); +// Attempt to get the current stack trace, returning a list of pointers to instructions. The +// returned array is a slice of `space`. Provide a larger `space` to get a deeper stack trace. +// If the platform doesn't support stack traces, returns an empty array. +// +// `ignoreCount` items will be truncated from the front of the trace. This is useful for chopping +// off a prefix of the trace that is uninteresting to the developer because it's just locations +// inside the debug infrastructure that is requesting the trace. Be careful to mark functions as +// KJ_NOINLINE if you intend to count them in `ignoreCount`. Note that, unfortunately, the +// ignored entries will still waste space in the `space` array (and the returned array's `begin()` +// is never exactly equal to `space.begin()` due to this effect, even if `ignoreCount` is zero +// since `getStackTrace()` needs to ignore its own internal frames). + +String stringifyStackTrace(ArrayPtr); +// Convert the stack trace to a string with file names and line numbers. This may involve executing +// suprocesses. + +String stringifyStackTraceAddresses(ArrayPtr trace); +StringPtr stringifyStackTraceAddresses(ArrayPtr trace, ArrayPtr scratch); +// Construct a string containing just enough information about a stack trace to be able to convert +// it to file and line numbers later using offline tools. This produces a sequence of +// space-separated code location identifiers. Each identifier may be an absolute address +// (hex number starting with 0x) or may be a module-relative address "@0x". The +// latter case is preferred when ASLR is in effect and has loaded different modules at different +// addresses. + +String getStackTrace(); +// Get a stack trace right now and stringify it. Useful for debugging. + +void printStackTraceOnCrash(); +// Registers signal handlers on common "crash" signals like SIGSEGV that will (attempt to) print +// a stack trace. You should call this as early as possible on program startup. Programs using +// KJ_MAIN get this automatically. + +void resetCrashHandlers(); +// Resets all signal handlers set by printStackTraceOnCrash(). + +kj::StringPtr trimSourceFilename(kj::StringPtr filename); +// Given a source code file name, trim off noisy prefixes like "src/" or +// "/ekam-provider/canonical/". + +kj::String getCaughtExceptionType(); +// Utility function which attempts to return the human-readable type name of the exception +// currently being thrown. This can be called inside a catch block, including a catch (...) block, +// for the purpose of error logging. This function is best-effort; on some platforms it may simply +// return "(unknown)". + +#if !KJ_NO_EXCEPTIONS + +class InFlightExceptionIterator { + // A class that can be used to iterate over exceptions that are in-flight in the current thread, + // meaning they are either uncaught, or caught by a catch block that is current executing. + // + // This is meant for debugging purposes, and the results are best-effort. The C++ standard + // library does not provide any way to inspect uncaught exceptions, so this class can only + // discover KJ exceptions thrown using throwFatalException() or throwRecoverableException(). + // All KJ code uses those two functions to throw exceptions, but if your own code uses a bare + // `throw`, or if the standard library throws an exception, these cannot be inspected. + // + // This class is safe to use in a signal handler. + +public: + InFlightExceptionIterator(); + + Maybe next(); + +private: + const Exception* ptr; +}; + +#endif // !KJ_NO_EXCEPTIONS + +kj::Exception getDestructionReason(void* traceSeparator, + kj::Exception::Type defaultType, const char* defaultFile, int defaultLine, + kj::StringPtr defaultDescription); +// Returns an exception that attempts to capture why a destructor has been invoked. If a KJ +// exception is currently in-flight (see InFlightExceptionIterator), then that exception is +// returned. Otherwise, an exception is constructed using the current stack trace and the type, +// file, line, and description provided. In the latter case, `traceSeparator` is appended to the +// stack trace; this should be a pointer to some dummy symbol which acts as a separator between the +// original stack trace and any new trace frames added later. + +kj::ArrayPtr computeRelativeTrace( + kj::ArrayPtr trace, kj::ArrayPtr relativeTo); +// Given two traces expected to have started from the same root, try to find the part of `trace` +// that is different from `relativeTo`, considering that either or both traces might be truncated. +// +// This is useful for debugging, when reporting several related traces at once. + +void requireOnStack(void* ptr, kj::StringPtr description); +// Throw an exception if `ptr` does not appear to point to something near the top of the stack. +// Used as a safety check for types that must be stack-allocated, like ExceptionCallback. + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/filesystem.h b/src/plugins/streamers/lstream/runtime/kj/kj/filesystem.h new file mode 100644 index 000000000..323420a44 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/filesystem.h @@ -0,0 +1,1123 @@ +// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "memory.h" +#include "io.h" +#include +#include "time.h" +#include "function.h" +#include "hash.h" + +KJ_BEGIN_HEADER + +namespace kj { + +template +class Vector; + +class PathPtr; + +class Path { + // A Path identifies a file in a directory tree. + // + // In KJ, we avoid representing paths as plain strings because this can lead to path injection + // bugs as well as numerous kinds of bugs relating to path parsing edge cases. The Path class's + // interface is designed to "make it hard to screw up". + // + // A "Path" is in fact a list of strings, each string being one component of the path (as would + // normally be separated by '/'s). Path components are not allowed to contain '/' nor '\0', nor + // are they allowed to be the special names "", ".", nor "..". + // + // If you explicitly want to parse a path that contains '/'s, ".", and "..", you must use + // parse() and/or eval(). However, users of this interface are encouraged to avoid parsing + // paths at all, and instead express paths as string arrays. + // + // Note that when using the Path class, ".." is always canonicalized in path space without + // consulting the actual filesystem. This means that "foo/some-symlink/../bar" is exactly + // equivalent to "foo/bar". This differs from the kernel's behavior when resolving paths passed + // to system calls: the kernel would have resolved "some-symlink" to its target physical path, + // and then would have interpreted ".." relative to that. In practice, the kernel's behavior is + // rarely what the user or programmer intended, hence canonicalizing in path space produces a + // better result. + // + // Path objects are "immutable": functions that "modify" the path return a new path. However, + // if the path being operated on is an rvalue, copying can be avoided. Hence it makes sense to + // write code like: + // + // Path p = ...; + // p = kj::mv(p).append("bar"); // in-place update, avoids string copying + +public: + Path(decltype(nullptr)); // empty path + + explicit Path(StringPtr name); + explicit Path(String&& name); + // Create a Path containing only one component. `name` is a single filename; it cannot contain + // '/' nor '\0' nor can it be exactly "" nor "." nor "..". + // + // If you want to allow '/'s and such, you must call Path::parse(). We force you to do this to + // prevent path injection bugs where you didn't consider what would happen if the path contained + // a '/'. + + explicit Path(std::initializer_list parts); + explicit Path(ArrayPtr parts); + explicit Path(Array parts); + // Construct a path from an array. Note that this means you can do: + // + // Path{"foo", "bar", "baz"} // equivalent to Path::parse("foo/bar/baz") + + KJ_DISALLOW_COPY(Path); + Path(Path&&) = default; + Path& operator=(Path&&) = default; + + Path clone() const; + + static Path parse(StringPtr path); + // Parses a path in traditional format. Components are separated by '/'. Any use of "." or + // ".." will be canonicalized (if they can't be canonicalized, e.g. because the path starts with + // "..", an exception is thrown). Multiple consecutive '/'s will be collapsed. A leading '/' + // is NOT accepted -- if that is a problem, you probably want `eval()`. Trailing '/'s are + // ignored. + + Path append(Path&& suffix) const&; + Path append(Path&& suffix) &&; + Path append(PathPtr suffix) const&; + Path append(PathPtr suffix) &&; + Path append(StringPtr suffix) const&; + Path append(StringPtr suffix) &&; + Path append(String&& suffix) const&; + Path append(String&& suffix) &&; + // Create a new path by appending the given path to this path. + // + // `suffix` cannot contain '/' characters. Instead, you can append an array: + // + // path.append({"foo", "bar"}) + // + // Or, use Path::parse(): + // + // path.append(Path::parse("foo//baz/../bar")) + + Path eval(StringPtr pathText) const&; + Path eval(StringPtr pathText) &&; + // Evaluates a traditional path relative to this one. `pathText` is parsed like `parse()` would, + // except that: + // - It can contain leading ".." components that traverse up the tree. + // - It can have a leading '/' which completely replaces the current path. + // + // THE NAME OF THIS METHOD WAS CHOSEN TO INSPIRE FEAR. + // + // Instead of using `path.eval(str)`, always consider whether you really want + // `path.append(Path::parse(str))`. The former is much riskier than the latter in terms of path + // injection vulnerabilities. + + PathPtr basename() const&; + Path basename() &&; + // Get the last component of the path. (Use `basename()[0]` to get just the string.) + + PathPtr parent() const&; + Path parent() &&; + // Get the parent path. + + String toString(bool absolute = false) const; + // Converts the path to a traditional path string, appropriate to pass to a unix system call. + // Never throws. + + const String& operator[](size_t i) const&; + String operator[](size_t i) &&; + size_t size() const; + const String* begin() const; + const String* end() const; + PathPtr slice(size_t start, size_t end) const&; + Path slice(size_t start, size_t end) &&; + // A Path can be accessed as an array of strings. + + bool operator==(PathPtr other) const; + bool operator!=(PathPtr other) const; + bool operator< (PathPtr other) const; + bool operator> (PathPtr other) const; + bool operator<=(PathPtr other) const; + bool operator>=(PathPtr other) const; + // Compare path components lexically. + + bool operator==(const Path& other) const; + bool operator!=(const Path& other) const; + bool operator< (const Path& other) const; + bool operator> (const Path& other) const; + bool operator<=(const Path& other) const; + bool operator>=(const Path& other) const; + + uint hashCode() const; + // Can use in HashMap. + + bool startsWith(PathPtr prefix) const; + bool endsWith(PathPtr suffix) const; + // Compare prefix / suffix. + + Path evalWin32(StringPtr pathText) const&; + Path evalWin32(StringPtr pathText) &&; + // Evaluates a Win32-style path, as might be written by a user. Differences from `eval()` + // include: + // + // - Backslashes can be used as path separators. + // - Absolute paths begin with a drive letter followed by a colon. The drive letter, including + // the colon, will become the first component of the path, e.g. "c:\foo" becomes {"c:", "foo"}. + // - A network path like "\\host\share\path" is parsed as {"host", "share", "path"}. + + Path evalNative(StringPtr pathText) const&; + Path evalNative(StringPtr pathText) &&; + // Alias for either eval() or evalWin32() depending on the target platform. Use this when you are + // parsing a path provided by a user and you want the user to be able to use the "natural" format + // for their platform. + + String toWin32String(bool absolute = false) const; + // Converts the path to a Win32 path string, as you might display to a user. + // + // This is meant for display. For making Win32 system calls, consider `toWin32Api()` instead. + // + // If `absolute` is true, the path is expected to be an absolute path, meaning the first + // component is a drive letter, namespace, or network host name. These are converted to their + // regular Win32 format -- i.e. this method does the reverse of `evalWin32()`. + // + // This throws if the path would have unexpected special meaning or is otherwise invalid on + // Windows, such as if it contains backslashes (within a path component), colons, or special + // names like "con". + + String toNativeString(bool absolute = false) const; + // Alias for either toString() or toWin32String() depending on the target platform. Use this when + // you are formatting a path to display to a user and you want to present it in the "natural" + // format for the user's platform. + + Array forWin32Api(bool absolute) const; + // Like toWin32String, but additionally: + // - Converts the path to UTF-16, with a NUL terminator included. + // - For absolute paths, adds the "\\?\" prefix which opts into permitting paths longer than + // MAX_PATH, and turns off relative path processing (which KJ paths already handle in userspace + // anyway). + // + // This method is good to use when making a Win32 API call, e.g.: + // + // DeleteFileW(path.forWin32Api(true).begin()); + + static Path parseWin32Api(ArrayPtr text); + // Parses an absolute path as returned by a Win32 API call like GetFinalPathNameByHandle() or + // GetCurrentDirectory(). A "\\?\" prefix is optional but understood if present. + // + // Since such Win32 API calls generally return a length, this function inputs an array slice. + // The slice should not include any NUL terminator. + +private: + Array parts; + + // TODO(perf): Consider unrolling one element from `parts`, so that a one-element path doesn't + // require allocation of an array. + + enum { ALREADY_CHECKED }; + Path(Array parts, decltype(ALREADY_CHECKED)); + + friend class PathPtr; + + static String stripNul(String input); + static void validatePart(StringPtr part); + static void evalPart(Vector& parts, ArrayPtr part); + static Path evalImpl(Vector&& parts, StringPtr path); + static Path evalWin32Impl(Vector&& parts, StringPtr path, bool fromApi = false); + static size_t countParts(StringPtr path); + static size_t countPartsWin32(StringPtr path); + static bool isWin32Drive(ArrayPtr part); + static bool isNetbiosName(ArrayPtr part); + static bool isWin32Special(StringPtr part); +}; + +class PathPtr { + // Points to a Path or a slice of a Path, but doesn't own it. + // + // PathPtr is to Path as ArrayPtr is to Array and StringPtr is to String. + +public: + PathPtr(decltype(nullptr)); + PathPtr(const Path& path); + + Path clone(); + Path append(Path&& suffix) const; + Path append(PathPtr suffix) const; + Path append(StringPtr suffix) const; + Path append(String&& suffix) const; + Path eval(StringPtr pathText) const; + PathPtr basename() const; + PathPtr parent() const; + String toString(bool absolute = false) const; + const String& operator[](size_t i) const; + size_t size() const; + const String* begin() const; + const String* end() const; + PathPtr slice(size_t start, size_t end) const; + bool operator==(PathPtr other) const; + bool operator!=(PathPtr other) const; + bool operator< (PathPtr other) const; + bool operator> (PathPtr other) const; + bool operator<=(PathPtr other) const; + bool operator>=(PathPtr other) const; + uint hashCode() const; + bool startsWith(PathPtr prefix) const; + bool endsWith(PathPtr suffix) const; + Path evalWin32(StringPtr pathText) const; + Path evalNative(StringPtr pathText) const; + String toWin32String(bool absolute = false) const; + String toNativeString(bool absolute = false) const; + Array forWin32Api(bool absolute) const; + // Equivalent to the corresponding methods of `Path`. + +private: + ArrayPtr parts; + + explicit PathPtr(ArrayPtr parts); + + String toWin32StringImpl(bool absolute, bool forApi) const; + + friend class Path; +}; + +// ======================================================================================= +// The filesystem API +// +// This API is strictly synchronous because, unfortunately, there's no such thing as asynchronous +// filesystem access in practice. The filesystem drivers on Linux are written to assume they can +// block. The AIO API is only actually asynchronous for reading/writing the raw file blocks, but if +// the filesystem needs to be involved (to allocate blocks, update metadata, etc.) that will block. +// It's best to imagine that the filesystem is just another tier of memory that happens to be +// slower than RAM (which is slower than L3 cache, which is slower than L2, which is slower than +// L1). You can't do asynchronous RAM access so why asynchronous filesystem? The only way to +// parallelize these is using threads. +// +// All KJ filesystem objects are thread-safe, and so all methods are marked "const" (even write +// methods). Of course, if you concurrently write the same bytes of a file from multiple threads, +// it's unspecified which write will "win". + +class FsNode { + // Base class for filesystem node types. + +public: + Own clone() const; + // Creates a new object of exactly the same type as this one, pointing at exactly the same + // external object. + // + // Under the hood, this will call dup(), so the FD number will not be the same. + + virtual Maybe getFd() const { return nullptr; } + // Get the underlying Unix file descriptor, if any. Returns nullptr if this object actually isn't + // wrapping a file descriptor. + + virtual Maybe getWin32Handle() const { return nullptr; } + // Get the underlying Win32 HANDLE, if any. Returns nullptr if this object actually isn't + // wrapping a handle. + + enum class Type { + FILE, + DIRECTORY, + SYMLINK, + BLOCK_DEVICE, + CHARACTER_DEVICE, + NAMED_PIPE, + SOCKET, + OTHER, + }; + + struct Metadata { + Type type = Type::FILE; + + uint64_t size = 0; + // Logical size of the file. + + uint64_t spaceUsed = 0; + // Physical size of the file on disk. May be smaller for sparse files, or larger for + // pre-allocated files. + + Date lastModified = UNIX_EPOCH; + // Last modification time of the file. + + uint linkCount = 1; + // Number of hard links pointing to this node. + + uint64_t hashCode = 0; + // Hint which can be used to determine if two FsNode instances point to the same underlying + // file object. If two FsNodes report different hashCodes, then they are not the same object. + // If they report the same hashCode, then they may or may not be the same object. + // + // The Unix filesystem implementation builds the hashCode based on st_dev and st_ino of + // `struct stat`. However, note that some filesystems -- especially FUSE-based -- may not fill + // in st_ino. + // + // The Windows filesystem implementation builds the hashCode based on dwVolumeSerialNumber and + // dwFileIndex{Low,High} of the BY_HANDLE_FILE_INFORMATION structure. However, these are again + // not guaranteed to be unique on all filesystems. In particular the documentation says that + // ReFS uses 128-bit identifiers which can't be represented here, and again virtual filesystems + // may often not report real identifiers. + // + // Of course, the process of hashing values into a single hash code can also cause collisions + // even if the filesystem reports reliable information. + // + // Additionally note that this value is not reliable when returned by `lstat()`. You should + // actually open the object, then call `stat()` on the opened object. + + // Not currently included: + // - Access control info: Differs wildly across platforms, and KJ prefers capabilities anyway. + // - Other timestamps: Differs across platforms. + // - Device number: If you care, you're probably doing platform-specific stuff anyway. + + Metadata() = default; + Metadata(Type type, uint64_t size, uint64_t spaceUsed, Date lastModified, uint linkCount, + uint64_t hashCode) + : type(type), size(size), spaceUsed(spaceUsed), lastModified(lastModified), + linkCount(linkCount), hashCode(hashCode) {} + // TODO(cleanup): This constructor is redundant in C++14, but needed in C++11. + }; + + virtual Metadata stat() const = 0; + + virtual void sync() const = 0; + virtual void datasync() const = 0; + // Maps to fsync() and fdatasync() system calls. + // + // Also, when creating or overwriting a file, the first call to sync() atomically links the file + // into the filesystem (*after* syncing the data), so than incomplete data is never visible to + // other processes. (In practice this works by writing into a temporary file and then rename()ing + // it.) + +protected: + virtual Own cloneFsNode() const = 0; + // Implements clone(). Required to return an object with exactly the same type as this one. + // Hence, every subclass must implement this. +}; + +class ReadableFile: public FsNode { +public: + Own clone() const; + + String readAllText() const; + // Read all text in the file and return as a big string. + + Array readAllBytes() const; + // Read all bytes in the file and return as a big byte array. + // + // This differs from mmap() in that the read is performed all at once. Future changes to the file + // do not affect the returned copy. Consider using mmap() instead, particularly for large files. + + virtual size_t read(uint64_t offset, ArrayPtr buffer) const = 0; + // Fills `buffer` with data starting at `offset`. Returns the number of bytes actually read -- + // the only time this is less than `buffer.size()` is when EOF occurs mid-buffer. + + virtual Array mmap(uint64_t offset, uint64_t size) const = 0; + // Maps the file to memory read-only. The returned array always has exactly the requested size. + // Depending on the capabilities of the OS and filesystem, the mapping may or may not reflect + // changes that happen to the file after mmap() returns. + // + // Multiple calls to mmap() on the same file may or may not return the same mapping (it is + // immutable, so there's no possibility of interference). + // + // If the file cannot be mmap()ed, an implementation may choose to allocate a buffer on the heap, + // read into it, and return that. This should only happen if a real mmap() is impossible. + // + // The returned array is always exactly the size requested. However, accessing bytes beyond the + // current end of the file may raise SIGBUS, or may simply return zero. + + virtual Array mmapPrivate(uint64_t offset, uint64_t size) const = 0; + // Like mmap() but returns a view that the caller can modify. Modifications will not be written + // to the underlying file. Every call to this method returns a unique mapping. Changes made to + // the underlying file by other clients may or may not be reflected in the mapping -- in fact, + // some changes may be reflected while others aren't, even within the same mapping. + // + // In practice this is often implemented using copy-on-write pages. When you first write to a + // page, a copy is made. Hence, changes to the underlying file within that page stop being + // reflected in the mapping. +}; + +class AppendableFile: public FsNode, public OutputStream { +public: + Own clone() const; + + // All methods are inherited. +}; + +class WritableFileMapping { +public: + virtual ArrayPtr get() const = 0; + // Gets the mapped bytes. The returned array can be modified, and those changes may be written to + // the underlying file, but there is no guarantee that they are written unless you subsequently + // call changed(). + + virtual void changed(ArrayPtr slice) const = 0; + // Notifies the implementation that the given bytes have changed. For some implementations this + // may be a no-op while for others it may be necessary in order for the changes to be written + // back at all. + // + // `slice` must be a slice of `bytes()`. + + virtual void sync(ArrayPtr slice) const = 0; + // Implies `changed()`, and then waits until the range has actually been written to disk before + // returning. + // + // `slice` must be a slice of `bytes()`. + // + // On Windows, this calls FlushViewOfFile(). The documentation for this function implies that in + // some circumstances, to fully sync to physical disk, you may need to call FlushFileBuffers() on + // the file HANDLE as well. The documentation is not very clear on when and why this is needed. + // If you believe your program needs this, you can accomplish it by calling `.sync()` on the File + // object after calling `.sync()` on the WritableFileMapping. +}; + +class File: public ReadableFile { +public: + Own clone() const; + + void writeAll(ArrayPtr bytes) const; + void writeAll(StringPtr text) const; + // Completely replace the file with the given bytes or text. + + virtual void write(uint64_t offset, ArrayPtr data) const = 0; + // Write the given data starting at the given offset in the file. + + virtual void zero(uint64_t offset, uint64_t size) const = 0; + // Write zeros to the file, starting at `offset` and continuing for `size` bytes. If the platform + // supports it, this will "punch a hole" in the file, such that blocks that are entirely zeros + // do not take space on disk. + + virtual void truncate(uint64_t size) const = 0; + // Set the file end pointer to `size`. If `size` is less than the current size, data past the end + // is truncated. If `size` is larger than the current size, zeros are added to the end of the + // file. If the platform supports it, blocks containing all-zeros will not be stored to disk. + + virtual Own mmapWritable(uint64_t offset, uint64_t size) const = 0; + // Like ReadableFile::mmap() but returns a mapping for which any changes will be immediately + // visible in other mappings of the file on the same system and will eventually be written back + // to the file. + + virtual size_t copy(uint64_t offset, const ReadableFile& from, uint64_t fromOffset, + uint64_t size) const; + // Copies bytes from one file to another. + // + // Copies `size` bytes or to EOF, whichever comes first. Returns the number of bytes actually + // copied. Hint: Pass kj::maxValue for `size` to always copy to EOF. + // + // The copy is not atomic. Concurrent writes may lead to garbage results. + // + // The default implementation performs a series of reads and writes. Subclasses can often provide + // superior implementations that offload the work to the OS or even implement copy-on-write. +}; + +class ReadableDirectory: public FsNode { + // Read-only subset of `Directory`. + +public: + Own clone() const; + + virtual Array listNames() const = 0; + // List the contents of this directory. Does NOT include "." nor "..". + + struct Entry { + FsNode::Type type; + String name; + + inline bool operator< (const Entry& other) const { return name < other.name; } + inline bool operator> (const Entry& other) const { return name > other.name; } + inline bool operator<=(const Entry& other) const { return name <= other.name; } + inline bool operator>=(const Entry& other) const { return name >= other.name; } + // Convenience comparison operators to sort entries by name. + }; + + virtual Array listEntries() const = 0; + // List the contents of the directory including the type of each file. On some platforms and + // filesystems, this is just as fast as listNames(), but on others it may require stat()ing each + // file. + + virtual bool exists(PathPtr path) const = 0; + // Does the specified path exist? + // + // If the path is a symlink, the symlink is followed and the return value indicates if the target + // exists. If you want to know if the symlink exists, use lstat(). (This implies that listNames() + // may return names for which exists() reports false.) + + FsNode::Metadata lstat(PathPtr path) const; + virtual Maybe tryLstat(PathPtr path) const = 0; + // Gets metadata about the path. If the path is a symlink, it is not followed -- the metadata + // describes the symlink itself. `tryLstat()` returns null if the path doesn't exist. + + Own openFile(PathPtr path) const; + virtual Maybe> tryOpenFile(PathPtr path) const = 0; + // Open a file for reading. + // + // `tryOpenFile()` returns null if the path doesn't exist. Other errors still throw exceptions. + + Own openSubdir(PathPtr path) const; + virtual Maybe> tryOpenSubdir(PathPtr path) const = 0; + // Opens a subdirectory. + // + // `tryOpenSubdir()` returns null if the path doesn't exist. Other errors still throw exceptions. + + String readlink(PathPtr path) const; + virtual Maybe tryReadlink(PathPtr path) const = 0; + // If `path` is a symlink, reads and returns the link contents. + // + // Note that tryReadlink() differs subtly from tryOpen*(). For example, tryOpenFile() throws if + // the path is not a file (e.g. if it's a directory); it only returns null if the path doesn't + // exist at all. tryReadlink() returns null if either the path doesn't exist, or if it does exist + // but isn't a symlink. This is because if it were to throw instead, then almost every real-world + // use case of tryReadlink() would be forced to perform an lstat() first for the sole purpose of + // checking if it is a link, wasting a syscall and a path traversal. + // + // See Directory::symlink() for warnings about symlinks. +}; + +enum class WriteMode { + // Mode for opening a file (or directory) for write. + // + // (To open a file or directory read-only, do not specify a mode.) + // + // WriteMode is a bitfield. Hence, it overloads the bitwise logic operators. To check if a + // particular bit is set in a bitfield, use kj::has(), like: + // + // if (kj::has(mode, WriteMode::MUST_EXIST)) { + // requireExists(path); + // } + // + // (`if (mode & WriteMode::MUST_EXIST)` doesn't work because WriteMode is an enum class, which + // cannot be converted to bool. Alas, C++ does not allow you to define a conversion operator + // on an enum type, so we can't define a conversion to bool.) + + // ----------------------------------------- + // Core flags + // + // At least one of CREATE or MODIFY must be specified. Optionally, the two flags can be combined + // with a bitwise-OR. + + CREATE = 1, + // Create a new empty file. + // + // When not combined with MODIFY, if the file already exists (including as a broken symlink), + // tryOpenFile() returns null (and openFile() throws). + // + // When combined with MODIFY, if the path already exists, it will be opened as if CREATE hadn't + // been specified at all. If the path refers to a broken symlink, the file at the target of the + // link will be created (if its parent directory exists). + + MODIFY = 2, + // Modify an existing file. + // + // When not combined with CREATE, if the file doesn't exist (including if it is a broken symlink), + // tryOpenFile() returns null (and openFile() throws). + // + // When combined with CREATE, if the path doesn't exist, it will be created as if MODIFY hadn't + // been specified at all. If the path refers to a broken symlink, the file at the target of the + // link will be created (if its parent directory exists). + + // ----------------------------------------- + // Additional flags + // + // Any number of these may be OR'd with the core flags. + + CREATE_PARENT = 4, + // Indicates that if the target node's parent directory doesn't exist, it should be created + // automatically, along with its parent, and so on. This creation is NOT atomic. + // + // This bit only makes sense with CREATE or REPLACE. + + EXECUTABLE = 8, + // Mark this file executable, if this is a meaningful designation on the host platform. + + PRIVATE = 16, + // Indicates that this file is sensitive and should have permissions masked so that it is only + // accessible by the current user. + // + // When this is not used, the platform's default access control settings are used. On Unix, + // that usually means the umask is applied. On Windows, it means permissions are inherited from + // the parent. +}; + +inline constexpr WriteMode operator|(WriteMode a, WriteMode b) { + return static_cast(static_cast(a) | static_cast(b)); +} +inline constexpr WriteMode operator&(WriteMode a, WriteMode b) { + return static_cast(static_cast(a) & static_cast(b)); +} +inline constexpr WriteMode operator+(WriteMode a, WriteMode b) { + return static_cast(static_cast(a) | static_cast(b)); +} +inline constexpr WriteMode operator-(WriteMode a, WriteMode b) { + return static_cast(static_cast(a) & ~static_cast(b)); +} +template > +bool has(T haystack, T needle) { + return (static_cast<__underlying_type(T)>(haystack) & + static_cast<__underlying_type(T)>(needle)) == + static_cast<__underlying_type(T)>(needle); +} + +enum class TransferMode { + // Specifies desired behavior for Directory::transfer(). + + MOVE, + // The node is moved to the new location, i.e. the old location is deleted. If possible, this + // move is performed without copying, otherwise it is performed as a copy followed by a delete. + + LINK, + // The new location becomes a synonym for the old location (a "hard link"). Filesystems have + // varying support for this -- typically, it is not supported on directories. + + COPY + // The new location becomes a copy of the old. + // + // Some filesystems may implement this in terms of copy-on-write. + // + // If the filesystem supports sparse files, COPY takes sparseness into account -- it will punch + // holes in the target file where holes exist in the source file. +}; + +class Directory: public ReadableDirectory { + // Refers to a specific directory on disk. + // + // A `Directory` object *only* provides access to children of the directory, not parents. That + // is, you cannot open the file "..", nor jump to the root directory with "/". + // + // On OSs that support it, a `Directory` is backed by an open handle to the directory node. This + // means: + // - If the directory is renamed on-disk, the `Directory` object still points at it. + // - Opening files in the directory only requires the OS to traverse the path from the directory + // to the file; it doesn't have to re-traverse all the way from the filesystem root. + // + // On Windows, a `Directory` object holds a lock on the underlying directory such that it cannot + // be renamed nor deleted while the object exists. This is necessary because Windows does not + // fully support traversing paths relative to file handles (it does for some operations but not + // all), so the KJ filesystem implementation is forced to remember the full path and needs to + // ensure that the path is not invalidated. If, in the future, Windows fully supports + // handle-relative paths, KJ may stop locking directories in this way, so do not rely on this + // behavior. + +public: + Own clone() const; + + template + class Replacer { + // Implements an atomic replacement of a file or directory, allowing changes to be made to + // storage in a way that avoids losing data in a power outage and prevents other processes + // from observing content in an inconsistent state. + // + // `T` may be `File` or `Directory`. For readability, the text below describes replacing a + // file, but the logic is the same for directories. + // + // When you call `Directory::replaceFile()`, a temporary file is created, but the specified + // path is not yet touched. You may call `get()` to obtain the temporary file object, through + // which you may initialize its content, knowing that no other process can see it yet. The file + // is atomically moved to its final path when you call `commit()`. If you destroy the Replacer + // without calling commit(), the temporary file is deleted. + // + // Note that most operating systems sadly do not support creating a truly unnamed temporary file + // and then linking it in later. Moreover, the file cannot necessarily be created in the system + // temporary directory because it might not be on the same filesystem as the target. Therefore, + // the replacement file may initially be created in the same directory as its eventual target. + // The implementation of Directory will choose a name that is unique and "hidden" according to + // the conventions of the filesystem. Additionally, the implementation of Directory will avoid + // returning these temporary files from its list*() methods, in order to avoid observable + // inconsistencies across platforms. + public: + explicit Replacer(WriteMode mode); + + virtual const T& get() = 0; + // Gets the File or Directory representing the replacement data. Fill in this object before + // calling commit(). + + void commit(); + virtual bool tryCommit() = 0; + // Commit the replacement. + // + // `tryCommit()` may return false based on the CREATE/MODIFY bits passed as the WriteMode when + // the replacement was initiated. (If CREATE but not MODIFY was used, tryCommit() returns + // false to indicate that the target file already existed. If MODIFY but not CREATE was used, + // tryCommit() returns false to indicate that the file didn't exist.) + // + // `commit()` is atomic, meaning that there is no point in time at which other processes + // observing the file will see it in an intermediate state -- they will either see the old + // content or the complete new content. This includes in the case of a power outage or machine + // failure: on recovery, the file will either be in the old state or the new state, but not in + // some intermediate state. + // + // It's important to note that a power failure *after commit() returns* can still revert the + // file to its previous state. That is, `commit()` does NOT guarantee that, upon return, the + // new content is durable. In order to guarantee this, you must call `sync()` on the immediate + // parent directory of the replaced file. + // + // Note that, sadly, not all filesystems / platforms are capable of supporting all of the + // guarantees documented above. In such cases, commit() will make a best-effort attempt to do + // what it claims. Some examples of possible problems include: + // - Any guarantees about durability through a power outage probably require a journaling + // filesystem. + // - Many platforms do not support atomically replacing a non-empty directory. Linux does as + // of kernel 3.15 (via the renameat2() syscall using RENAME_EXCHANGE). Where not supported, + // the old directory will be moved away just before the replacement is moved into place. + // - Many platforms do not support atomically requiring the existence or non-existence of a + // file before replacing it. In these cases, commit() may have to perform the check as a + // separate step, with a small window for a race condition. + // - Many platforms do not support "unlinking" a non-empty directory, meaning that a replaced + // directory will need to be deconstructed by deleting all contents. If another process has + // the directory open when it is replaced, that process will observe the contents + // disappearing after the replacement (actually, a swap) has taken place. This differs from + // files, where a process that has opened a file before it is replaced will continue see the + // file's old content unchanged after the replacement. + // - On Windows, there are multiple ways to replace one file with another in a single system + // call, but none are documented as being atomic. KJ always uses `MoveFileEx()` with + // MOVEFILE_REPLACE_EXISTING. While the alternative `ReplaceFile()` is attractive for many + // reasons, it has the critical problem that it cannot be used when the source file has open + // file handles, which is generally the case when using Replacer. + + protected: + const WriteMode mode; + }; + + using ReadableDirectory::openFile; + using ReadableDirectory::openSubdir; + using ReadableDirectory::tryOpenFile; + using ReadableDirectory::tryOpenSubdir; + + Own openFile(PathPtr path, WriteMode mode) const; + virtual Maybe> tryOpenFile(PathPtr path, WriteMode mode) const = 0; + // Open a file for writing. + // + // `tryOpenFile()` returns null if the path is required to exist but doesn't (MODIFY or REPLACE) + // or if the path is required not to exist but does (CREATE or RACE). These are the only cases + // where it returns null -- all other types of errors (like "access denied") throw exceptions. + + virtual Own> replaceFile(PathPtr path, WriteMode mode) const = 0; + // Construct a file which, when ready, will be atomically moved to `path`, replacing whatever + // is there already. See `Replacer` for detalis. + // + // The `CREATE` and `MODIFY` bits of `mode` are not enforced until commit time, hence + // `replaceFile()` has no "try" variant. + + virtual Own createTemporary() const = 0; + // Create a temporary file backed by this directory's filesystem, but which isn't linked into + // the directory tree. The file is deleted from disk when all references to it have been dropped. + + Own appendFile(PathPtr path, WriteMode mode) const; + virtual Maybe> tryAppendFile(PathPtr path, WriteMode mode) const = 0; + // Opens the file for appending only. Useful for log files. + // + // If the underlying filesystem supports it, writes to the file will always be appended even if + // other writers are writing to the same file at the same time -- however, some implementations + // may instead assume that no other process is changing the file size between writes. + + Own openSubdir(PathPtr path, WriteMode mode) const; + virtual Maybe> tryOpenSubdir(PathPtr path, WriteMode mode) const = 0; + // Opens a subdirectory for writing. + + virtual Own> replaceSubdir(PathPtr path, WriteMode mode) const = 0; + // Construct a directory which, when ready, will be atomically moved to `path`, replacing + // whatever is there already. See `Replacer` for detalis. + // + // The `CREATE` and `MODIFY` bits of `mode` are not enforced until commit time, hence + // `replaceSubdir()` has no "try" variant. + + void symlink(PathPtr linkpath, StringPtr content, WriteMode mode) const; + virtual bool trySymlink(PathPtr linkpath, StringPtr content, WriteMode mode) const = 0; + // Create a symlink. `content` is the raw text which will be written into the symlink node. + // How this text is interpreted is entirely dependent on the filesystem. Note in particular that: + // - Windows will require a path that uses backslashes as the separator. + // - InMemoryDirectory does not support symlinks containing "..". + // + // Unfortunately under many implementations symlink() can be used to break out of the directory + // by writing an absolute path or utilizing "..". Do not call this method with a value for + // `target` that you don't trust. + // + // `mode` must be CREATE or REPLACE, not MODIFY. CREATE_PARENT is honored but EXECUTABLE and + // PRIVATE have no effect. `trySymlink()` returns false in CREATE mode when the target already + // exists. + + void transfer(PathPtr toPath, WriteMode toMode, + PathPtr fromPath, TransferMode mode) const; + void transfer(PathPtr toPath, WriteMode toMode, + const Directory& fromDirectory, PathPtr fromPath, + TransferMode mode) const; + virtual bool tryTransfer(PathPtr toPath, WriteMode toMode, + const Directory& fromDirectory, PathPtr fromPath, + TransferMode mode) const; + virtual Maybe tryTransferTo(const Directory& toDirectory, PathPtr toPath, WriteMode toMode, + PathPtr fromPath, TransferMode mode) const; + // Move, link, or copy a file/directory tree from one location to another. + // + // Filesystems vary in what kinds of transfers are allowed, especially for TransferMode::LINK, + // and whether TransferMode::MOVE is implemented as an actual move vs. copy+delete. + // + // tryTransfer() returns false if the source location didn't exist, or when `toMode` is CREATE + // and the target already exists. The default implementation implements only TransferMode::COPY. + // + // tryTransferTo() exists to implement double-dispatch. It should be called as a fallback by + // implementations of tryTransfer() in cases where the target directory would otherwise fail or + // perform a pessimal transfer. The default implementation returns nullptr, which the caller + // should interpret as: "I don't have any special optimizations; do the obvious thing." + // + // `toMode` controls how the target path is created. CREATE_PARENT is honored but EXECUTABLE and + // PRIVATE have no effect. + + void remove(PathPtr path) const; + virtual bool tryRemove(PathPtr path) const = 0; + // Deletes/unlinks the given path. If the path names a directory, it is recursively deleted. + // + // tryRemove() returns false in the specific case that the path doesn't exist. remove() would + // throw in this case. In all other error cases (like "access denied"), tryRemove() still throws; + // it is only "does not exist" that produces a false return. + // + // WARNING: The Windows implementation of recursive deletion is currently not safe to call from a + // privileged process to delete directories writable by unprivileged users, due to a race + // condition in which the user could trick the algorithm into following a symlink and deleting + // everything at the destination. This race condition is not present in the Unix + // implementation. Fixing it for Windows would require rewriting a lot of code to use different + // APIs. If you're interested, see the TODO(security) in filesystem-disk-win32.c++. + + // TODO(someday): + // - Support sockets? There's no openat()-like interface for sockets, so it's hard to support + // them currently. Also you'd probably want to use them with the async library. + // - Support named pipes? Unclear if there's a use case that isn't better-served by sockets. + // Then again, they can be openat()ed. + // - Support watching for changes (inotify). Probably also requires the async library. Also + // lacks openat()-like semantics. + // - xattrs -- linux-specific + // - chown/chmod/etc. -- unix-specific, ACLs, eww + // - set timestamps -- only needed by archiving programs/ + // - advisory locks + // - sendfile? + // - fadvise and such + +private: + static void commitFailed(WriteMode mode); +}; + +class Filesystem { +public: + virtual const Directory& getRoot() const = 0; + // Get the filesystem's root directory, as of the time the Filesystem object was created. + + virtual const Directory& getCurrent() const = 0; + // Get the filesystem's current directory, as of the time the Filesystem object was created. + + virtual PathPtr getCurrentPath() const = 0; + // Get the path from the root to the current directory, as of the time the Filesystem object was + // created. Note that because a `Directory` does not provide access to its parent, if you want to + // follow `..` from the current directory, you must use `getCurrentPath().eval("..")` or + // `getCurrentPath().parent()`. + // + // This function attempts to determine the path as it appeared in the user's shell before this + // program was started. That means, if the user had `cd`ed into a symlink, the path through that + // symlink is returned, *not* the canonical path. + // + // Because of this, there is an important difference between how the operating system interprets + // "../foo" and what you get when you write `getCurrentPath().eval("../foo")`: The former + // will interpret ".." relative to the directory's canonical path, whereas the latter will + // interpret it relative to the path shown in the user's shell. In practice, the latter is + // almost always what the user wants! But the former behavior is what almost all commands do + // in practice, and it leads to confusion. KJ commands should implement the behavior the user + // expects. +}; + +// ======================================================================================= + +Own newInMemoryFile(const Clock& clock); +Own newInMemoryDirectory(const Clock& clock); +// Construct file and directory objects which reside in-memory. +// +// InMemoryFile has the following special properties: +// - The backing store is not sparse and never gets smaller even if you truncate the file. +// - While a non-private memory mapping exists, the backing store cannot get larger. Any operation +// which would expand it will throw. +// +// InMemoryDirectory has the following special properties: +// - Symlinks are processed using Path::parse(). This implies that a symlink cannot point to a +// parent directory -- InMemoryDirectory does not know its parent. +// - link() can link directory nodes in addition to files. +// - link() and rename() accept any kind of Directory as `fromDirectory` -- it doesn't need to be +// another InMemoryDirectory. However, for rename(), the from path must be a directory. + +Own newFileAppender(Own inner); +// Creates an AppendableFile by wrapping a File. Note that this implementation assumes it is the +// only writer. A correct implementation should always append to the file even if other writes +// are happening simultaneously, as is achieved with the O_APPEND flag to open(2), but that +// behavior is not possible to emulate on top of `File`. + +#if _WIN32 +typedef AutoCloseHandle OsFileHandle; +#else +typedef AutoCloseFd OsFileHandle; +#endif + +Own newDiskReadableFile(OsFileHandle fd); +Own newDiskAppendableFile(OsFileHandle fd); +Own newDiskFile(OsFileHandle fd); +Own newDiskReadableDirectory(OsFileHandle fd); +Own newDiskDirectory(OsFileHandle fd); +// Wrap a file descriptor (or Windows HANDLE) as various filesystem types. + +Own newDiskFilesystem(); +// Get at implementation of `Filesystem` representing the real filesystem. +// +// DO NOT CALL THIS except at the top level of your program, e.g. in main(). Anywhere else, you +// should instead have your caller pass in a Filesystem object, or a specific Directory object, +// or whatever it is that your code needs. This ensures that your code supports dependency +// injection, which makes it more reusable and testable. +// +// newDiskFilesystem() reads the current working directory at the time it is called. The returned +// object is not affected by subsequent calls to chdir(). + +// ======================================================================================= +// inline implementation details + +inline Path::Path(decltype(nullptr)): parts(nullptr) {} +inline Path::Path(std::initializer_list parts) + : Path(arrayPtr(parts.begin(), parts.end())) {} +inline Path::Path(Array parts, decltype(ALREADY_CHECKED)) + : parts(kj::mv(parts)) {} +inline Path Path::clone() const { return PathPtr(*this).clone(); } +inline Path Path::append(Path&& suffix) const& { return PathPtr(*this).append(kj::mv(suffix)); } +inline Path Path::append(PathPtr suffix) const& { return PathPtr(*this).append(suffix); } +inline Path Path::append(StringPtr suffix) const& { return append(Path(suffix)); } +inline Path Path::append(StringPtr suffix) && { return kj::mv(*this).append(Path(suffix)); } +inline Path Path::append(String&& suffix) const& { return append(Path(kj::mv(suffix))); } +inline Path Path::append(String&& suffix) && { return kj::mv(*this).append(Path(kj::mv(suffix))); } +inline Path Path::eval(StringPtr pathText) const& { return PathPtr(*this).eval(pathText); } +inline PathPtr Path::basename() const& { return PathPtr(*this).basename(); } +inline PathPtr Path::parent() const& { return PathPtr(*this).parent(); } +inline const String& Path::operator[](size_t i) const& { return parts[i]; } +inline String Path::operator[](size_t i) && { return kj::mv(parts[i]); } +inline size_t Path::size() const { return parts.size(); } +inline const String* Path::begin() const { return parts.begin(); } +inline const String* Path::end() const { return parts.end(); } +inline PathPtr Path::slice(size_t start, size_t end) const& { + return PathPtr(*this).slice(start, end); +} +inline bool Path::operator==(PathPtr other) const { return PathPtr(*this) == other; } +inline bool Path::operator!=(PathPtr other) const { return PathPtr(*this) != other; } +inline bool Path::operator< (PathPtr other) const { return PathPtr(*this) < other; } +inline bool Path::operator> (PathPtr other) const { return PathPtr(*this) > other; } +inline bool Path::operator<=(PathPtr other) const { return PathPtr(*this) <= other; } +inline bool Path::operator>=(PathPtr other) const { return PathPtr(*this) >= other; } +inline bool Path::operator==(const Path& other) const { return PathPtr(*this) == PathPtr(other); } +inline bool Path::operator!=(const Path& other) const { return PathPtr(*this) != PathPtr(other); } +inline bool Path::operator< (const Path& other) const { return PathPtr(*this) < PathPtr(other); } +inline bool Path::operator> (const Path& other) const { return PathPtr(*this) > PathPtr(other); } +inline bool Path::operator<=(const Path& other) const { return PathPtr(*this) <= PathPtr(other); } +inline bool Path::operator>=(const Path& other) const { return PathPtr(*this) >= PathPtr(other); } +inline uint Path::hashCode() const { return kj::hashCode(parts); } +inline bool Path::startsWith(PathPtr prefix) const { return PathPtr(*this).startsWith(prefix); } +inline bool Path::endsWith (PathPtr suffix) const { return PathPtr(*this).endsWith (suffix); } +inline String Path::toString(bool absolute) const { return PathPtr(*this).toString(absolute); } +inline Path Path::evalWin32(StringPtr pathText) const& { + return PathPtr(*this).evalWin32(pathText); +} +inline String Path::toWin32String(bool absolute) const { + return PathPtr(*this).toWin32String(absolute); +} +inline Array Path::forWin32Api(bool absolute) const { + return PathPtr(*this).forWin32Api(absolute); +} + +inline PathPtr::PathPtr(decltype(nullptr)): parts(nullptr) {} +inline PathPtr::PathPtr(const Path& path): parts(path.parts) {} +inline PathPtr::PathPtr(ArrayPtr parts): parts(parts) {} +inline Path PathPtr::append(StringPtr suffix) const { return append(Path(suffix)); } +inline Path PathPtr::append(String&& suffix) const { return append(Path(kj::mv(suffix))); } +inline const String& PathPtr::operator[](size_t i) const { return parts[i]; } +inline size_t PathPtr::size() const { return parts.size(); } +inline const String* PathPtr::begin() const { return parts.begin(); } +inline const String* PathPtr::end() const { return parts.end(); } +inline PathPtr PathPtr::slice(size_t start, size_t end) const { + return PathPtr(parts.slice(start, end)); +} +inline bool PathPtr::operator!=(PathPtr other) const { return !(*this == other); } +inline bool PathPtr::operator> (PathPtr other) const { return other < *this; } +inline bool PathPtr::operator<=(PathPtr other) const { return !(other < *this); } +inline bool PathPtr::operator>=(PathPtr other) const { return !(*this < other); } +inline uint PathPtr::hashCode() const { return kj::hashCode(parts); } +inline String PathPtr::toWin32String(bool absolute) const { + return toWin32StringImpl(absolute, false); +} + +#if _WIN32 +inline Path Path::evalNative(StringPtr pathText) const& { + return evalWin32(pathText); +} +inline Path Path::evalNative(StringPtr pathText) && { + return kj::mv(*this).evalWin32(pathText); +} +inline String Path::toNativeString(bool absolute) const { + return toWin32String(absolute); +} +inline Path PathPtr::evalNative(StringPtr pathText) const { + return evalWin32(pathText); +} +inline String PathPtr::toNativeString(bool absolute) const { + return toWin32String(absolute); +} +#else +inline Path Path::evalNative(StringPtr pathText) const& { + return eval(pathText); +} +inline Path Path::evalNative(StringPtr pathText) && { + return kj::mv(*this).eval(pathText); +} +inline String Path::toNativeString(bool absolute) const { + return toString(absolute); +} +inline Path PathPtr::evalNative(StringPtr pathText) const { + return eval(pathText); +} +inline String PathPtr::toNativeString(bool absolute) const { + return toString(absolute); +} +#endif // _WIN32, else + +inline Own FsNode::clone() const { return cloneFsNode(); } +inline Own ReadableFile::clone() const { + return cloneFsNode().downcast(); +} +inline Own AppendableFile::clone() const { + return cloneFsNode().downcast(); +} +inline Own File::clone() const { return cloneFsNode().downcast(); } +inline Own ReadableDirectory::clone() const { + return cloneFsNode().downcast(); +} +inline Own Directory::clone() const { + return cloneFsNode().downcast(); +} + +inline void Directory::transfer( + PathPtr toPath, WriteMode toMode, PathPtr fromPath, TransferMode mode) const { + return transfer(toPath, toMode, *this, fromPath, mode); +} + +template +inline Directory::Replacer::Replacer(WriteMode mode): mode(mode) {} + +template +void Directory::Replacer::commit() { + if (!tryCommit()) commitFailed(mode); +} + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/function.h b/src/plugins/streamers/lstream/runtime/kj/kj/function.h new file mode 100644 index 000000000..59ba5f35b --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/function.h @@ -0,0 +1,293 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "memory.h" + +KJ_BEGIN_HEADER + +namespace kj { + +template +class Function; +// Function wrapper using virtual-based polymorphism. Use this when template polymorphism is +// not possible. You can, for example, accept a Function as a parameter: +// +// void setFilter(Function filter); +// +// The caller of `setFilter()` may then pass any callable object as the parameter. The callable +// object does not have to have the exact signature specified, just one that is "compatible" -- +// i.e. the return type is covariant and the parameters are contravariant. +// +// Unlike `std::function`, `kj::Function`s are movable but not copyable, just like `kj::Own`. This +// is to avoid unexpected heap allocation or slow atomic reference counting. +// +// When a `Function` is constructed from an lvalue, it captures only a reference to the value. +// When constructed from an rvalue, it invokes the value's move constructor. So, for example: +// +// struct AddN { +// int n; +// int operator(int i) { return i + n; } +// } +// +// Function f1 = AddN{2}; +// // f1 owns an instance of AddN. It may safely be moved out +// // of the local scope. +// +// AddN adder(2); +// Function f2 = adder; +// // f2 contains a reference to `adder`. Thus, it becomes invalid +// // when `adder` goes out-of-scope. +// +// AddN adder2(2); +// Function f3 = kj::mv(adder2); +// // f3 owns an insatnce of AddN moved from `adder2`. f3 may safely +// // be moved out of the local scope. +// +// Additionally, a Function may be bound to a class method using KJ_BIND_METHOD(object, methodName). +// For example: +// +// class Printer { +// public: +// void print(int i); +// void print(kj::StringPtr s); +// }; +// +// Printer p; +// +// Function intPrinter = KJ_BIND_METHOD(p, print); +// // Will call Printer::print(int). +// +// Function strPrinter = KJ_BIND_METHOD(p, print); +// // Will call Printer::print(kj::StringPtr). +// +// Notice how KJ_BIND_METHOD is able to figure out which overload to use depending on the kind of +// Function it is binding to. + +template +class ConstFunction; +// Like Function, but wraps a "const" (i.e. thread-safe) call. + +template +class FunctionParam; +// Like Function, but used specifically as a call parameter type. Does not do any heap allocation. +// +// This type MUST NOT be used for anything other than a parameter type to a function or method. +// This is because if FunctionParam binds to a temporary, it assumes that the temporary will +// outlive the FunctionParam instance. This is true when FunctionParam is used as a parameter type, +// but not if it is used as a local variable nor a class member variable. + +template +class Function { +public: + template + inline Function(F&& f): impl(heap>(kj::fwd(f))) {} + Function() = default; + + // Make sure people don't accidentally end up wrapping a reference when they meant to return + // a function. + KJ_DISALLOW_COPY(Function); + Function(Function&) = delete; + Function& operator=(Function&) = delete; + template Function(const Function&) = delete; + template Function& operator=(const Function&) = delete; + template Function(const ConstFunction&) = delete; + template Function& operator=(const ConstFunction&) = delete; + Function(Function&&) = default; + Function& operator=(Function&&) = default; + + inline Return operator()(Params... params) { + return (*impl)(kj::fwd(params)...); + } + + Function reference() { + // Forms a new Function of the same type that delegates to this Function by reference. + // Therefore, this Function must outlive the returned Function, but otherwise they behave + // exactly the same. + + return *impl; + } + +private: + class Iface { + public: + virtual Return operator()(Params... params) = 0; + }; + + template + class Impl final: public Iface { + public: + explicit Impl(F&& f): f(kj::fwd(f)) {} + + Return operator()(Params... params) override { + return f(kj::fwd(params)...); + } + + private: + F f; + }; + + Own impl; +}; + +template +class ConstFunction { +public: + template + inline ConstFunction(F&& f): impl(heap>(kj::fwd(f))) {} + ConstFunction() = default; + + // Make sure people don't accidentally end up wrapping a reference when they meant to return + // a function. + KJ_DISALLOW_COPY(ConstFunction); + ConstFunction(ConstFunction&) = delete; + ConstFunction& operator=(ConstFunction&) = delete; + template ConstFunction(const ConstFunction&) = delete; + template ConstFunction& operator=(const ConstFunction&) = delete; + template ConstFunction(const Function&) = delete; + template ConstFunction& operator=(const Function&) = delete; + ConstFunction(ConstFunction&&) = default; + ConstFunction& operator=(ConstFunction&&) = default; + + inline Return operator()(Params... params) const { + return (*impl)(kj::fwd(params)...); + } + + ConstFunction reference() const { + // Forms a new ConstFunction of the same type that delegates to this ConstFunction by reference. + // Therefore, this ConstFunction must outlive the returned ConstFunction, but otherwise they + // behave exactly the same. + + return *impl; + } + +private: + class Iface { + public: + virtual Return operator()(Params... params) const = 0; + }; + + template + class Impl final: public Iface { + public: + explicit Impl(F&& f): f(kj::fwd(f)) {} + + Return operator()(Params... params) const override { + return f(kj::fwd(params)...); + } + + private: + F f; + }; + + Own impl; +}; + +template +class FunctionParam { +public: + template + FunctionParam(Func&& func) { + typedef Wrapper> WrapperType; + + // All instances of Wrapper are two pointers in size: a vtable, and a Func&. So if we + // allocate space for two pointers, we can construct a Wrapper in it! + static_assert(sizeof(WrapperType) == sizeof(space), + "expected WrapperType to be two pointers"); + + // Even if `func` is an rvalue reference, it's OK to use it as an lvalue here, because + // FunctionParam is used strictly for parameters. If we captured a temporary, we know that + // temporary will not be destroyed until after the function call completes. + ctor(*reinterpret_cast(space), func); + } + + FunctionParam(const FunctionParam& other) = default; + FunctionParam(FunctionParam&& other) = default; + // Magically, a plain copy works. + + inline Return operator()(Params... params) { + return (*reinterpret_cast(space))(kj::fwd(params)...); + } + +private: + alignas(void*) char space[2 * sizeof(void*)]; + + class WrapperBase { + public: + virtual Return operator()(Params... params) = 0; + }; + + template + class Wrapper: public WrapperBase { + public: + Wrapper(Func& func): func(func) {} + + inline Return operator()(Params... params) override { + return func(kj::fwd(params)...); + } + + private: + Func& func; + }; +}; + +namespace _ { // private + +template +class BoundMethod { +public: + BoundMethod(T&& t, Func&& func, ConstFunc&& constFunc) + : t(kj::fwd(t)), func(kj::mv(func)), constFunc(kj::mv(constFunc)) {} + + template + auto operator()(Params&&... params) { + return func(t, kj::fwd(params)...); + } + template + auto operator()(Params&&... params) const { + return constFunc(t, kj::fwd(params)...); + } + +private: + T t; + Func func; + ConstFunc constFunc; +}; + +template +BoundMethod boundMethod(T&& t, Func&& func, ConstFunc&& constFunc) { + return { kj::fwd(t), kj::fwd(func), kj::fwd(constFunc) }; +} + +} // namespace _ (private) + +#define KJ_BIND_METHOD(obj, method) \ + ::kj::_::boundMethod(obj, \ + [](auto& s, auto&&... p) mutable { return s.method(kj::fwd(p)...); }, \ + [](auto& s, auto&&... p) { return s.method(kj::fwd(p)...); }) +// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an +// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will +// contain a copy (by move) of it. The method is allowed to be overloaded. + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/hash.cc b/src/plugins/streamers/lstream/runtime/kj/kj/hash.cc new file mode 100644 index 000000000..bf80a5556 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/hash.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2018 Kenton Varda and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "hash.h" + +namespace kj { +namespace _ { // private + +uint HashCoder::operator*(ArrayPtr s) const { + // murmur2 adapted from libc++ source code. + // + // TODO(perf): Use CityHash or FarmHash on 64-bit machines? They seem optimized for x86-64; what + // about ARM? Ask Vlad for advice. + + constexpr uint m = 0x5bd1e995; + constexpr uint r = 24; + uint h = s.size(); + const byte* data = s.begin(); + uint len = s.size(); + for (; len >= 4; data += 4, len -= 4) { + uint k; + memcpy(&k, data, sizeof(k)); + k *= m; + k ^= k >> r; + k *= m; + h *= m; + h ^= k; + } + switch (len) { + case 3: + h ^= data[2] << 16; + KJ_FALLTHROUGH; + case 2: + h ^= data[1] << 8; + KJ_FALLTHROUGH; + case 1: + h ^= data[0]; + h *= m; + } + h ^= h >> 13; + h *= m; + h ^= h >> 15; + return h; +} + +} // namespace _ (private) +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/hash.h b/src/plugins/streamers/lstream/runtime/kj/kj/hash.h new file mode 100644 index 000000000..d6ff46fd8 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/hash.h @@ -0,0 +1,196 @@ +// Copyright (c) 2018 Kenton Varda and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "string.h" + +KJ_BEGIN_HEADER + +namespace kj { +namespace _ { // private + +struct HashCoder { + // This is a dummy type with only one instance: HASHCODER (below). To make an arbitrary type + // hashable, define `operator*(HashCoder, T)` to return any other type that is already hashable. + // Be sure to declare the operator in the same namespace as `T` **or** in the global scope. + // You can use the KJ_HASHCODE() macro as syntax sugar for this. + // + // A more usual way to accomplish what we're doing here would be to require that you define + // a function like `hashCode(T)` and then rely on argument-dependent lookup. However, this has + // the problem that it pollutes other people's namespaces and even the global namespace. For + // example, some other project may already have functions called `hashCode` which do something + // different. Declaring `operator*` with `HashCoder` as the left operand cannot conflict with + // anything. + + uint operator*(ArrayPtr s) const; + inline uint operator*(ArrayPtr s) const { return operator*(s.asConst()); } + + inline uint operator*(ArrayPtr s) const { return operator*(s.asBytes()); } + inline uint operator*(ArrayPtr s) const { return operator*(s.asBytes()); } + inline uint operator*(const Array& s) const { return operator*(s.asBytes()); } + inline uint operator*(const Array& s) const { return operator*(s.asBytes()); } + inline uint operator*(const String& s) const { return operator*(s.asBytes()); } + inline uint operator*(const StringPtr& s) const { return operator*(s.asBytes()); } + inline uint operator*(const ConstString& s) const { return operator*(s.asBytes()); } + + inline uint operator*(decltype(nullptr)) const { return 0; } + inline uint operator*(bool b) const { return b; } + inline uint operator*(char i) const { return i; } + inline uint operator*(signed char i) const { return i; } + inline uint operator*(unsigned char i) const { return i; } + inline uint operator*(signed short i) const { return i; } + inline uint operator*(unsigned short i) const { return i; } + inline uint operator*(signed int i) const { return i; } + inline uint operator*(unsigned int i) const { return i; } + + inline uint operator*(signed long i) const { + if (sizeof(i) == sizeof(uint)) { + return operator*(static_cast(i)); + } else { + return operator*(static_cast(i)); + } + } + inline uint operator*(unsigned long i) const { + if (sizeof(i) == sizeof(uint)) { + return operator*(static_cast(i)); + } else { + return operator*(static_cast(i)); + } + } + inline uint operator*(signed long long i) const { + return operator*(static_cast(i)); + } + inline uint operator*(unsigned long long i) const { + // Mix 64 bits to 32 bits in such a way that if our input values differ primarily in the upper + // 32 bits, we still get good diffusion. (I.e. we cannot just truncate!) + // + // 49123 is an arbitrarily-chosen prime that is vaguely close to 2^16. + // + // TODO(perf): I just made this up. Is it OK? + return static_cast(i) + static_cast(i >> 32) * 49123; + } + + template + uint operator*(T* ptr) const { + static_assert(!isSameType, char>(), "Wrap in StringPtr if you want to hash string " + "contents. If you want to hash the pointer, cast to void*"); + if (sizeof(ptr) == sizeof(uint)) { + // TODO(cleanup): In C++17, make the if() above be `if constexpr ()`, then change this to + // reinterpret_cast(ptr). + return reinterpret_cast(ptr); + } else { + return operator*(reinterpret_cast(ptr)); + } + } + + template () * instance())> + uint operator*(ArrayPtr arr) const; + template () * instance())> + uint operator*(const Array& arr) const; + template > + inline uint operator*(T e) const; + + template ().hashCode())> + inline Result operator*(T&& value) const { return kj::fwd(value).hashCode(); } +}; +static KJ_CONSTEXPR(const) HashCoder HASHCODER = HashCoder(); + +} // namespace _ (private) + +#define KJ_HASHCODE(...) operator*(::kj::_::HashCoder, __VA_ARGS__) +// Defines a hash function for a custom type. Example: +// +// class Foo {...}; +// inline uint KJ_HASHCODE(const Foo& foo) { return kj::hashCode(foo.x, foo.y); } +// +// This allows Foo to be passed to hashCode(). +// +// The function should be declared either in the same namespace as the target type or in the global +// namespace. It can return any type which itself is hashable -- that value will be hashed in turn +// until a `uint` comes out. + +inline uint hashCode(uint value) { return value; } +template +inline uint hashCode(T&& value) { return hashCode(_::HASHCODER * kj::fwd(value)); } +template +inline uint hashCode(T (&arr)[N]) { + static_assert(!isSameType, char>(), "Wrap in StringPtr if you want to hash string " + "contents. If you want to hash the pointer, cast to void*"); + static_assert(isSameType, char>(), "Wrap in ArrayPtr if you want to hash a C array. " + "If you want to hash the pointer, cast to void*"); + return 0; +} +template +inline uint hashCode(T&&... values) { + uint hashes[] = { hashCode(kj::fwd(values))... }; + return hashCode(kj::ArrayPtr(hashes).asBytes()); +} +// kj::hashCode() is a universal hashing function, like kj::str() is a universal stringification +// function. Throw stuff in, get a hash code. +// +// Hash codes may differ between different processes, even running exactly the same code. +// +// NOT SUITABLE FOR CRYPTOGRAPHY. This is for hash tables, not crypto. + +// ======================================================================================= +// inline implementation details + +namespace _ { // private + +template +inline uint HashCoder::operator*(ArrayPtr arr) const { + // Hash each array element to create a string of hashes, then murmur2 over those. + // + // TODO(perf): Choose a more-modern hash. (See hash.c++.) + + constexpr uint m = 0x5bd1e995; + constexpr uint r = 24; + uint h = arr.size() * sizeof(uint); + + for (auto& e: arr) { + uint k = kj::hashCode(e); + k *= m; + k ^= k >> r; + k *= m; + h *= m; + h ^= k; + } + + h ^= h >> 13; + h *= m; + h ^= h >> 15; + return h; +} +template +inline uint HashCoder::operator*(const Array& arr) const { + return operator*(arr.asPtr()); +} + +template +inline uint HashCoder::operator*(T e) const { + return operator*(static_cast<__underlying_type(T)>(e)); +} + +} // namespace _ (private) +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/io.cc b/src/plugins/streamers/lstream/runtime/kj/kj/io.cc new file mode 100644 index 000000000..59d12e586 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/io.cc @@ -0,0 +1,469 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#if _WIN32 +#include "win32-api-version.h" +#endif + +#include "io.h" +#include "debug.h" +#include "miniposix.h" +#include +#include +#include "vector.h" + +#if _WIN32 +#include +#include "windows-sanity.h" +#else +#include +#endif + +namespace kj { + +InputStream::~InputStream() noexcept(false) {} +OutputStream::~OutputStream() noexcept(false) {} +BufferedInputStream::~BufferedInputStream() noexcept(false) {} +BufferedOutputStream::~BufferedOutputStream() noexcept(false) {} + +size_t InputStream::read(void* buffer, size_t minBytes, size_t maxBytes) { + size_t n = tryRead(buffer, minBytes, maxBytes); + KJ_REQUIRE(n >= minBytes, "Premature EOF") { + // Pretend we read zeros from the input. + memset(reinterpret_cast(buffer) + n, 0, minBytes - n); + return minBytes; + } + return n; +} + +void InputStream::skip(size_t bytes) { + char scratch[8192]; + while (bytes > 0) { + size_t amount = std::min(bytes, sizeof(scratch)); + read(scratch, amount); + bytes -= amount; + } +} + + +namespace { + +Array readAll(InputStream& input, uint64_t limit, bool nulTerminate) { + Vector> parts; + constexpr size_t BLOCK_SIZE = 4096; + + for (;;) { + KJ_REQUIRE(limit > 0, "Reached limit before EOF."); + auto part = heapArray(kj::min(BLOCK_SIZE, limit)); + size_t n = input.tryRead(part.begin(), part.size(), part.size()); + limit -= n; + if (n < part.size()) { + auto result = heapArray(parts.size() * BLOCK_SIZE + n + nulTerminate); + byte* pos = result.begin(); + for (auto& p: parts) { + memcpy(pos, p.begin(), BLOCK_SIZE); + pos += BLOCK_SIZE; + } + memcpy(pos, part.begin(), n); + pos += n; + if (nulTerminate) *pos++ = '\0'; + KJ_ASSERT(pos == result.end()); + return result; + } else { + parts.add(kj::mv(part)); + } + } +} + +} // namespace + +String InputStream::readAllText(uint64_t limit) { + return String(readAll(*this, limit, true).releaseAsChars()); +} +Array InputStream::readAllBytes(uint64_t limit) { + return readAll(*this, limit, false); +} + +void OutputStream::write(ArrayPtr> pieces) { + for (auto piece: pieces) { + write(piece.begin(), piece.size()); + } +} + +ArrayPtr BufferedInputStream::getReadBuffer() { + auto result = tryGetReadBuffer(); + KJ_REQUIRE(result.size() > 0, "Premature EOF"); + return result; +} + +// ======================================================================================= + +BufferedInputStreamWrapper::BufferedInputStreamWrapper(InputStream& inner, ArrayPtr buffer) + : inner(inner), ownedBuffer(buffer == nullptr ? heapArray(8192) : nullptr), + buffer(buffer == nullptr ? ownedBuffer : buffer) {} + +BufferedInputStreamWrapper::~BufferedInputStreamWrapper() noexcept(false) {} + +ArrayPtr BufferedInputStreamWrapper::tryGetReadBuffer() { + if (bufferAvailable.size() == 0) { + size_t n = inner.tryRead(buffer.begin(), 1, buffer.size()); + bufferAvailable = buffer.slice(0, n); + } + + return bufferAvailable; +} + +size_t BufferedInputStreamWrapper::tryRead(void* dst, size_t minBytes, size_t maxBytes) { + if (minBytes <= bufferAvailable.size()) { + // Serve from current buffer. + size_t n = std::min(bufferAvailable.size(), maxBytes); + memcpy(dst, bufferAvailable.begin(), n); + bufferAvailable = bufferAvailable.slice(n, bufferAvailable.size()); + return n; + } else { + // Copy current available into destination. + memcpy(dst, bufferAvailable.begin(), bufferAvailable.size()); + size_t fromFirstBuffer = bufferAvailable.size(); + + dst = reinterpret_cast(dst) + fromFirstBuffer; + minBytes -= fromFirstBuffer; + maxBytes -= fromFirstBuffer; + + if (maxBytes <= buffer.size()) { + // Read the next buffer-full. + size_t n = inner.read(buffer.begin(), minBytes, buffer.size()); + size_t fromSecondBuffer = std::min(n, maxBytes); + memcpy(dst, buffer.begin(), fromSecondBuffer); + bufferAvailable = buffer.slice(fromSecondBuffer, n); + return fromFirstBuffer + fromSecondBuffer; + } else { + // Forward large read to the underlying stream. + bufferAvailable = nullptr; + return fromFirstBuffer + inner.read(dst, minBytes, maxBytes); + } + } +} + +void BufferedInputStreamWrapper::skip(size_t bytes) { + if (bytes <= bufferAvailable.size()) { + bufferAvailable = bufferAvailable.slice(bytes, bufferAvailable.size()); + } else { + bytes -= bufferAvailable.size(); + if (bytes <= buffer.size()) { + // Read the next buffer-full. + size_t n = inner.read(buffer.begin(), bytes, buffer.size()); + bufferAvailable = buffer.slice(bytes, n); + } else { + // Forward large skip to the underlying stream. + bufferAvailable = nullptr; + inner.skip(bytes); + } + } +} + +// ------------------------------------------------------------------- + +BufferedOutputStreamWrapper::BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr buffer) + : inner(inner), + ownedBuffer(buffer == nullptr ? heapArray(8192) : nullptr), + buffer(buffer == nullptr ? ownedBuffer : buffer), + bufferPos(this->buffer.begin()) {} + +BufferedOutputStreamWrapper::~BufferedOutputStreamWrapper() noexcept(false) { + unwindDetector.catchExceptionsIfUnwinding([&]() { + flush(); + }); +} + +void BufferedOutputStreamWrapper::flush() { + if (bufferPos > buffer.begin()) { + inner.write(buffer.begin(), bufferPos - buffer.begin()); + bufferPos = buffer.begin(); + } +} + +ArrayPtr BufferedOutputStreamWrapper::getWriteBuffer() { + return arrayPtr(bufferPos, buffer.end()); +} + +void BufferedOutputStreamWrapper::write(const void* src, size_t size) { + if (src == bufferPos) { + // Oh goody, the caller wrote directly into our buffer. + bufferPos += size; + } else { + size_t available = buffer.end() - bufferPos; + + if (size <= available) { + memcpy(bufferPos, src, size); + bufferPos += size; + } else if (size <= buffer.size()) { + // Too much for this buffer, but not a full buffer's worth, so we'll go ahead and copy. + memcpy(bufferPos, src, available); + inner.write(buffer.begin(), buffer.size()); + + size -= available; + src = reinterpret_cast(src) + available; + + memcpy(buffer.begin(), src, size); + bufferPos = buffer.begin() + size; + } else { + // Writing so much data that we might as well write directly to avoid a copy. + inner.write(buffer.begin(), bufferPos - buffer.begin()); + bufferPos = buffer.begin(); + inner.write(src, size); + } + } +} + +// ======================================================================================= + +ArrayInputStream::ArrayInputStream(ArrayPtr array): array(array) {} +ArrayInputStream::~ArrayInputStream() noexcept(false) {} + +ArrayPtr ArrayInputStream::tryGetReadBuffer() { + return array; +} + +size_t ArrayInputStream::tryRead(void* dst, size_t minBytes, size_t maxBytes) { + size_t n = std::min(maxBytes, array.size()); + memcpy(dst, array.begin(), n); + array = array.slice(n, array.size()); + return n; +} + +void ArrayInputStream::skip(size_t bytes) { + KJ_REQUIRE(array.size() >= bytes, "ArrayInputStream ended prematurely.") { + bytes = array.size(); + break; + } + array = array.slice(bytes, array.size()); +} + +// ------------------------------------------------------------------- + +ArrayOutputStream::ArrayOutputStream(ArrayPtr array): array(array), fillPos(array.begin()) {} +ArrayOutputStream::~ArrayOutputStream() noexcept(false) {} + +ArrayPtr ArrayOutputStream::getWriteBuffer() { + return arrayPtr(fillPos, array.end()); +} + +void ArrayOutputStream::write(const void* src, size_t size) { + if (src == fillPos && fillPos != array.end()) { + // Oh goody, the caller wrote directly into our buffer. + KJ_REQUIRE(size <= array.end() - fillPos, size, fillPos, array.end() - fillPos); + fillPos += size; + } else { + KJ_REQUIRE(size <= (size_t)(array.end() - fillPos), + "ArrayOutputStream's backing array was not large enough for the data written."); + memcpy(fillPos, src, size); + fillPos += size; + } +} + +// ------------------------------------------------------------------- + +VectorOutputStream::VectorOutputStream(size_t initialCapacity) + : vector(heapArray(initialCapacity)), fillPos(vector.begin()) {} +VectorOutputStream::~VectorOutputStream() noexcept(false) {} + +ArrayPtr VectorOutputStream::getWriteBuffer() { + // Grow if needed. + if (fillPos == vector.end()) { + grow(vector.size() + 1); + } + + return arrayPtr(fillPos, vector.end()); +} + +void VectorOutputStream::write(const void* src, size_t size) { + if (src == fillPos && fillPos != vector.end()) { + // Oh goody, the caller wrote directly into our buffer. + KJ_REQUIRE(size <= vector.end() - fillPos, size, fillPos, vector.end() - fillPos); + fillPos += size; + } else { + if (vector.end() - fillPos < size) { + grow(fillPos - vector.begin() + size); + } + + memcpy(fillPos, src, size); + fillPos += size; + } +} + +void VectorOutputStream::grow(size_t minSize) { + size_t newSize = vector.size() * 2; + while (newSize < minSize) newSize *= 2; + auto newVector = heapArray(newSize); + memcpy(newVector.begin(), vector.begin(), fillPos - vector.begin()); + fillPos = fillPos - vector.begin() + newVector.begin(); + vector = kj::mv(newVector); +} + +// ======================================================================================= + +AutoCloseFd::~AutoCloseFd() noexcept(false) { + if (fd >= 0) { + // Don't use SYSCALL() here because close() should not be repeated on EINTR. + if (miniposix::close(fd) < 0) { + KJ_FAIL_SYSCALL("close", errno, fd) { + // This ensures we don't throw an exception if unwinding. + break; + } + } + } +} + +FdInputStream::~FdInputStream() noexcept(false) {} + +size_t FdInputStream::tryRead(void* buffer, size_t minBytes, size_t maxBytes) { + byte* pos = reinterpret_cast(buffer); + byte* min = pos + minBytes; + byte* max = pos + maxBytes; + + while (pos < min) { + miniposix::ssize_t n; + KJ_SYSCALL(n = miniposix::read(fd, pos, max - pos), fd); + if (n == 0) { + break; + } + pos += n; + } + + return pos - reinterpret_cast(buffer); +} + +FdOutputStream::~FdOutputStream() noexcept(false) {} + +void FdOutputStream::write(const void* buffer, size_t size) { + const char* pos = reinterpret_cast(buffer); + + while (size > 0) { + miniposix::ssize_t n; + KJ_SYSCALL(n = miniposix::write(fd, pos, size), fd); + KJ_ASSERT(n > 0, "write() returned zero."); + pos += n; + size -= n; + } +} + +void FdOutputStream::write(ArrayPtr> pieces) { +#if _WIN32 + // Windows has no reasonable writev(). It has WriteFileGather, but this call has the unreasonable + // restriction that each segment must be page-aligned. So, fall back to the default implementation + + OutputStream::write(pieces); + +#else + const size_t iovmax = miniposix::iovMax(); + while (pieces.size() > iovmax) { + write(pieces.slice(0, iovmax)); + pieces = pieces.slice(iovmax, pieces.size()); + } + + KJ_STACK_ARRAY(struct iovec, iov, pieces.size(), 16, 128); + + for (uint i = 0; i < pieces.size(); i++) { + // writev() interface is not const-correct. :( + iov[i].iov_base = const_cast(pieces[i].begin()); + iov[i].iov_len = pieces[i].size(); + } + + struct iovec* current = iov.begin(); + + // Advance past any leading empty buffers so that a write full of only empty buffers does not + // cause a syscall at all. + while (current < iov.end() && current->iov_len == 0) { + ++current; + } + + while (current < iov.end()) { + // Issue the write. + ssize_t n = 0; + KJ_SYSCALL(n = ::writev(fd, current, iov.end() - current), fd); + KJ_ASSERT(n > 0, "writev() returned zero."); + + // Advance past all buffers that were fully-written. + while (current < iov.end() && static_cast(n) >= current->iov_len) { + n -= current->iov_len; + ++current; + } + + // If we only partially-wrote one of the buffers, adjust the pointer and size to include only + // the unwritten part. + if (n > 0) { + current->iov_base = reinterpret_cast(current->iov_base) + n; + current->iov_len -= n; + } + } +#endif +} + +// ======================================================================================= + +#if _WIN32 + +AutoCloseHandle::~AutoCloseHandle() noexcept(false) { + if (handle != (void*)-1) { + KJ_WIN32(CloseHandle(handle)); + } +} + +HandleInputStream::~HandleInputStream() noexcept(false) {} + +size_t HandleInputStream::tryRead(void* buffer, size_t minBytes, size_t maxBytes) { + byte* pos = reinterpret_cast(buffer); + byte* min = pos + minBytes; + byte* max = pos + maxBytes; + + while (pos < min) { + DWORD n; + KJ_WIN32(ReadFile(handle, pos, kj::min(max - pos, DWORD(kj::maxValue)), &n, nullptr)); + if (n == 0) { + break; + } + pos += n; + } + + return pos - reinterpret_cast(buffer); +} + +HandleOutputStream::~HandleOutputStream() noexcept(false) {} + +void HandleOutputStream::write(const void* buffer, size_t size) { + const char* pos = reinterpret_cast(buffer); + + while (size > 0) { + DWORD n; + KJ_WIN32(WriteFile(handle, pos, kj::min(size, DWORD(kj::maxValue)), &n, nullptr)); + KJ_ASSERT(n > 0, "write() returned zero."); + pos += n; + size -= n; + } +} + +#endif // _WIN32 + +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/io.h b/src/plugins/streamers/lstream/runtime/kj/kj/io.h new file mode 100644 index 000000000..3edc300ca --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/io.h @@ -0,0 +1,440 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include "common.h" +#include "array.h" +#include "exception.h" +#include + +KJ_BEGIN_HEADER + +namespace kj { + +// ======================================================================================= +// Abstract interfaces + +class InputStream { +public: + virtual ~InputStream() noexcept(false); + + size_t read(void* buffer, size_t minBytes, size_t maxBytes); + // Reads at least minBytes and at most maxBytes, copying them into the given buffer. Returns + // the size read. Throws an exception on errors. Implemented in terms of tryRead(). + // + // maxBytes is the number of bytes the caller really wants, but minBytes is the minimum amount + // needed by the caller before it can start doing useful processing. If the stream returns less + // than maxBytes, the caller will usually call read() again later to get the rest. Returning + // less than maxBytes is useful when it makes sense for the caller to parallelize processing + // with I/O. + // + // Never blocks if minBytes is zero. If minBytes is zero and maxBytes is non-zero, this may + // attempt a non-blocking read or may just return zero. To force a read, use a non-zero minBytes. + // To detect EOF without throwing an exception, use tryRead(). + // + // If the InputStream can't produce minBytes, it MUST throw an exception, as the caller is not + // expected to understand how to deal with partial reads. + + virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; + // Like read(), but may return fewer than minBytes on EOF. + + inline void read(void* buffer, size_t bytes) { read(buffer, bytes, bytes); } + // Convenience method for reading an exact number of bytes. + + virtual void skip(size_t bytes); + // Skips past the given number of bytes, discarding them. The default implementation read()s + // into a scratch buffer. + + String readAllText(uint64_t limit = kj::maxValue); + Array readAllBytes(uint64_t limit = kj::maxValue); + // Read until EOF and return as one big byte array or string. Throw an exception if EOF is not + // seen before reading `limit` bytes. + // + // To prevent runaway memory allocation, consider using a more conservative value for `limit` than + // the default, particularly on untrusted data streams which may never see EOF. +}; + +class OutputStream { +public: + virtual ~OutputStream() noexcept(false); + + virtual void write(const void* buffer, size_t size) = 0; + // Always writes the full size. Throws exception on error. + + virtual void write(ArrayPtr> pieces); + // Equivalent to write()ing each byte array in sequence, which is what the default implementation + // does. Override if you can do something better, e.g. use writev() to do the write in a single + // syscall. +}; + +class BufferedInputStream: public InputStream { + // An input stream which buffers some bytes in memory to reduce system call overhead. + // - OR - + // An input stream that actually reads from some in-memory data structure and wants to give its + // caller a direct pointer to that memory to potentially avoid a copy. + +public: + virtual ~BufferedInputStream() noexcept(false); + + ArrayPtr getReadBuffer(); + // Get a direct pointer into the read buffer, which contains the next bytes in the input. If the + // caller consumes any bytes, it should then call skip() to indicate this. This always returns a + // non-empty buffer or throws an exception. Implemented in terms of tryGetReadBuffer(). + + virtual ArrayPtr tryGetReadBuffer() = 0; + // Like getReadBuffer() but may return an empty buffer on EOF. +}; + +class BufferedOutputStream: public OutputStream { + // An output stream which buffers some bytes in memory to reduce system call overhead. + // - OR - + // An output stream that actually writes into some in-memory data structure and wants to give its + // caller a direct pointer to that memory to potentially avoid a copy. + +public: + virtual ~BufferedOutputStream() noexcept(false); + + virtual ArrayPtr getWriteBuffer() = 0; + // Get a direct pointer into the write buffer. The caller may choose to fill in some prefix of + // this buffer and then pass it to write(), in which case write() may avoid a copy. It is + // incorrect to pass to write any slice of this buffer which is not a prefix. +}; + +// ======================================================================================= +// Buffered streams implemented as wrappers around regular streams + +class BufferedInputStreamWrapper: public BufferedInputStream { + // Implements BufferedInputStream in terms of an InputStream. + // + // Note that the underlying stream's position is unpredictable once the wrapper is destroyed, + // unless the entire stream was consumed. To read a predictable number of bytes in a buffered + // way without going over, you'd need this wrapper to wrap some other wrapper which itself + // implements an artificial EOF at the desired point. Such a stream should be trivial to write + // but is not provided by the library at this time. + +public: + explicit BufferedInputStreamWrapper(InputStream& inner, ArrayPtr buffer = nullptr); + // Creates a buffered stream wrapping the given non-buffered stream. No guarantee is made about + // the position of the inner stream after a buffered wrapper has been created unless the entire + // input is read. + // + // If the second parameter is non-null, the stream uses the given buffer instead of allocating + // its own. This may improve performance if the buffer can be reused. + + KJ_DISALLOW_COPY_AND_MOVE(BufferedInputStreamWrapper); + ~BufferedInputStreamWrapper() noexcept(false); + + // implements BufferedInputStream ---------------------------------- + ArrayPtr tryGetReadBuffer() override; + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + InputStream& inner; + Array ownedBuffer; + ArrayPtr buffer; + ArrayPtr bufferAvailable; +}; + +class BufferedOutputStreamWrapper: public BufferedOutputStream { + // Implements BufferedOutputStream in terms of an OutputStream. Note that writes to the + // underlying stream may be delayed until flush() is called or the wrapper is destroyed. + +public: + explicit BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr buffer = nullptr); + // Creates a buffered stream wrapping the given non-buffered stream. + // + // If the second parameter is non-null, the stream uses the given buffer instead of allocating + // its own. This may improve performance if the buffer can be reused. + + KJ_DISALLOW_COPY_AND_MOVE(BufferedOutputStreamWrapper); + ~BufferedOutputStreamWrapper() noexcept(false); + + void flush(); + // Force the wrapper to write any remaining bytes in its buffer to the inner stream. Note that + // this only flushes this object's buffer; this object has no idea how to flush any other buffers + // that may be present in the underlying stream. + + // implements BufferedOutputStream --------------------------------- + ArrayPtr getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + OutputStream& inner; + Array ownedBuffer; + ArrayPtr buffer; + byte* bufferPos; + UnwindDetector unwindDetector; +}; + +// ======================================================================================= +// Array I/O + +class ArrayInputStream: public BufferedInputStream { +public: + explicit ArrayInputStream(ArrayPtr array); + KJ_DISALLOW_COPY_AND_MOVE(ArrayInputStream); + ~ArrayInputStream() noexcept(false); + + // implements BufferedInputStream ---------------------------------- + ArrayPtr tryGetReadBuffer() override; + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + void skip(size_t bytes) override; + +private: + ArrayPtr array; +}; + +class ArrayOutputStream: public BufferedOutputStream { +public: + explicit ArrayOutputStream(ArrayPtr array); + KJ_DISALLOW_COPY_AND_MOVE(ArrayOutputStream); + ~ArrayOutputStream() noexcept(false); + + ArrayPtr getArray() { + // Get the portion of the array which has been filled in. + return arrayPtr(array.begin(), fillPos); + } + + // implements BufferedInputStream ---------------------------------- + ArrayPtr getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + ArrayPtr array; + byte* fillPos; +}; + +class VectorOutputStream: public BufferedOutputStream { +public: + explicit VectorOutputStream(size_t initialCapacity = 4096); + KJ_DISALLOW_COPY_AND_MOVE(VectorOutputStream); + ~VectorOutputStream() noexcept(false); + + ArrayPtr getArray() { + // Get the portion of the array which has been filled in. + return arrayPtr(vector.begin(), fillPos); + } + + void clear() { fillPos = vector.begin(); } + + // implements BufferedInputStream ---------------------------------- + ArrayPtr getWriteBuffer() override; + void write(const void* buffer, size_t size) override; + +private: + Array vector; + byte* fillPos; + + void grow(size_t minSize); +}; + +// ======================================================================================= +// File descriptor I/O + +class AutoCloseFd { + // A wrapper around a file descriptor which automatically closes the descriptor when destroyed. + // The wrapper supports move construction for transferring ownership of the descriptor. If + // close() returns an error, the destructor throws an exception, UNLESS the destructor is being + // called during unwind from another exception, in which case the close error is ignored. + // + // If your code is not exception-safe, you should not use AutoCloseFd. In this case you will + // have to call close() yourself and handle errors appropriately. + +public: + inline AutoCloseFd(): fd(-1) {} + inline AutoCloseFd(decltype(nullptr)): fd(-1) {} + inline explicit AutoCloseFd(int fd): fd(fd) {} + inline AutoCloseFd(AutoCloseFd&& other) noexcept: fd(other.fd) { other.fd = -1; } + KJ_DISALLOW_COPY(AutoCloseFd); + ~AutoCloseFd() noexcept(false); + + inline AutoCloseFd& operator=(AutoCloseFd&& other) { + AutoCloseFd old(kj::mv(*this)); + fd = other.fd; + other.fd = -1; + return *this; + } + + inline AutoCloseFd& operator=(decltype(nullptr)) { + AutoCloseFd old(kj::mv(*this)); + return *this; + } + + inline operator int() const { return fd; } + inline int get() const { return fd; } + + operator bool() const = delete; + // Deleting this operator prevents accidental use in boolean contexts, which + // the int conversion operator above would otherwise allow. + + inline bool operator==(decltype(nullptr)) { return fd < 0; } + inline bool operator!=(decltype(nullptr)) { return fd >= 0; } + + inline int release() { + // Release ownership of an FD. Not recommended. + int result = fd; + fd = -1; + return result; + } + +private: + int fd; +}; + +inline auto KJ_STRINGIFY(const AutoCloseFd& fd) + -> decltype(kj::toCharSequence(implicitCast(fd))) { + return kj::toCharSequence(implicitCast(fd)); +} + +class FdInputStream: public InputStream { + // An InputStream wrapping a file descriptor. + +public: + explicit FdInputStream(int fd): fd(fd) {} + explicit FdInputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} + KJ_DISALLOW_COPY_AND_MOVE(FdInputStream); + ~FdInputStream() noexcept(false); + + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + + inline int getFd() const { return fd; } + +private: + int fd; + AutoCloseFd autoclose; +}; + +class FdOutputStream: public OutputStream { + // An OutputStream wrapping a file descriptor. + +public: + explicit FdOutputStream(int fd): fd(fd) {} + explicit FdOutputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} + KJ_DISALLOW_COPY_AND_MOVE(FdOutputStream); + ~FdOutputStream() noexcept(false); + + void write(const void* buffer, size_t size) override; + void write(ArrayPtr> pieces) override; + + inline int getFd() const { return fd; } + +private: + int fd; + AutoCloseFd autoclose; +}; + +// ======================================================================================= +// Win32 Handle I/O + +#ifdef _WIN32 + +class AutoCloseHandle { + // A wrapper around a Win32 HANDLE which automatically closes the handle when destroyed. + // The wrapper supports move construction for transferring ownership of the handle. If + // CloseHandle() returns an error, the destructor throws an exception, UNLESS the destructor is + // being called during unwind from another exception, in which case the close error is ignored. + // + // If your code is not exception-safe, you should not use AutoCloseHandle. In this case you will + // have to call close() yourself and handle errors appropriately. + +public: + inline AutoCloseHandle(): handle((void*)-1) {} + inline AutoCloseHandle(decltype(nullptr)): handle((void*)-1) {} + inline explicit AutoCloseHandle(void* handle): handle(handle) {} + inline AutoCloseHandle(AutoCloseHandle&& other) noexcept: handle(other.handle) { + other.handle = (void*)-1; + } + KJ_DISALLOW_COPY(AutoCloseHandle); + ~AutoCloseHandle() noexcept(false); + + inline AutoCloseHandle& operator=(AutoCloseHandle&& other) { + AutoCloseHandle old(kj::mv(*this)); + handle = other.handle; + other.handle = (void*)-1; + return *this; + } + + inline AutoCloseHandle& operator=(decltype(nullptr)) { + AutoCloseHandle old(kj::mv(*this)); + return *this; + } + + inline operator void*() const { return handle; } + inline void* get() const { return handle; } + + operator bool() const = delete; + // Deleting this operator prevents accidental use in boolean contexts, which + // the void* conversion operator above would otherwise allow. + + inline bool operator==(decltype(nullptr)) { return handle != (void*)-1; } + inline bool operator!=(decltype(nullptr)) { return handle == (void*)-1; } + + inline void* release() { + // Release ownership of an FD. Not recommended. + void* result = handle; + handle = (void*)-1; + return result; + } + +private: + void* handle; // -1 (aka INVALID_HANDLE_VALUE) if not valid. +}; + +class HandleInputStream: public InputStream { + // An InputStream wrapping a Win32 HANDLE. + +public: + explicit HandleInputStream(void* handle): handle(handle) {} + explicit HandleInputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} + KJ_DISALLOW_COPY_AND_MOVE(HandleInputStream); + ~HandleInputStream() noexcept(false); + + size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; + +private: + void* handle; + AutoCloseHandle autoclose; +}; + +class HandleOutputStream: public OutputStream { + // An OutputStream wrapping a Win32 HANDLE. + +public: + explicit HandleOutputStream(void* handle): handle(handle) {} + explicit HandleOutputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} + KJ_DISALLOW_COPY_AND_MOVE(HandleOutputStream); + ~HandleOutputStream() noexcept(false); + + void write(const void* buffer, size_t size) override; + +private: + void* handle; + AutoCloseHandle autoclose; +}; + +#endif // _WIN32 + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/list.cc b/src/plugins/streamers/lstream/runtime/kj/kj/list.cc new file mode 100644 index 000000000..a7aa006c5 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/list.cc @@ -0,0 +1,46 @@ +// Copyright (c) 2021 Cloudflare, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "list.h" +#include "debug.h" + +namespace kj { +namespace _ { + +void throwDoubleAdd() { + kj::throwFatalException(KJ_EXCEPTION(FAILED, + "tried to add element to kj::List but the element is already in a list")); +} +void throwRemovedNotPresent() { + kj::throwFatalException(KJ_EXCEPTION(FAILED, + "tried to remove element from kj::List but the element is not in a list")); +} +void throwRemovedWrongList() { + kj::throwFatalException(KJ_EXCEPTION(FAILED, + "tried to remove element from kj::List but the element is in a different list")); +} +void throwDestroyedWhileInList() { + kj::throwFatalException(KJ_EXCEPTION(FAILED, + "destroyed object that is still in a kj::List")); +} + +} // namespace _ +} // namespace kj diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/list.h b/src/plugins/streamers/lstream/runtime/kj/kj/list.h new file mode 100644 index 000000000..4575b0f96 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/list.h @@ -0,0 +1,227 @@ +// Copyright (c) 2021 Cloudflare, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "common.h" + +KJ_BEGIN_HEADER + +namespace kj { + +template +class ListLink; + +template T::*link> +class ListIterator; + +namespace _ { // (private) + +KJ_NORETURN(void throwDoubleAdd()); +KJ_NORETURN(void throwRemovedNotPresent()); +KJ_NORETURN(void throwRemovedWrongList()); +KJ_NORETURN(void throwDestroyedWhileInList()); + +} // namespace _ (private) + +template T::*link> +class List { + // A linked list that does no memory allocation. + // + // The list contains elements of type T that are allocated elsewhere. An existing object of type + // T can be added to the list and removed again without doing any heap allocation. This is + // achieved by requiring that T contains a field of type ListLink. A pointer-to-member to + // this field is the second parameter to the `List` template. + // + // kj::List is ideally suited to situations where an object wants to be able to "add itself" to + // a list of objects waiting for a notification, with the ability to remove itself early if it + // wants to stop waiting. With traditional STL containers, these operations would require memory + // allocation. + // + // Example: + // + // struct Item { + // ListLink link; + // // ... other members ... + // }; + // + // kj::List itemList; + // + // Item foo; + // itemList.add(foo); + // itemList.remove(foo); + // + // Note that you MUST manually remove an element from the list before destroying it. ListLinks + // do not automatically unlink themselves because this could lead to subtle thread-safety bugs + // if the List is guarded by a mutex, and that mutex is not currently locked. Normally, you should + // have T's destructor remove it from any lists. You can use `link.isLinked()` to check if the + // item is currently in a list. + // + // kj::List is a doubly-linked list in order to allow O(1) removal of any element given only a + // reference to the element. However, it only supports forward iteration. + // + // When iterating over a kj::List, you can safely remove current element which the iterator + // points to without breaking the iteration. However, removing any *other* element could + // invalidate the iterator. + +public: + List() = default; + KJ_DISALLOW_COPY_AND_MOVE(List); + + bool empty() const { + return head == nullptr; + } + + size_t size() const { + return listSize; + } + + void add(T& element) { + if ((element.*link).prev != nullptr) _::throwDoubleAdd(); + *tail = element; + (element.*link).prev = tail; + tail = &((element.*link).next); + ++listSize; + } + + void addFront(T& element) { + if ((element.*link).prev != nullptr) _::throwDoubleAdd(); + (element.*link).next = head; + (element.*link).prev = &head; + KJ_IF_MAYBE(oldHead, head) { + (oldHead->*link).prev = &(element.*link).next; + } else { + tail = &(element.*link).next; + } + head = element; + ++listSize; + } + + void remove(T& element) { + if ((element.*link).prev == nullptr) _::throwRemovedNotPresent(); + *((element.*link).prev) = (element.*link).next; + KJ_IF_MAYBE(n, (element.*link).next) { + (n->*link).prev = (element.*link).prev; + } else { + if (tail != &((element.*link).next)) _::throwRemovedWrongList(); + tail = (element.*link).prev; + } + (element.*link).next = nullptr; + (element.*link).prev = nullptr; + --listSize; + } + + typedef ListIterator Iterator; + typedef ListIterator ConstIterator; + + Iterator begin() { return Iterator(head); } + Iterator end() { return Iterator(nullptr); } + ConstIterator begin() const { return ConstIterator(head); } + ConstIterator end() const { return ConstIterator(nullptr); } + + T& front() { return *begin(); } + const T& front() const { return *begin(); } + +private: + Maybe head; + Maybe* tail = &head; + size_t listSize = 0; +}; + +template +class ListLink { +public: + ListLink(): next(nullptr), prev(nullptr) {} + ~ListLink() noexcept { + // Intentionally `noexcept` because we want to crash if a dangling pointer was left in a list. + if (prev != nullptr) _::throwDestroyedWhileInList(); + } + KJ_DISALLOW_COPY_AND_MOVE(ListLink); + + bool isLinked() const { return prev != nullptr; } + +private: + Maybe next; + Maybe* prev; + + template U::*link> + friend class List; + template U::*link> + friend class ListIterator; +}; + +template T::*link> +class ListIterator { +public: + ListIterator() = default; + + MaybeConstT& operator*() { + KJ_IREQUIRE(current != nullptr, "tried to dereference end of list"); + return *_::readMaybe(current); + } + const T& operator*() const { + KJ_IREQUIRE(current != nullptr, "tried to dereference end of list"); + return *_::readMaybe(current); + } + MaybeConstT* operator->() { + KJ_IREQUIRE(current != nullptr, "tried to dereference end of list"); + return _::readMaybe(current); + } + const T* operator->() const { + KJ_IREQUIRE(current != nullptr, "tried to dereference end of list"); + return _::readMaybe(current); + } + + inline ListIterator& operator++() { + current = next; + next = current.map([](MaybeConstT& obj) -> kj::Maybe { return (obj.*link).next; }) + .orDefault(nullptr); + return *this; + } + inline ListIterator operator++(int) { + ListIterator result = *this; + ++*this; + return result; + } + + inline bool operator==(const ListIterator& other) const { + return _::readMaybe(current) == _::readMaybe(other.current); + } + inline bool operator!=(const ListIterator& other) const { + return _::readMaybe(current) != _::readMaybe(other.current); + } + +private: + Maybe current; + + Maybe next; + // so that the current item can be removed from the list without invalidating the iterator + + explicit ListIterator(Maybe start) + : current(start), + next(start.map([](MaybeConstT& obj) -> kj::Maybe { return (obj.*link).next; }) + .orDefault(nullptr)) {} + friend class List; +}; + +} // namespace kj + +KJ_END_HEADER diff --git a/src/plugins/streamers/lstream/runtime/kj/kj/main.cc b/src/plugins/streamers/lstream/runtime/kj/kj/main.cc new file mode 100644 index 000000000..6b980de94 --- /dev/null +++ b/src/plugins/streamers/lstream/runtime/kj/kj/main.cc @@ -0,0 +1,827 @@ +// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors +// Licensed under the MIT License: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#if _WIN32 +#include "win32-api-version.h" +#endif + +#include "main.h" +#include "debug.h" +#include "arena.h" +#include "miniposix.h" +#include +#include +#include +#include +#include + +#if _WIN32 +#include +#include "windows-sanity.h" +#else +#include +#endif + +namespace kj { + +// ======================================================================================= + +TopLevelProcessContext::TopLevelProcessContext(StringPtr programName) + : programName(programName), + cleanShutdown(getenv("KJ_CLEAN_SHUTDOWN") != nullptr) { + printStackTraceOnCrash(); +} + +StringPtr TopLevelProcessContext::getProgramName() { + return programName; +} + +void TopLevelProcessContext::exit() { + int exitCode = hadErrors ? 1 : 0; + if (cleanShutdown) { +#if KJ_NO_EXCEPTIONS + // This is the best we can do. + warning("warning: KJ_CLEAN_SHUTDOWN may not work correctly when compiled " + "with -fno-exceptions."); + ::exit(exitCode); +#else + throw CleanShutdownException { exitCode }; +#endif + } + _exit(exitCode); +} + +#if _WIN32 +void setStandardIoMode(int fd) { + // Set mode to binary if the fd is not a console. + HANDLE handle = reinterpret_cast(_get_osfhandle(fd)); + DWORD consoleMode; + if (GetConsoleMode(handle, &consoleMode)) { + // It's a console. + } else { + KJ_SYSCALL(_setmode(fd, _O_BINARY)); + } +} +#else +void setStandardIoMode(int fd) {} +#endif + +static void writeLineToFd(int fd, StringPtr message) { + // Write the given message to the given file descriptor with a trailing newline iff the message + // is non-empty and doesn't already have a trailing newline. We use writev() to do this in a + // single system call without any copying (OS permitting). + + if (message.size() == 0) { + return; + } + +#if _WIN32 + KJ_STACK_ARRAY(char, newlineExpansionBuffer, 2 * (message.size() + 1), 128, 512); + char* p = newlineExpansionBuffer.begin(); + for(char ch : message) { + if(ch == '\n') { + *(p++) = '\r'; + } + *(p++) = ch; + } + if(!message.endsWith("\n")) { + *(p++) = '\r'; + *(p++) = '\n'; + } + + size_t newlineExpandedSize = p - newlineExpansionBuffer.begin(); + + KJ_ASSERT(newlineExpandedSize <= newlineExpansionBuffer.size()); + + HANDLE handle = reinterpret_cast(_get_osfhandle(fd)); + DWORD consoleMode; + bool redirectedToFile = !GetConsoleMode(handle, &consoleMode); + + DWORD writtenSize; + if(redirectedToFile) { + WriteFile(handle, newlineExpansionBuffer.begin(), newlineExpandedSize, &writtenSize, nullptr); + } else { + KJ_STACK_ARRAY(wchar_t, buffer, newlineExpandedSize, 128, 512); + + size_t finalSize = MultiByteToWideChar( + CP_UTF8, + 0, + newlineExpansionBuffer.begin(), + newlineExpandedSize, + buffer.begin(), + buffer.size()); + + KJ_ASSERT(finalSize <= buffer.size()); + + WriteConsoleW(handle, buffer.begin(), finalSize, &writtenSize, nullptr); + } +#else + // Unfortunately the writev interface requires non-const pointers even though it won't modify + // the data. + struct iovec vec[2]; + vec[0].iov_base = const_cast(message.begin()); + vec[0].iov_len = message.size(); + vec[1].iov_base = const_cast("\n"); + vec[1].iov_len = 1; + + struct iovec* pos = vec; + + // Only use the second item in the vec if the message doesn't already end with \n. + uint count = message.endsWith("\n") ? 1 : 2; + + for (;;) { + ssize_t n = writev(fd, pos, count); + if (n < 0) { + if (errno == EINTR) { + continue; + } else { + // This function is meant for writing to stdout and stderr. If writes fail on those FDs + // there's not a whole lot we can reasonably do, so just ignore it. + return; + } + } + + // Update chunks to discard what was successfully written. + for (;;) { + if (count == 0) { + // Done writing. + return; + } else if (pos->iov_len <= implicitCast(n)) { + // Wrote this entire chunk. + n -= pos->iov_len; + ++pos; + --count; + } else { + // Wrote only part of this chunk. Adjust the pointer and then retry. + pos->iov_base = reinterpret_cast(pos->iov_base) + n; + pos->iov_len -= n; + break; + } + } + } +#endif +} + +void TopLevelProcessContext::warning(StringPtr message) { + writeLineToFd(STDERR_FILENO, message); +} + +void TopLevelProcessContext::error(StringPtr message) { + hadErrors = true; + writeLineToFd(STDERR_FILENO, message); +} + +void TopLevelProcessContext::exitError(StringPtr message) { + error(message); + exit(); +} + +void TopLevelProcessContext::exitInfo(StringPtr message) { + writeLineToFd(STDOUT_FILENO, message); + exit(); +} + +void TopLevelProcessContext::increaseLoggingVerbosity() { + // At the moment, there is only one log level that isn't enabled by default. + _::Debug::setLogLevel(_::Debug::Severity::INFO); +} + +// ======================================================================================= + +int runMainAndExit(ProcessContext& context, MainFunc&& func, int argc, char* argv[]) { + setStandardIoMode(STDIN_FILENO); + setStandardIoMode(STDOUT_FILENO); + setStandardIoMode(STDERR_FILENO); + +#if !KJ_NO_EXCEPTIONS + try { +#endif + KJ_ASSERT(argc > 0); + + KJ_STACK_ARRAY(StringPtr, params, argc - 1, 8, 32); + for (int i = 1; i < argc; i++) { + params[i - 1] = argv[i]; + } + + KJ_IF_MAYBE(exception, runCatchingExceptions([&]() { + func(argv[0], params); + })) { + context.error(str("*** Uncaught exception ***\n", *exception)); + } + context.exit(); +#if !KJ_NO_EXCEPTIONS + } catch (const TopLevelProcessContext::CleanShutdownException& e) { + return e.exitCode; + } +#endif + KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT +} + +// ======================================================================================= + +struct MainBuilder::Impl { + inline Impl(ProcessContext& context, StringPtr version, + StringPtr briefDescription, StringPtr extendedDescription) + : context(context), version(version), + briefDescription(briefDescription), extendedDescription(extendedDescription) {} + + ProcessContext& context; + StringPtr version; + StringPtr briefDescription; + StringPtr extendedDescription; + + Arena arena; + + struct CharArrayCompare { + inline bool operator()(const ArrayPtr& a, const ArrayPtr& b) const { + int cmp = memcmp(a.begin(), b.begin(), min(a.size(), b.size())); + if (cmp == 0) { + return a.size() < b.size(); + } else { + return cmp < 0; + } + } + }; + + struct Option { + ArrayPtr names; + bool hasArg; + union { + Function* func; + Function* funcWithArg; + }; + StringPtr argTitle; + StringPtr helpText; + }; + + class OptionDisplayOrder; + + std::map shortOptions; + std::map, Option*, CharArrayCompare> longOptions; + + struct SubCommand { + Function func; + StringPtr helpText; + }; + std::map subCommands; + + struct Arg { + StringPtr title; + Function callback; + uint minCount; + uint maxCount; + }; + + Vector args; + + Maybe> finalCallback; + + Option& addOption(std::initializer_list names, bool hasArg, StringPtr helpText) { + KJ_REQUIRE(names.size() > 0, "option must have at least one name"); + + Option& option = arena.allocate