diff options
author | nalpp <nalpp@yandex-team.ru> | 2022-02-10 16:46:45 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:45 +0300 |
commit | 87f3eb38999df2d3c1cb77f8ffb9c52ec9c516fb (patch) | |
tree | f4ab0734eecf35b22f21952d1aa15496f267a6a3 | |
parent | 198698b9c1e18958addc9682fbfba4576d604757 (diff) | |
download | ydb-87f3eb38999df2d3c1cb77f8ffb9c52ec9c516fb.tar.gz |
Restoring authorship annotation for <nalpp@yandex-team.ru>. Commit 1 of 2.
235 files changed, 29935 insertions, 29935 deletions
diff --git a/build/external_resources/codenavigation/ya.make b/build/external_resources/codenavigation/ya.make index 8cfdf0d3d5..aa0ab3ca22 100644 --- a/build/external_resources/codenavigation/ya.make +++ b/build/external_resources/codenavigation/ya.make @@ -1,14 +1,14 @@ OWNER(g:yatool) - -RESOURCES_LIBRARY() - + +RESOURCES_LIBRARY() + NO_CODENAVIGATION() -NO_RUNTIME() - -IF (OS_LINUX) +NO_RUNTIME() + +IF (OS_LINUX) DECLARE_EXTERNAL_RESOURCE(CPPYNDEXER sbr:2218884955) DECLARE_EXTERNAL_RESOURCE(PYNDEXER sbr:2112287762) DECLARE_EXTERNAL_RESOURCE(PY3YNDEXER sbr:2670411952) -ENDIF() - -END() +ENDIF() + +END() diff --git a/build/platform/clang/ya.make b/build/platform/clang/ya.make index 342b928637..cd74e2106e 100644 --- a/build/platform/clang/ya.make +++ b/build/platform/clang/ya.make @@ -1,4 +1,4 @@ -RESOURCES_LIBRARY() +RESOURCES_LIBRARY() LICENSE(BSD-3-Clause) diff --git a/build/platform/lld/ya.make b/build/platform/lld/ya.make index c046e89098..034457514a 100644 --- a/build/platform/lld/ya.make +++ b/build/platform/lld/ya.make @@ -1,4 +1,4 @@ -RESOURCES_LIBRARY() +RESOURCES_LIBRARY() LICENSE(Service-Prebuilt-Tool) diff --git a/build/plugins/_common.py b/build/plugins/_common.py index 2f831a94db..7a4753ced4 100644 --- a/build/plugins/_common.py +++ b/build/plugins/_common.py @@ -1,4 +1,4 @@ -import sys +import sys import hashlib import base64 @@ -165,26 +165,26 @@ def skip_build_root(x): return x -def get_interpreter_path(): - interpreter_path = [sys.executable] - if 'ymake' in interpreter_path[0]: - interpreter_path.append('--python') - return interpreter_path - - -def filter_out_by_keyword(test_data, keyword): - def _iterate(): - i = 0 - while i < len(test_data): - if test_data[i] == keyword: - i += 2 - else: - yield test_data[i] - i += 1 - - return list(_iterate()) - - +def get_interpreter_path(): + interpreter_path = [sys.executable] + if 'ymake' in interpreter_path[0]: + interpreter_path.append('--python') + return interpreter_path + + +def filter_out_by_keyword(test_data, keyword): + def _iterate(): + i = 0 + while i < len(test_data): + if test_data[i] == keyword: + i += 2 + else: + yield test_data[i] + i += 1 + + return list(_iterate()) + + def generate_chunks(lst, chunk_size): for i in xrange(0, len(lst), chunk_size): yield lst[i:(i + chunk_size)] diff --git a/build/plugins/_custom_command.py b/build/plugins/_custom_command.py index 9692214b22..e621a95c2b 100644 --- a/build/plugins/_custom_command.py +++ b/build/plugins/_custom_command.py @@ -61,5 +61,5 @@ def addrule(*unused): pass -def addparser(*unused, **kwargs): +def addparser(*unused, **kwargs): pass diff --git a/build/plugins/_unpickler.py b/build/plugins/_unpickler.py index e01e7b3118..3cc8da879d 100644 --- a/build/plugins/_unpickler.py +++ b/build/plugins/_unpickler.py @@ -9,9 +9,9 @@ try: except Exception: import pickle -import _common as common - +import _common as common + def main(): parser = argparse.ArgumentParser() parser.add_argument('--data', help='pickled object of TCustomCommand class', required=True) diff --git a/build/plugins/java.py b/build/plugins/java.py index 16fc126734..5d25f013c8 100644 --- a/build/plugins/java.py +++ b/build/plugins/java.py @@ -39,10 +39,10 @@ def on_run_jbuild_program(unit, *args): """ flat, kv = common.sort_by_keywords({'IN': -1, 'IN_DIR': -1, 'OUT': -1, 'OUT_DIR': -1, 'CWD': 1, 'CLASSPATH': -1, 'CP_USE_COMMAND_FILE': 1, 'ADD_SRCS_TO_CLASSPATH': 0}, args) - depends = kv.get('CLASSPATH', []) + kv.get('JAR', []) + depends = kv.get('CLASSPATH', []) + kv.get('JAR', []) fake_out = None - if depends: - # XXX: hack to force ymake to build dependencies + if depends: + # XXX: hack to force ymake to build dependencies fake_out = "fake.out.{}".format(hash(tuple(args))) unit.on_run_java(['TOOL'] + depends + ["OUT", fake_out]) diff --git a/build/plugins/macros_with_error.py b/build/plugins/macros_with_error.py index e82fb56d2c..ab2d532893 100644 --- a/build/plugins/macros_with_error.py +++ b/build/plugins/macros_with_error.py @@ -1,13 +1,13 @@ -import sys - +import sys + import _common - + import ymake -def onmacros_with_error(unit, *args): - print >> sys.stderr, 'This macros will fail' - raise Exception('Expected fail in MACROS_WITH_ERROR') +def onmacros_with_error(unit, *args): + print >> sys.stderr, 'This macros will fail' + raise Exception('Expected fail in MACROS_WITH_ERROR') def onrestrict_path(unit, *args): diff --git a/build/plugins/res.py b/build/plugins/res.py index a937caba81..532e299b95 100644 --- a/build/plugins/res.py +++ b/build/plugins/res.py @@ -1,4 +1,4 @@ -from _common import iterpair, listid, pathid, rootrel_arc_src, tobuilddir, filter_out_by_keyword +from _common import iterpair, listid, pathid, rootrel_arc_src, tobuilddir, filter_out_by_keyword def split(lst, limit): diff --git a/build/plugins/scarab_cant_clash.py b/build/plugins/scarab_cant_clash.py index 77dc303183..6431d056bf 100644 --- a/build/plugins/scarab_cant_clash.py +++ b/build/plugins/scarab_cant_clash.py @@ -17,10 +17,10 @@ def onacceleo(unit, *args): classpath = ['$SCARAB', ] # XXX special word for ya make to replace following paths with real classpath classpath.append('tools/acceleo') - depends = [] + depends = [] if not unit.get('IDE_MSVS_CALL'): for jar in classpath[1:]: - depends.append(jar) + depends.append(jar) classpath = ':'.join(classpath) @@ -60,7 +60,7 @@ def onacceleo(unit, *args): if kv.get(k): run_java += [k] + kv[k] - if depends: - run_java += ['TOOL'] + depends - + if depends: + run_java += ['TOOL'] + depends + unit.on_run_java(run_java) diff --git a/build/scripts/compile_cuda.py b/build/scripts/compile_cuda.py index c0bec50b2a..ebbaa9610e 100644 --- a/build/scripts/compile_cuda.py +++ b/build/scripts/compile_cuda.py @@ -60,8 +60,8 @@ def main(): skip_list.append('-nostdinc++') for flag in skip_list: - if flag in cflags: - cflags.remove(flag) + if flag in cflags: + cflags.remove(flag) skip_prefix_list = [ '-fsanitize=', diff --git a/build/scripts/coverage-info.py b/build/scripts/coverage-info.py index 94491d9256..f5452c893e 100644 --- a/build/scripts/coverage-info.py +++ b/build/scripts/coverage-info.py @@ -242,9 +242,9 @@ def main(source_root, output, gcno_archive, gcda_archive, gcov_tool, prefix_filt else: output_dir = output + '.dir' - if not os.path.exists(output_dir): - os.makedirs(output_dir) - + if not os.path.exists(output_dir): + os.makedirs(output_dir) + teamcity_stat_file = None if teamcity_stat_output: teamcity_stat_file = os.path.join(output_dir, 'teamcity.out') diff --git a/build/scripts/fetch_from_sandbox.py b/build/scripts/fetch_from_sandbox.py index a99542e174..a71259e45c 100755 --- a/build/scripts/fetch_from_sandbox.py +++ b/build/scripts/fetch_from_sandbox.py @@ -31,14 +31,14 @@ class ResourceInfoError(Exception): pass -class UnsupportedProtocolException(Exception): - pass - - +class UnsupportedProtocolException(Exception): + pass + + def _sky_path(): return "/usr/local/bin/sky" - - + + def _is_skynet_avaliable(): if not os.path.exists(_sky_path()): return False @@ -52,28 +52,28 @@ def _is_skynet_avaliable(): def download_by_skynet(resource_info, file_name): - def sky_get(skynet_id, target_dir, timeout=None): + def sky_get(skynet_id, target_dir, timeout=None): cmd_args = [_sky_path(), 'get', "-N", "Backbone", "--user", "--wait", "--dir", target_dir, skynet_id] - if timeout is not None: - cmd_args += ["--timeout", str(timeout)] + if timeout is not None: + cmd_args += ["--timeout", str(timeout)] logging.info('Call skynet with args: %s', cmd_args) - stdout = subprocess.check_output(cmd_args).strip() - logging.debug('Skynet call with args %s is finished, result is %s', cmd_args, stdout) - return stdout - + stdout = subprocess.check_output(cmd_args).strip() + logging.debug('Skynet call with args %s is finished, result is %s', cmd_args, stdout) + return stdout + if not _is_skynet_avaliable(): - raise UnsupportedProtocolException("Skynet is not available") - - skynet_id = resource_info.get("skynet_id") - if not skynet_id: - raise ValueError("Resource does not have skynet_id") - + raise UnsupportedProtocolException("Skynet is not available") + + skynet_id = resource_info.get("skynet_id") + if not skynet_id: + raise ValueError("Resource does not have skynet_id") + temp_dir = os.path.abspath(fetch_from.uniq_string_generator()) - os.mkdir(temp_dir) - sky_get(skynet_id, temp_dir) - return os.path.join(temp_dir, file_name) - - + os.mkdir(temp_dir) + sky_get(skynet_id, temp_dir) + return os.path.join(temp_dir, file_name) + + def _urlopen(url, data=None, headers=None): n = 10 tout = 30 @@ -154,11 +154,11 @@ def fetch(resource_id, custom_fetcher): mds_id = resource_info.get('attributes', {}).get('mds') mds_link = MDS_PREFIX + mds_id if mds_id else None - def get_storage_links(): - storage_links = get_resource_http_links(resource_id) - random.shuffle(storage_links) - return storage_links - + def get_storage_links(): + storage_links = get_resource_http_links(resource_id) + random.shuffle(storage_links) + return storage_links + skynet = _is_skynet_avaliable() if not skynet: @@ -173,7 +173,7 @@ def fetch(resource_id, custom_fetcher): # Don't try too hard here: we will get back to proxy later on yield lambda: fetch_from.fetch_url(proxy_link, False, resource_file_name, expected_md5, tries=2) - for x in get_storage_links(): + for x in get_storage_links(): # Don't spend too much time connecting single host yield lambda: fetch_from.fetch_url(x, False, resource_file_name, expected_md5, tries=1) if mds_link is not None: diff --git a/build/scripts/move.py b/build/scripts/move.py index 3f611fbc2e..d710c493cd 100644 --- a/build/scripts/move.py +++ b/build/scripts/move.py @@ -1,15 +1,15 @@ -import os -import sys - -# /script/move.py <src-1> <tgt-1> <src-2> <tgt-2> ... <src-n> <tgt-n> -# renames src-1 to tgt-1, src-2 to tgt-2, ..., src-n to tgt-n. - - -def main(): - assert len(sys.argv) % 2 == 1 - for index in range(1, len(sys.argv), 2): - os.rename(sys.argv[index], sys.argv[index + 1]) - - -if __name__ == '__main__': - main() +import os +import sys + +# /script/move.py <src-1> <tgt-1> <src-2> <tgt-2> ... <src-n> <tgt-n> +# renames src-1 to tgt-1, src-2 to tgt-2, ..., src-n to tgt-n. + + +def main(): + assert len(sys.argv) % 2 == 1 + for index in range(1, len(sys.argv), 2): + os.rename(sys.argv[index], sys.argv[index + 1]) + + +if __name__ == '__main__': + main() diff --git a/build/scripts/python_yndexer.py b/build/scripts/python_yndexer.py index 3180665387..2ffcb104f4 100644 --- a/build/scripts/python_yndexer.py +++ b/build/scripts/python_yndexer.py @@ -1,53 +1,53 @@ -import os -import sys -import threading -import subprocess - - -def _try_to_kill(process): - try: - process.kill() - except Exception: - pass - - -def touch(path): - if not os.path.exists(path): - with open(path, 'w') as _: - pass - - -class Process(object): - def __init__(self, args): - self._process = subprocess.Popen(args) - self._event = threading.Event() - self._result = None - thread = threading.Thread(target=self._run) - thread.setDaemon(True) - thread.start() - - def _run(self): - self._process.communicate() - self._result = self._process.returncode - self._event.set() - - def wait(self, timeout): - self._event.wait(timeout=timeout) - _try_to_kill(self._process) - return self._result - - -if __name__ == '__main__': - yndexer = sys.argv[1] - timeout = int(sys.argv[2]) - output_file = sys.argv[3] - input_file = sys.argv[4] +import os +import sys +import threading +import subprocess + + +def _try_to_kill(process): + try: + process.kill() + except Exception: + pass + + +def touch(path): + if not os.path.exists(path): + with open(path, 'w') as _: + pass + + +class Process(object): + def __init__(self, args): + self._process = subprocess.Popen(args) + self._event = threading.Event() + self._result = None + thread = threading.Thread(target=self._run) + thread.setDaemon(True) + thread.start() + + def _run(self): + self._process.communicate() + self._result = self._process.returncode + self._event.set() + + def wait(self, timeout): + self._event.wait(timeout=timeout) + _try_to_kill(self._process) + return self._result + + +if __name__ == '__main__': + yndexer = sys.argv[1] + timeout = int(sys.argv[2]) + output_file = sys.argv[3] + input_file = sys.argv[4] partition_count = sys.argv[5] partition_index = sys.argv[6] - + process = Process([yndexer, '-f', input_file, '-y', output_file, '-c', partition_count, '-i', partition_index]) - result = process.wait(timeout=timeout) - - if result != 0: - print >> sys.stderr, 'Yndexing process finished with code', result - touch(output_file) + result = process.wait(timeout=timeout) + + if result != 0: + print >> sys.stderr, 'Yndexing process finished with code', result + touch(output_file) diff --git a/build/scripts/run_msvc_wine.py b/build/scripts/run_msvc_wine.py index 439d1f8831..885f6250db 100644 --- a/build/scripts/run_msvc_wine.py +++ b/build/scripts/run_msvc_wine.py @@ -470,7 +470,7 @@ def run_main(): 'tout': tout } - slave_cmd = [sys.executable, sys.argv[0], wine, 'slave', json.dumps(args)] + slave_cmd = [sys.executable, sys.argv[0], wine, 'slave', json.dumps(args)] p = run_subprocess(slave_cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False) out, _ = p.communicate() return p.wait(), out diff --git a/build/scripts/yndexer.py b/build/scripts/yndexer.py index a38e28ba99..007724d9a3 100644 --- a/build/scripts/yndexer.py +++ b/build/scripts/yndexer.py @@ -1,56 +1,56 @@ import sys import subprocess -import threading +import threading import os import re - + rx_resource_dir = re.compile(r'libraries: =([^:]*)') - -def _try_to_kill(process): - try: - process.kill() - except Exception: - pass - - -def touch(path): - if not os.path.exists(path): + +def _try_to_kill(process): + try: + process.kill() + except Exception: + pass + + +def touch(path): + if not os.path.exists(path): with open(path, 'w'): - pass - - -class Process(object): - def __init__(self, args): - self._process = subprocess.Popen(args) - self._event = threading.Event() - self._result = None - thread = threading.Thread(target=self._run) - thread.setDaemon(True) - thread.start() - - def _run(self): - self._process.communicate() - self._result = self._process.returncode - self._event.set() - - def wait(self, timeout): - self._event.wait(timeout=timeout) - _try_to_kill(self._process) - return self._result - - + pass + + +class Process(object): + def __init__(self, args): + self._process = subprocess.Popen(args) + self._event = threading.Event() + self._result = None + thread = threading.Thread(target=self._run) + thread.setDaemon(True) + thread.start() + + def _run(self): + self._process.communicate() + self._result = self._process.returncode + self._event.set() + + def wait(self, timeout): + self._event.wait(timeout=timeout) + _try_to_kill(self._process) + return self._result + + if __name__ == '__main__': args = sys.argv yndexer = args[1] - timeout = int(args[2]) - arc_root = args[3] - build_root = args[4] - input_file = args[5] - output_file = args[-1] - tail_args = args[6:-1] + timeout = int(args[2]) + arc_root = args[3] + build_root = args[4] + input_file = args[5] + output_file = args[-1] + tail_args = args[6:-1] subprocess.check_call(tail_args) @@ -71,9 +71,9 @@ if __name__ == '__main__': '-resource-dir', resource_dir, ] - process = Process(yndexer_args) - result = process.wait(timeout=timeout) - - if result != 0: - print >> sys.stderr, 'Yndexing process finished with code', result - touch(output_file) + process = Process(yndexer_args) + result = process.wait(timeout=timeout) + + if result != 0: + print >> sys.stderr, 'Yndexing process finished with code', result + touch(output_file) diff --git a/build/ya.conf.json b/build/ya.conf.json index 5f7cc875d6..4fed90c539 100644 --- a/build/ya.conf.json +++ b/build/ya.conf.json @@ -2788,13 +2788,13 @@ } ] }, - "python": { - "tools": { + "python": { + "tools": { "python": { "bottle": "python", "executable": "python" } - }, + }, "platforms": [ { "host": { @@ -2836,7 +2836,7 @@ "default": true } ] - }, + }, "ipython": { "tools": { "ipython": { @@ -2963,14 +2963,14 @@ } ] }, - "yndexer": { - "tools": { + "yndexer": { + "tools": { "yndexer": { "bottle": "yndexer", "executable": "yndexer" } - }, - "platforms": [ + }, + "platforms": [ { "host": { "os": "LINUX" @@ -2983,16 +2983,16 @@ }, "default": true } - ] - }, - "ytyndexer": { - "tools": { + ] + }, + "ytyndexer": { + "tools": { "ytyndexer": { "bottle": "ytyndexer", "executable": "ytyndexer" } - }, - "platforms": [ + }, + "platforms": [ { "host": { "os": "LINUX" @@ -3005,8 +3005,8 @@ }, "default": true } - ] - }, + ] + }, "ymakeyndexer": { "tools": { "ymakeyndexer": { @@ -3165,8 +3165,8 @@ } ] }, - "jdk": { - "tools": { + "jdk": { + "tools": { "javac": { "bottle": "jdk", "executable": "javac" @@ -3179,7 +3179,7 @@ "bottle": "jdk", "executable": "jar" } - }, + }, "platforms": [ { "host": { @@ -3200,7 +3200,7 @@ "default": true } ] - }, + }, "jdk10": { "tools": { "javac10": { @@ -5933,17 +5933,17 @@ ] } }, - "python": { - "formula": { + "python": { + "formula": { "sandbox_id": 981577320, - "match": "Python" - }, - "executable": { + "match": "Python" + }, + "executable": { "python": [ "python" ] - } - }, + } + }, "bloat": { "formula": { "sandbox_id": [ @@ -5957,17 +5957,17 @@ ] } }, - "jdk": { - "formula": { + "jdk": { + "formula": { "sandbox_id": [ 854293674, 854378931, 854302209, 1054292521 ], - "match": "jdk" - }, - "executable": { + "match": "jdk" + }, + "executable": { "javac": [ "bin", "javac" @@ -5980,8 +5980,8 @@ "bin", "jar" ] - } - }, + } + }, "jdk10": { "formula": { "sandbox_id": [ @@ -6532,28 +6532,28 @@ ] } }, - "yndexer": { - "formula": { + "yndexer": { + "formula": { "sandbox_id": 992600186, - "match": "YNDEXER" - }, - "executable": { + "match": "YNDEXER" + }, + "executable": { "yndexer": [ "yndexer" ] - } - }, - "ytyndexer": { - "formula": { + } + }, + "ytyndexer": { + "formula": { "sandbox_id": 1051903185, - "match": "YTYNDEXER" - }, - "executable": { + "match": "YTYNDEXER" + }, + "executable": { "ytyndexer": [ "ytyndexer" ] - } - }, + } + }, "ymakeyndexer": { "formula": { "sandbox_id": 239256113, @@ -6770,7 +6770,7 @@ }, "ag": { "formula": { - "sandbox_id": 75851513, + "sandbox_id": 75851513, "match": "Ag" }, "executable": { @@ -7071,17 +7071,17 @@ ] } }, - "kwmktorrent": { - "formula": { + "kwmktorrent": { + "formula": { "sandbox_id": 451506451, - "match": "KWMKTorrent" - }, - "executable": { + "match": "KWMKTorrent" + }, + "executable": { "kwmktorrent": [ "kwmktorrent" ] - } - }, + } + }, "kwmqbuild": { "formula": { "sandbox_id": 41067877, @@ -7095,8 +7095,8 @@ }, "gpt": { "formula": { - "sandbox_id": 21836503, - "match": "GooglePerformanceTools" + "sandbox_id": 21836503, + "match": "GooglePerformanceTools" } }, "ant": { diff --git a/build/ymake.core.conf b/build/ymake.core.conf index 081833998b..af41461307 100644 --- a/build/ymake.core.conf +++ b/build/ymake.core.conf @@ -113,13 +113,13 @@ otherwise { # tag:codenav when ($CODENAVIGATION && $NOCODENAVIGATION != "yes") { PY_PROGRAM_LINK_EXE=$LINK_EXE ${kv;hide:"pyndex $TARGET"} - YNDEXER_ARGS=$YMAKE_PYTHON ${input:"build/scripts/yndexer.py"} $CPPYNDEXER_RESOURCE_GLOBAL/yndexer 1500 $(SOURCE_ROOT) $ARCADIA_BUILD_ROOT ${input:SRC} + YNDEXER_ARGS=$YMAKE_PYTHON ${input:"build/scripts/yndexer.py"} $CPPYNDEXER_RESOURCE_GLOBAL/yndexer 1500 $(SOURCE_ROOT) $ARCADIA_BUILD_ROOT ${input:SRC} YNDEXER_OUTPUT=${output;noauto;suf=${OBJ_CROSS_SUF}.ydx.pb2:SRC} } otherwise { PY_PROGRAM_LINK_EXE=$LINK_EXE YNDEXER_ARGS= - YNDEXER_OUTPUT= + YNDEXER_OUTPUT= } COVERAGE_FLAGS= @@ -1304,10 +1304,10 @@ module _BASE_UNIT: _BARE_UNIT { CXXFLAGS += -nostdinc++ } - when ($CODENAVIGATION && $NOCODENAVIGATION != "yes") { - PEERDIR += build/external_resources/codenavigation - } - + when ($CODENAVIGATION && $NOCODENAVIGATION != "yes") { + PEERDIR += build/external_resources/codenavigation + } + when ($CYTHON_COVERAGE && $CYTHON_COVERAGE == "yes") { CFLAGS+=-DCYTHON_TRACE=1 -DCYTHON_TRACE_NOGIL=1 } @@ -1805,8 +1805,8 @@ module PYCR_PROGRAM: PY3_PROGRAM_BIN { ### @see: [DLL](#module_DLL) macro EXPORTS_SCRIPT(Arg) { SET(EXPORTS_FILE $Arg) -} - +} + ### @usage: NO_EXPORT_DYNAMIC_SYMBOLS() ### ### Disable exporting all non-hidden symbols as dynamic when linking a PROGRAM. @@ -1903,7 +1903,7 @@ USE_AFL=no ### ### Documentation: https://wiki.yandex-team.ru/yatool/fuzzing/ module FUZZ: _BASE_PROGRAM { - .NODE_TYPE=Program + .NODE_TYPE=Program .FINAL_TARGET=no .ALLOWED=FUZZ_DICTS FUZZ_OPTS @@ -1947,7 +1947,7 @@ otherwise { ### As with entire boost library usage of this technology is deprecated in Arcadia and restricted with configuration error in most of projects. ### No new module of this type should be introduced unless it is explicitly approved by C++ committee. module BOOSTTEST: _BASE_PROGRAM { - .NODE_TYPE=Program + .NODE_TYPE=Program .FINAL_TARGET=no .CMD=LINK_BOOSTTEST_CMD PEERDIR(library/cpp/testing/boost_test) @@ -2016,7 +2016,7 @@ macro YT_SPEC(Data...) { } # tag:test -TEST_SRCS_VALUE= +TEST_SRCS_VALUE= ### @usage: TEST_SRCS(Files...) ### ### In PY2TEST, PY3TEST and PY*_LIBRARY modules used as PY_SRCS macro and additionally used to mine test cases to be executed by testing framework. @@ -2031,7 +2031,7 @@ macro DISABLE_DATA_VALIDATION() { } # tag:test -TEST_DATA_VALUE= +TEST_DATA_VALUE= ### @usage: DATA([path...]) ### ### Specifies the path to the data necessary test. @@ -2047,7 +2047,7 @@ macro DATA(Data...) { } # tag:test -TEST_TAGS_VALUE= +TEST_TAGS_VALUE= ### @usage: TAG ([tag...]) ### ### Each test can have one or more tags used to filter tests list for running. @@ -2059,7 +2059,7 @@ macro TAG(Tags...) { } # tag:test -TEST_REQUIREMENTS_VALUE= +TEST_REQUIREMENTS_VALUE= ### @usage: REQUIREMENTS([cpu:<count>] [disk_usage:<size>] [ram:<size>] [ram_disk:<size>] [container:<id>] [network:<restricted|full>] [dns:dns64]) ### ### Allows you to specify the requirements of the test. @@ -2098,7 +2098,7 @@ macro USE_RECIPE(Data...) { } # tag:python-specific tag:test -TEST_PYTHON_PATH_VALUE= +TEST_PYTHON_PATH_VALUE= # tag:python-specific tag:test ### @usage: PYTHON_PATH(Path) @@ -2146,7 +2146,7 @@ macro NO_DOCTESTS() { ### ### Base logic of Python 2.x py.test modules: common module properties and dependencies. module _BASE_PYTEST: _BASE_PY_PROGRAM { - .NODE_TYPE=Program + .NODE_TYPE=Program .FINAL_TARGET=no .ALLOWED=YT_SPEC NO_DOCTESTS when ($USE_ARCADIA_PYTHON == "yes") { @@ -2165,7 +2165,7 @@ module _BASE_PYTEST: _BASE_PY_PROGRAM { ### ### Same as PY2TEST. Don't use this, use PY2TEST instead. module PYTEST_BIN: _BASE_PYTEST { - .NODE_TYPE=Program + .NODE_TYPE=Program SETUP_PYTEST_BIN() } @@ -2253,7 +2253,7 @@ macro STYLE(Globs...) { ### ### Documentation about the Arcadia test system: https://wiki.yandex-team.ru/yatool/test/ module GTEST_UGLY: _BASE_PROGRAM { - .NODE_TYPE=Program + .NODE_TYPE=Program .FINAL_TARGET=no PEERDIR(contrib/restricted/googletest/googlemock contrib/restricted/googletest/googletest) ADD_YTEST($MODULE_PREFIX$REALPRJNAME gtest) @@ -2287,7 +2287,7 @@ module GTEST_UGLY: _BASE_PROGRAM { ### ### @see: [RUN()](#macro_RUN) module EXECTEST: _BARE_UNIT { - .NODE_TYPE=Program + .NODE_TYPE=Program .FINAL_TARGET=no .ALLOWED=YT_SPEC .RESTRICTED=FORK_TEST_FILES @@ -2496,10 +2496,10 @@ macro _CONDITIONAL_SRCS(USE_CONDITIONAL_SRCS[], DYMMY...) { SRCS($USE_CONDITIONAL_SRCS) } -# XXX: dirty hack for correct LDFLAGS passing +# XXX: dirty hack for correct LDFLAGS passing RESOURCES_LIBRARY_LINK=$TOUCH_UNIT ${hide:LDFLAGS_GLOBAL} ${hide:LDFLAGS} RESOURCES_LIBRARY_SEM=ignored - + ### @usage: RESOURCES_LIBRARY() ### ### Definition of a module that brings its content from external source (Sandbox) via DECLARE_EXTERNAL_RESOURCE macro. @@ -2507,7 +2507,7 @@ RESOURCES_LIBRARY_SEM=ignored ### ### @see: [DECLARE_EXTERNAL_RESOURCE()](#macro_DECLARE_EXTERNAL_RESOURCE) module RESOURCES_LIBRARY: _BARE_UNIT { - .CMD=RESOURCES_LIBRARY_LINK + .CMD=RESOURCES_LIBRARY_LINK .SEM=RESOURCES_LIBRARY_SEM .ALLOWED=DECLARE_EXTERNAL_RESOURCE EXTRALIBS OBJADDE_GLOBAL .RESTRICTED=ALLOCATOR SIZE TAG DATA TEST_DATA DEPENDS FORK_TESTS FORK_SUBTESTS SPLIT_FACTOR TEST_CWD RUN TIMEOUT SRC SRCS PEERDIR SPLIT_DWARF @@ -2515,12 +2515,12 @@ module RESOURCES_LIBRARY: _BARE_UNIT { .PEERDIR_POLICY=as_include .EXTS=.o .obj .a .mf .supp .tidyjson .ld .GLOBAL=USER_CFLAGS USER_CXXFLAGS USER_CONLYFLAGS LDFLAGS _WHOLE_ARCHIVE_LIBS_VALUE RPATH - + MODULE_SUFFIX=.pkg.fake ENABLE(NEED_ADD_FAKE_SRC) WITHOUT_LICENSE_TEXTS() -} - +} + FAT_OBJECT_ARGS= FAT_OBJECT_OUTS= @@ -4108,7 +4108,7 @@ module PY3_LIBRARY: _PY3_LIBRARY { ### ### Documentation: https://wiki.yandex-team.ru/devtools/commandsandvars/py_srcs/ module _BASE_PY_PROGRAM: _BASE_PROGRAM { - .CMD=PY_PROGRAM_LINK_EXE + .CMD=PY_PROGRAM_LINK_EXE _ARCADIA_PYTHON_ADDINCL() when ($SANITIZER_TYPE && $SANITIZER_TYPE != "no") { @@ -6641,18 +6641,18 @@ macro NO_WSHADOW() { ### @usage: NO_PLATFORM_RESOURCES() # internal ### Exclude dependency on platform resources libraries. ### Most probably you'll never need this. If you think you need, please contact devtools@ for assistance. -macro NO_PLATFORM_RESOURCES() { - ENABLE(NOPLATFORM_RESOURCES) -} - +macro NO_PLATFORM_RESOURCES() { + ENABLE(NOPLATFORM_RESOURCES) +} + # tag:internal tag:codenav ### @usage: NO_CODENAVIGATION() # internal ### Disable codenaviagtion for a module. Needed to avoid PEERDIR loops in codenavigation support. ### Most probably you'll never need this. If you think you need, please contact devtools@ for assistance. -macro NO_CODENAVIGATION() { - ENABLE(NOCODENAVIGATION) -} - +macro NO_CODENAVIGATION() { + ENABLE(NOCODENAVIGATION) +} + ### @usage: NO_UTIL() ### Build module without dependency on util. ### Note: use this with care. Util most likely will be linked into executable anyway, diff --git a/build/ymake_conf.py b/build/ymake_conf.py index 30219eb85e..7593aefdfd 100755 --- a/build/ymake_conf.py +++ b/build/ymake_conf.py @@ -163,8 +163,8 @@ class Platform(object): )) @property - def library_path_variables(self): - return ['LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH'] + def library_path_variables(self): + return ['LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH'] def find_in_dict(self, dict_, default=None): if dict_ is None: @@ -266,7 +266,7 @@ def to_strings(o): def emit(key, *value): print('{0}={1}'.format(key, ' '.join(to_strings(value)))) - + def emit_with_comment(comment, key, *value): print('# {}'.format(comment)) @@ -520,13 +520,13 @@ class Build(object): if self.build_system == 'distbuild': emit('DISTBUILD', 'yes') - elif self.build_system != 'ymake': + elif self.build_system != 'ymake': raise ConfigureError() - python_bin = preset('BUILD_PYTHON_BIN', '$(PYTHON)/python') - - emit('YMAKE_PYTHON', python_bin) - emit('YMAKE_UNPICKLER', python_bin, '$ARCADIA_ROOT/build/plugins/_unpickler.py') + python_bin = preset('BUILD_PYTHON_BIN', '$(PYTHON)/python') + + emit('YMAKE_PYTHON', python_bin) + emit('YMAKE_UNPICKLER', python_bin, '$ARCADIA_ROOT/build/plugins/_unpickler.py') @property def is_release(self): @@ -1291,7 +1291,7 @@ class GnuToolchain(Toolchain): self.platform_projects.append(project) self.c_flags_platform.append('-B{}/{}'.format(var, bin)) if ldlibs: - for lib_path in self.build.host.library_path_variables: + for lib_path in self.build.host.library_path_variables: self.env.setdefault(lib_path, []).append('{}/{}'.format(var, ldlibs)) def print_toolchain(self): @@ -2566,7 +2566,7 @@ class MSVCCompiler(MSVC, Compiler): emit('DEBUG_INFO_FLAGS', debug_info_flags) append('C_WARNING_OPTS', c_warnings) append('CXX_WARNING_OPTS', cxx_warnings) - + if self.build.is_release: emit('CFLAGS_PER_TYPE', '$CFLAGS_RELEASE') if self.build.is_debug: diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonSerializableWebServiceRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonSerializableWebServiceRequest.h index 2ba298546e..83babb5b72 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonSerializableWebServiceRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonSerializableWebServiceRequest.h @@ -2,55 +2,55 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/AmazonWebServiceRequest.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/UnreferencedParam.h> -#include <aws/core/http/HttpTypes.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> - -namespace Aws -{ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/AmazonWebServiceRequest.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/UnreferencedParam.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> + +namespace Aws +{ static const char JSON_CONTENT_TYPE[] = "application/json"; static const char AMZN_JSON_CONTENT_TYPE_1_0[] = "application/x-amz-json-1.0"; static const char AMZN_JSON_CONTENT_TYPE_1_1[] = "application/x-amz-json-1.1"; static const char FORM_CONTENT_TYPE[] = "application/x-www-form-urlencoded"; static const char AMZN_XML_CONTENT_TYPE[] = "application/xml"; static const char AMZN_EVENTSTREAM_CONTENT_TYPE[] = "application/vnd.amazon.eventstream"; - - /** - * High-level abstraction over AWS requests. GetBody() calls SerializePayload() and uses a stringbuf under the hood. - * This is for payloads such as query, xml, or json - */ - class AWS_CORE_API AmazonSerializableWebServiceRequest : public AmazonWebServiceRequest - { - public: - AmazonSerializableWebServiceRequest() - { - //prevent unreferenced var warnings - //for these values. - AWS_UNREFERENCED_PARAM(JSON_CONTENT_TYPE); - AWS_UNREFERENCED_PARAM(AMZN_JSON_CONTENT_TYPE_1_0); - AWS_UNREFERENCED_PARAM(AMZN_JSON_CONTENT_TYPE_1_1); - AWS_UNREFERENCED_PARAM(FORM_CONTENT_TYPE); - AWS_UNREFERENCED_PARAM(AMZN_XML_CONTENT_TYPE); - } - - virtual ~AmazonSerializableWebServiceRequest() {} - - /** - * Convert payload into String. - */ - virtual Aws::String SerializePayload() const = 0; - - /** - * Loads serialized payload into string buf and returns the stream - */ - std::shared_ptr<Aws::IOStream> GetBody() const override; - }; - -} // namespace Aws - + + /** + * High-level abstraction over AWS requests. GetBody() calls SerializePayload() and uses a stringbuf under the hood. + * This is for payloads such as query, xml, or json + */ + class AWS_CORE_API AmazonSerializableWebServiceRequest : public AmazonWebServiceRequest + { + public: + AmazonSerializableWebServiceRequest() + { + //prevent unreferenced var warnings + //for these values. + AWS_UNREFERENCED_PARAM(JSON_CONTENT_TYPE); + AWS_UNREFERENCED_PARAM(AMZN_JSON_CONTENT_TYPE_1_0); + AWS_UNREFERENCED_PARAM(AMZN_JSON_CONTENT_TYPE_1_1); + AWS_UNREFERENCED_PARAM(FORM_CONTENT_TYPE); + AWS_UNREFERENCED_PARAM(AMZN_XML_CONTENT_TYPE); + } + + virtual ~AmazonSerializableWebServiceRequest() {} + + /** + * Convert payload into String. + */ + virtual Aws::String SerializePayload() const = 0; + + /** + * Loads serialized payload into string buf and returns the stream + */ + std::shared_ptr<Aws::IOStream> GetBody() const override; + }; + +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonStreamingWebServiceRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonStreamingWebServiceRequest.h index c267d06aaf..a8261d7c38 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonStreamingWebServiceRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonStreamingWebServiceRequest.h @@ -2,82 +2,82 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/UnreferencedParam.h> -#include <aws/core/http/HttpTypes.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/AmazonWebServiceRequest.h> - -namespace Aws -{ - static const char* DEFAULT_CONTENT_TYPE = "binary/octet-stream"; - - /** - * High-level abstraction over AWS requests that don't have well formed payloads. GetBody() uses an underlying stream that has been set by a call to SetBody() - * Also supports request specific headers such as in rest protocols. - */ - class AWS_CORE_API AmazonStreamingWebServiceRequest : public AmazonWebServiceRequest - { - public: - /** - * Initializes members to defaults - */ - AmazonStreamingWebServiceRequest() : m_contentType(DEFAULT_CONTENT_TYPE) - { - } - - virtual ~AmazonStreamingWebServiceRequest(); - - /** - * Get the user set stream - */ - inline std::shared_ptr<Aws::IOStream> GetBody() const override { return m_bodyStream; } - /** - * Set the body stream to use for the request. - */ - inline void SetBody(const std::shared_ptr<Aws::IOStream>& body) { m_bodyStream = body; } - /** - * Gets all headers that will be needed in the request. Calls GetRequestSpecificHeaders(), which is the chance for subclasses to add - * headers from their modeled data. - */ - inline Aws::Http::HeaderValueCollection GetHeaders() const override - { - auto headers = GetRequestSpecificHeaders(); - headers.insert(Aws::Http::HeaderValuePair(Aws::Http::CONTENT_TYPE_HEADER, GetContentType())); - - return headers; - } - - /** + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/UnreferencedParam.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/AmazonWebServiceRequest.h> + +namespace Aws +{ + static const char* DEFAULT_CONTENT_TYPE = "binary/octet-stream"; + + /** + * High-level abstraction over AWS requests that don't have well formed payloads. GetBody() uses an underlying stream that has been set by a call to SetBody() + * Also supports request specific headers such as in rest protocols. + */ + class AWS_CORE_API AmazonStreamingWebServiceRequest : public AmazonWebServiceRequest + { + public: + /** + * Initializes members to defaults + */ + AmazonStreamingWebServiceRequest() : m_contentType(DEFAULT_CONTENT_TYPE) + { + } + + virtual ~AmazonStreamingWebServiceRequest(); + + /** + * Get the user set stream + */ + inline std::shared_ptr<Aws::IOStream> GetBody() const override { return m_bodyStream; } + /** + * Set the body stream to use for the request. + */ + inline void SetBody(const std::shared_ptr<Aws::IOStream>& body) { m_bodyStream = body; } + /** + * Gets all headers that will be needed in the request. Calls GetRequestSpecificHeaders(), which is the chance for subclasses to add + * headers from their modeled data. + */ + inline Aws::Http::HeaderValueCollection GetHeaders() const override + { + auto headers = GetRequestSpecificHeaders(); + headers.insert(Aws::Http::HeaderValuePair(Aws::Http::CONTENT_TYPE_HEADER, GetContentType())); + + return headers; + } + + /** * AmazonStreamingWebServiceRequest always returns true. */ bool IsStreaming() const override { return true; } /** - * Get the user set contentType. Defaults to binary/octet-stream - */ - const Aws::String& GetContentType() const { return m_contentType; } - /** - * Set the content type. - */ - void SetContentType(const Aws::String& contentType) { m_contentType = contentType; } - - protected: - /** - * Override this method to put data members from a subclass into the headers collection. - */ - virtual Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const { return Aws::Http::HeaderValueCollection(); }; - - private: - std::shared_ptr<Aws::IOStream> m_bodyStream; - Aws::String m_contentType; - }; - -} // namespace Aws - + * Get the user set contentType. Defaults to binary/octet-stream + */ + const Aws::String& GetContentType() const { return m_contentType; } + /** + * Set the content type. + */ + void SetContentType(const Aws::String& contentType) { m_contentType = contentType; } + + protected: + /** + * Override this method to put data members from a subclass into the headers collection. + */ + virtual Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const { return Aws::Http::HeaderValueCollection(); }; + + private: + std::shared_ptr<Aws::IOStream> m_bodyStream; + Aws::String m_contentType; + }; + +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h index 1fc7c0e7e0..8d6d081c3d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceRequest.h @@ -2,66 +2,66 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/UnreferencedParam.h> -#include <aws/core/http/HttpTypes.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/stream/ResponseStream.h> -#include <aws/core/auth/AWSAuthSigner.h> - -namespace Aws -{ - namespace Http - { - class URI; - } // namespace Http - - class AmazonWebServiceRequest; - - /** - * Closure definition for handling a retry notification. This is only for if you want to be notified that a particular request is being retried. - */ - typedef std::function<void(const AmazonWebServiceRequest&)> RequestRetryHandler; + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/UnreferencedParam.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/stream/ResponseStream.h> +#include <aws/core/auth/AWSAuthSigner.h> + +namespace Aws +{ + namespace Http + { + class URI; + } // namespace Http + + class AmazonWebServiceRequest; + + /** + * Closure definition for handling a retry notification. This is only for if you want to be notified that a particular request is being retried. + */ + typedef std::function<void(const AmazonWebServiceRequest&)> RequestRetryHandler; typedef std::function<void(const Aws::Http::HttpRequest&)> RequestSignedHandler; - - /** - * Base level abstraction for all modeled AWS requests - */ - class AWS_CORE_API AmazonWebServiceRequest - { - public: - /** - * Sets up default response stream factory. initializes other pointers to nullptr. - */ - AmazonWebServiceRequest(); - virtual ~AmazonWebServiceRequest() = default; - - /** - * Get the payload for the request - */ - virtual std::shared_ptr<Aws::IOStream> GetBody() const = 0; - /** - * Get the headers for the request - */ - virtual Aws::Http::HeaderValueCollection GetHeaders() const = 0; - /** - * Do nothing virtual, override this to add query strings to the request - */ - virtual void AddQueryStringParameters(Aws::Http::URI& uri) const { AWS_UNREFERENCED_PARAM(uri); } - - /** - * Put the request to a url for later presigning. This will push the body to the url and - * then adds the existing query string parameters as normal. - */ - virtual void PutToPresignedUrl(Aws::Http::URI& uri) const { DumpBodyToUrl(uri); AddQueryStringParameters(uri); } - - /** + + /** + * Base level abstraction for all modeled AWS requests + */ + class AWS_CORE_API AmazonWebServiceRequest + { + public: + /** + * Sets up default response stream factory. initializes other pointers to nullptr. + */ + AmazonWebServiceRequest(); + virtual ~AmazonWebServiceRequest() = default; + + /** + * Get the payload for the request + */ + virtual std::shared_ptr<Aws::IOStream> GetBody() const = 0; + /** + * Get the headers for the request + */ + virtual Aws::Http::HeaderValueCollection GetHeaders() const = 0; + /** + * Do nothing virtual, override this to add query strings to the request + */ + virtual void AddQueryStringParameters(Aws::Http::URI& uri) const { AWS_UNREFERENCED_PARAM(uri); } + + /** + * Put the request to a url for later presigning. This will push the body to the url and + * then adds the existing query string parameters as normal. + */ + virtual void PutToPresignedUrl(Aws::Http::URI& uri) const { DumpBodyToUrl(uri); AddQueryStringParameters(uri); } + + /** * Defaults to false, if this is set to true, it's a streaming request, which means the payload is not well structured bits. */ virtual bool IsStreaming() const { return false; } @@ -71,11 +71,11 @@ namespace Aws */ inline virtual bool IsEventStreamRequest() const { return false; } /** - * Defaults to true, if this is set to false, then signers, if they support body signing, will not do so - */ - virtual bool SignBody() const { return true; } - - /** + * Defaults to true, if this is set to false, then signers, if they support body signing, will not do so + */ + virtual bool SignBody() const { return true; } + + /** * Defaults to false, if this is set to true, it supports chunked transfer encoding. */ virtual bool IsChunked() const { return false; } @@ -90,84 +90,84 @@ namespace Aws inline virtual const RequestSignedHandler& GetRequestSignedHandler() const { return m_onRequestSigned; } /** - * Retrieves the factory for creating response streams. - */ - const Aws::IOStreamFactory& GetResponseStreamFactory() const { return m_responseStreamFactory; } - /** - * Set the response stream factory. - */ - void SetResponseStreamFactory(const Aws::IOStreamFactory& factory) { m_responseStreamFactory = factory; } - /** + * Retrieves the factory for creating response streams. + */ + const Aws::IOStreamFactory& GetResponseStreamFactory() const { return m_responseStreamFactory; } + /** + * Set the response stream factory. + */ + void SetResponseStreamFactory(const Aws::IOStreamFactory& factory) { m_responseStreamFactory = factory; } + /** * Register closure for data received event. - */ - inline virtual void SetDataReceivedEventHandler(const Aws::Http::DataReceivedEventHandler& dataReceivedEventHandler) { m_onDataReceived = dataReceivedEventHandler; } - /** - * register closure for data sent event - */ - inline virtual void SetDataSentEventHandler(const Aws::Http::DataSentEventHandler& dataSentEventHandler) { m_onDataSent = dataSentEventHandler; } - /** - * Register closure for handling whether or not to continue a request. - */ - inline virtual void SetContinueRequestHandler(const Aws::Http::ContinueRequestHandler& continueRequestHandler) { m_continueRequest = continueRequestHandler; } - /** + */ + inline virtual void SetDataReceivedEventHandler(const Aws::Http::DataReceivedEventHandler& dataReceivedEventHandler) { m_onDataReceived = dataReceivedEventHandler; } + /** + * register closure for data sent event + */ + inline virtual void SetDataSentEventHandler(const Aws::Http::DataSentEventHandler& dataSentEventHandler) { m_onDataSent = dataSentEventHandler; } + /** + * Register closure for handling whether or not to continue a request. + */ + inline virtual void SetContinueRequestHandler(const Aws::Http::ContinueRequestHandler& continueRequestHandler) { m_continueRequest = continueRequestHandler; } + /** * Register closure for data received event. */ - inline virtual void SetDataReceivedEventHandler(Aws::Http::DataReceivedEventHandler&& dataReceivedEventHandler) { m_onDataReceived = std::move(dataReceivedEventHandler); } - /** + inline virtual void SetDataReceivedEventHandler(Aws::Http::DataReceivedEventHandler&& dataReceivedEventHandler) { m_onDataReceived = std::move(dataReceivedEventHandler); } + /** * register closure for data sent event */ - inline virtual void SetDataSentEventHandler(Aws::Http::DataSentEventHandler&& dataSentEventHandler) { m_onDataSent = std::move(dataSentEventHandler); } - /** - * Register closure for handling whether or not to cancel a request. - */ - inline virtual void SetContinueRequestHandler(Aws::Http::ContinueRequestHandler&& continueRequestHandler) { m_continueRequest = std::move(continueRequestHandler); } - /** + inline virtual void SetDataSentEventHandler(Aws::Http::DataSentEventHandler&& dataSentEventHandler) { m_onDataSent = std::move(dataSentEventHandler); } + /** + * Register closure for handling whether or not to cancel a request. + */ + inline virtual void SetContinueRequestHandler(Aws::Http::ContinueRequestHandler&& continueRequestHandler) { m_continueRequest = std::move(continueRequestHandler); } + /** * Register closure for notification that a request is being retried */ - inline virtual void SetRequestRetryHandler(const RequestRetryHandler& handler) { m_requestRetryHandler = handler; } - /** + inline virtual void SetRequestRetryHandler(const RequestRetryHandler& handler) { m_requestRetryHandler = handler; } + /** * Register closure for notification that a request is being retried */ - inline virtual void SetRequestRetryHandler(RequestRetryHandler&& handler) { m_requestRetryHandler = std::move(handler); } - /** + inline virtual void SetRequestRetryHandler(RequestRetryHandler&& handler) { m_requestRetryHandler = std::move(handler); } + /** * get closure for data received event. */ - inline virtual const Aws::Http::DataReceivedEventHandler& GetDataReceivedEventHandler() const { return m_onDataReceived; } - /** + inline virtual const Aws::Http::DataReceivedEventHandler& GetDataReceivedEventHandler() const { return m_onDataReceived; } + /** * get closure for data sent event */ - inline virtual const Aws::Http::DataSentEventHandler& GetDataSentEventHandler() const { return m_onDataSent; } - /** - * get closure for handling whether or not to cancel a request. - */ - inline virtual const Aws::Http::ContinueRequestHandler& GetContinueRequestHandler() const { return m_continueRequest; } - /** - * get closure for notification that a request is being retried - */ - inline virtual const RequestRetryHandler& GetRequestRetryHandler() const { return m_requestRetryHandler; } - /** - * If this is set to true, content-md5 needs to be computed and set on the request - */ - inline virtual bool ShouldComputeContentMd5() const { return false; } - - virtual const char* GetServiceRequestName() const = 0; - - protected: - /** - * Default does nothing. Override this to convert what would otherwise be the payload of the - * request to a query string format. - */ - virtual void DumpBodyToUrl(Aws::Http::URI& uri) const { AWS_UNREFERENCED_PARAM(uri); } - - private: - Aws::IOStreamFactory m_responseStreamFactory; - - Aws::Http::DataReceivedEventHandler m_onDataReceived; - Aws::Http::DataSentEventHandler m_onDataSent; - Aws::Http::ContinueRequestHandler m_continueRequest; + inline virtual const Aws::Http::DataSentEventHandler& GetDataSentEventHandler() const { return m_onDataSent; } + /** + * get closure for handling whether or not to cancel a request. + */ + inline virtual const Aws::Http::ContinueRequestHandler& GetContinueRequestHandler() const { return m_continueRequest; } + /** + * get closure for notification that a request is being retried + */ + inline virtual const RequestRetryHandler& GetRequestRetryHandler() const { return m_requestRetryHandler; } + /** + * If this is set to true, content-md5 needs to be computed and set on the request + */ + inline virtual bool ShouldComputeContentMd5() const { return false; } + + virtual const char* GetServiceRequestName() const = 0; + + protected: + /** + * Default does nothing. Override this to convert what would otherwise be the payload of the + * request to a query string format. + */ + virtual void DumpBodyToUrl(Aws::Http::URI& uri) const { AWS_UNREFERENCED_PARAM(uri); } + + private: + Aws::IOStreamFactory m_responseStreamFactory; + + Aws::Http::DataReceivedEventHandler m_onDataReceived; + Aws::Http::DataSentEventHandler m_onDataSent; + Aws::Http::ContinueRequestHandler m_continueRequest; RequestSignedHandler m_onRequestSigned; - RequestRetryHandler m_requestRetryHandler; - }; - -} // namespace Aws - + RequestRetryHandler m_requestRetryHandler; + }; + +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h index cde25d80f6..1b344b7dc5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/AmazonWebServiceResult.h @@ -2,76 +2,76 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/http/HttpTypes.h> -#include <utility> -#include <aws/core/http/HttpResponse.h> - -namespace Aws -{ - /** - * Container for web response to an AWS Request. - */ - template <typename PAYLOAD_TYPE> - class AmazonWebServiceResult - { - public: + +#pragma once + +#include <aws/core/http/HttpTypes.h> +#include <utility> +#include <aws/core/http/HttpResponse.h> + +namespace Aws +{ + /** + * Container for web response to an AWS Request. + */ + template <typename PAYLOAD_TYPE> + class AmazonWebServiceResult + { + public: AmazonWebServiceResult() : m_responseCode(Http::HttpResponseCode::REQUEST_NOT_MADE) {} - - /** - * Sets payload, header collection and a response code. - */ - AmazonWebServiceResult(const PAYLOAD_TYPE& payload, const Http::HeaderValueCollection& headers, Http::HttpResponseCode responseCode = Http::HttpResponseCode::OK) : - m_payload(payload), - m_responseHeaders(headers), - m_responseCode(responseCode) - {} - - /** - * Sets payload, header collection and a response code, but transfers ownership of payload and headers (for move only operations). - */ - AmazonWebServiceResult(PAYLOAD_TYPE&& payload, Http::HeaderValueCollection&& headers, Http::HttpResponseCode responseCode = Http::HttpResponseCode::OK) : - m_payload(std::forward<PAYLOAD_TYPE>(payload)), - m_responseHeaders(std::forward<Http::HeaderValueCollection>(headers)), - m_responseCode(responseCode) - {} - - AmazonWebServiceResult(const AmazonWebServiceResult& result) : - m_payload(result.m_payload), - m_responseHeaders(result.m_responseHeaders), - m_responseCode(result.m_responseCode) - {} - - AmazonWebServiceResult(AmazonWebServiceResult&& result) : - m_payload(std::move(result.m_payload)), - m_responseHeaders(std::move(result.m_responseHeaders)), - m_responseCode(result.m_responseCode) - {} - - /** - * Get the payload from the response - */ - inline const PAYLOAD_TYPE& GetPayload() const { return m_payload; } - /** - * Get the payload from the response and take ownership of it. - */ - inline PAYLOAD_TYPE TakeOwnershipOfPayload() { return std::move(m_payload); } - /** - * Get the headers from the response - */ - inline const Http::HeaderValueCollection& GetHeaderValueCollection() const { return m_responseHeaders; } - /** - * Get the http response code from the response - */ - inline Http::HttpResponseCode GetResponseCode() const { return m_responseCode; } - - private: - PAYLOAD_TYPE m_payload; - Http::HeaderValueCollection m_responseHeaders; - Http::HttpResponseCode m_responseCode; - }; - - -} + + /** + * Sets payload, header collection and a response code. + */ + AmazonWebServiceResult(const PAYLOAD_TYPE& payload, const Http::HeaderValueCollection& headers, Http::HttpResponseCode responseCode = Http::HttpResponseCode::OK) : + m_payload(payload), + m_responseHeaders(headers), + m_responseCode(responseCode) + {} + + /** + * Sets payload, header collection and a response code, but transfers ownership of payload and headers (for move only operations). + */ + AmazonWebServiceResult(PAYLOAD_TYPE&& payload, Http::HeaderValueCollection&& headers, Http::HttpResponseCode responseCode = Http::HttpResponseCode::OK) : + m_payload(std::forward<PAYLOAD_TYPE>(payload)), + m_responseHeaders(std::forward<Http::HeaderValueCollection>(headers)), + m_responseCode(responseCode) + {} + + AmazonWebServiceResult(const AmazonWebServiceResult& result) : + m_payload(result.m_payload), + m_responseHeaders(result.m_responseHeaders), + m_responseCode(result.m_responseCode) + {} + + AmazonWebServiceResult(AmazonWebServiceResult&& result) : + m_payload(std::move(result.m_payload)), + m_responseHeaders(std::move(result.m_responseHeaders)), + m_responseCode(result.m_responseCode) + {} + + /** + * Get the payload from the response + */ + inline const PAYLOAD_TYPE& GetPayload() const { return m_payload; } + /** + * Get the payload from the response and take ownership of it. + */ + inline PAYLOAD_TYPE TakeOwnershipOfPayload() { return std::move(m_payload); } + /** + * Get the headers from the response + */ + inline const Http::HeaderValueCollection& GetHeaderValueCollection() const { return m_responseHeaders; } + /** + * Get the http response code from the response + */ + inline Http::HttpResponseCode GetResponseCode() const { return m_responseCode; } + + private: + PAYLOAD_TYPE m_payload; + Http::HeaderValueCollection m_responseHeaders; + Http::HttpResponseCode m_responseCode; + }; + + +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h index 4fcdb17779..693421bf17 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Aws.h @@ -2,261 +2,261 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/utils/logging/LogLevel.h> -#include <aws/core/utils/logging/LogSystemInterface.h> -#include <aws/core/utils/memory/MemorySystemInterface.h> -#include <aws/core/utils/crypto/Factories.h> -#include <aws/core/http/HttpClientFactory.h> -#include <aws/core/monitoring/MonitoringManager.h> -#include <aws/core/Core_EXPORTS.h> - -namespace Aws -{ - static const char* DEFAULT_LOG_PREFIX = "aws_sdk_"; - - /** - * SDK wide options for logging - */ - struct LoggingOptions - { - LoggingOptions() : logLevel(Aws::Utils::Logging::LogLevel::Off), defaultLogPrefix(DEFAULT_LOG_PREFIX) - { } - - /** - * Defaults to Off, if this is set to something else, then logging will be turned on and logLevel will be passed to the logger - */ - Aws::Utils::Logging::LogLevel logLevel; - - /** - * Defaults to aws_sdk_. This will only be used if the default logger is used. - */ - const char* defaultLogPrefix; - - /** - * Defaults to empty, if logLevel has been set and this field is empty, then the default log interface will be used. - * otherwise, we will call this closure to create a logger - */ - std::function<std::shared_ptr<Aws::Utils::Logging::LogSystemInterface>()> logger_create_fn; - }; - - /** - * SDK wide options for memory management - */ - struct MemoryManagementOptions - { - MemoryManagementOptions() : memoryManager(nullptr) - { } - - /** - * Defaults to nullptr. If custom memory management is being used and this hasn't been set then the default memory - * manager will be used. If this has been set and custom memory management has been turned on, then this will be installed - * at startup time. - */ - Aws::Utils::Memory::MemorySystemInterface* memoryManager; - }; - - /** - * SDK wide options for http - */ - struct HttpOptions - { - HttpOptions() : initAndCleanupCurl(true), installSigPipeHandler(false) - { } - - /** - * Defaults to empty, if this is set, then the result of your closure will be installed and used instead of the system defaults - */ - std::function<std::shared_ptr<Aws::Http::HttpClientFactory>()> httpClientFactory_create_fn; - /** - * libCurl infects everything with its global state. If it is being used then we automatically initialize and clean it up. - * If this is a problem for you, set this to false. If you manually initialize libcurl please add the option CURL_GLOBAL_ALL to your init call. - */ - bool initAndCleanupCurl; - /** - * Installs a global SIGPIPE handler that logs the error and prevents it from terminating the current process. +#pragma once + +#include <aws/core/utils/logging/LogLevel.h> +#include <aws/core/utils/logging/LogSystemInterface.h> +#include <aws/core/utils/memory/MemorySystemInterface.h> +#include <aws/core/utils/crypto/Factories.h> +#include <aws/core/http/HttpClientFactory.h> +#include <aws/core/monitoring/MonitoringManager.h> +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ + static const char* DEFAULT_LOG_PREFIX = "aws_sdk_"; + + /** + * SDK wide options for logging + */ + struct LoggingOptions + { + LoggingOptions() : logLevel(Aws::Utils::Logging::LogLevel::Off), defaultLogPrefix(DEFAULT_LOG_PREFIX) + { } + + /** + * Defaults to Off, if this is set to something else, then logging will be turned on and logLevel will be passed to the logger + */ + Aws::Utils::Logging::LogLevel logLevel; + + /** + * Defaults to aws_sdk_. This will only be used if the default logger is used. + */ + const char* defaultLogPrefix; + + /** + * Defaults to empty, if logLevel has been set and this field is empty, then the default log interface will be used. + * otherwise, we will call this closure to create a logger + */ + std::function<std::shared_ptr<Aws::Utils::Logging::LogSystemInterface>()> logger_create_fn; + }; + + /** + * SDK wide options for memory management + */ + struct MemoryManagementOptions + { + MemoryManagementOptions() : memoryManager(nullptr) + { } + + /** + * Defaults to nullptr. If custom memory management is being used and this hasn't been set then the default memory + * manager will be used. If this has been set and custom memory management has been turned on, then this will be installed + * at startup time. + */ + Aws::Utils::Memory::MemorySystemInterface* memoryManager; + }; + + /** + * SDK wide options for http + */ + struct HttpOptions + { + HttpOptions() : initAndCleanupCurl(true), installSigPipeHandler(false) + { } + + /** + * Defaults to empty, if this is set, then the result of your closure will be installed and used instead of the system defaults + */ + std::function<std::shared_ptr<Aws::Http::HttpClientFactory>()> httpClientFactory_create_fn; + /** + * libCurl infects everything with its global state. If it is being used then we automatically initialize and clean it up. + * If this is a problem for you, set this to false. If you manually initialize libcurl please add the option CURL_GLOBAL_ALL to your init call. + */ + bool initAndCleanupCurl; + /** + * Installs a global SIGPIPE handler that logs the error and prevents it from terminating the current process. * This can be used on operating systems on which CURL is being used. In some situations CURL cannot avoid - * triggering a SIGPIPE. - * For more information see: https://curl.haxx.se/libcurl/c/CURLOPT_NOSIGNAL.html - * NOTE: CURLOPT_NOSIGNAL is already being set. - */ - bool installSigPipeHandler; - }; - - /** - * SDK wide options for crypto - */ - struct CryptoOptions - { - CryptoOptions() : initAndCleanupOpenSSL(true) - { } - - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::HashFactory>()> md5Factory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::HashFactory>()> sha256Factory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::HMACFactory>()> sha256HMACFactory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_CBCFactory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_CTRFactory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_GCMFactory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_KeyWrapFactory_create_fn; - /** - * If set, this closure will be used to create and install the factory. - */ - std::function<std::shared_ptr<Aws::Utils::Crypto::SecureRandomFactory>()> secureRandomFactory_create_fn; - /** - * OpenSSL infects everything with its global state. If it is being used then we automatically initialize and clean it up. + * triggering a SIGPIPE. + * For more information see: https://curl.haxx.se/libcurl/c/CURLOPT_NOSIGNAL.html + * NOTE: CURLOPT_NOSIGNAL is already being set. + */ + bool installSigPipeHandler; + }; + + /** + * SDK wide options for crypto + */ + struct CryptoOptions + { + CryptoOptions() : initAndCleanupOpenSSL(true) + { } + + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::HashFactory>()> md5Factory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::HashFactory>()> sha256Factory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::HMACFactory>()> sha256HMACFactory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_CBCFactory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_CTRFactory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_GCMFactory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::SymmetricCipherFactory>()> aes_KeyWrapFactory_create_fn; + /** + * If set, this closure will be used to create and install the factory. + */ + std::function<std::shared_ptr<Aws::Utils::Crypto::SecureRandomFactory>()> secureRandomFactory_create_fn; + /** + * OpenSSL infects everything with its global state. If it is being used then we automatically initialize and clean it up. * If this is a problem for you, set this to false. Be aware that if you don't use our init and cleanup and you are using - * crypto functionality, you are responsible for installing thread locking, and loading strings and error messages. - */ - bool initAndCleanupOpenSSL; - }; - - /** + * crypto functionality, you are responsible for installing thread locking, and loading strings and error messages. + */ + bool initAndCleanupOpenSSL; + }; + + /** * MonitoringOptions is used to set up monitoring functionalities globally and(or) for users to customize monitoring listeners. - */ - struct MonitoringOptions - { - /** + */ + struct MonitoringOptions + { + /** * These factory functions will be used to try to create customized monitoring listener factories, then be used to create monitoring listener instances. - * Based on functions and factory's implementation, it may fail to create an instance. - * If a function failed to create factory or a created factory failed to create an instance, SDK just ignore it. - * By default, SDK will try to create a default Client Side Monitoring Listener. - */ - std::vector<Aws::Monitoring::MonitoringFactoryCreateFunction> customizedMonitoringFactory_create_fn; - }; - - - /** - * You may notice that instead of taking pointers directly to your factories, we take a closure. This is because - * if you have installed custom memory management, the allocation for your factories needs to happen after - * the memory system has been initialized and shutdown needs to happen prior to the memory management being shutdown. - * - * Common Recipes: - * - * Just use defaults: - * - * SDKOptions options; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - * - * Turn logging on using the default logger: - * - * SDKOptions options; - * options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - * - * Install custom memory manager: - * - * MyMemoryManager memoryManager; - * - * SDKOptions options; - * options.memoryManagementOptions.memoryManager = &memoryManager; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - * - * Override default http client factory - * - * SDKOptions options; - * options.httpOptions.httpClientFactory_create_fn = [](){ return Aws::MakeShared<MyCustomHttpClientFactory>("ALLOC_TAG", arg1); }; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - */ - struct SDKOptions - { - /** - * SDK wide options for logging - */ - LoggingOptions loggingOptions; - /** - * SDK wide options for memory management - */ - MemoryManagementOptions memoryManagementOptions; - /** - * SDK wide options for http - */ - HttpOptions httpOptions; - /** - * SDK wide options for crypto - */ - CryptoOptions cryptoOptions; - - /** - * Options used to set up customized monitoring implementations + * Based on functions and factory's implementation, it may fail to create an instance. + * If a function failed to create factory or a created factory failed to create an instance, SDK just ignore it. + * By default, SDK will try to create a default Client Side Monitoring Listener. + */ + std::vector<Aws::Monitoring::MonitoringFactoryCreateFunction> customizedMonitoringFactory_create_fn; + }; + + + /** + * You may notice that instead of taking pointers directly to your factories, we take a closure. This is because + * if you have installed custom memory management, the allocation for your factories needs to happen after + * the memory system has been initialized and shutdown needs to happen prior to the memory management being shutdown. + * + * Common Recipes: + * + * Just use defaults: + * + * SDKOptions options; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + * + * Turn logging on using the default logger: + * + * SDKOptions options; + * options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + * + * Install custom memory manager: + * + * MyMemoryManager memoryManager; + * + * SDKOptions options; + * options.memoryManagementOptions.memoryManager = &memoryManager; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + * + * Override default http client factory + * + * SDKOptions options; + * options.httpOptions.httpClientFactory_create_fn = [](){ return Aws::MakeShared<MyCustomHttpClientFactory>("ALLOC_TAG", arg1); }; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + */ + struct SDKOptions + { + /** + * SDK wide options for logging + */ + LoggingOptions loggingOptions; + /** + * SDK wide options for memory management + */ + MemoryManagementOptions memoryManagementOptions; + /** + * SDK wide options for http + */ + HttpOptions httpOptions; + /** + * SDK wide options for crypto + */ + CryptoOptions cryptoOptions; + + /** + * Options used to set up customized monitoring implementations * Put your monitoring factory in a closure (a create factory function) and put all closures in a vector. - * Basic usage can be found in aws-cpp-sdk-core-tests/monitoring/MonitoringTest.cpp - */ - MonitoringOptions monitoringOptions; - }; - - /* - * Initialize SDK wide state for the SDK. This method must be called before doing anything else with this library. - * - * Common Recipes: - * - * Just use defaults: - * - * SDKOptions options; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - * - * Turn logging on using the default logger: - * - * SDKOptions options; - * options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - * - * Install custom memory manager: - * - * MyMemoryManager memoryManager; - * - * SDKOptions options; - * options.memoryManagementOptions.memoryManager = &memoryManager; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - * - * Override default http client factory - * - * SDKOptions options; - * options.httpOptions.httpClientFactory_create_fn = [](){ return Aws::MakeShared<MyCustomHttpClientFactory>("ALLOC_TAG", arg1); }; - * Aws::InitAPI(options); - * ..... - * Aws::ShutdownAPI(options); - */ - AWS_CORE_API void InitAPI(const SDKOptions& options); - - /** - * Shutdown SDK wide state for the SDK. This method must be called when you are finished using the SDK. - * Do not call any other SDK methods after calling ShutdownAPI. - */ - AWS_CORE_API void ShutdownAPI(const SDKOptions& options); -} + * Basic usage can be found in aws-cpp-sdk-core-tests/monitoring/MonitoringTest.cpp + */ + MonitoringOptions monitoringOptions; + }; + + /* + * Initialize SDK wide state for the SDK. This method must be called before doing anything else with this library. + * + * Common Recipes: + * + * Just use defaults: + * + * SDKOptions options; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + * + * Turn logging on using the default logger: + * + * SDKOptions options; + * options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + * + * Install custom memory manager: + * + * MyMemoryManager memoryManager; + * + * SDKOptions options; + * options.memoryManagementOptions.memoryManager = &memoryManager; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + * + * Override default http client factory + * + * SDKOptions options; + * options.httpOptions.httpClientFactory_create_fn = [](){ return Aws::MakeShared<MyCustomHttpClientFactory>("ALLOC_TAG", arg1); }; + * Aws::InitAPI(options); + * ..... + * Aws::ShutdownAPI(options); + */ + AWS_CORE_API void InitAPI(const SDKOptions& options); + + /** + * Shutdown SDK wide state for the SDK. This method must be called when you are finished using the SDK. + * Do not call any other SDK methods after calling ShutdownAPI. + */ + AWS_CORE_API void ShutdownAPI(const SDKOptions& options); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h index 12e9dfc9be..f7a40fbda9 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h @@ -2,29 +2,29 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/SDKConfig.h> - + +#pragma once + +#include <aws/core/SDKConfig.h> + #if defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32) - #ifdef _MSC_VER - #pragma warning(disable : 4251) - #endif // _MSC_VER - - #ifdef USE_IMPORT_EXPORT - #ifdef AWS_CORE_EXPORTS - #define AWS_CORE_API __declspec(dllexport) - #else // AWS_CORE_EXPORTS - #define AWS_CORE_API __declspec(dllimport) - #endif // AWS_CORE_EXPORTS - #else // USE_IMPORT_EXPORT - #define AWS_CORE_API - #endif // USE_IMPORT_EXPORT + #ifdef _MSC_VER + #pragma warning(disable : 4251) + #endif // _MSC_VER + + #ifdef USE_IMPORT_EXPORT + #ifdef AWS_CORE_EXPORTS + #define AWS_CORE_API __declspec(dllexport) + #else // AWS_CORE_EXPORTS + #define AWS_CORE_API __declspec(dllimport) + #endif // AWS_CORE_EXPORTS + #else // USE_IMPORT_EXPORT + #define AWS_CORE_API + #endif // USE_IMPORT_EXPORT #else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32) - #define AWS_CORE_API + #define AWS_CORE_API #endif // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32) - + #ifdef _MSC_VER #define AWS_SUPPRESS_WARNING_PUSH(W) \ __pragma(warning(push)) \ @@ -89,15 +89,15 @@ // Update: When deprecating a function/components, we won't remove the existing tests // immediately, so we need AWS_DISABLE_DEPRECATION as well. #if defined(AWS_DISABLE_DEPRECATION) - #define AWS_DEPRECATED(msg) -#elif defined (__cplusplus) && __cplusplus > 201103L // standard attributes are available since C++14 - #define AWS_DEPRECATED(msg) [[deprecated(msg)]] -#else - #ifdef _MSC_VER - #define AWS_DEPRECATED(msg) __declspec(deprecated(msg)) + #define AWS_DEPRECATED(msg) +#elif defined (__cplusplus) && __cplusplus > 201103L // standard attributes are available since C++14 + #define AWS_DEPRECATED(msg) [[deprecated(msg)]] +#else + #ifdef _MSC_VER + #define AWS_DEPRECATED(msg) __declspec(deprecated(msg)) #elif defined (__clang__) || defined (__GNUC__) - #define AWS_DEPRECATED(msg) __attribute__((deprecated(msg))) - #else - #define AWS_DEPRECATED(msg) - #endif -#endif + #define AWS_DEPRECATED(msg) __attribute__((deprecated(msg))) + #else + #define AWS_DEPRECATED(msg) + #endif +#endif diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h index cebe4891b7..65d372be45 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Globals.h @@ -2,34 +2,34 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -namespace Aws -{ - namespace Utils - { - class EnumParseOverflowContainer; - } - /** - * This is used to handle the Enum round tripping problem - * for when a service updates their enumerations, but the user does not - * have an up to date client. This container will be initialized during Aws::InitAPI - * and will be cleaned on Aws::ShutdownAPI. - */ - AWS_CORE_API Utils::EnumParseOverflowContainer* GetEnumOverflowContainer(); - - /** - * Initializes a global overflow container to a new instance. - * This should only be called once from within Aws::InitAPI - */ - void InitializeEnumOverflowContainer(); - - /** - * Destroys the global overflow container instance. - * This should only be called once from within Aws::ShutdownAPI - */ - void CleanupEnumOverflowContainer(); -} + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ + namespace Utils + { + class EnumParseOverflowContainer; + } + /** + * This is used to handle the Enum round tripping problem + * for when a service updates their enumerations, but the user does not + * have an up to date client. This container will be initialized during Aws::InitAPI + * and will be cleaned on Aws::ShutdownAPI. + */ + AWS_CORE_API Utils::EnumParseOverflowContainer* GetEnumOverflowContainer(); + + /** + * Initializes a global overflow container to a new instance. + * This should only be called once from within Aws::InitAPI + */ + void InitializeEnumOverflowContainer(); + + /** + * Destroys the global overflow container instance. + * This should only be called once from within Aws::ShutdownAPI + */ + void CleanupEnumOverflowContainer(); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/NoResult.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/NoResult.h index c4f233cbb9..9e49f1bdaa 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/NoResult.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/NoResult.h @@ -2,13 +2,13 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -namespace Aws -{ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ namespace Utils { namespace Xml @@ -20,7 +20,7 @@ namespace Json class JsonValue; } } // namespace Utils - + class AWS_CORE_API NoResult { public: @@ -28,5 +28,5 @@ public: NoResult(const Aws::AmazonWebServiceResult<Aws::Utils::Xml::XmlDocument>&) {}; NoResult(const Aws::AmazonWebServiceResult<Aws::Utils::Json::JsonValue>&) {}; }; - -} // namespace Aws + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h index a728c829ed..b71377666c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Region.h @@ -2,20 +2,20 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - /** - * AWS Regions - */ - namespace Region - { + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + /** + * AWS Regions + */ + namespace Region + { // AWS_GLOBAL is a pseudo region that can be used to tell SDK to use the service global endpoint if there is any. // You can specify this region to corresponding environment variable, config file item and in your code. // For services without global region, the request will be directed to us-east-1 @@ -47,7 +47,7 @@ namespace Aws // If a pseudo region, for example, aws-global or us-east-1-fips is provided, it should be converted to the region name used for signing. Aws::String AWS_CORE_API ComputeSignerRegion(const Aws::String& region); - } - -} // namespace Aws - + } + +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/SDKConfig.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/SDKConfig.h index 9561d20253..a3f3f72a18 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/SDKConfig.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/SDKConfig.h @@ -2,6 +2,6 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - + /* #undef USE_AWS_MEMORY_MANAGEMENT */ - + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Version.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Version.h index 71215ec6bd..c24b5ec590 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Version.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/Version.h @@ -2,18 +2,18 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ -namespace Version -{ - AWS_CORE_API const char* GetVersionString(); - AWS_CORE_API unsigned GetVersionMajor(); - AWS_CORE_API unsigned GetVersionMinor(); - AWS_CORE_API unsigned GetVersionPatch(); - AWS_CORE_API const char* GetCompilerVersionString(); -} //namespace Version -} //namespace Aws + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ +namespace Version +{ + AWS_CORE_API const char* GetVersionString(); + AWS_CORE_API unsigned GetVersionMajor(); + AWS_CORE_API unsigned GetVersionMinor(); + AWS_CORE_API unsigned GetVersionPatch(); + AWS_CORE_API const char* GetCompilerVersionString(); +} //namespace Version +} //namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h index 9304d56ee7..7ebbdb8ae4 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/VersionConfig.h @@ -2,5 +2,5 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - + #define AWS_SDK_VERSION_STRING "1.8.113" diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h index 8061ee1e25..9d048d0d12 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSigner.h @@ -2,80 +2,80 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/Region.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSSet.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/Array.h> -#include <aws/core/utils/threading/ReaderWriterLock.h> + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/Region.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSSet.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/Array.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> #include <aws/core/utils/crypto/Sha256.h> #include <aws/core/utils/crypto/Sha256HMAC.h> - -#include <memory> -#include <atomic> -#include <chrono> - -namespace Aws -{ - namespace Http - { - class HttpClientFactory; - class HttpRequest; - } // namespace Http - - namespace Utils - { + +#include <memory> +#include <atomic> +#include <chrono> + +namespace Aws +{ + namespace Http + { + class HttpClientFactory; + class HttpRequest; + } // namespace Http + + namespace Utils + { namespace Event { class Message; } - } // namespace Utils - - namespace Auth - { - class AWSCredentials; - class AWSCredentialsProvider; - AWS_CORE_API extern const char SIGV4_SIGNER[]; + } // namespace Utils + + namespace Auth + { + class AWSCredentials; + class AWSCredentialsProvider; + AWS_CORE_API extern const char SIGV4_SIGNER[]; AWS_CORE_API extern const char EVENTSTREAM_SIGV4_SIGNER[]; AWS_CORE_API extern const char SIGNATURE[]; - AWS_CORE_API extern const char NULL_SIGNER[]; - } // namespace Auth - - namespace Client - { - struct ClientConfiguration; - - /** - * Auth Signer interface. Takes a generic AWS request and applies crypto tamper resistent signatures on the request. - */ - class AWS_CORE_API AWSAuthSigner - { - public: - AWSAuthSigner() : m_clockSkew() { m_clockSkew.store(std::chrono::milliseconds(0L)); } - virtual ~AWSAuthSigner() = default; - - /** - * Signs the request itself (usually by adding a signature header) based on info in the request and uri. - */ - virtual bool SignRequest(Aws::Http::HttpRequest& request) const = 0; - - /** - * Signs the request itself (usually by adding a signature header) based on info in the request and uri. + AWS_CORE_API extern const char NULL_SIGNER[]; + } // namespace Auth + + namespace Client + { + struct ClientConfiguration; + + /** + * Auth Signer interface. Takes a generic AWS request and applies crypto tamper resistent signatures on the request. + */ + class AWS_CORE_API AWSAuthSigner + { + public: + AWSAuthSigner() : m_clockSkew() { m_clockSkew.store(std::chrono::milliseconds(0L)); } + virtual ~AWSAuthSigner() = default; + + /** + * Signs the request itself (usually by adding a signature header) based on info in the request and uri. + */ + virtual bool SignRequest(Aws::Http::HttpRequest& request) const = 0; + + /** + * Signs the request itself (usually by adding a signature header) based on info in the request and uri. * If signBody is false and https is being used then the body of the payload will not be signed. - * The default virtual function, just calls SignRequest. - */ + * The default virtual function, just calls SignRequest. + */ virtual bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const { AWS_UNREFERENCED_PARAM(signBody); return SignRequest(request); } - - /** + + /** * Signs the request itself (usually by adding a signature header) based on info in the request and uri. * If signBody is false and https is being used then the body of the payload will not be signed. * The default virtual function, just calls SignRequest. @@ -118,115 +118,115 @@ namespace Aws virtual bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& /* priorSignature */) const { return false; } /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * The URI can then be used in a normal HTTP call until expiration. - */ - virtual bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds) const = 0; - - /** - * Generates a signed Uri using the injected signer. for the supplied uri and http method and region. expirationInSeconds defaults - * to 0 which is the default 7 days. + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * The URI can then be used in a normal HTTP call until expiration. + */ + virtual bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds) const = 0; + + /** + * Generates a signed Uri using the injected signer. for the supplied uri and http method and region. expirationInSeconds defaults + * to 0 which is the default 7 days. * Using m_region by default if parameter region is nullptr. - */ - virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const = 0; - - /** - * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, and service name. expirationInSeconds defaults - * to 0 which is the default 7 days. + */ + virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const = 0; + + /** + * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, and service name. expirationInSeconds defaults + * to 0 which is the default 7 days. * Using m_region by default if parameter region is nullptr. * Using m_serviceName by default if parameter serviceName is nullptr. - */ - virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const = 0; - - /** - * Return the signer's name - */ - virtual const char* GetName() const = 0; - - /** - * This handles detection of clock skew between clients and the server and adjusts the clock so that the next request will not - * fail on the timestamp check. - */ - virtual void SetClockSkew(const std::chrono::milliseconds& clockSkew) { m_clockSkew = clockSkew; } - - /** - * Gets the timestamp being used by the signer. This may include a clock skew if a clock skew has been detected. - */ - virtual Aws::Utils::DateTime GetSigningTimestamp() const { return Aws::Utils::DateTime::Now() + GetClockSkewOffset(); } - + */ + virtual bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const = 0; + + /** + * Return the signer's name + */ + virtual const char* GetName() const = 0; + + /** + * This handles detection of clock skew between clients and the server and adjusts the clock so that the next request will not + * fail on the timestamp check. + */ + virtual void SetClockSkew(const std::chrono::milliseconds& clockSkew) { m_clockSkew = clockSkew; } + + /** + * Gets the timestamp being used by the signer. This may include a clock skew if a clock skew has been detected. + */ + virtual Aws::Utils::DateTime GetSigningTimestamp() const { return Aws::Utils::DateTime::Now() + GetClockSkewOffset(); } + protected: - virtual std::chrono::milliseconds GetClockSkewOffset() const { return m_clockSkew.load(); } - - std::atomic<std::chrono::milliseconds> m_clockSkew; - }; - - /** - * AWS Auth v4 Signer implementation of the AWSAuthSigner interface. More information on AWS Auth v4 Can be found here: - * http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html - */ - class AWS_CORE_API AWSAuthV4Signer : public AWSAuthSigner - { - - public: - /** - * Even though different payload signing polices, HTTP will force payload signing to be on. - */ - enum class PayloadSigningPolicy - { - /** - * Sign the request based on the value returned by AmazonWebServiceRequest::SignBody() - */ - RequestDependent, - /** - * Always sign the body of the request. - */ - Always, - /** - * Never sign the body of the request - */ - Never - }; - /** - * credentialsProvider, source of AWS Credentials to sign requests with - * serviceName, canonical service name to sign with - * region, region string to use in signature - * signPayloads, if Always, the payload will have a sha256 computed on the body of the request. If this is set - * to Never, the sha256 will not be computed on the body. This is only useful for Amazon S3 over Https. If - * Https is not used then this flag will be ignored. If set to RequestDependent, compute or not is based on - * the value from AmazonWebServiceRequest::SignBody() - */ - AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, - const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy = PayloadSigningPolicy::RequestDependent, - bool urlEscapePath = true); - - virtual ~AWSAuthV4Signer(); - - /** - * AWSAuthV4signer's implementation of virtual function from base class - * Return Auth Signer's name, here the value is specified in Aws::Auth::DEFAULT_AUTHV4_SIGNER. - */ - const char* GetName() const override { return Aws::Auth::SIGV4_SIGNER; } - - /** - * Signs the request itself based on info in the request and uri. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - */ + virtual std::chrono::milliseconds GetClockSkewOffset() const { return m_clockSkew.load(); } + + std::atomic<std::chrono::milliseconds> m_clockSkew; + }; + + /** + * AWS Auth v4 Signer implementation of the AWSAuthSigner interface. More information on AWS Auth v4 Can be found here: + * http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html + */ + class AWS_CORE_API AWSAuthV4Signer : public AWSAuthSigner + { + + public: + /** + * Even though different payload signing polices, HTTP will force payload signing to be on. + */ + enum class PayloadSigningPolicy + { + /** + * Sign the request based on the value returned by AmazonWebServiceRequest::SignBody() + */ + RequestDependent, + /** + * Always sign the body of the request. + */ + Always, + /** + * Never sign the body of the request + */ + Never + }; + /** + * credentialsProvider, source of AWS Credentials to sign requests with + * serviceName, canonical service name to sign with + * region, region string to use in signature + * signPayloads, if Always, the payload will have a sha256 computed on the body of the request. If this is set + * to Never, the sha256 will not be computed on the body. This is only useful for Amazon S3 over Https. If + * Https is not used then this flag will be ignored. If set to RequestDependent, compute or not is based on + * the value from AmazonWebServiceRequest::SignBody() + */ + AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, + const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy = PayloadSigningPolicy::RequestDependent, + bool urlEscapePath = true); + + virtual ~AWSAuthV4Signer(); + + /** + * AWSAuthV4signer's implementation of virtual function from base class + * Return Auth Signer's name, here the value is specified in Aws::Auth::DEFAULT_AUTHV4_SIGNER. + */ + const char* GetName() const override { return Aws::Auth::SIGV4_SIGNER; } + + /** + * Signs the request itself based on info in the request and uri. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + */ bool SignRequest(Aws::Http::HttpRequest& request) const override { return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), true/*signBody*/); } - - /** - * Signs the request itself based on info in the request and uri. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false - * and https is being used then the body of the payload will not be signed. - */ + + /** + * Signs the request itself based on info in the request and uri. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false + * and https is being used then the body of the payload will not be signed. + */ bool SignRequest(Aws::Http::HttpRequest& request, bool signBody) const override { return SignRequest(request, m_region.c_str(), m_serviceName.c_str(), signBody); } - - /** + + /** * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. If signBody is false * and https is being used then the body of the payload will not be signed. * Using m_region by default if parameter region is nullptr. @@ -244,84 +244,84 @@ namespace Aws bool SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const override; /** + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * the region the signer was initialized with will be used for the signature. + * The URI can then be used in a normal HTTP call until expiration. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + * expirationInSeconds defaults to 0 which provides a URI good for 7 days. + */ + bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds = 0) const override; + + /** * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * the region the signer was initialized with will be used for the signature. - * The URI can then be used in a normal HTTP call until expiration. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - * expirationInSeconds defaults to 0 which provides a URI good for 7 days. - */ - bool PresignRequest(Aws::Http::HttpRequest& request, long long expirationInSeconds = 0) const override; - - /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * The URI can then be used in a normal HTTP call until expiration. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - * expirationInSeconds defaults to 0 which provides a URI good for 7 days. + * The URI can then be used in a normal HTTP call until expiration. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + * expirationInSeconds defaults to 0 which provides a URI good for 7 days. * Using m_region by default if parameter region is nullptr. - */ - bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const override; - - /** - * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. - * The URI can then be used in a normal HTTP call until expiration. - * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. - * expirationInSeconds defaults to 0 which provides a URI good for 7 days. + */ + bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds = 0) const override; + + /** + * Takes a request and signs the URI based on the HttpMethod, URI and other info from the request. + * The URI can then be used in a normal HTTP call until expiration. + * Uses AWS Auth V4 signing method with SHA256 HMAC algorithm. + * expirationInSeconds defaults to 0 which provides a URI good for 7 days. * Using m_region by default if parameter region is nullptr. * Using m_serviceName by default if parameter serviceName is nullptr. - */ - bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const override; - + */ + bool PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationInSeconds = 0) const override; + Aws::String GetServiceName() const { return m_serviceName; } Aws::String GetRegion() const { return m_region; } Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, const Aws::String& stringToSign, const Aws::String& simpleDate) const; bool ShouldSignHeader(const Aws::String& header) const; - protected: - bool m_includeSha256HashHeader; - - private: - - Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, + protected: + bool m_includeSha256HashHeader; + + private: + + Aws::String GenerateSignature(const Aws::Auth::AWSCredentials& credentials, const Aws::String& stringToSign, const Aws::String& simpleDate, const Aws::String& region, - const Aws::String& serviceName) const; - - Aws::String GenerateSignature(const Aws::String& stringToSign, const Aws::Utils::ByteBuffer& key) const; - bool ServiceRequireUnsignedPayload(const Aws::String& serviceName) const; - Aws::String ComputePayloadHash(Aws::Http::HttpRequest&) const; - Aws::String GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, - const Aws::String& canonicalRequestHash, const Aws::String& region, - const Aws::String& serviceName) const; - Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, const Aws::String& simpleDate) const; - Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; - - - std::shared_ptr<Auth::AWSCredentialsProvider> m_credentialsProvider; - const Aws::String m_serviceName; - const Aws::String m_region; - Aws::UniquePtr<Aws::Utils::Crypto::Sha256> m_hash; - Aws::UniquePtr<Aws::Utils::Crypto::Sha256HMAC> m_HMAC; - - Aws::Set<Aws::String> m_unsignedHeaders; - - //these next four fields are ONLY for caching purposes and do not change - //the logical state of the signer. They are marked mutable so the - //interface can remain const. - mutable Aws::Utils::ByteBuffer m_partialSignature; - mutable Aws::String m_currentDateStr; - mutable Aws::String m_currentSecretKey; - mutable Utils::Threading::ReaderWriterLock m_partialSignatureLock; - PayloadSigningPolicy m_payloadSigningPolicy; - bool m_urlEscapePath; - }; - + const Aws::String& serviceName) const; + + Aws::String GenerateSignature(const Aws::String& stringToSign, const Aws::Utils::ByteBuffer& key) const; + bool ServiceRequireUnsignedPayload(const Aws::String& serviceName) const; + Aws::String ComputePayloadHash(Aws::Http::HttpRequest&) const; + Aws::String GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, + const Aws::String& canonicalRequestHash, const Aws::String& region, + const Aws::String& serviceName) const; + Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, const Aws::String& simpleDate) const; + Aws::Utils::ByteBuffer ComputeHash(const Aws::String& secretKey, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const; + + + std::shared_ptr<Auth::AWSCredentialsProvider> m_credentialsProvider; + const Aws::String m_serviceName; + const Aws::String m_region; + Aws::UniquePtr<Aws::Utils::Crypto::Sha256> m_hash; + Aws::UniquePtr<Aws::Utils::Crypto::Sha256HMAC> m_HMAC; + + Aws::Set<Aws::String> m_unsignedHeaders; + + //these next four fields are ONLY for caching purposes and do not change + //the logical state of the signer. They are marked mutable so the + //interface can remain const. + mutable Aws::Utils::ByteBuffer m_partialSignature; + mutable Aws::String m_currentDateStr; + mutable Aws::String m_currentSecretKey; + mutable Utils::Threading::ReaderWriterLock m_partialSignatureLock; + PayloadSigningPolicy m_payloadSigningPolicy; + bool m_urlEscapePath; + }; + class AWS_CORE_API AWSAuthEventStreamV4Signer : public AWSAuthSigner { public: AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, const char* serviceName, const Aws::String& region); - + const char* GetName() const override { return Aws::Auth::EVENTSTREAM_SIGV4_SIGNER; } bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& priorSignature) const override; @@ -382,44 +382,44 @@ namespace Aws }; - /** - * A no-op implementation of the AWSAuthSigner interface - */ - class AWS_CORE_API AWSNullSigner : public AWSAuthSigner - { - public: - /** - * AWSNullSigner's implementation of virtual function from base class - * Here the returned value is specified in Aws::Auth::NULL_SIGNER. - */ - const char* GetName() const override { return Aws::Auth::NULL_SIGNER; } - - /** - * Do nothing - */ - bool SignRequest(Aws::Http::HttpRequest&) const override { return true; } - - /** - * Do nothing - */ + /** + * A no-op implementation of the AWSAuthSigner interface + */ + class AWS_CORE_API AWSNullSigner : public AWSAuthSigner + { + public: + /** + * AWSNullSigner's implementation of virtual function from base class + * Here the returned value is specified in Aws::Auth::NULL_SIGNER. + */ + const char* GetName() const override { return Aws::Auth::NULL_SIGNER; } + + /** + * Do nothing + */ + bool SignRequest(Aws::Http::HttpRequest&) const override { return true; } + + /** + * Do nothing + */ bool SignEventMessage(Aws::Utils::Event::Message&, Aws::String& /* priorSignature */) const override { return true; } /** * Do nothing */ - bool PresignRequest(Aws::Http::HttpRequest&, long long) const override { return false; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, const char*, long long) const override { return false; } - - /** - * Do nothing - */ - bool PresignRequest(Aws::Http::HttpRequest&, const char*, const char*, long long) const override { return false; } - }; - - } // namespace Client -} // namespace Aws - + bool PresignRequest(Aws::Http::HttpRequest&, long long) const override { return false; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, const char*, long long) const override { return false; } + + /** + * Do nothing + */ + bool PresignRequest(Aws::Http::HttpRequest&, const char*, const char*, long long) const override { return false; } + }; + + } // namespace Client +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h index 305c58cd9d..84b5613738 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSAuthSignerProvider.h @@ -2,37 +2,37 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <memory> - - -namespace Aws -{ - namespace Client - { - class AWSAuthSigner; - } - namespace Auth - { + + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <memory> + + +namespace Aws +{ + namespace Client + { + class AWSAuthSigner; + } + namespace Auth + { class AWSCredentialsProvider; - class AWS_CORE_API AWSAuthSignerProvider - { - public: - virtual std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const = 0; + class AWS_CORE_API AWSAuthSignerProvider + { + public: + virtual std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const = 0; virtual void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) = 0; - virtual ~AWSAuthSignerProvider() = default; - }; - - class AWS_CORE_API DefaultAuthSignerProvider : public AWSAuthSignerProvider - { - public: + virtual ~AWSAuthSignerProvider() = default; + }; + + class AWS_CORE_API DefaultAuthSignerProvider : public AWSAuthSignerProvider + { + public: /** * Creates a Signature-V4 signer provider that supports the different implementations of Signature-V4 * used for standard and event-stream requests. @@ -43,11 +43,11 @@ namespace Aws */ DefaultAuthSignerProvider(const std::shared_ptr<AWSCredentialsProvider>& credentialsProvider, const Aws::String& serviceName, const Aws::String& region); - explicit DefaultAuthSignerProvider(const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer); + explicit DefaultAuthSignerProvider(const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer); void AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) override; - std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const override; - private: - Aws::Vector<std::shared_ptr<Aws::Client::AWSAuthSigner>> m_signers; - }; - } -} + std::shared_ptr<Aws::Client::AWSAuthSigner> GetSigner(const Aws::String& signerName) const override; + private: + Aws::Vector<std::shared_ptr<Aws::Client::AWSAuthSigner>> m_signers; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h index a3a46964e8..43ec431f8f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProvider.h @@ -2,34 +2,34 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/UnreferencedParam.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/threading/ReaderWriterLock.h> -#include <aws/core/internal/AWSHttpResourceClient.h> + + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/UnreferencedParam.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> +#include <aws/core/internal/AWSHttpResourceClient.h> #include <aws/core/auth/AWSCredentials.h> #include <aws/core/config/AWSProfileConfigLoader.h> #include <aws/core/client/RetryStrategy.h> -#include <memory> - -namespace Aws -{ - namespace Auth - { +#include <memory> + +namespace Aws +{ + namespace Auth + { constexpr int REFRESH_THRESHOLD = 1000 * 60 * 5; - + /** * Returns the full path of the config file. */ AWS_CORE_API Aws::String GetConfigProfileFilename(); //defaults to "config" - - /** + + /** * Returns the default profile name. * The value is the first non-empty value of the following: * 1. AWS_PROFILE environment variable @@ -44,233 +44,233 @@ namespace Aws AWS_CORE_API AWSCredentials GetCredentialsFromProcess(const Aws::String& process); /** - * Abstract class for retrieving AWS credentials. Create a derived class from this to allow - * various methods of storing and retrieving credentials. Examples would be cognito-identity, some encrypted store etc... - */ - class AWS_CORE_API AWSCredentialsProvider - { - public: - /** - * Initializes provider. Sets last Loaded time count to 0, forcing a refresh on the - * first call to GetAWSCredentials. - */ - AWSCredentialsProvider() : m_lastLoadedMs(0) - { - } - - virtual ~AWSCredentialsProvider() = default; - - /** - * The core of the credential provider interface. Override this method to control how credentials are retrieved. - */ - virtual AWSCredentials GetAWSCredentials() = 0; - - protected: - /** - * The default implementation keeps up with the cache times and lets you know if it's time to refresh your internal caching - * to aid your implementation of GetAWSCredentials. - */ - virtual bool IsTimeToRefresh(long reloadFrequency); - virtual void Reload(); - mutable Aws::Utils::Threading::ReaderWriterLock m_reloadLock; - private: - long long m_lastLoadedMs; - }; - - /** - * Simply a provider that always returns empty credentials. This is useful for a client that needs to make unsigned - * calls. - */ - class AWS_CORE_API AnonymousAWSCredentialsProvider : public AWSCredentialsProvider - { - public: - /** - * Returns empty credentials object. - */ + * Abstract class for retrieving AWS credentials. Create a derived class from this to allow + * various methods of storing and retrieving credentials. Examples would be cognito-identity, some encrypted store etc... + */ + class AWS_CORE_API AWSCredentialsProvider + { + public: + /** + * Initializes provider. Sets last Loaded time count to 0, forcing a refresh on the + * first call to GetAWSCredentials. + */ + AWSCredentialsProvider() : m_lastLoadedMs(0) + { + } + + virtual ~AWSCredentialsProvider() = default; + + /** + * The core of the credential provider interface. Override this method to control how credentials are retrieved. + */ + virtual AWSCredentials GetAWSCredentials() = 0; + + protected: + /** + * The default implementation keeps up with the cache times and lets you know if it's time to refresh your internal caching + * to aid your implementation of GetAWSCredentials. + */ + virtual bool IsTimeToRefresh(long reloadFrequency); + virtual void Reload(); + mutable Aws::Utils::Threading::ReaderWriterLock m_reloadLock; + private: + long long m_lastLoadedMs; + }; + + /** + * Simply a provider that always returns empty credentials. This is useful for a client that needs to make unsigned + * calls. + */ + class AWS_CORE_API AnonymousAWSCredentialsProvider : public AWSCredentialsProvider + { + public: + /** + * Returns empty credentials object. + */ inline AWSCredentials GetAWSCredentials() override { return AWSCredentials(); } - }; - - /** - * A simple string provider. It takes the AccessKeyId and the SecretKey as constructor args and - * provides them through the interface. This is the default class for AWSClients that take string - * arguments for credentials. - */ - class AWS_CORE_API SimpleAWSCredentialsProvider : public AWSCredentialsProvider - { - public: - /** - * Initializes object from awsAccessKeyId, awsSecretAccessKey, and sessionToken parameters. sessionToken parameter is defaulted to empty. - */ - inline SimpleAWSCredentialsProvider(const Aws::String& awsAccessKeyId, const Aws::String& awsSecretAccessKey, const Aws::String& sessionToken = "") + }; + + /** + * A simple string provider. It takes the AccessKeyId and the SecretKey as constructor args and + * provides them through the interface. This is the default class for AWSClients that take string + * arguments for credentials. + */ + class AWS_CORE_API SimpleAWSCredentialsProvider : public AWSCredentialsProvider + { + public: + /** + * Initializes object from awsAccessKeyId, awsSecretAccessKey, and sessionToken parameters. sessionToken parameter is defaulted to empty. + */ + inline SimpleAWSCredentialsProvider(const Aws::String& awsAccessKeyId, const Aws::String& awsSecretAccessKey, const Aws::String& sessionToken = "") : m_credentials(awsAccessKeyId, awsSecretAccessKey, sessionToken) - { } - - /** - * Initializes object from credentials object. everything is copied. - */ - inline SimpleAWSCredentialsProvider(const AWSCredentials& credentials) + { } + + /** + * Initializes object from credentials object. everything is copied. + */ + inline SimpleAWSCredentialsProvider(const AWSCredentials& credentials) : m_credentials(credentials) - { } - - /** - * Returns the credentials this object was initialized with as an AWSCredentials object. - */ - inline AWSCredentials GetAWSCredentials() override - { + { } + + /** + * Returns the credentials this object was initialized with as an AWSCredentials object. + */ + inline AWSCredentials GetAWSCredentials() override + { return m_credentials; - } - - private: + } + + private: AWSCredentials m_credentials; - }; - - /** - * Reads AWS credentials from the Environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN if they exist. If they - * are not found, empty credentials are returned. - */ - class AWS_CORE_API EnvironmentAWSCredentialsProvider : public AWSCredentialsProvider - { - public: - /** - * Reads AWS credentials from the Environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN if they exist. If they - * are not found, empty credentials are returned. Credentials are not cached. - */ - AWSCredentials GetAWSCredentials() override; - }; - - /** - * Reads credentials profile from the default Profile Config File. Refreshes at set interval for credential rotation. - * Looks for environment variables AWS_SHARED_CREDENTIALS_FILE and AWS_PROFILE. If they aren't found, then it defaults + }; + + /** + * Reads AWS credentials from the Environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN if they exist. If they + * are not found, empty credentials are returned. + */ + class AWS_CORE_API EnvironmentAWSCredentialsProvider : public AWSCredentialsProvider + { + public: + /** + * Reads AWS credentials from the Environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN if they exist. If they + * are not found, empty credentials are returned. Credentials are not cached. + */ + AWSCredentials GetAWSCredentials() override; + }; + + /** + * Reads credentials profile from the default Profile Config File. Refreshes at set interval for credential rotation. + * Looks for environment variables AWS_SHARED_CREDENTIALS_FILE and AWS_PROFILE. If they aren't found, then it defaults * to the default profile in ~/.aws/credentials. - * Optionally a user can specify the profile and it will override the environment variable - * and defaults. To alter the file this pulls from, then the user should alter the AWS_SHARED_CREDENTIALS_FILE variable. - */ - class AWS_CORE_API ProfileConfigFileAWSCredentialsProvider : public AWSCredentialsProvider - { - public: - - /** - * Initializes with refreshRateMs as the frequency at which the file is reparsed in milliseconds. Defaults to 5 minutes. - */ - ProfileConfigFileAWSCredentialsProvider(long refreshRateMs = REFRESH_THRESHOLD); - - /** - * Initializes with a profile override and - * refreshRateMs as the frequency at which the file is reparsed in milliseconds. Defaults to 5 minutes. - */ - ProfileConfigFileAWSCredentialsProvider(const char* profile, long refreshRateMs = REFRESH_THRESHOLD); - - /** - * Retrieves the credentials if found, otherwise returns empty credential set. - */ - AWSCredentials GetAWSCredentials() override; - - /** - * Returns the fullpath of the calculated credentials profile file - */ - static Aws::String GetCredentialsProfileFilename(); - - /** - * Returns the directory storing the profile file. - */ - static Aws::String GetProfileDirectory(); - - protected: - void Reload() override; - private: - - /** + * Optionally a user can specify the profile and it will override the environment variable + * and defaults. To alter the file this pulls from, then the user should alter the AWS_SHARED_CREDENTIALS_FILE variable. + */ + class AWS_CORE_API ProfileConfigFileAWSCredentialsProvider : public AWSCredentialsProvider + { + public: + + /** + * Initializes with refreshRateMs as the frequency at which the file is reparsed in milliseconds. Defaults to 5 minutes. + */ + ProfileConfigFileAWSCredentialsProvider(long refreshRateMs = REFRESH_THRESHOLD); + + /** + * Initializes with a profile override and + * refreshRateMs as the frequency at which the file is reparsed in milliseconds. Defaults to 5 minutes. + */ + ProfileConfigFileAWSCredentialsProvider(const char* profile, long refreshRateMs = REFRESH_THRESHOLD); + + /** + * Retrieves the credentials if found, otherwise returns empty credential set. + */ + AWSCredentials GetAWSCredentials() override; + + /** + * Returns the fullpath of the calculated credentials profile file + */ + static Aws::String GetCredentialsProfileFilename(); + + /** + * Returns the directory storing the profile file. + */ + static Aws::String GetProfileDirectory(); + + protected: + void Reload() override; + private: + + /** * Checks to see if the refresh interval has expired and reparses the file if it has. */ - void RefreshIfExpired(); - - Aws::String m_profileToUse; + void RefreshIfExpired(); + + Aws::String m_profileToUse; Aws::Config::AWSConfigFileProfileConfigLoader m_credentialsFileLoader; - long m_loadFrequencyMs; - }; - - /** - * Credentials provider implementation that loads credentials from the Amazon - * EC2 Instance Metadata Service. - */ - class AWS_CORE_API InstanceProfileCredentialsProvider : public AWSCredentialsProvider - { - public: - /** - * Initializes the provider to refresh credentials form the EC2 instance metadata service every 5 minutes. - * Constructs an EC2MetadataClient using the default http stack (most likely what you want). - */ - InstanceProfileCredentialsProvider(long refreshRateMs = REFRESH_THRESHOLD); - - /** - * Initializes the provider to refresh credentials form the EC2 instance metadata service every 5 minutes, - * uses a supplied EC2MetadataClient. - */ - InstanceProfileCredentialsProvider(const std::shared_ptr<Aws::Config::EC2InstanceProfileConfigLoader>&, long refreshRateMs = REFRESH_THRESHOLD); - - /** - * Retrieves the credentials if found, otherwise returns empty credential set. - */ - AWSCredentials GetAWSCredentials() override; - - protected: - void Reload() override; - - private: - void RefreshIfExpired(); - - std::shared_ptr<Aws::Config::AWSProfileConfigLoader> m_ec2MetadataConfigLoader; - long m_loadFrequencyMs; - }; - - /** - * ECS credentials provider implementation that loads credentials from the Amazon - * ECS metadata service or an arbitrary endpoint. - */ - class AWS_CORE_API TaskRoleCredentialsProvider : public AWSCredentialsProvider - { - public: - /** - * Initializes the provider to retrieve credentials from the ECS metadata service every 5 minutes, - * or before it expires. - * @param resourcePath A path appended to the metadata service endpoint. - * @param refreshRateMs The number of milliseconds after which the credentials will be fetched again. - */ - TaskRoleCredentialsProvider(const char* resourcePath, long refreshRateMs = REFRESH_THRESHOLD); - - /** - * Initializes the provider to retrieve credentials from a provided endpoint every 5 minutes or before it - * expires. - * @param endpoint The full URI to resolve to get credentials. - * @param token An optional authorization token passed to the URI via the 'Authorization' HTTP header. - * @param refreshRateMs The number of milliseconds after which the credentials will be fetched again. - */ - TaskRoleCredentialsProvider(const char* endpoint, const char* token, long refreshRateMs = REFRESH_THRESHOLD); - - /** - * Initializes the provider to retrieve credentials using the provided client. - * @param client The ECSCredentialsClient instance to use when retrieving credentials. - * @param refreshRateMs The number of milliseconds after which the credentials will be fetched again. - */ - TaskRoleCredentialsProvider(const std::shared_ptr<Aws::Internal::ECSCredentialsClient>& client, - long refreshRateMs = REFRESH_THRESHOLD); - /** - * Retrieves the credentials if found, otherwise returns empty credential set. - */ - AWSCredentials GetAWSCredentials() override; - - protected: - void Reload() override; - private: - bool ExpiresSoon() const; - void RefreshIfExpired(); - - private: - std::shared_ptr<Aws::Internal::ECSCredentialsClient> m_ecsCredentialsClient; - long m_loadFrequencyMs; - Aws::Auth::AWSCredentials m_credentials; - }; - + long m_loadFrequencyMs; + }; + + /** + * Credentials provider implementation that loads credentials from the Amazon + * EC2 Instance Metadata Service. + */ + class AWS_CORE_API InstanceProfileCredentialsProvider : public AWSCredentialsProvider + { + public: + /** + * Initializes the provider to refresh credentials form the EC2 instance metadata service every 5 minutes. + * Constructs an EC2MetadataClient using the default http stack (most likely what you want). + */ + InstanceProfileCredentialsProvider(long refreshRateMs = REFRESH_THRESHOLD); + + /** + * Initializes the provider to refresh credentials form the EC2 instance metadata service every 5 minutes, + * uses a supplied EC2MetadataClient. + */ + InstanceProfileCredentialsProvider(const std::shared_ptr<Aws::Config::EC2InstanceProfileConfigLoader>&, long refreshRateMs = REFRESH_THRESHOLD); + + /** + * Retrieves the credentials if found, otherwise returns empty credential set. + */ + AWSCredentials GetAWSCredentials() override; + + protected: + void Reload() override; + + private: + void RefreshIfExpired(); + + std::shared_ptr<Aws::Config::AWSProfileConfigLoader> m_ec2MetadataConfigLoader; + long m_loadFrequencyMs; + }; + + /** + * ECS credentials provider implementation that loads credentials from the Amazon + * ECS metadata service or an arbitrary endpoint. + */ + class AWS_CORE_API TaskRoleCredentialsProvider : public AWSCredentialsProvider + { + public: + /** + * Initializes the provider to retrieve credentials from the ECS metadata service every 5 minutes, + * or before it expires. + * @param resourcePath A path appended to the metadata service endpoint. + * @param refreshRateMs The number of milliseconds after which the credentials will be fetched again. + */ + TaskRoleCredentialsProvider(const char* resourcePath, long refreshRateMs = REFRESH_THRESHOLD); + + /** + * Initializes the provider to retrieve credentials from a provided endpoint every 5 minutes or before it + * expires. + * @param endpoint The full URI to resolve to get credentials. + * @param token An optional authorization token passed to the URI via the 'Authorization' HTTP header. + * @param refreshRateMs The number of milliseconds after which the credentials will be fetched again. + */ + TaskRoleCredentialsProvider(const char* endpoint, const char* token, long refreshRateMs = REFRESH_THRESHOLD); + + /** + * Initializes the provider to retrieve credentials using the provided client. + * @param client The ECSCredentialsClient instance to use when retrieving credentials. + * @param refreshRateMs The number of milliseconds after which the credentials will be fetched again. + */ + TaskRoleCredentialsProvider(const std::shared_ptr<Aws::Internal::ECSCredentialsClient>& client, + long refreshRateMs = REFRESH_THRESHOLD); + /** + * Retrieves the credentials if found, otherwise returns empty credential set. + */ + AWSCredentials GetAWSCredentials() override; + + protected: + void Reload() override; + private: + bool ExpiresSoon() const; + void RefreshIfExpired(); + + private: + std::shared_ptr<Aws::Internal::ECSCredentialsClient> m_ecsCredentialsClient; + long m_loadFrequencyMs; + Aws::Auth::AWSCredentials m_credentials; + }; + /** * Process credentials provider that loads credentials by running another command (or program) configured in config file * The configuration format is as following: @@ -312,5 +312,5 @@ namespace Aws Aws::String m_profileToUse; Aws::Auth::AWSCredentials m_credentials; }; - } // namespace Auth -} // namespace Aws + } // namespace Auth +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h index dae8cf5a42..b45e250b6c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/auth/AWSCredentialsProviderChain.h @@ -2,67 +2,67 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <aws/core/auth/AWSCredentialsProvider.h> -#include <memory> - -namespace Aws -{ - namespace Auth - { - /** - * Abstract class for providing chains of credentials providers. When a credentials provider in the chain returns empty credentials, - * We go on to the next provider until we have either exhausted the installed providers in the chain or something returns non-empty credentials. - */ - class AWS_CORE_API AWSCredentialsProviderChain : public AWSCredentialsProvider - { - public: - virtual ~AWSCredentialsProviderChain() = default; - - /** - * When a credentials provider in the chain returns empty credentials, - * We go on to the next provider until we have either exhausted the installed providers in the chain or something returns non-empty credentials. - */ - virtual AWSCredentials GetAWSCredentials(); - - /** - * Gets all providers stored in this chain. - */ - const Aws::Vector<std::shared_ptr<AWSCredentialsProvider>>& GetProviders() { return m_providerChain; } - - protected: - /** - * This class is only allowed to be initialized by subclasses. - */ - AWSCredentialsProviderChain() = default; - - /** - * Adds a provider to the back of the chain. - */ - void AddProvider(const std::shared_ptr<AWSCredentialsProvider>& provider) { m_providerChain.push_back(provider); } - - - private: - Aws::Vector<std::shared_ptr<AWSCredentialsProvider> > m_providerChain; - }; - - /** - * Creates an AWSCredentialsProviderChain which uses in order EnvironmentAWSCredentialsProvider, ProfileConfigFileAWSCredentialsProvider, - * and InstanceProfileCredentialsProvider. - */ - class AWS_CORE_API DefaultAWSCredentialsProviderChain : public AWSCredentialsProviderChain - { - public: - /** - * Initializes the provider chain with EnvironmentAWSCredentialsProvider, ProfileConfigFileAWSCredentialsProvider, - * and InstanceProfileCredentialsProvider in that order. - */ - DefaultAWSCredentialsProviderChain(); - }; - - } // namespace Auth -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <memory> + +namespace Aws +{ + namespace Auth + { + /** + * Abstract class for providing chains of credentials providers. When a credentials provider in the chain returns empty credentials, + * We go on to the next provider until we have either exhausted the installed providers in the chain or something returns non-empty credentials. + */ + class AWS_CORE_API AWSCredentialsProviderChain : public AWSCredentialsProvider + { + public: + virtual ~AWSCredentialsProviderChain() = default; + + /** + * When a credentials provider in the chain returns empty credentials, + * We go on to the next provider until we have either exhausted the installed providers in the chain or something returns non-empty credentials. + */ + virtual AWSCredentials GetAWSCredentials(); + + /** + * Gets all providers stored in this chain. + */ + const Aws::Vector<std::shared_ptr<AWSCredentialsProvider>>& GetProviders() { return m_providerChain; } + + protected: + /** + * This class is only allowed to be initialized by subclasses. + */ + AWSCredentialsProviderChain() = default; + + /** + * Adds a provider to the back of the chain. + */ + void AddProvider(const std::shared_ptr<AWSCredentialsProvider>& provider) { m_providerChain.push_back(provider); } + + + private: + Aws::Vector<std::shared_ptr<AWSCredentialsProvider> > m_providerChain; + }; + + /** + * Creates an AWSCredentialsProviderChain which uses in order EnvironmentAWSCredentialsProvider, ProfileConfigFileAWSCredentialsProvider, + * and InstanceProfileCredentialsProvider. + */ + class AWS_CORE_API DefaultAWSCredentialsProviderChain : public AWSCredentialsProviderChain + { + public: + /** + * Initializes the provider chain with EnvironmentAWSCredentialsProvider, ProfileConfigFileAWSCredentialsProvider, + * and InstanceProfileCredentialsProvider in that order. + */ + DefaultAWSCredentialsProviderChain(); + }; + + } // namespace Auth +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h index 186206a66e..d091e0f29e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSClient.h @@ -1,129 +1,129 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/client/CoreErrors.h> -#include <aws/core/http/HttpTypes.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/AmazonWebServiceResult.h> -#include <aws/core/utils/crypto/Hash.h> -#include <aws/core/auth/AWSAuthSignerProvider.h> -#include <memory> -#include <atomic> - + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/CoreErrors.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/AmazonWebServiceResult.h> +#include <aws/core/utils/crypto/Hash.h> +#include <aws/core/auth/AWSAuthSignerProvider.h> +#include <memory> +#include <atomic> + struct aws_array_list; -namespace Aws -{ - namespace Utils - { - template<typename R, typename E> - class Outcome; - - namespace Xml - { - class XmlDocument; - } // namespace Xml - - namespace Json - { - class JsonValue; - } // namespace Json - - namespace RateLimits - { - class RateLimiterInterface; - } // namespace RateLimits - - namespace Crypto - { - class MD5; - } // namespace Crypto - } // namespace Utils - - namespace Http - { - class HttpClient; - - class HttpClientFactory; - - class HttpRequest; - - class HttpResponse; - - class URI; - } // namespace Http - - namespace Auth - { - AWS_CORE_API extern const char SIGV4_SIGNER[]; - AWS_CORE_API extern const char NULL_SIGNER[]; - } - - class AmazonWebServiceRequest; - - namespace Client - { - template<typename ERROR_TYPE> - class AWSError; - class AWSErrorMarshaller; - class AWSRestfulJsonErrorMarshaller; - class AWSAuthSigner; - struct ClientConfiguration; - class RetryStrategy; - - typedef Utils::Outcome<std::shared_ptr<Aws::Http::HttpResponse>, AWSError<CoreErrors>> HttpResponseOutcome; - typedef Utils::Outcome<AmazonWebServiceResult<Utils::Stream::ResponseStream>, AWSError<CoreErrors>> StreamOutcome; - - /** - * Abstract AWS Client. Contains most of the functionality necessary to build an http request, get it signed, and send it accross the wire. - */ - class AWS_CORE_API AWSClient - { - public: - /** - * configuration will be used for http client settings, retry strategy, throttles, and signing information. - * supplied signer will be used for all requests, aws sdk clients will use default AuthV4Signer. - * errorMarshaller tells the client how to convert error payloads into AWSError objects. - */ - AWSClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - /** - * Configuration will be used for http client settings, retry strategy, throttles, and signing information. - * Pass a signer provider to determine the proper signer for a given request; AWS services will use - * SigV4 signer. errorMarshaller tells the client how to convert error payloads into AWSError objects. - */ - AWSClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - virtual ~AWSClient() { }; - - /** +namespace Aws +{ + namespace Utils + { + template<typename R, typename E> + class Outcome; + + namespace Xml + { + class XmlDocument; + } // namespace Xml + + namespace Json + { + class JsonValue; + } // namespace Json + + namespace RateLimits + { + class RateLimiterInterface; + } // namespace RateLimits + + namespace Crypto + { + class MD5; + } // namespace Crypto + } // namespace Utils + + namespace Http + { + class HttpClient; + + class HttpClientFactory; + + class HttpRequest; + + class HttpResponse; + + class URI; + } // namespace Http + + namespace Auth + { + AWS_CORE_API extern const char SIGV4_SIGNER[]; + AWS_CORE_API extern const char NULL_SIGNER[]; + } + + class AmazonWebServiceRequest; + + namespace Client + { + template<typename ERROR_TYPE> + class AWSError; + class AWSErrorMarshaller; + class AWSRestfulJsonErrorMarshaller; + class AWSAuthSigner; + struct ClientConfiguration; + class RetryStrategy; + + typedef Utils::Outcome<std::shared_ptr<Aws::Http::HttpResponse>, AWSError<CoreErrors>> HttpResponseOutcome; + typedef Utils::Outcome<AmazonWebServiceResult<Utils::Stream::ResponseStream>, AWSError<CoreErrors>> StreamOutcome; + + /** + * Abstract AWS Client. Contains most of the functionality necessary to build an http request, get it signed, and send it accross the wire. + */ + class AWS_CORE_API AWSClient + { + public: + /** + * configuration will be used for http client settings, retry strategy, throttles, and signing information. + * supplied signer will be used for all requests, aws sdk clients will use default AuthV4Signer. + * errorMarshaller tells the client how to convert error payloads into AWSError objects. + */ + AWSClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + /** + * Configuration will be used for http client settings, retry strategy, throttles, and signing information. + * Pass a signer provider to determine the proper signer for a given request; AWS services will use + * SigV4 signer. errorMarshaller tells the client how to convert error payloads into AWSError objects. + */ + AWSClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + virtual ~AWSClient() { }; + + /** * Generates a signed Uri using the injected signer. for the supplied uri and http method. expirationInSeconds defaults - * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. - */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, long long expirationInSeconds = 0); - - /** + * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. + */ + Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, long long expirationInSeconds = 0); + + /** * Generates a signed Uri using the injected signer. for the supplied uri, http method and customized headers. expirationInSeconds defaults - * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. - */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); - - /** + * to 0 which is the default 7 days. The implication of this function is using auth signer v4 to sign it. + */ + Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); + + /** * Generates a signed Uri using the injected signer. for the supplied uri and http method and region. expirationInSeconds defaults * to 0 which is the default 7 days. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, long long expirationInSeconds = 0) const; - - /** + Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, long long expirationInSeconds = 0) const; + + /** * Generates a signed Uri using the injected signer. for the supplied uri, http method and customized headers. expirationInSeconds defaults * to 0 which is the default 7 days. */ @@ -133,8 +133,8 @@ namespace Aws * Generates a signed Uri using the injected signer. for the supplied uri and http method, region, and service name. expirationInSeconds defaults * to 0 which is the default 7 days. */ - Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds = 0) const; - + Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds = 0) const; + /** * Generates a signed Uri using the injected signer. for the supplied uri, http method and customized headers. expirationInSeconds defaults * to 0 which is the default 7 days. @@ -142,25 +142,25 @@ namespace Aws Aws::String GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds = 0); Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, - const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; - - Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, - const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; - - Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, - const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; - - /** - * Stop all requests immediately. - * In flight requests will likely fail. - */ - void DisableRequestProcessing(); - - /** - * Enable/ReEnable requests. - */ - void EnableRequestProcessing(); - + const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + + Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, + const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + + Aws::String GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, + const Aws::Http::QueryStringParameterCollection& extraParams = Aws::Http::QueryStringParameterCollection(), long long expirationInSeconds = 0) const; + + /** + * Stop all requests immediately. + * In flight requests will likely fail. + */ + void DisableRequestProcessing(); + + /** + * Enable/ReEnable requests. + */ + void EnableRequestProcessing(); + inline virtual const char* GetServiceClientName() const { return m_serviceName.c_str(); } /** * service client name is part of userAgent. @@ -168,106 +168,106 @@ namespace Aws * Note: this API should only be called in your extended class constructors. */ virtual void SetServiceClientName(const Aws::String& name); - - protected: - /** + + protected: + /** * Calls AttemptOneRequest until it either, succeeds, runs out of retries from the retry strategy, - * or encounters and error that is not retryable. - */ - HttpResponseOutcome AttemptExhaustively(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod httpMethod, + * or encounters and error that is not retryable. + */ + HttpResponseOutcome AttemptExhaustively(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod httpMethod, const char* signerName, const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** + + /** * Calls AttemptOneRequest until it either, succeeds, runs out of retries from the retry strategy, - * or encounters and error that is not retryable. This method is for payloadless requests e.g. GET, DELETE, HEAD + * or encounters and error that is not retryable. This method is for payloadless requests e.g. GET, DELETE, HEAD * * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid * name. - */ + */ HttpResponseOutcome AttemptExhaustively(const Aws::Http::URI& uri, - Http::HttpMethod httpMethod, - const char* signerName, + Http::HttpMethod httpMethod, + const char* signerName, const char* requestName = "", const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** - * Build an Http Request from the AmazonWebServiceRequest object. Signs the request, sends it accross the wire - * then reports the http response. - */ - HttpResponseOutcome AttemptOneRequest(const std::shared_ptr<Http::HttpRequest>& httpRequest, - const Aws::AmazonWebServiceRequest& request, + + /** + * Build an Http Request from the AmazonWebServiceRequest object. Signs the request, sends it accross the wire + * then reports the http response. + */ + HttpResponseOutcome AttemptOneRequest(const std::shared_ptr<Http::HttpRequest>& httpRequest, + const Aws::AmazonWebServiceRequest& request, const char* signerName, const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** - * Signs an Http Request, sends it accross the wire - * then reports the http response. This method is for payloadless requests e.g. GET, DELETE, HEAD + + /** + * Signs an Http Request, sends it accross the wire + * then reports the http response. This method is for payloadless requests e.g. GET, DELETE, HEAD * * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid * name. - */ - HttpResponseOutcome AttemptOneRequest(const std::shared_ptr<Http::HttpRequest>& httpRequest, - const char* signerName, + */ + HttpResponseOutcome AttemptOneRequest(const std::shared_ptr<Http::HttpRequest>& httpRequest, + const char* signerName, const char* requestName = "", const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** - * This is used for structureless response payloads (file streams, binary data etc...). It calls AttemptExhaustively, but upon - * return transfers ownership of the underlying stream for the http response to the caller. - */ - StreamOutcome MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + + /** + * This is used for structureless response payloads (file streams, binary data etc...). It calls AttemptExhaustively, but upon + * return transfers ownership of the underlying stream for the http response to the caller. + */ + StreamOutcome MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, const char* signerName = Aws::Auth::SIGV4_SIGNER, const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** - * This is used for structureless response payloads (file streams, binary data etc...). It calls AttemptExhaustively, but upon - * return transfers ownership of the underlying stream for the http response to the caller. + + /** + * This is used for structureless response payloads (file streams, binary data etc...). It calls AttemptExhaustively, but upon + * return transfers ownership of the underlying stream for the http response to the caller. * * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid * name. - */ - StreamOutcome MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, + */ + StreamOutcome MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, const char* requestName = "", const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** - * Abstract. Subclassing clients should override this to tell the client how to marshall error payloads - */ - virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const = 0; - - /** - * Transforms the AmazonWebServicesResult object into an HttpRequest. - */ - virtual void BuildHttpRequest(const Aws::AmazonWebServiceRequest& request, - const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest) const; - - /** - * Gets the underlying ErrorMarshaller for subclasses to use. - */ - const std::shared_ptr<AWSErrorMarshaller>& GetErrorMarshaller() const - { - return m_errorMarshaller; - } - - /** + + /** + * Abstract. Subclassing clients should override this to tell the client how to marshall error payloads + */ + virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const = 0; + + /** + * Transforms the AmazonWebServicesResult object into an HttpRequest. + */ + virtual void BuildHttpRequest(const Aws::AmazonWebServiceRequest& request, + const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest) const; + + /** + * Gets the underlying ErrorMarshaller for subclasses to use. + */ + const std::shared_ptr<AWSErrorMarshaller>& GetErrorMarshaller() const + { + return m_errorMarshaller; + } + + /** * Gets the corresponding signer from the signers map by name. - */ - Aws::Client::AWSAuthSigner* GetSignerByName(const char* name) const; + */ + Aws::Client::AWSAuthSigner* GetSignerByName(const char* name) const; protected: - + /** * Creates an HttpRequest instance with the given URI and sets the proper headers from the * AmazonWebRequest, and finally signs that request with the given the signer. @@ -284,154 +284,154 @@ namespace Aws */ std::shared_ptr<Aws::Http::HttpResponse> MakeHttpRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const; Aws::String m_region; - private: - /** - * Try to adjust signer's clock - * return true if signer's clock is adjusted, false otherwise. - */ - bool AdjustClockSkew(HttpResponseOutcome& outcome, const char* signerName) const; - void AddHeadersToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const Http::HeaderValueCollection& headerValues) const; + private: + /** + * Try to adjust signer's clock + * return true if signer's clock is adjusted, false otherwise. + */ + bool AdjustClockSkew(HttpResponseOutcome& outcome, const char* signerName) const; + void AddHeadersToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const Http::HeaderValueCollection& headerValues) const; void AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const std::shared_ptr<Aws::IOStream>& body, bool needsContentMd5 = false, bool isChunked = false) const; - void AddCommonHeaders(Aws::Http::HttpRequest& httpRequest) const; - void InitializeGlobalStatics(); - std::shared_ptr<Aws::Http::HttpRequest> ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, - Aws::Http::HttpMethod method, const Aws::Http::QueryStringParameterCollection& extraParams) const; - - std::shared_ptr<Aws::Http::HttpClient> m_httpClient; - std::shared_ptr<Aws::Auth::AWSAuthSignerProvider> m_signerProvider; - std::shared_ptr<AWSErrorMarshaller> m_errorMarshaller; - std::shared_ptr<RetryStrategy> m_retryStrategy; - std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> m_writeRateLimiter; - std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> m_readRateLimiter; - Aws::String m_userAgent; + void AddCommonHeaders(Aws::Http::HttpRequest& httpRequest) const; + void InitializeGlobalStatics(); + std::shared_ptr<Aws::Http::HttpRequest> ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, + Aws::Http::HttpMethod method, const Aws::Http::QueryStringParameterCollection& extraParams) const; + + std::shared_ptr<Aws::Http::HttpClient> m_httpClient; + std::shared_ptr<Aws::Auth::AWSAuthSignerProvider> m_signerProvider; + std::shared_ptr<AWSErrorMarshaller> m_errorMarshaller; + std::shared_ptr<RetryStrategy> m_retryStrategy; + std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> m_writeRateLimiter; + std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> m_readRateLimiter; + Aws::String m_userAgent; bool m_customizedUserAgent; - std::shared_ptr<Aws::Utils::Crypto::Hash> m_hash; + std::shared_ptr<Aws::Utils::Crypto::Hash> m_hash; long m_requestTimeoutMs; - bool m_enableClockSkewAdjustment; + bool m_enableClockSkewAdjustment; Aws::String m_serviceName; - }; - - typedef Utils::Outcome<AmazonWebServiceResult<Utils::Json::JsonValue>, AWSError<CoreErrors>> JsonOutcome; + }; + + typedef Utils::Outcome<AmazonWebServiceResult<Utils::Json::JsonValue>, AWSError<CoreErrors>> JsonOutcome; AWS_CORE_API Aws::String GetAuthorizationHeader(const Aws::Http::HttpRequest& httpRequest); - - /** - * AWSClient that handles marshalling json response bodies. You would inherit from this class - * to create a client that uses Json as its payload format. - */ - class AWS_CORE_API AWSJsonClient : public AWSClient - { - public: - typedef AWSClient BASECLASS; - - /** - * Simply calls AWSClient constructor. - */ - AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - /** - * Simply calls AWSClient constructor. - */ - AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - virtual ~AWSJsonClient() = default; - - protected: - /** - * Converts/Parses an http response into a meaningful AWSError object using the json message structure. - */ - virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; - - /** - * Returns a Json document or an error from the request. Does some marshalling json and raw streams, - * then just calls AttemptExhaustively. - * - * method defaults to POST - */ - JsonOutcome MakeRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + + /** + * AWSClient that handles marshalling json response bodies. You would inherit from this class + * to create a client that uses Json as its payload format. + */ + class AWS_CORE_API AWSJsonClient : public AWSClient + { + public: + typedef AWSClient BASECLASS; + + /** + * Simply calls AWSClient constructor. + */ + AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + /** + * Simply calls AWSClient constructor. + */ + AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + virtual ~AWSJsonClient() = default; + + protected: + /** + * Converts/Parses an http response into a meaningful AWSError object using the json message structure. + */ + virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; + + /** + * Returns a Json document or an error from the request. Does some marshalling json and raw streams, + * then just calls AttemptExhaustively. + * + * method defaults to POST + */ + JsonOutcome MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, const char* signerName = Aws::Auth::SIGV4_SIGNER, const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - /** - * Returns a Json document or an error from the request. Does some marshalling json and raw streams, - * then just calls AttemptExhaustively. - * + + /** + * Returns a Json document or an error from the request. Does some marshalling json and raw streams, + * then just calls AttemptExhaustively. + * * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid * name. * - * method defaults to POST - */ - JsonOutcome MakeRequest(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, + * method defaults to POST + */ + JsonOutcome MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, const char* requestName = "", const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; JsonOutcome MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const; - }; - - typedef Utils::Outcome<AmazonWebServiceResult<Utils::Xml::XmlDocument>, AWSError<CoreErrors>> XmlOutcome; - - /** - * AWSClient that handles marshalling xml response bodies. You would inherit from this class - * to create a client that uses Xml as its payload format. - */ - class AWS_CORE_API AWSXMLClient : public AWSClient - { - public: - - typedef AWSClient BASECLASS; - - AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); - - virtual ~AWSXMLClient() = default; - - protected: - /** - * Converts/Parses an http response into a meaningful AWSError object. Using the XML message structure. - */ - virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; - - /** - * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, - * then just calls AttemptExhaustively. - * - * method defaults to POST - */ - XmlOutcome MakeRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + }; + + typedef Utils::Outcome<AmazonWebServiceResult<Utils::Xml::XmlDocument>, AWSError<CoreErrors>> XmlOutcome; + + /** + * AWSClient that handles marshalling xml response bodies. You would inherit from this class + * to create a client that uses Xml as its payload format. + */ + class AWS_CORE_API AWSXMLClient : public AWSClient + { + public: + + typedef AWSClient BASECLASS; + + AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller); + + virtual ~AWSXMLClient() = default; + + protected: + /** + * Converts/Parses an http response into a meaningful AWSError object. Using the XML message structure. + */ + virtual AWSError<CoreErrors> BuildAWSError(const std::shared_ptr<Aws::Http::HttpResponse>& response) const override; + + /** + * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, + * then just calls AttemptExhaustively. + * + * method defaults to POST + */ + XmlOutcome MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, const char* signerName = Aws::Auth::SIGV4_SIGNER, const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - - - /** - * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, - * then just calls AttemptExhaustively. - * + + + /** + * Returns an xml document or an error from the request. Does some marshalling xml and raw streams, + * then just calls AttemptExhaustively. + * * requestName is used for metrics and defaults to empty string, to avoid empty names in metrics provide a valid * name. * - * method defaults to POST - */ - XmlOutcome MakeRequest(const Aws::Http::URI& uri, - Http::HttpMethod method = Http::HttpMethod::HTTP_POST, - const char* signerName = Aws::Auth::SIGV4_SIGNER, + * method defaults to POST + */ + XmlOutcome MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method = Http::HttpMethod::HTTP_POST, + const char* signerName = Aws::Auth::SIGV4_SIGNER, const char* requestName = "", const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; @@ -457,7 +457,7 @@ namespace Aws const char* requestName = "", const char* signerRegionOverride = nullptr, const char* signerServiceNameOverride = nullptr) const; - }; - - } // namespace Client -} // namespace Aws + }; + + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h index c88c1bdd5d..0919684698 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSError.h @@ -2,21 +2,21 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/http/HttpResponse.h> + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/http/HttpResponse.h> #include <aws/core/utils/xml/XmlSerializer.h> #include <aws/core/utils/json/JsonSerializer.h> -#include <aws/core/utils/StringUtils.h> - -namespace Aws -{ - namespace Client - { - enum class CoreErrors; +#include <aws/core/utils/StringUtils.h> + +namespace Aws +{ + namespace Client + { + enum class CoreErrors; class XmlErrorMarshaller; class JsonErrorMarshaller; @@ -27,35 +27,35 @@ namespace Aws JSON }; - /** - * Container for Error enumerations with additional exception information. Name, message, retryable etc.... - */ - template<typename ERROR_TYPE> - class AWSError - { + /** + * Container for Error enumerations with additional exception information. Name, message, retryable etc.... + */ + template<typename ERROR_TYPE> + class AWSError + { // Allow ErrorMarshaller to set error payload. friend class XmlErrorMarshaller; friend class JsonErrorMarshaller; template<typename T> friend class AWSError; - public: - /** - * Initializes AWSError object as empty with the error not being retryable. - */ + public: + /** + * Initializes AWSError object as empty with the error not being retryable. + */ AWSError() : m_responseCode(Aws::Http::HttpResponseCode::REQUEST_NOT_MADE), m_isRetryable(false) {} - /** - * Initializes AWSError object with errorType, exceptionName, message, and retryable flag. - */ - AWSError(ERROR_TYPE errorType, Aws::String exceptionName, const Aws::String message, bool isRetryable) : + /** + * Initializes AWSError object with errorType, exceptionName, message, and retryable flag. + */ + AWSError(ERROR_TYPE errorType, Aws::String exceptionName, const Aws::String message, bool isRetryable) : m_errorType(errorType), m_exceptionName(exceptionName), m_message(message), m_responseCode(Aws::Http::HttpResponseCode::REQUEST_NOT_MADE), m_isRetryable(isRetryable), m_errorPayloadType(ErrorPayloadType::NOT_SET) {} - /** - * Initializes AWSError object with errorType and retryable flag. ExceptionName and message are empty. - */ - AWSError(ERROR_TYPE errorType, bool isRetryable) : + /** + * Initializes AWSError object with errorType and retryable flag. ExceptionName and message are empty. + */ + AWSError(ERROR_TYPE errorType, bool isRetryable) : m_errorType(errorType), m_responseCode(Aws::Http::HttpResponseCode::REQUEST_NOT_MADE), m_isRetryable(isRetryable), m_errorPayloadType(ErrorPayloadType::NOT_SET) {} - + AWSError(AWSError&& rhs) = default; AWSError(const AWSError& rhs) = default; @@ -66,8 +66,8 @@ namespace Aws m_requestId(std::move(rhs.m_requestId)), m_responseHeaders(std::move(rhs.m_responseHeaders)), m_responseCode(rhs.m_responseCode), m_isRetryable(rhs.m_isRetryable), m_errorPayloadType(rhs.m_errorPayloadType), m_xmlPayload(std::move(rhs.m_xmlPayload)), m_jsonPayload(std::move(rhs.m_jsonPayload)) - {} - + {} + template<typename OTHER_ERROR_TYPE> AWSError(const AWSError<OTHER_ERROR_TYPE>& rhs) : m_errorType(static_cast<ERROR_TYPE>(rhs.m_errorType)), m_exceptionName(rhs.m_exceptionName), @@ -77,7 +77,7 @@ namespace Aws m_xmlPayload(rhs.m_xmlPayload), m_jsonPayload(rhs.m_jsonPayload) {} - /** + /** * Copy assignment operator */ AWSError& operator=(const AWSError<ERROR_TYPE>&) = default; @@ -88,26 +88,26 @@ namespace Aws AWSError& operator=(AWSError<ERROR_TYPE>&& other) = default; /** - * Gets underlying errorType. - */ - inline const ERROR_TYPE GetErrorType() const { return m_errorType; } - /** - * Gets the underlying ExceptionName. - */ - inline const Aws::String& GetExceptionName() const { return m_exceptionName; } - /** - *Sets the underlying ExceptionName. - */ - inline void SetExceptionName(const Aws::String& exceptionName) { m_exceptionName = exceptionName; } - /** - * Gets the error message. - */ - inline const Aws::String& GetMessage() const { return m_message; } - /** - * Sets the error message - */ - inline void SetMessage(const Aws::String& message) { m_message = message; } - /** + * Gets underlying errorType. + */ + inline const ERROR_TYPE GetErrorType() const { return m_errorType; } + /** + * Gets the underlying ExceptionName. + */ + inline const Aws::String& GetExceptionName() const { return m_exceptionName; } + /** + *Sets the underlying ExceptionName. + */ + inline void SetExceptionName(const Aws::String& exceptionName) { m_exceptionName = exceptionName; } + /** + * Gets the error message. + */ + inline const Aws::String& GetMessage() const { return m_message; } + /** + * Sets the error message + */ + inline void SetMessage(const Aws::String& message) { m_message = message; } + /** * Gets the resolved remote host IP address. * This value is only available after DNS resolution and with CURL http client right now. * Otherwise an empty string is returned. @@ -128,30 +128,30 @@ namespace Aws */ inline void SetRequestId(const Aws::String& requestId) { m_requestId = requestId; } /** - * Returns whether or not this error is eligible for retry. - */ - inline bool ShouldRetry() const { return m_isRetryable; } - /** - * Gets the response headers from the http response. - */ - inline const Aws::Http::HeaderValueCollection& GetResponseHeaders() const { return m_responseHeaders; } - /** - * Sets the response headers from the http response. - */ - inline void SetResponseHeaders(const Aws::Http::HeaderValueCollection& headers) { m_responseHeaders = headers; } - /** - * Tests whether or not a header exists. - */ - inline bool ResponseHeaderExists(const Aws::String& headerName) const { return m_responseHeaders.find(Aws::Utils::StringUtils::ToLower(headerName.c_str())) != m_responseHeaders.end(); } - /** - * Gets the response code from the http response - */ - inline Aws::Http::HttpResponseCode GetResponseCode() const { return m_responseCode; } - /** - * Sets the response code from the http response - */ - inline void SetResponseCode(Aws::Http::HttpResponseCode responseCode) { m_responseCode = responseCode; } - + * Returns whether or not this error is eligible for retry. + */ + inline bool ShouldRetry() const { return m_isRetryable; } + /** + * Gets the response headers from the http response. + */ + inline const Aws::Http::HeaderValueCollection& GetResponseHeaders() const { return m_responseHeaders; } + /** + * Sets the response headers from the http response. + */ + inline void SetResponseHeaders(const Aws::Http::HeaderValueCollection& headers) { m_responseHeaders = headers; } + /** + * Tests whether or not a header exists. + */ + inline bool ResponseHeaderExists(const Aws::String& headerName) const { return m_responseHeaders.find(Aws::Utils::StringUtils::ToLower(headerName.c_str())) != m_responseHeaders.end(); } + /** + * Gets the response code from the http response + */ + inline Aws::Http::HttpResponseCode GetResponseCode() const { return m_responseCode; } + /** + * Sets the response code from the http response + */ + inline void SetResponseCode(Aws::Http::HttpResponseCode responseCode) { m_responseCode = responseCode; } + protected: inline ErrorPayloadType GetErrorPayloadType() { return m_errorPayloadType; } inline void SetXmlPayload(const Aws::Utils::Xml::XmlDocument& xmlPayload) @@ -185,36 +185,36 @@ namespace Aws return m_jsonPayload; } - ERROR_TYPE m_errorType; - Aws::String m_exceptionName; - Aws::String m_message; + ERROR_TYPE m_errorType; + Aws::String m_exceptionName; + Aws::String m_message; Aws::String m_remoteHostIpAddress; Aws::String m_requestId; - Aws::Http::HeaderValueCollection m_responseHeaders; - Aws::Http::HttpResponseCode m_responseCode; - bool m_isRetryable; + Aws::Http::HeaderValueCollection m_responseHeaders; + Aws::Http::HttpResponseCode m_responseCode; + bool m_isRetryable; ErrorPayloadType m_errorPayloadType; Aws::Utils::Xml::XmlDocument m_xmlPayload; Aws::Utils::Json::JsonValue m_jsonPayload; - }; - - template<typename T> - Aws::OStream& operator << (Aws::OStream& s, const AWSError<T>& e) - { - s << "HTTP response code: " << static_cast<int>(e.GetResponseCode()) << "\n" + }; + + template<typename T> + Aws::OStream& operator << (Aws::OStream& s, const AWSError<T>& e) + { + s << "HTTP response code: " << static_cast<int>(e.GetResponseCode()) << "\n" << "Resolved remote host IP address: " << e.GetRemoteHostIpAddress() << "\n" << "Request ID: " << e.GetRequestId() << "\n" - << "Exception name: " << e.GetExceptionName() << "\n" - << "Error message: " << e.GetMessage() << "\n" - << e.GetResponseHeaders().size() << " response headers:"; - - for (auto&& header : e.GetResponseHeaders()) - { - s << "\n" << header.first << " : " << header.second; - } - return s; - } - - } // namespace Client -} // namespace Aws + << "Exception name: " << e.GetExceptionName() << "\n" + << "Error message: " << e.GetMessage() << "\n" + << e.GetResponseHeaders().size() << " response headers:"; + + for (auto&& header : e.GetResponseHeaders()) + { + s << "\n" << header.first << " : " << header.second; + } + return s; + } + + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h index 628b9565fd..f86076227e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AWSErrorMarshaller.h @@ -2,20 +2,20 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Http - { - class HttpResponse; - enum class HttpResponseCode; - } - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Http + { + class HttpResponse; + enum class HttpResponseCode; + } + namespace Utils { namespace Xml @@ -28,31 +28,31 @@ namespace Aws } } - namespace Client - { - enum class CoreErrors; - - template<typename ERROR_TYPE> - class AWSError; - - /** - * Marshaller for core error types. - */ - class AWS_CORE_API AWSErrorMarshaller - { + namespace Client + { + enum class CoreErrors; + + template<typename ERROR_TYPE> + class AWSError; + + /** + * Marshaller for core error types. + */ + class AWS_CORE_API AWSErrorMarshaller + { public: - virtual ~AWSErrorMarshaller() {} - - /** - * Converts an exceptionName and message into an Error object, if it can be parsed. Otherwise, it returns - * and AWSError with CoreErrors::UNKNOWN as the error type. - */ - virtual AWSError<CoreErrors> Marshall(const Aws::Http::HttpResponse& response) const = 0; - /** - * Attempts to finds an error code by the exception name. Otherwise returns CoreErrors::UNKNOWN as the error type. - */ - virtual AWSError<CoreErrors> FindErrorByName(const char* exceptionName) const; - virtual AWSError<CoreErrors> FindErrorByHttpResponseCode(Aws::Http::HttpResponseCode code) const; + virtual ~AWSErrorMarshaller() {} + + /** + * Converts an exceptionName and message into an Error object, if it can be parsed. Otherwise, it returns + * and AWSError with CoreErrors::UNKNOWN as the error type. + */ + virtual AWSError<CoreErrors> Marshall(const Aws::Http::HttpResponse& response) const = 0; + /** + * Attempts to finds an error code by the exception name. Otherwise returns CoreErrors::UNKNOWN as the error type. + */ + virtual AWSError<CoreErrors> FindErrorByName(const char* exceptionName) const; + virtual AWSError<CoreErrors> FindErrorByHttpResponseCode(Aws::Http::HttpResponseCode code) const; /** * Attempts to extract region from error. */ @@ -61,37 +61,37 @@ namespace Aws * Attempts to extract endpoint from error. */ virtual Aws::String ExtractEndpoint(const AWSError<CoreErrors>&) const { return {}; } - protected: - AWSError<CoreErrors> Marshall(const Aws::String& exceptionName, const Aws::String& message) const; - }; - - class AWS_CORE_API JsonErrorMarshaller : public AWSErrorMarshaller - { - using AWSErrorMarshaller::Marshall; + protected: + AWSError<CoreErrors> Marshall(const Aws::String& exceptionName, const Aws::String& message) const; + }; + + class AWS_CORE_API JsonErrorMarshaller : public AWSErrorMarshaller + { + using AWSErrorMarshaller::Marshall; public: - /** - * Converts an exceptionName and message into an Error object, if it can be parsed. Otherwise, it returns - * and AWSError with CoreErrors::UNKNOWN as the error type. - */ - AWSError<CoreErrors> Marshall(const Aws::Http::HttpResponse& response) const override; + /** + * Converts an exceptionName and message into an Error object, if it can be parsed. Otherwise, it returns + * and AWSError with CoreErrors::UNKNOWN as the error type. + */ + AWSError<CoreErrors> Marshall(const Aws::Http::HttpResponse& response) const override; protected: const Aws::Utils::Json::JsonValue& GetJsonPayloadFromError(const AWSError<CoreErrors>&) const; - }; - - class AWS_CORE_API XmlErrorMarshaller : public AWSErrorMarshaller - { - using AWSErrorMarshaller::Marshall; + }; + + class AWS_CORE_API XmlErrorMarshaller : public AWSErrorMarshaller + { + using AWSErrorMarshaller::Marshall; public: - /** - * Converts an exceptionName and message into an Error object, if it can be parsed. Otherwise, it returns - * and AWSError with CoreErrors::UNKNOWN as the error type. - */ - AWSError<CoreErrors> Marshall(const Aws::Http::HttpResponse& response) const override; + /** + * Converts an exceptionName and message into an Error object, if it can be parsed. Otherwise, it returns + * and AWSError with CoreErrors::UNKNOWN as the error type. + */ + AWSError<CoreErrors> Marshall(const Aws::Http::HttpResponse& response) const override; protected: const Aws::Utils::Xml::XmlDocument& GetXmlPayloadFromError(const AWSError<CoreErrors>&) const; - }; - - } // namespace Client -} // namespace Aws + }; + + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h index 6831791ffc..933dca67c0 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/AsyncCallerContext.h @@ -2,58 +2,58 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Client - { - /** - * Call-back context for all async client methods. This allows you to pass a context to your callbacks so that you can identify your requests. - * It is entirely intended that you override this class in-lieu of using a void* for the user context. The base class just gives you the ability to - * pass a uuid for your context. - */ - class AWS_CORE_API AsyncCallerContext - { - public: - /** - * Initializes object with generated UUID - */ - AsyncCallerContext(); - - /** - * Initializes object with UUID - */ - AsyncCallerContext(const Aws::String& uuid) : m_uuid(uuid) {} - - /** - * Initializes object with UUID - */ - AsyncCallerContext(const char* uuid) : m_uuid(uuid) {} - - virtual ~AsyncCallerContext() {} - - /** - * Gets underlying UUID - */ - inline const Aws::String& GetUUID() const { return m_uuid; } - - /** - * Sets underlying UUID - */ - inline void SetUUID(const Aws::String& value) { m_uuid = value; } - - /** - * Sets underlying UUID - */ - inline void SetUUID(const char* value) { m_uuid.assign(value); } - - private: - Aws::String m_uuid; - }; - } -} - + +#pragma once + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Client + { + /** + * Call-back context for all async client methods. This allows you to pass a context to your callbacks so that you can identify your requests. + * It is entirely intended that you override this class in-lieu of using a void* for the user context. The base class just gives you the ability to + * pass a uuid for your context. + */ + class AWS_CORE_API AsyncCallerContext + { + public: + /** + * Initializes object with generated UUID + */ + AsyncCallerContext(); + + /** + * Initializes object with UUID + */ + AsyncCallerContext(const Aws::String& uuid) : m_uuid(uuid) {} + + /** + * Initializes object with UUID + */ + AsyncCallerContext(const char* uuid) : m_uuid(uuid) {} + + virtual ~AsyncCallerContext() {} + + /** + * Gets underlying UUID + */ + inline const Aws::String& GetUUID() const { return m_uuid; } + + /** + * Sets underlying UUID + */ + inline void SetUUID(const Aws::String& value) { m_uuid = value; } + + /** + * Sets underlying UUID + */ + inline void SetUUID(const char* value) { m_uuid.assign(value); } + + private: + Aws::String m_uuid; + }; + } +} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h index ba54baaa83..6ffd1fe3fd 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/ClientConfiguration.h @@ -2,35 +2,35 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/http/Scheme.h> -#include <aws/core/Region.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/http/HttpTypes.h> -#include <memory> - -namespace Aws -{ - namespace Utils - { - namespace Threading - { - class Executor; - } // namespace Threading - - namespace RateLimits - { - class RateLimiterInterface; - } // namespace RateLimits - } // namespace Utils - namespace Client - { - class RetryStrategy; // forward declare - - /** + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/http/Scheme.h> +#include <aws/core/Region.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/http/HttpTypes.h> +#include <memory> + +namespace Aws +{ + namespace Utils + { + namespace Threading + { + class Executor; + } // namespace Threading + + namespace RateLimits + { + class RateLimiterInterface; + } // namespace RateLimits + } // namespace Utils + namespace Client + { + class RetryStrategy; // forward declare + + /** * Sets the behaviors of the underlying HTTP clients handling response with 30x status code. * By default, HTTP clients will always redirect the 30x response automatically, except when * specifying aws-global as the client region, then SDK will handle 30x response and redirect @@ -47,37 +47,37 @@ namespace Aws * This mutable structure is used to configure any of the AWS clients. * Default values can only be overwritten prior to passing to the client constructors. */ - struct AWS_CORE_API ClientConfiguration - { - ClientConfiguration(); + struct AWS_CORE_API ClientConfiguration + { + ClientConfiguration(); - /** + /** * Create a configuration based on settings in the aws configuration file for the given profile name. * The configuration file location can be set via the environment variable AWS_CONFIG_FILE */ ClientConfiguration(const char* profileName); /** - * User Agent string user for http calls. This is filled in for you in the constructor. Don't override this unless you have a really good reason. - */ - Aws::String userAgent; - /** - * Http scheme to use. E.g. Http or Https. Default HTTPS - */ - Aws::Http::Scheme scheme; - /** - * AWS Region to use in signing requests. Default US_EAST_1 - */ - Aws::String region; - /** - * Use dual stack endpoint in the endpoint calculation. It is your responsibility to verify that the service supports ipv6 in the region you select. - */ - bool useDualStack; - /** - * Max concurrent tcp connections for a single http client to use. Default 25. - */ - unsigned maxConnections; - /** + * User Agent string user for http calls. This is filled in for you in the constructor. Don't override this unless you have a really good reason. + */ + Aws::String userAgent; + /** + * Http scheme to use. E.g. Http or Https. Default HTTPS + */ + Aws::Http::Scheme scheme; + /** + * AWS Region to use in signing requests. Default US_EAST_1 + */ + Aws::String region; + /** + * Use dual stack endpoint in the endpoint calculation. It is your responsibility to verify that the service supports ipv6 in the region you select. + */ + bool useDualStack; + /** + * Max concurrent tcp connections for a single http client to use. Default 25. + */ + unsigned maxConnections; + /** * This is currently only applicable for Curl to set the http request level timeout, including possible dns lookup time, connection establish time, ssl handshake time and actual data transmission time. * the corresponding Curl option is CURLOPT_TIMEOUT_MS * defaults to 0, no http request level timeout. @@ -89,13 +89,13 @@ namespace Aws * For Curl, it's the low speed time, which contains the time in number milliseconds that transfer speed should be below "lowSpeedLimit" for the library to consider it too slow and abort. * Note that for Curl this config is converted to seconds by rounding down to the nearest whole second except when the value is greater than 0 and less than 1000. In this case it is set to one second. When it's 0, low speed limit check will be disabled. * Note that for Windows when this config is 0, the behavior is not specified by Windows. - */ - long requestTimeoutMs; - /** - * Socket connect timeout. Default 1000 ms. Unless you are very far away from your the data center you are talking to. 1000ms is more than sufficient. - */ - long connectTimeoutMs; - /** + */ + long requestTimeoutMs; + /** + * Socket connect timeout. Default 1000 ms. Unless you are very far away from your the data center you are talking to. 1000ms is more than sufficient. + */ + long connectTimeoutMs; + /** * Enable TCP keep-alive. Default true; * No-op for WinHTTP, WinINet and IXMLHTTPRequest2 client. */ @@ -112,34 +112,34 @@ namespace Aws */ unsigned long lowSpeedLimit; /** - * Strategy to use in case of failed requests. Default is DefaultRetryStrategy (e.g. exponential backoff) - */ - std::shared_ptr<RetryStrategy> retryStrategy; - /** - * Override the http endpoint used to talk to a service. - */ - Aws::String endpointOverride; - /** - * If you have users going through a proxy, set the proxy scheme here. Default HTTP - */ - Aws::Http::Scheme proxyScheme; - /** - * If you have users going through a proxy, set the host here. - */ - Aws::String proxyHost; - /** - * If you have users going through a proxy, set the port here. - */ - unsigned proxyPort; - /** - * If you have users going through a proxy, set the username here. - */ - Aws::String proxyUserName; - /** - * If you have users going through a proxy, set the password here. - */ - Aws::String proxyPassword; - /** + * Strategy to use in case of failed requests. Default is DefaultRetryStrategy (e.g. exponential backoff) + */ + std::shared_ptr<RetryStrategy> retryStrategy; + /** + * Override the http endpoint used to talk to a service. + */ + Aws::String endpointOverride; + /** + * If you have users going through a proxy, set the proxy scheme here. Default HTTP + */ + Aws::Http::Scheme proxyScheme; + /** + * If you have users going through a proxy, set the host here. + */ + Aws::String proxyHost; + /** + * If you have users going through a proxy, set the port here. + */ + unsigned proxyPort; + /** + * If you have users going through a proxy, set the username here. + */ + Aws::String proxyUserName; + /** + * If you have users going through a proxy, set the password here. + */ + Aws::String proxyPassword; + /** * SSL Certificate file to use for connecting to an HTTPS proxy. * Used to set CURLOPT_PROXY_SSLCERT in libcurl. Example: client.pem */ @@ -165,68 +165,68 @@ namespace Aws */ Aws::String proxySSLKeyPassword; /** - * Threading Executor implementation. Default uses std::thread::detach() - */ - std::shared_ptr<Aws::Utils::Threading::Executor> executor; - /** - * If you need to test and want to get around TLS validation errors, do that here. - * you probably shouldn't use this flag in a production scenario. - */ - bool verifySSL; - /** - * If your Certificate Authority path is different from the default, you can tell - * clients that aren't using the default trust store where to find your CA trust store. - * If you are on windows or apple, you likely don't want this. - */ - Aws::String caPath; - /** + * Threading Executor implementation. Default uses std::thread::detach() + */ + std::shared_ptr<Aws::Utils::Threading::Executor> executor; + /** + * If you need to test and want to get around TLS validation errors, do that here. + * you probably shouldn't use this flag in a production scenario. + */ + bool verifySSL; + /** + * If your Certificate Authority path is different from the default, you can tell + * clients that aren't using the default trust store where to find your CA trust store. + * If you are on windows or apple, you likely don't want this. + */ + Aws::String caPath; + /** * Same as caPath, but useful if you have users going through a proxy. * Used to set CURLOPT_PROXY_CAPATH in libcurl. */ Aws::String proxyCaPath; /** - * If you certificate file is different from the default, you can tell clients that - * aren't using the default trust store where to find your ca file. + * If you certificate file is different from the default, you can tell clients that + * aren't using the default trust store where to find your ca file. * If you are on windows or apple, you likely don't want this. - */ - Aws::String caFile; - /** + */ + Aws::String caFile; + /** * Same as caFile, but useful if you have users going through a proxy. * Used to set CURLOPT_PROXY_CAINFO in libcurl. */ Aws::String proxyCaFile; /** - * Rate Limiter implementation for outgoing bandwidth. Default is wide-open. - */ - std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> writeRateLimiter; - /** - * Rate Limiter implementation for incoming bandwidth. Default is wide-open. - */ - std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> readRateLimiter; - /** - * Override the http implementation the default factory returns. - */ - Aws::Http::TransferLibType httpLibOverride; - /** + * Rate Limiter implementation for outgoing bandwidth. Default is wide-open. + */ + std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> writeRateLimiter; + /** + * Rate Limiter implementation for incoming bandwidth. Default is wide-open. + */ + std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> readRateLimiter; + /** + * Override the http implementation the default factory returns. + */ + Aws::Http::TransferLibType httpLibOverride; + /** * Sets the behavior how http stack handles 30x redirect codes. - */ + */ FollowRedirectsPolicy followRedirects; - - /** - * Only works for Curl http client. - * Curl will by default add "Expect: 100-Continue" header in a Http request so as to avoid sending http - * payload to wire if server respond error immediately after receiving the header. - * Set this option to true will tell Curl to send http request header and body together. - * This can save one round-trip time and especially useful when the payload is small and network latency is more important. + + /** + * Only works for Curl http client. + * Curl will by default add "Expect: 100-Continue" header in a Http request so as to avoid sending http + * payload to wire if server respond error immediately after receiving the header. + * Set this option to true will tell Curl to send http request header and body together. + * This can save one round-trip time and especially useful when the payload is small and network latency is more important. * But be careful when Http request has large payload such S3 PutObject. You don't want to spend long time sending a large payload just getting a error response for server. - * The default value will be false. - */ - bool disableExpectHeader; - - /** - * If set to true clock skew will be adjusted after each http attempt, default to true. - */ - bool enableClockSkewAdjustment; + * The default value will be false. + */ + bool disableExpectHeader; + + /** + * If set to true clock skew will be adjusted after each http attempt, default to true. + */ + bool enableClockSkewAdjustment; /** * Enable host prefix injection. @@ -249,7 +249,7 @@ namespace Aws */ Aws::String profileName; - }; - - } // namespace Client -} // namespace Aws + }; + + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h index 52ebe51c82..b79feb2f78 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/CoreErrors.h @@ -2,66 +2,66 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include "aws/core/Core_EXPORTS.h" - -namespace Aws -{ +#pragma once + +#include "aws/core/Core_EXPORTS.h" + +namespace Aws +{ namespace Http - { - enum class HttpResponseCode; - } - namespace Client - { - template<typename ERROR_TYPE> - class AWSError; - - enum class CoreErrors - { - INCOMPLETE_SIGNATURE = 0, - INTERNAL_FAILURE = 1, - INVALID_ACTION = 2, - INVALID_CLIENT_TOKEN_ID = 3, - INVALID_PARAMETER_COMBINATION = 4, - INVALID_QUERY_PARAMETER = 5, - INVALID_PARAMETER_VALUE = 6, + { + enum class HttpResponseCode; + } + namespace Client + { + template<typename ERROR_TYPE> + class AWSError; + + enum class CoreErrors + { + INCOMPLETE_SIGNATURE = 0, + INTERNAL_FAILURE = 1, + INVALID_ACTION = 2, + INVALID_CLIENT_TOKEN_ID = 3, + INVALID_PARAMETER_COMBINATION = 4, + INVALID_QUERY_PARAMETER = 5, + INVALID_PARAMETER_VALUE = 6, MISSING_ACTION = 7, // SDK should never allow - MISSING_AUTHENTICATION_TOKEN = 8, // SDK should never allow + MISSING_AUTHENTICATION_TOKEN = 8, // SDK should never allow MISSING_PARAMETER = 9, // SDK should never allow - OPT_IN_REQUIRED = 10, - REQUEST_EXPIRED = 11, - SERVICE_UNAVAILABLE = 12, - THROTTLING = 13, - VALIDATION = 14, - ACCESS_DENIED = 15, + OPT_IN_REQUIRED = 10, + REQUEST_EXPIRED = 11, + SERVICE_UNAVAILABLE = 12, + THROTTLING = 13, + VALIDATION = 14, + ACCESS_DENIED = 15, RESOURCE_NOT_FOUND = 16, // Shared with multiple services UNRECOGNIZED_CLIENT = 17, // Most likely caused by an invalid access key or secret key - MALFORMED_QUERY_STRING = 18, // Where does this come from? (cognito identity uses it) - SLOW_DOWN = 19, - REQUEST_TIME_TOO_SKEWED = 20, - INVALID_SIGNATURE = 21, - SIGNATURE_DOES_NOT_MATCH = 22, - INVALID_ACCESS_KEY_ID = 23, - REQUEST_TIMEOUT = 24, - + MALFORMED_QUERY_STRING = 18, // Where does this come from? (cognito identity uses it) + SLOW_DOWN = 19, + REQUEST_TIME_TOO_SKEWED = 20, + INVALID_SIGNATURE = 21, + SIGNATURE_DOES_NOT_MATCH = 22, + INVALID_ACCESS_KEY_ID = 23, + REQUEST_TIMEOUT = 24, + NETWORK_CONNECTION = 99, // General failure to send message to service - - // These are needed for logical reasons + + // These are needed for logical reasons UNKNOWN = 100, // Unknown to the SDK - CLIENT_SIGNING_FAILURE = 101, // Client failed to sign the request + CLIENT_SIGNING_FAILURE = 101, // Client failed to sign the request USER_CANCELLED = 102, // User cancelled the request - SERVICE_EXTENSION_START_RANGE = 128 - }; + SERVICE_EXTENSION_START_RANGE = 128 + }; + + namespace CoreErrorsMapper + { + /** + * Finds a CoreErrors member if possible. Otherwise, returns UNKNOWN + */ + AWS_CORE_API AWSError<CoreErrors> GetErrorForName(const char* errorName); - namespace CoreErrorsMapper - { - /** - * Finds a CoreErrors member if possible. Otherwise, returns UNKNOWN - */ - AWS_CORE_API AWSError<CoreErrors> GetErrorForName(const char* errorName); - - /** + /** * Build the mapping between predefined exception names and Aws CoreErrors using Aws::Map. */ AWS_CORE_API void InitCoreErrorsMapper(); @@ -71,9 +71,9 @@ namespace Aws */ AWS_CORE_API void CleanupCoreErrorsMapper(); /** - * Finds a CoreErrors member if possible by HTTP response code - */ - AWS_CORE_API AWSError<CoreErrors> GetErrorForHttpResponseCode(Aws::Http::HttpResponseCode code); - } // namespace CoreErrorsMapper - } // namespace Client -} // namespace Aws + * Finds a CoreErrors member if possible by HTTP response code + */ + AWS_CORE_API AWSError<CoreErrors> GetErrorForHttpResponseCode(Aws::Http::HttpResponseCode code); + } // namespace CoreErrorsMapper + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/DefaultRetryStrategy.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/DefaultRetryStrategy.h index 0357c5ed0c..30884b6668 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/DefaultRetryStrategy.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/DefaultRetryStrategy.h @@ -2,35 +2,35 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/client/RetryStrategy.h> - -namespace Aws -{ -namespace Client -{ - -class AWS_CORE_API DefaultRetryStrategy : public RetryStrategy -{ -public: - - DefaultRetryStrategy(long maxRetries = 10, long scaleFactor = 25) : + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/RetryStrategy.h> + +namespace Aws +{ +namespace Client +{ + +class AWS_CORE_API DefaultRetryStrategy : public RetryStrategy +{ +public: + + DefaultRetryStrategy(long maxRetries = 10, long scaleFactor = 25) : m_scaleFactor(scaleFactor), m_maxRetries(maxRetries) - {} - + {} + bool ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const override; - + long CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const override; - + virtual long GetMaxAttempts() const override { return m_maxRetries + 1; } protected: - long m_scaleFactor; - long m_maxRetries; -}; - -} // namespace Client -} // namespace Aws + long m_scaleFactor; + long m_maxRetries; +}; + +} // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h index 930eaa581d..6c3c380b02 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/client/RetryStrategy.h @@ -2,15 +2,15 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> + +#pragma once + +#include <aws/core/Core_EXPORTS.h> #include <aws/core/utils/threading/ReaderWriterLock.h> #include <memory> - -namespace Aws -{ + +namespace Aws +{ namespace Http { class HttpResponse; @@ -22,31 +22,31 @@ namespace Aws class Outcome; } - namespace Client - { - enum class CoreErrors; - template<typename ERROR_TYPE> - class AWSError; - + namespace Client + { + enum class CoreErrors; + template<typename ERROR_TYPE> + class AWSError; + typedef Utils::Outcome<std::shared_ptr<Aws::Http::HttpResponse>, AWSError<CoreErrors>> HttpResponseOutcome; - /** - * Interface for defining a Retry Strategy. Override this class to provide your own custom retry behavior. - */ - class AWS_CORE_API RetryStrategy - { - public: + /** + * Interface for defining a Retry Strategy. Override this class to provide your own custom retry behavior. + */ + class AWS_CORE_API RetryStrategy + { + public: virtual ~RetryStrategy() = default; - /** - * Returns true if the error can be retried given the error and the number of times already tried. - */ - virtual bool ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const = 0; - - /** + /** + * Returns true if the error can be retried given the error and the number of times already tried. + */ + virtual bool ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const = 0; + + /** * Calculates the time in milliseconds the client should sleep before attempting another request based on the error and attemptedRetries count. - */ - virtual long CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const = 0; - + */ + virtual long CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const = 0; + /** * Gets max number of attempts allowed for an operation. * Returns non positive value if not defined. @@ -63,8 +63,8 @@ namespace Aws */ virtual void RequestBookkeeping(const HttpResponseOutcome& /* httpResponseOutcome */) {} virtual void RequestBookkeeping(const HttpResponseOutcome& /* httpResponseOutcome */, const AWSError<CoreErrors>& /* lastError */) {} - }; - + }; + /** * The container for retry quotas. * A failed request will acquire retry quotas to retry. @@ -117,5 +117,5 @@ namespace Aws std::shared_ptr<RetryQuotaContainer> m_retryQuotaContainer; long m_maxAttempts; }; - } // namespace Client -} // namespace Aws + } // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h index 84c62713da..ff98224e4d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/config/AWSProfileConfigLoader.h @@ -2,164 +2,164 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/utils/memory/stl/AWSString.h> + +#pragma once + +#include <aws/core/utils/memory/stl/AWSString.h> #include <aws/core/utils/memory/stl/AWSMap.h> #include <aws/core/auth/AWSCredentials.h> -#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/DateTime.h> #include <aws/core/utils/threading/ReaderWriterLock.h> - -namespace Aws -{ - namespace Internal - { - class EC2MetadataClient; - } - - namespace Config - { - /** - * Simple data container for a Profile. - */ - class Profile - { - public: - inline const Aws::String& GetName() const { return m_name; } - inline void SetName(const Aws::String& value) { m_name = value; } - inline const Aws::Auth::AWSCredentials& GetCredentials() const { return m_credentials; } - inline void SetCredentials(const Aws::Auth::AWSCredentials& value) { m_credentials = value; } - inline const Aws::String& GetRegion() const { return m_region; } - inline void SetRegion(const Aws::String& value) { m_region = value; } - inline const Aws::String& GetRoleArn() const { return m_roleArn; } - inline void SetRoleArn(const Aws::String& value) { m_roleArn = value; } - inline const Aws::String& GetExternalId() const { return m_externalId; } - inline void SetExternalId(const Aws::String& value) { m_externalId = value; } - inline const Aws::String& GetSourceProfile() const { return m_sourceProfile; } - inline void SetSourceProfile(const Aws::String& value ) { m_sourceProfile = value; } + +namespace Aws +{ + namespace Internal + { + class EC2MetadataClient; + } + + namespace Config + { + /** + * Simple data container for a Profile. + */ + class Profile + { + public: + inline const Aws::String& GetName() const { return m_name; } + inline void SetName(const Aws::String& value) { m_name = value; } + inline const Aws::Auth::AWSCredentials& GetCredentials() const { return m_credentials; } + inline void SetCredentials(const Aws::Auth::AWSCredentials& value) { m_credentials = value; } + inline const Aws::String& GetRegion() const { return m_region; } + inline void SetRegion(const Aws::String& value) { m_region = value; } + inline const Aws::String& GetRoleArn() const { return m_roleArn; } + inline void SetRoleArn(const Aws::String& value) { m_roleArn = value; } + inline const Aws::String& GetExternalId() const { return m_externalId; } + inline void SetExternalId(const Aws::String& value) { m_externalId = value; } + inline const Aws::String& GetSourceProfile() const { return m_sourceProfile; } + inline void SetSourceProfile(const Aws::String& value ) { m_sourceProfile = value; } inline const Aws::String& GetCredentialProcess() const { return m_credentialProcess; } inline void SetCredentialProcess(const Aws::String& value ) { m_credentialProcess = value; } - inline void SetAllKeyValPairs(const Aws::Map<Aws::String, Aws::String>& map) { m_allKeyValPairs = map; } - inline const Aws::String GetValue(const Aws::String& key) const - { - auto iter = m_allKeyValPairs.find(key); + inline void SetAllKeyValPairs(const Aws::Map<Aws::String, Aws::String>& map) { m_allKeyValPairs = map; } + inline const Aws::String GetValue(const Aws::String& key) const + { + auto iter = m_allKeyValPairs.find(key); if (iter == m_allKeyValPairs.end()) return {}; - return iter->second; - } - - private: - Aws::String m_name; - Aws::String m_region; - Aws::Auth::AWSCredentials m_credentials; - Aws::String m_roleArn; - Aws::String m_externalId; - Aws::String m_sourceProfile; + return iter->second; + } + + private: + Aws::String m_name; + Aws::String m_region; + Aws::Auth::AWSCredentials m_credentials; + Aws::String m_roleArn; + Aws::String m_externalId; + Aws::String m_sourceProfile; Aws::String m_credentialProcess; - Aws::Map<Aws::String, Aws::String> m_allKeyValPairs; - }; - - /** - * Loads Configuration such as .aws/config, .aws/credentials or ec2 metadata service. - */ - class AWS_CORE_API AWSProfileConfigLoader - { - public: - virtual ~AWSProfileConfigLoader() = default; - - /** - * Load the configuration - */ - bool Load(); - - /** - * Over writes the entire config source with the newly configured profile data. - */ - bool PersistProfiles(const Aws::Map<Aws::String, Aws::Config::Profile>& profiles); - - /** - * Gets all profiles from the configuration file. - */ - inline const Aws::Map<Aws::String, Aws::Config::Profile>& GetProfiles() const { return m_profiles; }; - - /** - * the timestamp from the last time the profile information was loaded from file. - */ - inline const Aws::Utils::DateTime& LastLoadTime() const { return m_lastLoadTime; } - + Aws::Map<Aws::String, Aws::String> m_allKeyValPairs; + }; + + /** + * Loads Configuration such as .aws/config, .aws/credentials or ec2 metadata service. + */ + class AWS_CORE_API AWSProfileConfigLoader + { + public: + virtual ~AWSProfileConfigLoader() = default; + + /** + * Load the configuration + */ + bool Load(); + + /** + * Over writes the entire config source with the newly configured profile data. + */ + bool PersistProfiles(const Aws::Map<Aws::String, Aws::Config::Profile>& profiles); + + /** + * Gets all profiles from the configuration file. + */ + inline const Aws::Map<Aws::String, Aws::Config::Profile>& GetProfiles() const { return m_profiles; }; + + /** + * the timestamp from the last time the profile information was loaded from file. + */ + inline const Aws::Utils::DateTime& LastLoadTime() const { return m_lastLoadTime; } + using ProfilesContainer = Aws::Map<Aws::String, Aws::Config::Profile>; - protected: - /** - * Subclasses override this method to implement fetching the profiles. - */ - virtual bool LoadInternal() = 0; - - /** - * Subclasses override this method to implement persisting the profiles. Default returns false. - */ - virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) { return false; } - + protected: + /** + * Subclasses override this method to implement fetching the profiles. + */ + virtual bool LoadInternal() = 0; + + /** + * Subclasses override this method to implement persisting the profiles. Default returns false. + */ + virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) { return false; } + ProfilesContainer m_profiles; - Aws::Utils::DateTime m_lastLoadTime; - }; - - /** - * Reads configuration from a config file (e.g. $HOME/.aws/config or $HOME/.aws/credentials - */ - class AWS_CORE_API AWSConfigFileProfileConfigLoader : public AWSProfileConfigLoader - { - public: - /** - * fileName - file to load config from - * useProfilePrefix - whether or not the profiles are prefixed with "profile", credentials file is not - * while the config file is. Defaults to off. - */ - AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix = false); - - virtual ~AWSConfigFileProfileConfigLoader() = default; - - /** - * File path being used for the config loader. - */ - const Aws::String& GetFileName() const { return m_fileName; } - + Aws::Utils::DateTime m_lastLoadTime; + }; + + /** + * Reads configuration from a config file (e.g. $HOME/.aws/config or $HOME/.aws/credentials + */ + class AWS_CORE_API AWSConfigFileProfileConfigLoader : public AWSProfileConfigLoader + { + public: + /** + * fileName - file to load config from + * useProfilePrefix - whether or not the profiles are prefixed with "profile", credentials file is not + * while the config file is. Defaults to off. + */ + AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix = false); + + virtual ~AWSConfigFileProfileConfigLoader() = default; + + /** + * File path being used for the config loader. + */ + const Aws::String& GetFileName() const { return m_fileName; } + /** * Give loader the ability to change the file path to load config from. * This can avoid creating new loader object if the file changed. */ void SetFileName(const Aws::String& fileName) { m_fileName = fileName; } - protected: - virtual bool LoadInternal() override; - virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) override; - - private: - Aws::String m_fileName; - bool m_useProfilePrefix; - }; - - static const char* const INSTANCE_PROFILE_KEY = "InstanceProfile"; - - /** - * Loads configuration from the EC2 Metadata Service - */ - class AWS_CORE_API EC2InstanceProfileConfigLoader : public AWSProfileConfigLoader - { - public: - /** - * If client is nullptr, the default EC2MetadataClient will be created. - */ - EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& = nullptr); - - virtual ~EC2InstanceProfileConfigLoader() = default; - - protected: - virtual bool LoadInternal() override; - - private: - std::shared_ptr<Aws::Internal::EC2MetadataClient> m_ec2metadataClient; - }; + protected: + virtual bool LoadInternal() override; + virtual bool PersistInternal(const Aws::Map<Aws::String, Aws::Config::Profile>&) override; + + private: + Aws::String m_fileName; + bool m_useProfilePrefix; + }; + + static const char* const INSTANCE_PROFILE_KEY = "InstanceProfile"; + + /** + * Loads configuration from the EC2 Metadata Service + */ + class AWS_CORE_API EC2InstanceProfileConfigLoader : public AWSProfileConfigLoader + { + public: + /** + * If client is nullptr, the default EC2MetadataClient will be created. + */ + EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& = nullptr); + + virtual ~EC2InstanceProfileConfigLoader() = default; + + protected: + virtual bool LoadInternal() override; + + private: + std::shared_ptr<Aws::Internal::EC2MetadataClient> m_ec2metadataClient; + }; /** * Stores the contents of config file and credentials file to avoid multiple file readings. @@ -246,5 +246,5 @@ namespace Aws AWS_CORE_API Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles(); - } -} + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h index 9a010a67db..a78c8637f2 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/cjson/cJSON.h @@ -1,108 +1,108 @@ -/* - Copyright (c) 2009-2017 Dave Gamble and cJSON contributors - - 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 cJSON__h -#define cJSON__h - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* project version */ -#define CJSON_VERSION_MAJOR 1 -#define CJSON_VERSION_MINOR 7 -#define CJSON_VERSION_PATCH 7 - -#include <stddef.h> - -/* cJSON Types: */ -#define cJSON_Invalid (0) -#define cJSON_False (1 << 0) -#define cJSON_True (1 << 1) -#define cJSON_NULL (1 << 2) -#define cJSON_Number (1 << 3) -#define cJSON_String (1 << 4) -#define cJSON_Array (1 << 5) -#define cJSON_Object (1 << 6) -#define cJSON_Raw (1 << 7) /* raw json */ - -#define cJSON_IsReference 256 -#define cJSON_StringIsConst 512 - -/* The cJSON structure: */ -typedef struct cJSON -{ - /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ - struct cJSON *next; - struct cJSON *prev; - /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ - struct cJSON *child; - - /* The type of the item, as above. */ - int type; - - /* The item's string, if type==cJSON_String and type == cJSON_Raw */ - char *valuestring; - /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ - int valueint; - /* The item's number, if type==cJSON_Number */ - double valuedouble; - - /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ - char *string; -} cJSON; - -typedef struct cJSON_Hooks -{ - void *(*malloc_fn)(size_t sz); - void (*free_fn)(void *ptr); -} cJSON_Hooks; - -typedef int cJSON_bool; - -#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) -#define __WINDOWS__ -#endif -#ifdef __WINDOWS__ - -/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options: - -CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols -CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) -CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol - -For *nix builds that support visibility attribute, you can define similar behavior by - -setting default visibility to hidden by adding --fvisibility=hidden (for gcc) -or --xldscope=hidden (for sun cc) -to CFLAGS - -then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does - -*/ - +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + 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 cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 7 + +#include <stddef.h> + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + /* Decide calling convention based on the cmake parameters defined in C++ SDK. */ #ifdef USE_IMPORT_EXPORT #ifdef AWS_CORE_EXPORTS @@ -114,176 +114,176 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ #define CJSON_HIDE_SYMBOLS #endif // USE_IMPORT_EXPORT -/* export symbols by default, this is necessary for copy pasting the C and header file */ -#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_EXPORT_SYMBOLS -#endif - -#if defined(CJSON_HIDE_SYMBOLS) -#define CJSON_PUBLIC(type) type __stdcall -#elif defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall -#elif defined(CJSON_IMPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall -#endif -#else /* !WIN32 */ -#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) -#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type -#else -#define CJSON_PUBLIC(type) type -#endif -#endif - -/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. - * This is to prevent stack overflows. */ -#ifndef CJSON_NESTING_LIMIT -#define CJSON_NESTING_LIMIT 1000 -#endif - -/* returns the version of cJSON as a string */ -CJSON_PUBLIC(const char*) cJSON_Version(void); - -/* Supply malloc, realloc and free functions to cJSON */ -CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); - -/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ -/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ -CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ -CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); - -/* Render a cJSON entity to text for transfer/storage. */ -CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); -/* Render a cJSON entity to text for transfer/storage without any formatting. */ -CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); -/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ -CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); -/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ -/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ -CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); -/* Delete a cJSON entity and all subentities. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON *c); - -/* Returns the number of items in an array (or object). */ -CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); -/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ -CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); -/* Get item "string" from object. Case insensitive. */ -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); -CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); - -/* Check if the item is a string and return its valuestring */ -CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item); - -/* These functions check the type of an item */ -CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); - -/* These calls create a cJSON item of the appropriate type. */ -CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); -CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type __stdcall +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall +#endif +#else /* !WIN32 */ +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check if the item is a string and return its valuestring */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); CJSON_PUBLIC(cJSON *) cJSON_CreateInt64(long long num); -CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); -/* raw json */ -CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); -CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); - -/* Create a string where valuestring references a string so - * it will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); -/* Create an object/arrray that only references it's elements so - * they will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); -CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); - -/* These utilities create an Array of count items. */ -CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); - -/* Append item to the specified array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); -/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. - * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before - * writing to `item->string` */ -CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); -/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); - +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/arrray that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + /* Remove/Detach items from Arrays/Objects. */ -CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); -CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); -CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); -CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); - -/* Update array items. */ -CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); -CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); -CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); -CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); - -/* Duplicate a cJSON item */ -CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); -/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will -need to be released. With recurse!=0, it will duplicate any children connected to the item. -The item->next and ->prev pointers are always zero on return from Duplicate. */ -/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. - * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ -CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); - - -CJSON_PUBLIC(void) cJSON_Minify(char *json); - -/* Helper functions for creating and adding items to an object at the same time. - * They return the added item or NULL on failure. */ -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); -CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); -CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); - -/* When assigning an integer value, it needs to be propagated to valuedouble too. */ -#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) -/* helper for the cJSON_SetNumberValue macro */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); -#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) - -/* Macro for iterating over an array or object */ -#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) - -/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ -CJSON_PUBLIC(void *) cJSON_malloc(size_t size); -CJSON_PUBLIC(void) cJSON_free(void *object); - -#ifdef __cplusplus -} -#endif - -#endif +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + + +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/tinyxml2/tinyxml2.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/tinyxml2/tinyxml2.h index 3721ed1f97..401d9c94e9 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/tinyxml2/tinyxml2.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/external/tinyxml2/tinyxml2.h @@ -1,2292 +1,2292 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ -/* -This file has been modified from its original version by Amazon: - (1) Memory management operations use aws memory management api +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ +/* +This file has been modified from its original version by Amazon: + (1) Memory management operations use aws memory management api (2) Import-export preprocessor logic tweaked for better integration into core library - (3) Wrapped everything in Amazon namespace to prevent static linking issues if the user includes a version of this code through another dependency -*/ -#ifndef TINYXML2_INCLUDED -#define TINYXML2_INCLUDED - -#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) -# include <ctype.h> -# include <limits.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# if defined(__PS3__) -# include <stddef.h> -# endif -#else -# include <cctype> -# include <climits> -# include <cstdio> -# include <cstdlib> -# include <cstring> -#endif -#include <stdint.h> - -#include <aws/core/utils/memory/AWSMemory.h> - -/* - TODO: intern strings instead of allocation. -*/ -/* - gcc: - g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe - - Formatting, Artistic Style: - AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h -*/ - -#if defined( _DEBUG ) || defined (__DEBUG__) -# ifndef DEBUG -# define DEBUG -# endif -#endif - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4251) -#endif - -#ifdef _WIN32 - #ifdef USE_IMPORT_EXPORT - #ifdef AWS_CORE_EXPORTS - #define TINYXML2_LIB __declspec(dllexport) - #else - #define TINYXML2_LIB __declspec(dllimport) - #endif // AWS_CORE_EXPORTS - #endif // USE_IMPORT_EXPORT -#elif __GNUC__ >= 4 - #define TINYXML2_LIB __attribute__((visibility("default"))) -#endif // _WIN32 - -#ifndef TINYXML2_LIB - #define TINYXML2_LIB -#endif // TINYXML2_LIB - -#if defined(DEBUG) -# if defined(_MSC_VER) -# // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like -# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } -# elif defined (ANDROID_NDK) -# include <android/log.h> -# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } -# else -# include <assert.h> -# define TIXMLASSERT assert -# endif -#else -# define TIXMLASSERT( x ) {} -#endif - - -/* Versioning, past 1.0.14: - http://semver.org/ -*/ -static const int TIXML2_MAJOR_VERSION = 6; -static const int TIXML2_MINOR_VERSION = 1; -static const int TIXML2_PATCH_VERSION = 0; - -#define TINYXML2_MAJOR_VERSION 6 -#define TINYXML2_MINOR_VERSION 1 -#define TINYXML2_PATCH_VERSION 0 - -namespace Aws -{ -namespace External -{ -namespace tinyxml2 -{ -class XMLDocument; -class XMLElement; -class XMLAttribute; -class XMLComment; -class XMLText; -class XMLDeclaration; -class XMLUnknown; -class XMLPrinter; - -static const char* ALLOCATION_TAG = "AWS::TinyXML"; - -/* - A class that wraps strings. Normally stores the start and end - pointers into the XML file itself, and will apply normalization - and entity translation if actually read. Can also store (and memory - manage) a traditional char[] -*/ -class TINYXML2_LIB StrPair -{ -public: - enum { - NEEDS_ENTITY_PROCESSING = 0x01, - NEEDS_NEWLINE_NORMALIZATION = 0x02, - NEEDS_WHITESPACE_COLLAPSING = 0x04, - - TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_NAME = 0, - ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - COMMENT = NEEDS_NEWLINE_NORMALIZATION - }; - - StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} - ~StrPair(); - - void Set( char* start, char* end, int flags ) { - TIXMLASSERT( start ); - TIXMLASSERT( end ); - Reset(); - _start = start; - _end = end; - _flags = flags | NEEDS_FLUSH; - } - - const char* GetStr(); - - bool Empty() const { - return _start == _end; - } - - void SetInternedStr( const char* str ) { - Reset(); - _start = const_cast<char*>(str); - } - - void SetStr( const char* str, int flags=0 ); - - char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr ); - char* ParseName( char* in ); - - void TransferTo( StrPair* other ); - void Reset(); - -private: - void CollapseWhitespace(); - - enum { - NEEDS_FLUSH = 0x100, - NEEDS_DELETE = 0x200 - }; - - int _flags; - char* _start; - char* _end; - - StrPair( const StrPair& other ); // not supported - void operator=( StrPair& other ); // not supported, use TransferTo() -}; - - -/* - A dynamic array of Plain Old Data. Doesn't support constructors, etc. - Has a small initial memory pool, so that low or no usage will not - cause a call to new/delete -*/ -template <class T, int INITIAL_SIZE> -class DynArray -{ -public: - DynArray() : - _mem( _pool ), - _allocated( INITIAL_SIZE ), - _size( 0 ) - { - } - - ~DynArray() { - if ( _mem != _pool ) { - Aws::DeleteArray<T>(_mem); - } - } - - void Clear() { - _size = 0; - } - - void Push( T t ) { - TIXMLASSERT( _size < INT_MAX ); - EnsureCapacity( _size+1 ); - _mem[_size] = t; - ++_size; - } - - T* PushArr( int count ) { - TIXMLASSERT( count >= 0 ); - TIXMLASSERT( _size <= INT_MAX - count ); - EnsureCapacity( _size+count ); - T* ret = &_mem[_size]; - _size += count; - return ret; - } - - T Pop() { - TIXMLASSERT( _size > 0 ); - --_size; - return _mem[_size]; - } - - void PopArr( int count ) { - TIXMLASSERT( _size >= count ); - _size -= count; - } - - bool Empty() const { - return _size == 0; - } - - T& operator[](int i) { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& operator[](int i) const { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& PeekTop() const { - TIXMLASSERT( _size > 0 ); - return _mem[ _size - 1]; - } - - int Size() const { - TIXMLASSERT( _size >= 0 ); - return _size; - } - - int Capacity() const { - TIXMLASSERT( _allocated >= INITIAL_SIZE ); - return _allocated; - } - - void SwapRemove(int i) { - TIXMLASSERT(i >= 0 && i < _size); - TIXMLASSERT(_size > 0); - _mem[i] = _mem[_size - 1]; - --_size; - } - - const T* Mem() const { - TIXMLASSERT( _mem ); - return _mem; - } - - T* Mem() { - TIXMLASSERT( _mem ); - return _mem; - } - -private: - DynArray( const DynArray& ); // not supported - void operator=( const DynArray& ); // not supported - - void EnsureCapacity( int cap ) { - TIXMLASSERT( cap > 0 ); - if ( cap > _allocated ) { - TIXMLASSERT( cap <= INT_MAX / 2 ); - int newAllocated = cap * 2; - T* newMem = Aws::NewArray<T>(newAllocated, ALLOCATION_TAG); - TIXMLASSERT( newAllocated >= _size ); - memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs - if ( _mem != _pool ) { - Aws::DeleteArray<T>(_mem); - } - _mem = newMem; - _allocated = newAllocated; - } - } - - T* _mem; - T _pool[INITIAL_SIZE]; - int _allocated; // objects allocated - int _size; // number objects in use -}; - - -/* - Parent virtual class of a pool for fast allocation - and deallocation of objects. -*/ -class MemPool -{ -public: - MemPool() {} - virtual ~MemPool() {} - - virtual int ItemSize() const = 0; - virtual void* Alloc() = 0; - virtual void Free( void* ) = 0; - virtual void SetTracked() = 0; - virtual void Clear() = 0; -}; - - -/* - Template child class to create pools of the correct type. -*/ -template< int ITEM_SIZE > -class MemPoolT : public MemPool -{ -public: - MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} - ~MemPoolT() { - Clear(); - } - - void Clear() { - // Delete the blocks. - while( !_blockPtrs.Empty()) { - Block* lastBlock = _blockPtrs.Pop(); - Aws::Delete(lastBlock); - } - _root = 0; - _currentAllocs = 0; - _nAllocs = 0; - _maxAllocs = 0; - _nUntracked = 0; - } - - virtual int ItemSize() const { - return ITEM_SIZE; - } - int CurrentAllocs() const { - return _currentAllocs; - } - - virtual void* Alloc() { - if ( !_root ) { - // Need a new block. - Block* block = Aws::New<Block>(ALLOCATION_TAG); - _blockPtrs.Push( block ); - - Item* blockItems = block->items; - for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) { - blockItems[i].next = &(blockItems[i + 1]); - } - blockItems[ITEMS_PER_BLOCK - 1].next = 0; - _root = blockItems; - } - Item* const result = _root; - TIXMLASSERT( result != 0 ); - _root = _root->next; - - ++_currentAllocs; - if ( _currentAllocs > _maxAllocs ) { - _maxAllocs = _currentAllocs; - } - ++_nAllocs; - ++_nUntracked; - return result; - } - - virtual void Free( void* mem ) { - if ( !mem ) { - return; - } - --_currentAllocs; - Item* item = static_cast<Item*>( mem ); -#ifdef DEBUG - memset( item, 0xfe, sizeof( *item ) ); -#endif - item->next = _root; - _root = item; - } - void Trace( const char* name ) { - printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", - name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, - ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); - } - - void SetTracked() { - --_nUntracked; - } - - int Untracked() const { - return _nUntracked; - } - - // This number is perf sensitive. 4k seems like a good tradeoff on my machine. - // The test file is large, 170k. - // Release: VS2010 gcc(no opt) - // 1k: 4000 - // 2k: 4000 - // 4k: 3900 21000 - // 16k: 5200 - // 32k: 4300 - // 64k: 4000 21000 - // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK - // in private part if ITEMS_PER_BLOCK is private - enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE }; - -private: - MemPoolT( const MemPoolT& ); // not supported - void operator=( const MemPoolT& ); // not supported - - union Item { - Item* next; - char itemData[ITEM_SIZE]; - }; - struct Block { - Item items[ITEMS_PER_BLOCK]; - }; - DynArray< Block*, 10 > _blockPtrs; - Item* _root; - - int _currentAllocs; - int _nAllocs; - int _maxAllocs; - int _nUntracked; -}; - - - -/** - Implements the interface to the "Visitor pattern" (see the Accept() method.) - If you call the Accept() method, it requires being passed a XMLVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs - are simply called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, <b>no children of this node or its siblings</b> will be visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the XMLDocument, although all nodes support visiting. - - You should never change the document from a callback. - - @sa XMLNode::Accept() -*/ -class TINYXML2_LIB XMLVisitor -{ -public: - virtual ~XMLVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { - return true; - } - /// Visit a document. - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - /// Visit an element. - virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { - return true; - } - /// Visit an element. - virtual bool VisitExit( const XMLElement& /*element*/ ) { - return true; - } - - /// Visit a declaration. - virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { - return true; - } - /// Visit a text node. - virtual bool Visit( const XMLText& /*text*/ ) { - return true; - } - /// Visit a comment node. - virtual bool Visit( const XMLComment& /*comment*/ ) { - return true; - } - /// Visit an unknown node. - virtual bool Visit( const XMLUnknown& /*unknown*/ ) { - return true; - } -}; - -// WARNING: must match XMLDocument::_errorNames[] -enum XMLError { - XML_SUCCESS = 0, - XML_NO_ATTRIBUTE, - XML_WRONG_ATTRIBUTE_TYPE, - XML_ERROR_FILE_NOT_FOUND, - XML_ERROR_FILE_COULD_NOT_BE_OPENED, - XML_ERROR_FILE_READ_ERROR, - UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version - XML_ERROR_PARSING_ELEMENT, - XML_ERROR_PARSING_ATTRIBUTE, - UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version - XML_ERROR_PARSING_TEXT, - XML_ERROR_PARSING_CDATA, - XML_ERROR_PARSING_COMMENT, - XML_ERROR_PARSING_DECLARATION, - XML_ERROR_PARSING_UNKNOWN, - XML_ERROR_EMPTY_DOCUMENT, - XML_ERROR_MISMATCHED_ELEMENT, - XML_ERROR_PARSING, - XML_CAN_NOT_CONVERT_TEXT, - XML_NO_TEXT_NODE, - - XML_ERROR_COUNT -}; - - -/* - Utility functionality. -*/ -class TINYXML2_LIB XMLUtil -{ -public: - static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) { - TIXMLASSERT( p ); - - while( IsWhiteSpace(*p) ) { - if (curLineNumPtr && *p == '\n') { - ++(*curLineNumPtr); - } - ++p; - } - TIXMLASSERT( p ); - return p; - } - static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) { - return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) ); - } - - // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't - // correct, but simple, and usually works. - static bool IsWhiteSpace( char p ) { - return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) ); - } - - inline static bool IsNameStartChar( unsigned char ch ) { - if ( ch >= 128 ) { - // This is a heuristic guess in attempt to not implement Unicode-aware isalpha() - return true; - } - if ( isalpha( ch ) ) { - return true; - } - return ch == ':' || ch == '_'; - } - - inline static bool IsNameChar( unsigned char ch ) { - return IsNameStartChar( ch ) - || isdigit( ch ) - || ch == '.' - || ch == '-'; - } - - inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { - if ( p == q ) { - return true; - } - TIXMLASSERT( p ); - TIXMLASSERT( q ); - TIXMLASSERT( nChar >= 0 ); - return strncmp( p, q, nChar ) == 0; - } - - inline static bool IsUTF8Continuation( char p ) { - return ( p & 0x80 ) != 0; - } - - static const char* ReadBOM( const char* p, bool* hasBOM ); - // p is the starting location, - // the UTF-8 value of the entity will be placed in value, and length filled in. - static const char* GetCharacterRef( const char* p, char* value, int* length ); - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - - // converts primitive types to strings - static void ToStr( int v, char* buffer, int bufferSize ); - static void ToStr( unsigned v, char* buffer, int bufferSize ); - static void ToStr( bool v, char* buffer, int bufferSize ); - static void ToStr( float v, char* buffer, int bufferSize ); - static void ToStr( double v, char* buffer, int bufferSize ); - static void ToStr(int64_t v, char* buffer, int bufferSize); - - // converts strings to primitive types - static bool ToInt( const char* str, int* value ); - static bool ToUnsigned( const char* str, unsigned* value ); - static bool ToBool( const char* str, bool* value ); - static bool ToFloat( const char* str, float* value ); - static bool ToDouble( const char* str, double* value ); - static bool ToInt64(const char* str, int64_t* value); - - // Changes what is serialized for a boolean value. - // Default to "true" and "false". Shouldn't be changed - // unless you have a special testing or compatibility need. - // Be careful: static, global, & not thread safe. - // Be sure to set static const memory as parameters. - static void SetBoolSerialization(const char* writeTrue, const char* writeFalse); - -private: - static const char* writeBoolTrue; - static const char* writeBoolFalse; -}; - - -/** XMLNode is a base class for every object that is in the - XML Document Object Model (DOM), except XMLAttributes. - Nodes have siblings, a parent, and children which can - be navigated. A node is always in a XMLDocument. - The type of a XMLNode can be queried, and it can - be cast to its more defined type. - - A XMLDocument allocates memory for all its Nodes. - When the XMLDocument gets deleted, all its Nodes - will also be deleted. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - @endverbatim -*/ -class TINYXML2_LIB XMLNode -{ - friend class XMLDocument; - friend class XMLElement; -public: - - /// Get the XMLDocument that owns this XMLNode. - const XMLDocument* GetDocument() const { - TIXMLASSERT( _document ); - return _document; - } - /// Get the XMLDocument that owns this XMLNode. - XMLDocument* GetDocument() { - TIXMLASSERT( _document ); - return _document; - } - - /// Safely cast to an Element, or null. - virtual XMLElement* ToElement() { - return 0; - } - /// Safely cast to Text, or null. - virtual XMLText* ToText() { - return 0; - } - /// Safely cast to a Comment, or null. - virtual XMLComment* ToComment() { - return 0; - } - /// Safely cast to a Document, or null. - virtual XMLDocument* ToDocument() { - return 0; - } - /// Safely cast to a Declaration, or null. - virtual XMLDeclaration* ToDeclaration() { - return 0; - } - /// Safely cast to an Unknown, or null. - virtual XMLUnknown* ToUnknown() { - return 0; - } - - virtual const XMLElement* ToElement() const { - return 0; - } - virtual const XMLText* ToText() const { - return 0; - } - virtual const XMLComment* ToComment() const { - return 0; - } - virtual const XMLDocument* ToDocument() const { - return 0; - } - virtual const XMLDeclaration* ToDeclaration() const { - return 0; - } - virtual const XMLUnknown* ToUnknown() const { - return 0; - } - - /** The meaning of 'value' changes for the specific type. - @verbatim - Document: empty (NULL is returned, not an empty string) - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - const char* Value() const; - - /** Set the Value of an XML node. - @sa Value() - */ - void SetValue( const char* val, bool staticMem=false ); - - /// Gets the line number the node is in, if the document was parsed from a file. - int GetLineNum() const { return _parseLineNum; } - - /// Get the parent of this node on the DOM. - const XMLNode* Parent() const { - return _parent; - } - - XMLNode* Parent() { - return _parent; - } - - /// Returns true if this node has no children. - bool NoChildren() const { - return !_firstChild; - } - - /// Get the first child node, or null if none exists. - const XMLNode* FirstChild() const { - return _firstChild; - } - - XMLNode* FirstChild() { - return _firstChild; - } - - /** Get the first child element, or optionally the first child - element with the specified name. - */ - const XMLElement* FirstChildElement( const char* name = 0 ) const; - - XMLElement* FirstChildElement( const char* name = 0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name )); - } - - /// Get the last child node, or null if none exists. - const XMLNode* LastChild() const { - return _lastChild; - } - - XMLNode* LastChild() { - return _lastChild; - } - - /** Get the last child element or optionally the last child - element with the specified name. - */ - const XMLElement* LastChildElement( const char* name = 0 ) const; - - XMLElement* LastChildElement( const char* name = 0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) ); - } - - /// Get the previous (left) sibling node of this node. - const XMLNode* PreviousSibling() const { - return _prev; - } - - XMLNode* PreviousSibling() { - return _prev; - } - - /// Get the previous (left) sibling element of this node, with an optionally supplied name. - const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ; - - XMLElement* PreviousSiblingElement( const char* name = 0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) ); - } - - /// Get the next (right) sibling node of this node. - const XMLNode* NextSibling() const { - return _next; - } - - XMLNode* NextSibling() { - return _next; - } - - /// Get the next (right) sibling element of this node, with an optionally supplied name. - const XMLElement* NextSiblingElement( const char* name = 0 ) const; - - XMLElement* NextSiblingElement( const char* name = 0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) ); - } - - /** - Add a child node as the last (right) child. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the node does not - belong to the same document. - */ - XMLNode* InsertEndChild( XMLNode* addThis ); - - XMLNode* LinkEndChild( XMLNode* addThis ) { - return InsertEndChild( addThis ); - } - /** - Add a child node as the first (left) child. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the node does not - belong to the same document. - */ - XMLNode* InsertFirstChild( XMLNode* addThis ); - /** - Add a node after the specified child node. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the afterThis node - is not a child of this node, or if the node does not - belong to the same document. - */ - XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); - - /** - Delete all the children of this node. - */ - void DeleteChildren(); - - /** - Delete a child of this node. - */ - void DeleteChild( XMLNode* node ); - - /** - Make a copy of this node, but not its children. - You may pass in a Document pointer that will be - the owner of the new Node. If the 'document' is - null, then the node returned will be allocated - from the current Document. (this->GetDocument()) - - Note: if called on a XMLDocument, this will return null. - */ - virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; - - /** - Make a copy of this node and all its children. - - If the 'target' is null, then the nodes will + (3) Wrapped everything in Amazon namespace to prevent static linking issues if the user includes a version of this code through another dependency +*/ +#ifndef TINYXML2_INCLUDED +#define TINYXML2_INCLUDED + +#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) +# include <ctype.h> +# include <limits.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +# if defined(__PS3__) +# include <stddef.h> +# endif +#else +# include <cctype> +# include <climits> +# include <cstdio> +# include <cstdlib> +# include <cstring> +#endif +#include <stdint.h> + +#include <aws/core/utils/memory/AWSMemory.h> + +/* + TODO: intern strings instead of allocation. +*/ +/* + gcc: + g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe + + Formatting, Artistic Style: + AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h +*/ + +#if defined( _DEBUG ) || defined (__DEBUG__) +# ifndef DEBUG +# define DEBUG +# endif +#endif + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4251) +#endif + +#ifdef _WIN32 + #ifdef USE_IMPORT_EXPORT + #ifdef AWS_CORE_EXPORTS + #define TINYXML2_LIB __declspec(dllexport) + #else + #define TINYXML2_LIB __declspec(dllimport) + #endif // AWS_CORE_EXPORTS + #endif // USE_IMPORT_EXPORT +#elif __GNUC__ >= 4 + #define TINYXML2_LIB __attribute__((visibility("default"))) +#endif // _WIN32 + +#ifndef TINYXML2_LIB + #define TINYXML2_LIB +#endif // TINYXML2_LIB + +#if defined(DEBUG) +# if defined(_MSC_VER) +# // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like +# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } +# elif defined (ANDROID_NDK) +# include <android/log.h> +# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } +# else +# include <assert.h> +# define TIXMLASSERT assert +# endif +#else +# define TIXMLASSERT( x ) {} +#endif + + +/* Versioning, past 1.0.14: + http://semver.org/ +*/ +static const int TIXML2_MAJOR_VERSION = 6; +static const int TIXML2_MINOR_VERSION = 1; +static const int TIXML2_PATCH_VERSION = 0; + +#define TINYXML2_MAJOR_VERSION 6 +#define TINYXML2_MINOR_VERSION 1 +#define TINYXML2_PATCH_VERSION 0 + +namespace Aws +{ +namespace External +{ +namespace tinyxml2 +{ +class XMLDocument; +class XMLElement; +class XMLAttribute; +class XMLComment; +class XMLText; +class XMLDeclaration; +class XMLUnknown; +class XMLPrinter; + +static const char* ALLOCATION_TAG = "AWS::TinyXML"; + +/* + A class that wraps strings. Normally stores the start and end + pointers into the XML file itself, and will apply normalization + and entity translation if actually read. Can also store (and memory + manage) a traditional char[] +*/ +class TINYXML2_LIB StrPair +{ +public: + enum { + NEEDS_ENTITY_PROCESSING = 0x01, + NEEDS_NEWLINE_NORMALIZATION = 0x02, + NEEDS_WHITESPACE_COLLAPSING = 0x04, + + TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_NAME = 0, + ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + COMMENT = NEEDS_NEWLINE_NORMALIZATION + }; + + StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} + ~StrPair(); + + void Set( char* start, char* end, int flags ) { + TIXMLASSERT( start ); + TIXMLASSERT( end ); + Reset(); + _start = start; + _end = end; + _flags = flags | NEEDS_FLUSH; + } + + const char* GetStr(); + + bool Empty() const { + return _start == _end; + } + + void SetInternedStr( const char* str ) { + Reset(); + _start = const_cast<char*>(str); + } + + void SetStr( const char* str, int flags=0 ); + + char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr ); + char* ParseName( char* in ); + + void TransferTo( StrPair* other ); + void Reset(); + +private: + void CollapseWhitespace(); + + enum { + NEEDS_FLUSH = 0x100, + NEEDS_DELETE = 0x200 + }; + + int _flags; + char* _start; + char* _end; + + StrPair( const StrPair& other ); // not supported + void operator=( StrPair& other ); // not supported, use TransferTo() +}; + + +/* + A dynamic array of Plain Old Data. Doesn't support constructors, etc. + Has a small initial memory pool, so that low or no usage will not + cause a call to new/delete +*/ +template <class T, int INITIAL_SIZE> +class DynArray +{ +public: + DynArray() : + _mem( _pool ), + _allocated( INITIAL_SIZE ), + _size( 0 ) + { + } + + ~DynArray() { + if ( _mem != _pool ) { + Aws::DeleteArray<T>(_mem); + } + } + + void Clear() { + _size = 0; + } + + void Push( T t ) { + TIXMLASSERT( _size < INT_MAX ); + EnsureCapacity( _size+1 ); + _mem[_size] = t; + ++_size; + } + + T* PushArr( int count ) { + TIXMLASSERT( count >= 0 ); + TIXMLASSERT( _size <= INT_MAX - count ); + EnsureCapacity( _size+count ); + T* ret = &_mem[_size]; + _size += count; + return ret; + } + + T Pop() { + TIXMLASSERT( _size > 0 ); + --_size; + return _mem[_size]; + } + + void PopArr( int count ) { + TIXMLASSERT( _size >= count ); + _size -= count; + } + + bool Empty() const { + return _size == 0; + } + + T& operator[](int i) { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + const T& operator[](int i) const { + TIXMLASSERT( i>= 0 && i < _size ); + return _mem[i]; + } + + const T& PeekTop() const { + TIXMLASSERT( _size > 0 ); + return _mem[ _size - 1]; + } + + int Size() const { + TIXMLASSERT( _size >= 0 ); + return _size; + } + + int Capacity() const { + TIXMLASSERT( _allocated >= INITIAL_SIZE ); + return _allocated; + } + + void SwapRemove(int i) { + TIXMLASSERT(i >= 0 && i < _size); + TIXMLASSERT(_size > 0); + _mem[i] = _mem[_size - 1]; + --_size; + } + + const T* Mem() const { + TIXMLASSERT( _mem ); + return _mem; + } + + T* Mem() { + TIXMLASSERT( _mem ); + return _mem; + } + +private: + DynArray( const DynArray& ); // not supported + void operator=( const DynArray& ); // not supported + + void EnsureCapacity( int cap ) { + TIXMLASSERT( cap > 0 ); + if ( cap > _allocated ) { + TIXMLASSERT( cap <= INT_MAX / 2 ); + int newAllocated = cap * 2; + T* newMem = Aws::NewArray<T>(newAllocated, ALLOCATION_TAG); + TIXMLASSERT( newAllocated >= _size ); + memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs + if ( _mem != _pool ) { + Aws::DeleteArray<T>(_mem); + } + _mem = newMem; + _allocated = newAllocated; + } + } + + T* _mem; + T _pool[INITIAL_SIZE]; + int _allocated; // objects allocated + int _size; // number objects in use +}; + + +/* + Parent virtual class of a pool for fast allocation + and deallocation of objects. +*/ +class MemPool +{ +public: + MemPool() {} + virtual ~MemPool() {} + + virtual int ItemSize() const = 0; + virtual void* Alloc() = 0; + virtual void Free( void* ) = 0; + virtual void SetTracked() = 0; + virtual void Clear() = 0; +}; + + +/* + Template child class to create pools of the correct type. +*/ +template< int ITEM_SIZE > +class MemPoolT : public MemPool +{ +public: + MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} + ~MemPoolT() { + Clear(); + } + + void Clear() { + // Delete the blocks. + while( !_blockPtrs.Empty()) { + Block* lastBlock = _blockPtrs.Pop(); + Aws::Delete(lastBlock); + } + _root = 0; + _currentAllocs = 0; + _nAllocs = 0; + _maxAllocs = 0; + _nUntracked = 0; + } + + virtual int ItemSize() const { + return ITEM_SIZE; + } + int CurrentAllocs() const { + return _currentAllocs; + } + + virtual void* Alloc() { + if ( !_root ) { + // Need a new block. + Block* block = Aws::New<Block>(ALLOCATION_TAG); + _blockPtrs.Push( block ); + + Item* blockItems = block->items; + for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) { + blockItems[i].next = &(blockItems[i + 1]); + } + blockItems[ITEMS_PER_BLOCK - 1].next = 0; + _root = blockItems; + } + Item* const result = _root; + TIXMLASSERT( result != 0 ); + _root = _root->next; + + ++_currentAllocs; + if ( _currentAllocs > _maxAllocs ) { + _maxAllocs = _currentAllocs; + } + ++_nAllocs; + ++_nUntracked; + return result; + } + + virtual void Free( void* mem ) { + if ( !mem ) { + return; + } + --_currentAllocs; + Item* item = static_cast<Item*>( mem ); +#ifdef DEBUG + memset( item, 0xfe, sizeof( *item ) ); +#endif + item->next = _root; + _root = item; + } + void Trace( const char* name ) { + printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", + name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, + ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); + } + + void SetTracked() { + --_nUntracked; + } + + int Untracked() const { + return _nUntracked; + } + + // This number is perf sensitive. 4k seems like a good tradeoff on my machine. + // The test file is large, 170k. + // Release: VS2010 gcc(no opt) + // 1k: 4000 + // 2k: 4000 + // 4k: 3900 21000 + // 16k: 5200 + // 32k: 4300 + // 64k: 4000 21000 + // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK + // in private part if ITEMS_PER_BLOCK is private + enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE }; + +private: + MemPoolT( const MemPoolT& ); // not supported + void operator=( const MemPoolT& ); // not supported + + union Item { + Item* next; + char itemData[ITEM_SIZE]; + }; + struct Block { + Item items[ITEMS_PER_BLOCK]; + }; + DynArray< Block*, 10 > _blockPtrs; + Item* _root; + + int _currentAllocs; + int _nAllocs; + int _maxAllocs; + int _nUntracked; +}; + + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a XMLVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, <b>no children of this node or its siblings</b> will be visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the XMLDocument, although all nodes support visiting. + + You should never change the document from a callback. + + @sa XMLNode::Accept() +*/ +class TINYXML2_LIB XMLVisitor +{ +public: + virtual ~XMLVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { + return true; + } + /// Visit a document. + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + /// Visit an element. + virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { + return true; + } + /// Visit an element. + virtual bool VisitExit( const XMLElement& /*element*/ ) { + return true; + } + + /// Visit a declaration. + virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { + return true; + } + /// Visit a text node. + virtual bool Visit( const XMLText& /*text*/ ) { + return true; + } + /// Visit a comment node. + virtual bool Visit( const XMLComment& /*comment*/ ) { + return true; + } + /// Visit an unknown node. + virtual bool Visit( const XMLUnknown& /*unknown*/ ) { + return true; + } +}; + +// WARNING: must match XMLDocument::_errorNames[] +enum XMLError { + XML_SUCCESS = 0, + XML_NO_ATTRIBUTE, + XML_WRONG_ATTRIBUTE_TYPE, + XML_ERROR_FILE_NOT_FOUND, + XML_ERROR_FILE_COULD_NOT_BE_OPENED, + XML_ERROR_FILE_READ_ERROR, + UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version + XML_ERROR_PARSING_ELEMENT, + XML_ERROR_PARSING_ATTRIBUTE, + UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version + XML_ERROR_PARSING_TEXT, + XML_ERROR_PARSING_CDATA, + XML_ERROR_PARSING_COMMENT, + XML_ERROR_PARSING_DECLARATION, + XML_ERROR_PARSING_UNKNOWN, + XML_ERROR_EMPTY_DOCUMENT, + XML_ERROR_MISMATCHED_ELEMENT, + XML_ERROR_PARSING, + XML_CAN_NOT_CONVERT_TEXT, + XML_NO_TEXT_NODE, + + XML_ERROR_COUNT +}; + + +/* + Utility functionality. +*/ +class TINYXML2_LIB XMLUtil +{ +public: + static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) { + TIXMLASSERT( p ); + + while( IsWhiteSpace(*p) ) { + if (curLineNumPtr && *p == '\n') { + ++(*curLineNumPtr); + } + ++p; + } + TIXMLASSERT( p ); + return p; + } + static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) { + return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) ); + } + + // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't + // correct, but simple, and usually works. + static bool IsWhiteSpace( char p ) { + return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) ); + } + + inline static bool IsNameStartChar( unsigned char ch ) { + if ( ch >= 128 ) { + // This is a heuristic guess in attempt to not implement Unicode-aware isalpha() + return true; + } + if ( isalpha( ch ) ) { + return true; + } + return ch == ':' || ch == '_'; + } + + inline static bool IsNameChar( unsigned char ch ) { + return IsNameStartChar( ch ) + || isdigit( ch ) + || ch == '.' + || ch == '-'; + } + + inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { + if ( p == q ) { + return true; + } + TIXMLASSERT( p ); + TIXMLASSERT( q ); + TIXMLASSERT( nChar >= 0 ); + return strncmp( p, q, nChar ) == 0; + } + + inline static bool IsUTF8Continuation( char p ) { + return ( p & 0x80 ) != 0; + } + + static const char* ReadBOM( const char* p, bool* hasBOM ); + // p is the starting location, + // the UTF-8 value of the entity will be placed in value, and length filled in. + static const char* GetCharacterRef( const char* p, char* value, int* length ); + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + + // converts primitive types to strings + static void ToStr( int v, char* buffer, int bufferSize ); + static void ToStr( unsigned v, char* buffer, int bufferSize ); + static void ToStr( bool v, char* buffer, int bufferSize ); + static void ToStr( float v, char* buffer, int bufferSize ); + static void ToStr( double v, char* buffer, int bufferSize ); + static void ToStr(int64_t v, char* buffer, int bufferSize); + + // converts strings to primitive types + static bool ToInt( const char* str, int* value ); + static bool ToUnsigned( const char* str, unsigned* value ); + static bool ToBool( const char* str, bool* value ); + static bool ToFloat( const char* str, float* value ); + static bool ToDouble( const char* str, double* value ); + static bool ToInt64(const char* str, int64_t* value); + + // Changes what is serialized for a boolean value. + // Default to "true" and "false". Shouldn't be changed + // unless you have a special testing or compatibility need. + // Be careful: static, global, & not thread safe. + // Be sure to set static const memory as parameters. + static void SetBoolSerialization(const char* writeTrue, const char* writeFalse); + +private: + static const char* writeBoolTrue; + static const char* writeBoolFalse; +}; + + +/** XMLNode is a base class for every object that is in the + XML Document Object Model (DOM), except XMLAttributes. + Nodes have siblings, a parent, and children which can + be navigated. A node is always in a XMLDocument. + The type of a XMLNode can be queried, and it can + be cast to its more defined type. + + A XMLDocument allocates memory for all its Nodes. + When the XMLDocument gets deleted, all its Nodes + will also be deleted. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + @endverbatim +*/ +class TINYXML2_LIB XMLNode +{ + friend class XMLDocument; + friend class XMLElement; +public: + + /// Get the XMLDocument that owns this XMLNode. + const XMLDocument* GetDocument() const { + TIXMLASSERT( _document ); + return _document; + } + /// Get the XMLDocument that owns this XMLNode. + XMLDocument* GetDocument() { + TIXMLASSERT( _document ); + return _document; + } + + /// Safely cast to an Element, or null. + virtual XMLElement* ToElement() { + return 0; + } + /// Safely cast to Text, or null. + virtual XMLText* ToText() { + return 0; + } + /// Safely cast to a Comment, or null. + virtual XMLComment* ToComment() { + return 0; + } + /// Safely cast to a Document, or null. + virtual XMLDocument* ToDocument() { + return 0; + } + /// Safely cast to a Declaration, or null. + virtual XMLDeclaration* ToDeclaration() { + return 0; + } + /// Safely cast to an Unknown, or null. + virtual XMLUnknown* ToUnknown() { + return 0; + } + + virtual const XMLElement* ToElement() const { + return 0; + } + virtual const XMLText* ToText() const { + return 0; + } + virtual const XMLComment* ToComment() const { + return 0; + } + virtual const XMLDocument* ToDocument() const { + return 0; + } + virtual const XMLDeclaration* ToDeclaration() const { + return 0; + } + virtual const XMLUnknown* ToUnknown() const { + return 0; + } + + /** The meaning of 'value' changes for the specific type. + @verbatim + Document: empty (NULL is returned, not an empty string) + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + const char* Value() const; + + /** Set the Value of an XML node. + @sa Value() + */ + void SetValue( const char* val, bool staticMem=false ); + + /// Gets the line number the node is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } + + /// Get the parent of this node on the DOM. + const XMLNode* Parent() const { + return _parent; + } + + XMLNode* Parent() { + return _parent; + } + + /// Returns true if this node has no children. + bool NoChildren() const { + return !_firstChild; + } + + /// Get the first child node, or null if none exists. + const XMLNode* FirstChild() const { + return _firstChild; + } + + XMLNode* FirstChild() { + return _firstChild; + } + + /** Get the first child element, or optionally the first child + element with the specified name. + */ + const XMLElement* FirstChildElement( const char* name = 0 ) const; + + XMLElement* FirstChildElement( const char* name = 0 ) { + return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name )); + } + + /// Get the last child node, or null if none exists. + const XMLNode* LastChild() const { + return _lastChild; + } + + XMLNode* LastChild() { + return _lastChild; + } + + /** Get the last child element or optionally the last child + element with the specified name. + */ + const XMLElement* LastChildElement( const char* name = 0 ) const; + + XMLElement* LastChildElement( const char* name = 0 ) { + return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) ); + } + + /// Get the previous (left) sibling node of this node. + const XMLNode* PreviousSibling() const { + return _prev; + } + + XMLNode* PreviousSibling() { + return _prev; + } + + /// Get the previous (left) sibling element of this node, with an optionally supplied name. + const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ; + + XMLElement* PreviousSiblingElement( const char* name = 0 ) { + return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) ); + } + + /// Get the next (right) sibling node of this node. + const XMLNode* NextSibling() const { + return _next; + } + + XMLNode* NextSibling() { + return _next; + } + + /// Get the next (right) sibling element of this node, with an optionally supplied name. + const XMLElement* NextSiblingElement( const char* name = 0 ) const; + + XMLElement* NextSiblingElement( const char* name = 0 ) { + return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) ); + } + + /** + Add a child node as the last (right) child. + If the child node is already part of the document, + it is moved from its old location to the new location. + Returns the addThis argument or 0 if the node does not + belong to the same document. + */ + XMLNode* InsertEndChild( XMLNode* addThis ); + + XMLNode* LinkEndChild( XMLNode* addThis ) { + return InsertEndChild( addThis ); + } + /** + Add a child node as the first (left) child. + If the child node is already part of the document, + it is moved from its old location to the new location. + Returns the addThis argument or 0 if the node does not + belong to the same document. + */ + XMLNode* InsertFirstChild( XMLNode* addThis ); + /** + Add a node after the specified child node. + If the child node is already part of the document, + it is moved from its old location to the new location. + Returns the addThis argument or 0 if the afterThis node + is not a child of this node, or if the node does not + belong to the same document. + */ + XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); + + /** + Delete all the children of this node. + */ + void DeleteChildren(); + + /** + Delete a child of this node. + */ + void DeleteChild( XMLNode* node ); + + /** + Make a copy of this node, but not its children. + You may pass in a Document pointer that will be + the owner of the new Node. If the 'document' is + null, then the node returned will be allocated + from the current Document. (this->GetDocument()) + + Note: if called on a XMLDocument, this will return null. + */ + virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; + + /** + Make a copy of this node and all its children. + + If the 'target' is null, then the nodes will be allocated in the current document. If 'target' is specified, the memory will be allocated is the - specified XMLDocument. - + specified XMLDocument. + NOTE: This is probably not the correct tool to - copy a document, since XMLDocuments can have multiple - top level XMLNodes. You probably want to use - XMLDocument::DeepCopy() - */ - XMLNode* DeepClone( XMLDocument* target ) const; - - /** - Test if 2 nodes are the same, but don't test children. - The 2 nodes do not need to be in the same Document. - - Note: if called on a XMLDocument, this will return false. - */ - virtual bool ShallowEqual( const XMLNode* compare ) const = 0; - - /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the XMLVisitor interface. - - This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - XMLPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( XMLVisitor* visitor ) const = 0; - + copy a document, since XMLDocuments can have multiple + top level XMLNodes. You probably want to use + XMLDocument::DeepCopy() + */ + XMLNode* DeepClone( XMLDocument* target ) const; + + /** + Test if 2 nodes are the same, but don't test children. + The 2 nodes do not need to be in the same Document. + + Note: if called on a XMLDocument, this will return false. + */ + virtual bool ShallowEqual( const XMLNode* compare ) const = 0; + + /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the XMLVisitor interface. + + This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + XMLPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( XMLVisitor* visitor ) const = 0; + /** Set user data into the XMLNode. TinyXML-2 in - no way processes or interprets user data. - It is initially 0. - */ - void SetUserData(void* userData) { _userData = userData; } - - /** - Get user data set into the XMLNode. TinyXML-2 in - no way processes or interprets user data. - It is initially 0. - */ - void* GetUserData() const { return _userData; } - -protected: - XMLNode( XMLDocument* ); - virtual ~XMLNode(); - - virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); - - XMLDocument* _document; - XMLNode* _parent; - mutable StrPair _value; - int _parseLineNum; - - XMLNode* _firstChild; - XMLNode* _lastChild; - - XMLNode* _prev; - XMLNode* _next; - - void* _userData; - -private: - MemPool* _memPool; - void Unlink( XMLNode* child ); - static void DeleteNode( XMLNode* node ); - void InsertChildPreamble( XMLNode* insertThis ) const; - const XMLElement* ToElementWithName( const char* name ) const; - - XMLNode( const XMLNode& ); // not supported - XMLNode& operator=( const XMLNode& ); // not supported -}; - - -/** XML text. - - Note that a text node can have child element nodes, for example: - @verbatim - <root>This is <b>bold</b></root> - @endverbatim - - A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCData() and query it with CData(). -*/ -class TINYXML2_LIB XMLText : public XMLNode -{ - friend class XMLDocument; -public: - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLText* ToText() { - return this; - } - virtual const XMLText* ToText() const { - return this; - } - - /// Declare whether this should be CDATA or standard text. - void SetCData( bool isCData ) { - _isCData = isCData; - } - /// Returns true if this is a CDATA text element. - bool CData() const { - return _isCData; - } - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} - virtual ~XMLText() {} - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - bool _isCData; - - XMLText( const XMLText& ); // not supported - XMLText& operator=( const XMLText& ); // not supported -}; - - -/** An XML Comment. */ -class TINYXML2_LIB XMLComment : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLComment* ToComment() { - return this; - } - virtual const XMLComment* ToComment() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLComment( XMLDocument* doc ); - virtual ~XMLComment(); - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); - -private: - XMLComment( const XMLComment& ); // not supported - XMLComment& operator=( const XMLComment& ); // not supported -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - <?xml version="1.0" standalone="yes"?> - @endverbatim - - TinyXML-2 will happily read or write files without a declaration, - however. - - The text of the declaration isn't interpreted. It is parsed - and written as a string. -*/ -class TINYXML2_LIB XMLDeclaration : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLDeclaration* ToDeclaration() { - return this; - } - virtual const XMLDeclaration* ToDeclaration() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLDeclaration( XMLDocument* doc ); - virtual ~XMLDeclaration(); - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - XMLDeclaration( const XMLDeclaration& ); // not supported - XMLDeclaration& operator=( const XMLDeclaration& ); // not supported -}; - - -/** Any tag that TinyXML-2 doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into XMLUnknowns. -*/ -class TINYXML2_LIB XMLUnknown : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLUnknown* ToUnknown() { - return this; - } - virtual const XMLUnknown* ToUnknown() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLUnknown( XMLDocument* doc ); - virtual ~XMLUnknown(); - - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - XMLUnknown( const XMLUnknown& ); // not supported - XMLUnknown& operator=( const XMLUnknown& ); // not supported -}; - - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not XMLNodes. You may only query the - Next() attribute in a list. -*/ -class TINYXML2_LIB XMLAttribute -{ - friend class XMLElement; -public: - /// The name of the attribute. - const char* Name() const; - - /// The value of the attribute. - const char* Value() const; - - /// Gets the line number the attribute is in, if the document was parsed from a file. - int GetLineNum() const { return _parseLineNum; } - - /// The next attribute in the list. - const XMLAttribute* Next() const { - return _next; - } - - /** IntValue interprets the attribute as an integer, and returns the value. - If the value isn't an integer, 0 will be returned. There is no error checking; - use QueryIntValue() if you need error checking. - */ - int IntValue() const { - int i = 0; - QueryIntValue(&i); - return i; - } - - int64_t Int64Value() const { - int64_t i = 0; - QueryInt64Value(&i); - return i; - } - - /// Query as an unsigned integer. See IntValue() - unsigned UnsignedValue() const { - unsigned i=0; - QueryUnsignedValue( &i ); - return i; - } - /// Query as a boolean. See IntValue() - bool BoolValue() const { - bool b=false; - QueryBoolValue( &b ); - return b; - } - /// Query as a double. See IntValue() - double DoubleValue() const { - double d=0; - QueryDoubleValue( &d ); - return d; - } - /// Query as a float. See IntValue() - float FloatValue() const { - float f=0; - QueryFloatValue( &f ); - return f; - } - - /** QueryIntValue interprets the attribute as an integer, and returns the value - in the provided parameter. The function will return XML_SUCCESS on success, - and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. - */ - XMLError QueryIntValue( int* value ) const; - /// See QueryIntValue - XMLError QueryUnsignedValue( unsigned int* value ) const; - /// See QueryIntValue - XMLError QueryInt64Value(int64_t* value) const; - /// See QueryIntValue - XMLError QueryBoolValue( bool* value ) const; - /// See QueryIntValue - XMLError QueryDoubleValue( double* value ) const; - /// See QueryIntValue - XMLError QueryFloatValue( float* value ) const; - - /// Set the attribute to a string value. - void SetAttribute( const char* value ); - /// Set the attribute to value. - void SetAttribute( int value ); - /// Set the attribute to value. - void SetAttribute( unsigned value ); - /// Set the attribute to value. - void SetAttribute(int64_t value); - /// Set the attribute to value. - void SetAttribute( bool value ); - /// Set the attribute to value. - void SetAttribute( double value ); - /// Set the attribute to value. - void SetAttribute( float value ); - -private: - enum { BUF_SIZE = 200 }; - - XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {} - virtual ~XMLAttribute() {} - - XMLAttribute( const XMLAttribute& ); // not supported - void operator=( const XMLAttribute& ); // not supported - void SetName( const char* name ); - - char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr ); - - mutable StrPair _name; - mutable StrPair _value; - int _parseLineNum; - XMLAttribute* _next; - MemPool* _memPool; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TINYXML2_LIB XMLElement : public XMLNode -{ - friend class XMLDocument; -public: - /// Get the name of an element (which is the Value() of the node.) - const char* Name() const { - return Value(); - } - /// Set the name of the element. - void SetName( const char* str, bool staticMem=false ) { - SetValue( str, staticMem ); - } - - virtual XMLElement* ToElement() { - return this; - } - virtual const XMLElement* ToElement() const { - return this; - } - virtual bool Accept( XMLVisitor* visitor ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none - exists. For example: - - @verbatim - const char* value = ele->Attribute( "foo" ); - @endverbatim - - The 'value' parameter is normally null. However, if specified, - the attribute will only be returned if the 'name' and 'value' - match. This allow you to write code: - - @verbatim - if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); - @endverbatim - - rather than: - @verbatim - if ( ele->Attribute( "foo" ) ) { - if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); - } - @endverbatim - */ - const char* Attribute( const char* name, const char* value=0 ) const; - - /** Given an attribute name, IntAttribute() returns the value - of the attribute interpreted as an integer. The default - value will be returned if the attribute isn't present, - or if there is an error. (For a method with error - checking, see QueryIntAttribute()). - */ - int IntAttribute(const char* name, int defaultValue = 0) const; - /// See IntAttribute() - unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const; - /// See IntAttribute() - int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const; - /// See IntAttribute() - bool BoolAttribute(const char* name, bool defaultValue = false) const; - /// See IntAttribute() - double DoubleAttribute(const char* name, double defaultValue = 0) const; - /// See IntAttribute() - float FloatAttribute(const char* name, float defaultValue = 0) const; - - /** Given an attribute name, QueryIntAttribute() returns - XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - XMLError QueryIntAttribute( const char* name, int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryIntValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryUnsignedValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryInt64Attribute(const char* name, int64_t* value) const { - const XMLAttribute* a = FindAttribute(name); - if (!a) { - return XML_NO_ATTRIBUTE; - } - return a->QueryInt64Value(value); - } - - /// See QueryIntAttribute() - XMLError QueryBoolAttribute( const char* name, bool* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryBoolValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryDoubleAttribute( const char* name, double* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryDoubleValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryFloatAttribute( const char* name, float* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryFloatValue( value ); - } - - - /** Given an attribute name, QueryAttribute() returns - XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. It is overloaded for the primitive types, - and is a generally more convenient replacement of - QueryIntAttribute() and related functions. - - If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - int QueryAttribute( const char* name, int* value ) const { - return QueryIntAttribute( name, value ); - } - - int QueryAttribute( const char* name, unsigned int* value ) const { - return QueryUnsignedAttribute( name, value ); - } - - int QueryAttribute(const char* name, int64_t* value) const { - return QueryInt64Attribute(name, value); - } - - int QueryAttribute( const char* name, bool* value ) const { - return QueryBoolAttribute( name, value ); - } - - int QueryAttribute( const char* name, double* value ) const { - return QueryDoubleAttribute( name, value ); - } - - int QueryAttribute( const char* name, float* value ) const { - return QueryFloatAttribute( name, value ); - } - - /// Sets the named attribute to value. - void SetAttribute( const char* name, const char* value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, int value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, unsigned value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - - /// Sets the named attribute to value. - void SetAttribute(const char* name, int64_t value) { - XMLAttribute* a = FindOrCreateAttribute(name); - a->SetAttribute(value); - } - - /// Sets the named attribute to value. - void SetAttribute( const char* name, bool value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, double value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, float value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - - /** - Delete an attribute. - */ - void DeleteAttribute( const char* name ); - - /// Return the first attribute in the list. - const XMLAttribute* FirstAttribute() const { - return _rootAttribute; - } - /// Query a specific attribute in the list. - const XMLAttribute* FindAttribute( const char* name ) const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the XMLText child - and accessing it directly. - - If the first child of 'this' is a XMLText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - <foo>This is text</foo> - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - <foo><b>This is text</b></foo> - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - <foo>This is <b>text</b></foo> - @endverbatim - GetText() will return "This is ". - */ - const char* GetText() const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, SetText() is limited compared to creating an XMLText child - and mutating it directly. - - If the first child of 'this' is a XMLText, SetText() sets its value to - the given string, otherwise it will create a first child that is an XMLText. - - This is a convenient method for setting the text of simple contained text: - @verbatim - <foo>This is text</foo> - fooElement->SetText( "Hullaballoo!" ); - <foo>Hullaballoo!</foo> - @endverbatim - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - <foo><b>This is text</b></foo> - @endverbatim - - then it will not change "This is text", but rather prefix it with a text element: - @verbatim - <foo>Hullaballoo!<b>This is text</b></foo> - @endverbatim - - For this XML: - @verbatim - <foo /> - @endverbatim - SetText() will generate - @verbatim - <foo>Hullaballoo!</foo> - @endverbatim - */ - void SetText( const char* inText ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( int value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. + no way processes or interprets user data. + It is initially 0. + */ + void SetUserData(void* userData) { _userData = userData; } + + /** + Get user data set into the XMLNode. TinyXML-2 in + no way processes or interprets user data. + It is initially 0. + */ + void* GetUserData() const { return _userData; } + +protected: + XMLNode( XMLDocument* ); + virtual ~XMLNode(); + + virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); + + XMLDocument* _document; + XMLNode* _parent; + mutable StrPair _value; + int _parseLineNum; + + XMLNode* _firstChild; + XMLNode* _lastChild; + + XMLNode* _prev; + XMLNode* _next; + + void* _userData; + +private: + MemPool* _memPool; + void Unlink( XMLNode* child ); + static void DeleteNode( XMLNode* node ); + void InsertChildPreamble( XMLNode* insertThis ) const; + const XMLElement* ToElementWithName( const char* name ) const; + + XMLNode( const XMLNode& ); // not supported + XMLNode& operator=( const XMLNode& ); // not supported +}; + + +/** XML text. + + Note that a text node can have child element nodes, for example: + @verbatim + <root>This is <b>bold</b></root> + @endverbatim + + A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCData() and query it with CData(). +*/ +class TINYXML2_LIB XMLText : public XMLNode +{ + friend class XMLDocument; +public: + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLText* ToText() { + return this; + } + virtual const XMLText* ToText() const { + return this; + } + + /// Declare whether this should be CDATA or standard text. + void SetCData( bool isCData ) { + _isCData = isCData; + } + /// Returns true if this is a CDATA text element. + bool CData() const { + return _isCData; + } + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} + virtual ~XMLText() {} + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + bool _isCData; + + XMLText( const XMLText& ); // not supported + XMLText& operator=( const XMLText& ); // not supported +}; + + +/** An XML Comment. */ +class TINYXML2_LIB XMLComment : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLComment* ToComment() { + return this; + } + virtual const XMLComment* ToComment() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLComment( XMLDocument* doc ); + virtual ~XMLComment(); + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); + +private: + XMLComment( const XMLComment& ); // not supported + XMLComment& operator=( const XMLComment& ); // not supported +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + <?xml version="1.0" standalone="yes"?> + @endverbatim + + TinyXML-2 will happily read or write files without a declaration, + however. + + The text of the declaration isn't interpreted. It is parsed + and written as a string. +*/ +class TINYXML2_LIB XMLDeclaration : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLDeclaration* ToDeclaration() { + return this; + } + virtual const XMLDeclaration* ToDeclaration() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLDeclaration( XMLDocument* doc ); + virtual ~XMLDeclaration(); + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + XMLDeclaration( const XMLDeclaration& ); // not supported + XMLDeclaration& operator=( const XMLDeclaration& ); // not supported +}; + + +/** Any tag that TinyXML-2 doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into XMLUnknowns. +*/ +class TINYXML2_LIB XMLUnknown : public XMLNode +{ + friend class XMLDocument; +public: + virtual XMLUnknown* ToUnknown() { + return this; + } + virtual const XMLUnknown* ToUnknown() const { + return this; + } + + virtual bool Accept( XMLVisitor* visitor ) const; + + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + XMLUnknown( XMLDocument* doc ); + virtual ~XMLUnknown(); + + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + XMLUnknown( const XMLUnknown& ); // not supported + XMLUnknown& operator=( const XMLUnknown& ); // not supported +}; + + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not XMLNodes. You may only query the + Next() attribute in a list. +*/ +class TINYXML2_LIB XMLAttribute +{ + friend class XMLElement; +public: + /// The name of the attribute. + const char* Name() const; + + /// The value of the attribute. + const char* Value() const; + + /// Gets the line number the attribute is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } + + /// The next attribute in the list. + const XMLAttribute* Next() const { + return _next; + } + + /** IntValue interprets the attribute as an integer, and returns the value. + If the value isn't an integer, 0 will be returned. There is no error checking; + use QueryIntValue() if you need error checking. + */ + int IntValue() const { + int i = 0; + QueryIntValue(&i); + return i; + } + + int64_t Int64Value() const { + int64_t i = 0; + QueryInt64Value(&i); + return i; + } + + /// Query as an unsigned integer. See IntValue() + unsigned UnsignedValue() const { + unsigned i=0; + QueryUnsignedValue( &i ); + return i; + } + /// Query as a boolean. See IntValue() + bool BoolValue() const { + bool b=false; + QueryBoolValue( &b ); + return b; + } + /// Query as a double. See IntValue() + double DoubleValue() const { + double d=0; + QueryDoubleValue( &d ); + return d; + } + /// Query as a float. See IntValue() + float FloatValue() const { + float f=0; + QueryFloatValue( &f ); + return f; + } + + /** QueryIntValue interprets the attribute as an integer, and returns the value + in the provided parameter. The function will return XML_SUCCESS on success, + and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. + */ + XMLError QueryIntValue( int* value ) const; + /// See QueryIntValue + XMLError QueryUnsignedValue( unsigned int* value ) const; + /// See QueryIntValue + XMLError QueryInt64Value(int64_t* value) const; + /// See QueryIntValue + XMLError QueryBoolValue( bool* value ) const; + /// See QueryIntValue + XMLError QueryDoubleValue( double* value ) const; + /// See QueryIntValue + XMLError QueryFloatValue( float* value ) const; + + /// Set the attribute to a string value. + void SetAttribute( const char* value ); + /// Set the attribute to value. + void SetAttribute( int value ); + /// Set the attribute to value. + void SetAttribute( unsigned value ); + /// Set the attribute to value. + void SetAttribute(int64_t value); + /// Set the attribute to value. + void SetAttribute( bool value ); + /// Set the attribute to value. + void SetAttribute( double value ); + /// Set the attribute to value. + void SetAttribute( float value ); + +private: + enum { BUF_SIZE = 200 }; + + XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {} + virtual ~XMLAttribute() {} + + XMLAttribute( const XMLAttribute& ); // not supported + void operator=( const XMLAttribute& ); // not supported + void SetName( const char* name ); + + char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr ); + + mutable StrPair _name; + mutable StrPair _value; + int _parseLineNum; + XMLAttribute* _next; + MemPool* _memPool; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TINYXML2_LIB XMLElement : public XMLNode +{ + friend class XMLDocument; +public: + /// Get the name of an element (which is the Value() of the node.) + const char* Name() const { + return Value(); + } + /// Set the name of the element. + void SetName( const char* str, bool staticMem=false ) { + SetValue( str, staticMem ); + } + + virtual XMLElement* ToElement() { + return this; + } + virtual const XMLElement* ToElement() const { + return this; + } + virtual bool Accept( XMLVisitor* visitor ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none + exists. For example: + + @verbatim + const char* value = ele->Attribute( "foo" ); + @endverbatim + + The 'value' parameter is normally null. However, if specified, + the attribute will only be returned if the 'name' and 'value' + match. This allow you to write code: + + @verbatim + if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); + @endverbatim + + rather than: + @verbatim + if ( ele->Attribute( "foo" ) ) { + if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); + } + @endverbatim + */ + const char* Attribute( const char* name, const char* value=0 ) const; + + /** Given an attribute name, IntAttribute() returns the value + of the attribute interpreted as an integer. The default + value will be returned if the attribute isn't present, + or if there is an error. (For a method with error + checking, see QueryIntAttribute()). + */ + int IntAttribute(const char* name, int defaultValue = 0) const; + /// See IntAttribute() + unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const; + /// See IntAttribute() + int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const; + /// See IntAttribute() + bool BoolAttribute(const char* name, bool defaultValue = false) const; + /// See IntAttribute() + double DoubleAttribute(const char* name, double defaultValue = 0) const; + /// See IntAttribute() + float FloatAttribute(const char* name, float defaultValue = 0) const; + + /** Given an attribute name, QueryIntAttribute() returns + XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + XMLError QueryIntAttribute( const char* name, int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryIntValue( value ); + } + + /// See QueryIntAttribute() + XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryUnsignedValue( value ); + } + + /// See QueryIntAttribute() + XMLError QueryInt64Attribute(const char* name, int64_t* value) const { + const XMLAttribute* a = FindAttribute(name); + if (!a) { + return XML_NO_ATTRIBUTE; + } + return a->QueryInt64Value(value); + } + + /// See QueryIntAttribute() + XMLError QueryBoolAttribute( const char* name, bool* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryBoolValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryDoubleAttribute( const char* name, double* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryDoubleValue( value ); + } + /// See QueryIntAttribute() + XMLError QueryFloatAttribute( const char* name, float* value ) const { + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return XML_NO_ATTRIBUTE; + } + return a->QueryFloatValue( value ); + } + + + /** Given an attribute name, QueryAttribute() returns + XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion + can't be performed, or XML_NO_ATTRIBUTE if the attribute + doesn't exist. It is overloaded for the primitive types, + and is a generally more convenient replacement of + QueryIntAttribute() and related functions. + + If successful, the result of the conversion + will be written to 'value'. If not successful, nothing will + be written to 'value'. This allows you to provide default + value: + + @verbatim + int value = 10; + QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 + @endverbatim + */ + int QueryAttribute( const char* name, int* value ) const { + return QueryIntAttribute( name, value ); + } + + int QueryAttribute( const char* name, unsigned int* value ) const { + return QueryUnsignedAttribute( name, value ); + } + + int QueryAttribute(const char* name, int64_t* value) const { + return QueryInt64Attribute(name, value); + } + + int QueryAttribute( const char* name, bool* value ) const { + return QueryBoolAttribute( name, value ); + } + + int QueryAttribute( const char* name, double* value ) const { + return QueryDoubleAttribute( name, value ); + } + + int QueryAttribute( const char* name, float* value ) const { + return QueryFloatAttribute( name, value ); + } + + /// Sets the named attribute to value. + void SetAttribute( const char* name, const char* value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, int value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, unsigned value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + + /// Sets the named attribute to value. + void SetAttribute(const char* name, int64_t value) { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + + /// Sets the named attribute to value. + void SetAttribute( const char* name, bool value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, double value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + /// Sets the named attribute to value. + void SetAttribute( const char* name, float value ) { + XMLAttribute* a = FindOrCreateAttribute( name ); + a->SetAttribute( value ); + } + + /** + Delete an attribute. + */ + void DeleteAttribute( const char* name ); + + /// Return the first attribute in the list. + const XMLAttribute* FirstAttribute() const { + return _rootAttribute; + } + /// Query a specific attribute in the list. + const XMLAttribute* FindAttribute( const char* name ) const; + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the XMLText child + and accessing it directly. + + If the first child of 'this' is a XMLText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + <foo>This is text</foo> + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + <foo><b>This is text</b></foo> + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + <foo>This is <b>text</b></foo> + @endverbatim + GetText() will return "This is ". + */ + const char* GetText() const; + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, SetText() is limited compared to creating an XMLText child + and mutating it directly. + + If the first child of 'this' is a XMLText, SetText() sets its value to + the given string, otherwise it will create a first child that is an XMLText. + + This is a convenient method for setting the text of simple contained text: + @verbatim + <foo>This is text</foo> + fooElement->SetText( "Hullaballoo!" ); + <foo>Hullaballoo!</foo> + @endverbatim + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + <foo><b>This is text</b></foo> + @endverbatim + + then it will not change "This is text", but rather prefix it with a text element: + @verbatim + <foo>Hullaballoo!<b>This is text</b></foo> + @endverbatim + + For this XML: + @verbatim + <foo /> + @endverbatim + SetText() will generate + @verbatim + <foo>Hullaballoo!</foo> + @endverbatim + */ + void SetText( const char* inText ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText( int value ); + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( unsigned value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText(int64_t value); - /// Convenience method for setting text inside an element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(int64_t value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( bool value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( double value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. + /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText( float value ); - - /** - Convenience method to query the value of a child text node. This is probably best - shown by example. Given you have a document is this form: - @verbatim - <point> - <x>1</x> - <y>1.4</y> - </point> - @endverbatim - - The QueryIntText() and similar functions provide a safe and easier way to get to the - "value" of x and y. - - @verbatim - int x = 0; - float y = 0; // types of x and y are contrived for example - const XMLElement* xElement = pointElement->FirstChildElement( "x" ); - const XMLElement* yElement = pointElement->FirstChildElement( "y" ); - xElement->QueryIntText( &x ); - yElement->QueryFloatText( &y ); - @endverbatim - - @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted - to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. - - */ - XMLError QueryIntText( int* ival ) const; - /// See QueryIntText() - XMLError QueryUnsignedText( unsigned* uval ) const; - /// See QueryIntText() - XMLError QueryInt64Text(int64_t* uval) const; - /// See QueryIntText() - XMLError QueryBoolText( bool* bval ) const; - /// See QueryIntText() - XMLError QueryDoubleText( double* dval ) const; - /// See QueryIntText() - XMLError QueryFloatText( float* fval ) const; - - int IntText(int defaultValue = 0) const; - - /// See QueryIntText() - unsigned UnsignedText(unsigned defaultValue = 0) const; - /// See QueryIntText() - int64_t Int64Text(int64_t defaultValue = 0) const; - /// See QueryIntText() - bool BoolText(bool defaultValue = false) const; - /// See QueryIntText() - double DoubleText(double defaultValue = 0) const; - /// See QueryIntText() - float FloatText(float defaultValue = 0) const; - - // internal: - enum ElementClosingType { - OPEN, // <foo> - CLOSED, // <foo/> - CLOSING // </foo> - }; - ElementClosingType ClosingType() const { - return _closingType; - } - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); - -private: - XMLElement( XMLDocument* doc ); - virtual ~XMLElement(); - XMLElement( const XMLElement& ); // not supported - void operator=( const XMLElement& ); // not supported - - XMLAttribute* FindAttribute( const char* name ) { - return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name )); - } - XMLAttribute* FindOrCreateAttribute( const char* name ); - //void LinkAttribute( XMLAttribute* attrib ); - char* ParseAttributes( char* p, int* curLineNumPtr ); - static void DeleteAttribute( XMLAttribute* attribute ); - XMLAttribute* CreateAttribute(); - - enum { BUF_SIZE = 200 }; - ElementClosingType _closingType; - // The attribute list is ordered; there is no 'lastAttribute' - // because the list needs to be scanned for dupes before adding - // a new attribute. - XMLAttribute* _rootAttribute; -}; - - -enum Whitespace { - PRESERVE_WHITESPACE, - COLLAPSE_WHITESPACE -}; - - -/** A Document binds together all the functionality. - It can be saved, loaded, and printed to the screen. - All Nodes are connected and allocated to a Document. - If the Document is deleted, all its Nodes are also deleted. -*/ -class TINYXML2_LIB XMLDocument : public XMLNode -{ - friend class XMLElement; - // Gives access to SetError, but over-access for everything else. - // Wishing C++ had "internal" scope. + + /** + Convenience method to query the value of a child text node. This is probably best + shown by example. Given you have a document is this form: + @verbatim + <point> + <x>1</x> + <y>1.4</y> + </point> + @endverbatim + + The QueryIntText() and similar functions provide a safe and easier way to get to the + "value" of x and y. + + @verbatim + int x = 0; + float y = 0; // types of x and y are contrived for example + const XMLElement* xElement = pointElement->FirstChildElement( "x" ); + const XMLElement* yElement = pointElement->FirstChildElement( "y" ); + xElement->QueryIntText( &x ); + yElement->QueryFloatText( &y ); + @endverbatim + + @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted + to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. + + */ + XMLError QueryIntText( int* ival ) const; + /// See QueryIntText() + XMLError QueryUnsignedText( unsigned* uval ) const; + /// See QueryIntText() + XMLError QueryInt64Text(int64_t* uval) const; + /// See QueryIntText() + XMLError QueryBoolText( bool* bval ) const; + /// See QueryIntText() + XMLError QueryDoubleText( double* dval ) const; + /// See QueryIntText() + XMLError QueryFloatText( float* fval ) const; + + int IntText(int defaultValue = 0) const; + + /// See QueryIntText() + unsigned UnsignedText(unsigned defaultValue = 0) const; + /// See QueryIntText() + int64_t Int64Text(int64_t defaultValue = 0) const; + /// See QueryIntText() + bool BoolText(bool defaultValue = false) const; + /// See QueryIntText() + double DoubleText(double defaultValue = 0) const; + /// See QueryIntText() + float FloatText(float defaultValue = 0) const; + + // internal: + enum ElementClosingType { + OPEN, // <foo> + CLOSED, // <foo/> + CLOSING // </foo> + }; + ElementClosingType ClosingType() const { + return _closingType; + } + virtual XMLNode* ShallowClone( XMLDocument* document ) const; + virtual bool ShallowEqual( const XMLNode* compare ) const; + +protected: + char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + +private: + XMLElement( XMLDocument* doc ); + virtual ~XMLElement(); + XMLElement( const XMLElement& ); // not supported + void operator=( const XMLElement& ); // not supported + + XMLAttribute* FindAttribute( const char* name ) { + return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name )); + } + XMLAttribute* FindOrCreateAttribute( const char* name ); + //void LinkAttribute( XMLAttribute* attrib ); + char* ParseAttributes( char* p, int* curLineNumPtr ); + static void DeleteAttribute( XMLAttribute* attribute ); + XMLAttribute* CreateAttribute(); + + enum { BUF_SIZE = 200 }; + ElementClosingType _closingType; + // The attribute list is ordered; there is no 'lastAttribute' + // because the list needs to be scanned for dupes before adding + // a new attribute. + XMLAttribute* _rootAttribute; +}; + + +enum Whitespace { + PRESERVE_WHITESPACE, + COLLAPSE_WHITESPACE +}; + + +/** A Document binds together all the functionality. + It can be saved, loaded, and printed to the screen. + All Nodes are connected and allocated to a Document. + If the Document is deleted, all its Nodes are also deleted. +*/ +class TINYXML2_LIB XMLDocument : public XMLNode +{ + friend class XMLElement; + // Gives access to SetError, but over-access for everything else. + // Wishing C++ had "internal" scope. friend class XMLNode; - friend class XMLText; - friend class XMLComment; - friend class XMLDeclaration; - friend class XMLUnknown; -public: - /// constructor - XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); - ~XMLDocument(); - - virtual XMLDocument* ToDocument() { - TIXMLASSERT( this == _document ); - return this; - } - virtual const XMLDocument* ToDocument() const { - TIXMLASSERT( this == _document ); - return this; - } - - /** - Parse an XML file from a character string. - Returns XML_SUCCESS (0) on success, or - an errorID. - - You may optionally pass in the 'nBytes', which is - the number of bytes which will be parsed. If not - specified, TinyXML-2 will assume 'xml' points to a - null terminated string. - */ - XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); - - /** - Load an XML file from disk. - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError LoadFile( const char* filename ); - - /** - Load an XML file from disk. You are responsible - for providing and closing the FILE*. - - NOTE: The file should be opened as binary ("rb") - not text in order for TinyXML-2 to correctly - do newline normalization. - - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError LoadFile( FILE* ); - - /** - Save the XML file to disk. - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError SaveFile( const char* filename, bool compact = false ); - - /** - Save the XML file to disk. You are responsible + friend class XMLText; + friend class XMLComment; + friend class XMLDeclaration; + friend class XMLUnknown; +public: + /// constructor + XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); + ~XMLDocument(); + + virtual XMLDocument* ToDocument() { + TIXMLASSERT( this == _document ); + return this; + } + virtual const XMLDocument* ToDocument() const { + TIXMLASSERT( this == _document ); + return this; + } + + /** + Parse an XML file from a character string. + Returns XML_SUCCESS (0) on success, or + an errorID. + + You may optionally pass in the 'nBytes', which is + the number of bytes which will be parsed. If not + specified, TinyXML-2 will assume 'xml' points to a + null terminated string. + */ + XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); + + /** + Load an XML file from disk. + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError LoadFile( const char* filename ); + + /** + Load an XML file from disk. You are responsible for providing and closing the FILE*. - Returns XML_SUCCESS (0) on success, or - an errorID. - */ - XMLError SaveFile( FILE* fp, bool compact = false ); - - bool ProcessEntities() const { - return _processEntities; - } - Whitespace WhitespaceMode() const { - return _whitespaceMode; - } - - /** - Returns true if this document has a leading Byte Order Mark of UTF8. - */ - bool HasBOM() const { - return _writeBOM; - } - /** Sets whether to write the BOM when writing the file. - */ - void SetBOM( bool useBOM ) { - _writeBOM = useBOM; - } - - /** Return the root element of DOM. Equivalent to FirstChildElement(). - To get the first node, use FirstChild(). - */ - XMLElement* RootElement() { - return FirstChildElement(); - } - const XMLElement* RootElement() const { - return FirstChildElement(); - } - - /** Print the Document. If the Printer is not provided, it will - print to stdout. If you provide Printer, this can print to a file: - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Or you can use a printer to print to memory: - @verbatim - XMLPrinter printer; - doc.Print( &printer ); - // printer.CStr() has a const char* to the XML - @endverbatim - */ - void Print( XMLPrinter* streamer=0 ) const; - virtual bool Accept( XMLVisitor* visitor ) const; - - /** - Create a new Element associated with - this Document. The memory for the Element - is managed by the Document. - */ - XMLElement* NewElement( const char* name ); - /** - Create a new Comment associated with - this Document. The memory for the Comment - is managed by the Document. - */ - XMLComment* NewComment( const char* comment ); - /** - Create a new Text associated with - this Document. The memory for the Text - is managed by the Document. - */ - XMLText* NewText( const char* text ); - /** - Create a new Declaration associated with - this Document. The memory for the object - is managed by the Document. - - If the 'text' param is null, the standard - declaration is used.: - @verbatim - <?xml version="1.0" encoding="UTF-8"?> - @endverbatim - */ - XMLDeclaration* NewDeclaration( const char* text=0 ); - /** - Create a new Unknown associated with - this Document. The memory for the object - is managed by the Document. - */ - XMLUnknown* NewUnknown( const char* text ); - - /** - Delete a node associated with this document. - It will be unlinked from the DOM. - */ - void DeleteNode( XMLNode* node ); - - void ClearError() { - SetError(XML_SUCCESS, 0, 0); - } - - /// Return true if there was an error parsing the document. - bool Error() const { - return _errorID != XML_SUCCESS; - } - /// Return the errorID. - XMLError ErrorID() const { - return _errorID; - } - const char* ErrorName() const; - static const char* ErrorIDToName(XMLError errorID); - + NOTE: The file should be opened as binary ("rb") + not text in order for TinyXML-2 to correctly + do newline normalization. + + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError LoadFile( FILE* ); + + /** + Save the XML file to disk. + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError SaveFile( const char* filename, bool compact = false ); + + /** + Save the XML file to disk. You are responsible + for providing and closing the FILE*. + + Returns XML_SUCCESS (0) on success, or + an errorID. + */ + XMLError SaveFile( FILE* fp, bool compact = false ); + + bool ProcessEntities() const { + return _processEntities; + } + Whitespace WhitespaceMode() const { + return _whitespaceMode; + } + + /** + Returns true if this document has a leading Byte Order Mark of UTF8. + */ + bool HasBOM() const { + return _writeBOM; + } + /** Sets whether to write the BOM when writing the file. + */ + void SetBOM( bool useBOM ) { + _writeBOM = useBOM; + } + + /** Return the root element of DOM. Equivalent to FirstChildElement(). + To get the first node, use FirstChild(). + */ + XMLElement* RootElement() { + return FirstChildElement(); + } + const XMLElement* RootElement() const { + return FirstChildElement(); + } + + /** Print the Document. If the Printer is not provided, it will + print to stdout. If you provide Printer, this can print to a file: + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Or you can use a printer to print to memory: + @verbatim + XMLPrinter printer; + doc.Print( &printer ); + // printer.CStr() has a const char* to the XML + @endverbatim + */ + void Print( XMLPrinter* streamer=0 ) const; + virtual bool Accept( XMLVisitor* visitor ) const; + + /** + Create a new Element associated with + this Document. The memory for the Element + is managed by the Document. + */ + XMLElement* NewElement( const char* name ); + /** + Create a new Comment associated with + this Document. The memory for the Comment + is managed by the Document. + */ + XMLComment* NewComment( const char* comment ); + /** + Create a new Text associated with + this Document. The memory for the Text + is managed by the Document. + */ + XMLText* NewText( const char* text ); + /** + Create a new Declaration associated with + this Document. The memory for the object + is managed by the Document. + + If the 'text' param is null, the standard + declaration is used.: + @verbatim + <?xml version="1.0" encoding="UTF-8"?> + @endverbatim + */ + XMLDeclaration* NewDeclaration( const char* text=0 ); + /** + Create a new Unknown associated with + this Document. The memory for the object + is managed by the Document. + */ + XMLUnknown* NewUnknown( const char* text ); + + /** + Delete a node associated with this document. + It will be unlinked from the DOM. + */ + void DeleteNode( XMLNode* node ); + + void ClearError() { + SetError(XML_SUCCESS, 0, 0); + } + + /// Return true if there was an error parsing the document. + bool Error() const { + return _errorID != XML_SUCCESS; + } + /// Return the errorID. + XMLError ErrorID() const { + return _errorID; + } + const char* ErrorName() const; + static const char* ErrorIDToName(XMLError errorID); + /** Returns a "long form" error description. A hopefully helpful - diagnostic with location, line number, and/or additional info. - */ - const char* ErrorStr() const; - - /// A (trivial) utility function that prints the ErrorStr() to stdout. - void PrintError() const; - + diagnostic with location, line number, and/or additional info. + */ + const char* ErrorStr() const; + + /// A (trivial) utility function that prints the ErrorStr() to stdout. + void PrintError() const; + /// Return the line where the error occurred, or zero if unknown. - int ErrorLineNum() const - { - return _errorLineNum; - } - - /// Clear the document, resetting it to the initial state. - void Clear(); - - /** - Copies this document to a target document. - The target will be completely cleared before the copy. - If you want to copy a sub-tree, see XMLNode::DeepClone(). - - NOTE: that the 'target' must be non-null. - */ - void DeepCopy(XMLDocument* target) const; - - // internal - char* Identify( char* p, XMLNode** node ); - - // internal - void MarkInUse(XMLNode*); - - virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { - return 0; - } - virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { - return false; - } - -private: - XMLDocument( const XMLDocument& ); // not supported - void operator=( const XMLDocument& ); // not supported - - bool _writeBOM; - bool _processEntities; - XMLError _errorID; - Whitespace _whitespaceMode; - mutable StrPair _errorStr; - int _errorLineNum; - char* _charBuffer; - int _parseCurLineNum; - // Memory tracking does add some overhead. - // However, the code assumes that you don't - // have a bunch of unlinked nodes around. - // Therefore it takes less memory to track - // in the document vs. a linked list in the XMLNode, - // and the performance is the same. - DynArray<XMLNode*, 10> _unlinked; - - MemPoolT< sizeof(XMLElement) > _elementPool; - MemPoolT< sizeof(XMLAttribute) > _attributePool; - MemPoolT< sizeof(XMLText) > _textPool; - MemPoolT< sizeof(XMLComment) > _commentPool; - - static const char* _errorNames[XML_ERROR_COUNT]; - - void Parse(); - - void SetError( XMLError error, int lineNum, const char* format, ... ); - - template<class NodeType, int PoolElementSize> - NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool ); -}; - -template<class NodeType, int PoolElementSize> -inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool ) -{ - TIXMLASSERT( sizeof( NodeType ) == PoolElementSize ); - TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() ); - NodeType* returnNode = new (pool.Alloc()) NodeType( this ); - TIXMLASSERT( returnNode ); - returnNode->_memPool = &pool; - - _unlinked.Push(returnNode); - return returnNode; -} - -/** - A XMLHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2 - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - <Document> - <Element attributeA = "valueA"> - <Child attributeB = "value1" /> - <Child attributeB = "value2" /> - </Element> - </Document> - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - XMLElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - XMLElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - XMLElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - XMLElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. XMLHandle addresses the verbosity - of such code. A XMLHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - XMLHandle docHandle( &document ); - XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - XMLHandle handleCopy = handle; - @endverbatim - - See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. -*/ -class TINYXML2_LIB XMLHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - XMLHandle( XMLNode* node ) : _node( node ) { - } - /// Create a handle from a node. - XMLHandle( XMLNode& node ) : _node( &node ) { - } - /// Copy constructor - XMLHandle( const XMLHandle& ref ) : _node( ref._node ) { - } - /// Assignment - XMLHandle& operator=( const XMLHandle& ref ) { - _node = ref._node; - return *this; - } - - /// Get the first child of this handle. - XMLHandle FirstChild() { - return XMLHandle( _node ? _node->FirstChild() : 0 ); - } - /// Get the first child element of this handle. - XMLHandle FirstChildElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 ); - } - /// Get the last child of this handle. - XMLHandle LastChild() { - return XMLHandle( _node ? _node->LastChild() : 0 ); - } - /// Get the last child element of this handle. - XMLHandle LastChildElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->LastChildElement( name ) : 0 ); - } - /// Get the previous sibling of this handle. - XMLHandle PreviousSibling() { - return XMLHandle( _node ? _node->PreviousSibling() : 0 ); - } - /// Get the previous sibling element of this handle. - XMLHandle PreviousSiblingElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); - } - /// Get the next sibling of this handle. - XMLHandle NextSibling() { - return XMLHandle( _node ? _node->NextSibling() : 0 ); - } - /// Get the next sibling element of this handle. - XMLHandle NextSiblingElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 ); - } - - /// Safe cast to XMLNode. This can return null. - XMLNode* ToNode() { - return _node; - } - /// Safe cast to XMLElement. This can return null. - XMLElement* ToElement() { - return ( _node ? _node->ToElement() : 0 ); - } - /// Safe cast to XMLText. This can return null. - XMLText* ToText() { - return ( _node ? _node->ToText() : 0 ); - } - /// Safe cast to XMLUnknown. This can return null. - XMLUnknown* ToUnknown() { - return ( _node ? _node->ToUnknown() : 0 ); - } - /// Safe cast to XMLDeclaration. This can return null. - XMLDeclaration* ToDeclaration() { - return ( _node ? _node->ToDeclaration() : 0 ); - } - -private: - XMLNode* _node; -}; - - -/** - A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the - same in all regards, except for the 'const' qualifiers. See XMLHandle for API. -*/ -class TINYXML2_LIB XMLConstHandle -{ -public: - XMLConstHandle( const XMLNode* node ) : _node( node ) { - } - XMLConstHandle( const XMLNode& node ) : _node( &node ) { - } - XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) { - } - - XMLConstHandle& operator=( const XMLConstHandle& ref ) { - _node = ref._node; - return *this; - } - - const XMLConstHandle FirstChild() const { - return XMLConstHandle( _node ? _node->FirstChild() : 0 ); - } - const XMLConstHandle FirstChildElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 ); - } - const XMLConstHandle LastChild() const { - return XMLConstHandle( _node ? _node->LastChild() : 0 ); - } - const XMLConstHandle LastChildElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 ); - } - const XMLConstHandle PreviousSibling() const { - return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); - } - const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); - } - const XMLConstHandle NextSibling() const { - return XMLConstHandle( _node ? _node->NextSibling() : 0 ); - } - const XMLConstHandle NextSiblingElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 ); - } - - - const XMLNode* ToNode() const { - return _node; - } - const XMLElement* ToElement() const { - return ( _node ? _node->ToElement() : 0 ); - } - const XMLText* ToText() const { - return ( _node ? _node->ToText() : 0 ); - } - const XMLUnknown* ToUnknown() const { - return ( _node ? _node->ToUnknown() : 0 ); - } - const XMLDeclaration* ToDeclaration() const { - return ( _node ? _node->ToDeclaration() : 0 ); - } - -private: - const XMLNode* _node; -}; - - -/** - Printing functionality. The XMLPrinter gives you more - options than the XMLDocument::Print() method. - - It can: - -# Print to memory. - -# Print to a file you provide. - -# Print XML without a XMLDocument. - - Print to Memory - - @verbatim - XMLPrinter printer; - doc.Print( &printer ); - SomeFunction( printer.CStr() ); - @endverbatim - - Print to a File - - You provide the file pointer. - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Print without a XMLDocument - - When loading, an XML parser is very useful. However, sometimes - when saving, it just gets in the way. The code is often set up - for streaming, and constructing the DOM is just overhead. - - The Printer supports the streaming case. The following code - prints out a trivially simple XML file without ever creating - an XML document. - - @verbatim - XMLPrinter printer( fp ); - printer.OpenElement( "foo" ); - printer.PushAttribute( "foo", "bar" ); - printer.CloseElement(); - @endverbatim -*/ -class TINYXML2_LIB XMLPrinter : public XMLVisitor -{ -public: - /** Construct the printer. If the FILE* is specified, - this will print to the FILE. Else it will print - to memory, and the result is available in CStr(). - If 'compact' is set to true, then output is created - with only required whitespace and newlines. - */ - XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); - virtual ~XMLPrinter() {} - - /** If streaming, write the BOM and declaration. */ - void PushHeader( bool writeBOM, bool writeDeclaration ); - /** If streaming, start writing an element. - The element must be closed with CloseElement() - */ - void OpenElement( const char* name, bool compactMode=false ); - /// If streaming, add an attribute to an open element. - void PushAttribute( const char* name, const char* value ); - void PushAttribute( const char* name, int value ); - void PushAttribute( const char* name, unsigned value ); - void PushAttribute(const char* name, int64_t value); - void PushAttribute( const char* name, bool value ); - void PushAttribute( const char* name, double value ); - /// If streaming, close the Element. - virtual void CloseElement( bool compactMode=false ); - - /// Add a text node. - void PushText( const char* text, bool cdata=false ); - /// Add a text node from an integer. - void PushText( int value ); - /// Add a text node from an unsigned. - void PushText( unsigned value ); - /// Add a text node from an unsigned. - void PushText(int64_t value); - /// Add a text node from a bool. - void PushText( bool value ); - /// Add a text node from a float. - void PushText( float value ); - /// Add a text node from a double. - void PushText( double value ); - - /// Add a comment - void PushComment( const char* comment ); - - void PushDeclaration( const char* value ); - void PushUnknown( const char* value ); - - virtual bool VisitEnter( const XMLDocument& /*doc*/ ); - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); - virtual bool VisitExit( const XMLElement& element ); - - virtual bool Visit( const XMLText& text ); - virtual bool Visit( const XMLComment& comment ); - virtual bool Visit( const XMLDeclaration& declaration ); - virtual bool Visit( const XMLUnknown& unknown ); - - /** - If in print to memory mode, return a pointer to - the XML file in memory. - */ - const char* CStr() const { - return _buffer.Mem(); - } - /** - If in print to memory mode, return the size - of the XML file in memory. (Note the size returned - includes the terminating null.) - */ - int CStrSize() const { - return _buffer.Size(); - } - /** - If in print to memory mode, reset the buffer to the - beginning. - */ - void ClearBuffer() { - _buffer.Clear(); - _buffer.Push(0); - _firstElement = true; - } - -protected: - virtual bool CompactMode( const XMLElement& ) { return _compactMode; } - - /** Prints out the space before an element. You may override to change - the space and tabs used. A PrintSpace() override should call Print(). - */ - virtual void PrintSpace( int depth ); - void Print( const char* format, ... ); - void Write( const char* data, size_t size ); - inline void Write( const char* data ) { Write( data, strlen( data ) ); } - void Putc( char ch ); - - void SealElementIfJustOpened(); - bool _elementJustOpened; - DynArray< const char*, 10 > _stack; - -private: - void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. - - bool _firstElement; - FILE* _fp; - int _depth; - int _textDepth; - bool _processEntities; - bool _compactMode; - - enum { - ENTITY_RANGE = 64, - BUF_SIZE = 200 - }; - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; - - DynArray< char, 20 > _buffer; - - // Prohibit cloning, intentionally not implemented - XMLPrinter( const XMLPrinter& ); - XMLPrinter& operator=( const XMLPrinter& ); -}; - - -} // tinyxml2 -} // namespace External -} // namespace Aws - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif // TINYXML2_INCLUDED
\ No newline at end of file + int ErrorLineNum() const + { + return _errorLineNum; + } + + /// Clear the document, resetting it to the initial state. + void Clear(); + + /** + Copies this document to a target document. + The target will be completely cleared before the copy. + If you want to copy a sub-tree, see XMLNode::DeepClone(). + + NOTE: that the 'target' must be non-null. + */ + void DeepCopy(XMLDocument* target) const; + + // internal + char* Identify( char* p, XMLNode** node ); + + // internal + void MarkInUse(XMLNode*); + + virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { + return 0; + } + virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { + return false; + } + +private: + XMLDocument( const XMLDocument& ); // not supported + void operator=( const XMLDocument& ); // not supported + + bool _writeBOM; + bool _processEntities; + XMLError _errorID; + Whitespace _whitespaceMode; + mutable StrPair _errorStr; + int _errorLineNum; + char* _charBuffer; + int _parseCurLineNum; + // Memory tracking does add some overhead. + // However, the code assumes that you don't + // have a bunch of unlinked nodes around. + // Therefore it takes less memory to track + // in the document vs. a linked list in the XMLNode, + // and the performance is the same. + DynArray<XMLNode*, 10> _unlinked; + + MemPoolT< sizeof(XMLElement) > _elementPool; + MemPoolT< sizeof(XMLAttribute) > _attributePool; + MemPoolT< sizeof(XMLText) > _textPool; + MemPoolT< sizeof(XMLComment) > _commentPool; + + static const char* _errorNames[XML_ERROR_COUNT]; + + void Parse(); + + void SetError( XMLError error, int lineNum, const char* format, ... ); + + template<class NodeType, int PoolElementSize> + NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool ); +}; + +template<class NodeType, int PoolElementSize> +inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool ) +{ + TIXMLASSERT( sizeof( NodeType ) == PoolElementSize ); + TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() ); + NodeType* returnNode = new (pool.Alloc()) NodeType( this ); + TIXMLASSERT( returnNode ); + returnNode->_memPool = &pool; + + _unlinked.Push(returnNode); + return returnNode; +} + +/** + A XMLHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2 + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + <Document> + <Element attributeA = "valueA"> + <Child attributeB = "value1" /> + <Child attributeB = "value2" /> + </Element> + </Document> + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + XMLElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + XMLElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + XMLElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + XMLElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. XMLHandle addresses the verbosity + of such code. A XMLHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + XMLHandle docHandle( &document ); + XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + XMLHandle handleCopy = handle; + @endverbatim + + See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. +*/ +class TINYXML2_LIB XMLHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + XMLHandle( XMLNode* node ) : _node( node ) { + } + /// Create a handle from a node. + XMLHandle( XMLNode& node ) : _node( &node ) { + } + /// Copy constructor + XMLHandle( const XMLHandle& ref ) : _node( ref._node ) { + } + /// Assignment + XMLHandle& operator=( const XMLHandle& ref ) { + _node = ref._node; + return *this; + } + + /// Get the first child of this handle. + XMLHandle FirstChild() { + return XMLHandle( _node ? _node->FirstChild() : 0 ); + } + /// Get the first child element of this handle. + XMLHandle FirstChildElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 ); + } + /// Get the last child of this handle. + XMLHandle LastChild() { + return XMLHandle( _node ? _node->LastChild() : 0 ); + } + /// Get the last child element of this handle. + XMLHandle LastChildElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->LastChildElement( name ) : 0 ); + } + /// Get the previous sibling of this handle. + XMLHandle PreviousSibling() { + return XMLHandle( _node ? _node->PreviousSibling() : 0 ); + } + /// Get the previous sibling element of this handle. + XMLHandle PreviousSiblingElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); + } + /// Get the next sibling of this handle. + XMLHandle NextSibling() { + return XMLHandle( _node ? _node->NextSibling() : 0 ); + } + /// Get the next sibling element of this handle. + XMLHandle NextSiblingElement( const char* name = 0 ) { + return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 ); + } + + /// Safe cast to XMLNode. This can return null. + XMLNode* ToNode() { + return _node; + } + /// Safe cast to XMLElement. This can return null. + XMLElement* ToElement() { + return ( _node ? _node->ToElement() : 0 ); + } + /// Safe cast to XMLText. This can return null. + XMLText* ToText() { + return ( _node ? _node->ToText() : 0 ); + } + /// Safe cast to XMLUnknown. This can return null. + XMLUnknown* ToUnknown() { + return ( _node ? _node->ToUnknown() : 0 ); + } + /// Safe cast to XMLDeclaration. This can return null. + XMLDeclaration* ToDeclaration() { + return ( _node ? _node->ToDeclaration() : 0 ); + } + +private: + XMLNode* _node; +}; + + +/** + A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the + same in all regards, except for the 'const' qualifiers. See XMLHandle for API. +*/ +class TINYXML2_LIB XMLConstHandle +{ +public: + XMLConstHandle( const XMLNode* node ) : _node( node ) { + } + XMLConstHandle( const XMLNode& node ) : _node( &node ) { + } + XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) { + } + + XMLConstHandle& operator=( const XMLConstHandle& ref ) { + _node = ref._node; + return *this; + } + + const XMLConstHandle FirstChild() const { + return XMLConstHandle( _node ? _node->FirstChild() : 0 ); + } + const XMLConstHandle FirstChildElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 ); + } + const XMLConstHandle LastChild() const { + return XMLConstHandle( _node ? _node->LastChild() : 0 ); + } + const XMLConstHandle LastChildElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 ); + } + const XMLConstHandle PreviousSibling() const { + return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); + } + const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); + } + const XMLConstHandle NextSibling() const { + return XMLConstHandle( _node ? _node->NextSibling() : 0 ); + } + const XMLConstHandle NextSiblingElement( const char* name = 0 ) const { + return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 ); + } + + + const XMLNode* ToNode() const { + return _node; + } + const XMLElement* ToElement() const { + return ( _node ? _node->ToElement() : 0 ); + } + const XMLText* ToText() const { + return ( _node ? _node->ToText() : 0 ); + } + const XMLUnknown* ToUnknown() const { + return ( _node ? _node->ToUnknown() : 0 ); + } + const XMLDeclaration* ToDeclaration() const { + return ( _node ? _node->ToDeclaration() : 0 ); + } + +private: + const XMLNode* _node; +}; + + +/** + Printing functionality. The XMLPrinter gives you more + options than the XMLDocument::Print() method. + + It can: + -# Print to memory. + -# Print to a file you provide. + -# Print XML without a XMLDocument. + + Print to Memory + + @verbatim + XMLPrinter printer; + doc.Print( &printer ); + SomeFunction( printer.CStr() ); + @endverbatim + + Print to a File + + You provide the file pointer. + @verbatim + XMLPrinter printer( fp ); + doc.Print( &printer ); + @endverbatim + + Print without a XMLDocument + + When loading, an XML parser is very useful. However, sometimes + when saving, it just gets in the way. The code is often set up + for streaming, and constructing the DOM is just overhead. + + The Printer supports the streaming case. The following code + prints out a trivially simple XML file without ever creating + an XML document. + + @verbatim + XMLPrinter printer( fp ); + printer.OpenElement( "foo" ); + printer.PushAttribute( "foo", "bar" ); + printer.CloseElement(); + @endverbatim +*/ +class TINYXML2_LIB XMLPrinter : public XMLVisitor +{ +public: + /** Construct the printer. If the FILE* is specified, + this will print to the FILE. Else it will print + to memory, and the result is available in CStr(). + If 'compact' is set to true, then output is created + with only required whitespace and newlines. + */ + XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); + virtual ~XMLPrinter() {} + + /** If streaming, write the BOM and declaration. */ + void PushHeader( bool writeBOM, bool writeDeclaration ); + /** If streaming, start writing an element. + The element must be closed with CloseElement() + */ + void OpenElement( const char* name, bool compactMode=false ); + /// If streaming, add an attribute to an open element. + void PushAttribute( const char* name, const char* value ); + void PushAttribute( const char* name, int value ); + void PushAttribute( const char* name, unsigned value ); + void PushAttribute(const char* name, int64_t value); + void PushAttribute( const char* name, bool value ); + void PushAttribute( const char* name, double value ); + /// If streaming, close the Element. + virtual void CloseElement( bool compactMode=false ); + + /// Add a text node. + void PushText( const char* text, bool cdata=false ); + /// Add a text node from an integer. + void PushText( int value ); + /// Add a text node from an unsigned. + void PushText( unsigned value ); + /// Add a text node from an unsigned. + void PushText(int64_t value); + /// Add a text node from a bool. + void PushText( bool value ); + /// Add a text node from a float. + void PushText( float value ); + /// Add a text node from a double. + void PushText( double value ); + + /// Add a comment + void PushComment( const char* comment ); + + void PushDeclaration( const char* value ); + void PushUnknown( const char* value ); + + virtual bool VisitEnter( const XMLDocument& /*doc*/ ); + virtual bool VisitExit( const XMLDocument& /*doc*/ ) { + return true; + } + + virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); + virtual bool VisitExit( const XMLElement& element ); + + virtual bool Visit( const XMLText& text ); + virtual bool Visit( const XMLComment& comment ); + virtual bool Visit( const XMLDeclaration& declaration ); + virtual bool Visit( const XMLUnknown& unknown ); + + /** + If in print to memory mode, return a pointer to + the XML file in memory. + */ + const char* CStr() const { + return _buffer.Mem(); + } + /** + If in print to memory mode, return the size + of the XML file in memory. (Note the size returned + includes the terminating null.) + */ + int CStrSize() const { + return _buffer.Size(); + } + /** + If in print to memory mode, reset the buffer to the + beginning. + */ + void ClearBuffer() { + _buffer.Clear(); + _buffer.Push(0); + _firstElement = true; + } + +protected: + virtual bool CompactMode( const XMLElement& ) { return _compactMode; } + + /** Prints out the space before an element. You may override to change + the space and tabs used. A PrintSpace() override should call Print(). + */ + virtual void PrintSpace( int depth ); + void Print( const char* format, ... ); + void Write( const char* data, size_t size ); + inline void Write( const char* data ) { Write( data, strlen( data ) ); } + void Putc( char ch ); + + void SealElementIfJustOpened(); + bool _elementJustOpened; + DynArray< const char*, 10 > _stack; + +private: + void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. + + bool _firstElement; + FILE* _fp; + int _depth; + int _textDepth; + bool _processEntities; + bool _compactMode; + + enum { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; + + DynArray< char, 20 > _buffer; + + // Prohibit cloning, intentionally not implemented + XMLPrinter( const XMLPrinter& ); + XMLPrinter& operator=( const XMLPrinter& ); +}; + + +} // tinyxml2 +} // namespace External +} // namespace Aws + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // TINYXML2_INCLUDED
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClient.h index 4c292064d7..4730d48f7e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClient.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClient.h @@ -2,80 +2,80 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <memory> -#include <atomic> -#include <mutex> -#include <condition_variable> - -namespace Aws -{ - namespace Utils - { - namespace RateLimits - { - class RateLimiterInterface; - } // namespace RateLimits - } // namespace Utils - - namespace Http - { - class HttpRequest; - class HttpResponse; - - /** - * Abstract HttpClient. All it does is make HttpRequests and return their response. - */ - class AWS_CORE_API HttpClient - { - public: - HttpClient(); - virtual ~HttpClient() {} - - /** + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <memory> +#include <atomic> +#include <mutex> +#include <condition_variable> + +namespace Aws +{ + namespace Utils + { + namespace RateLimits + { + class RateLimiterInterface; + } // namespace RateLimits + } // namespace Utils + + namespace Http + { + class HttpRequest; + class HttpResponse; + + /** + * Abstract HttpClient. All it does is make HttpRequests and return their response. + */ + class AWS_CORE_API HttpClient + { + public: + HttpClient(); + virtual ~HttpClient() {} + + /** * Takes an http request, makes it, and returns the newly allocated HttpResponse. - */ + */ virtual std::shared_ptr<HttpResponse> MakeRequest(const std::shared_ptr<HttpRequest>& request, - Aws::Utils::RateLimits::RateLimiterInterface* readLimiter = nullptr, - Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter = nullptr) const = 0; - - /** + Aws::Utils::RateLimits::RateLimiterInterface* readLimiter = nullptr, + Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter = nullptr) const = 0; + + /** * If yes, the http client supports transfer-encoding:chunked. - */ + */ virtual bool SupportsChunkedTransferEncoding() const { return true; } - - /** - * Stops all requests in progress and prevents any others from initiating. - */ - void DisableRequestProcessing(); - /** - * Enables/ReEnables request processing. - */ - void EnableRequestProcessing(); - /** - * Returns true if request processing is enabled. - */ - bool IsRequestProcessingEnabled() const; - /** - * Sleeps current thread for sleepTime. - */ - void RetryRequestSleep(std::chrono::milliseconds sleepTime); - - bool ContinueRequest(const Aws::Http::HttpRequest&) const; - - private: - - std::atomic< bool > m_disableRequestProcessing; - - std::mutex m_requestProcessingSignalLock; - std::condition_variable m_requestProcessingSignal; - }; - - } // namespace Http -} // namespace Aws - - + + /** + * Stops all requests in progress and prevents any others from initiating. + */ + void DisableRequestProcessing(); + /** + * Enables/ReEnables request processing. + */ + void EnableRequestProcessing(); + /** + * Returns true if request processing is enabled. + */ + bool IsRequestProcessingEnabled() const; + /** + * Sleeps current thread for sleepTime. + */ + void RetryRequestSleep(std::chrono::milliseconds sleepTime); + + bool ContinueRequest(const Aws::Http::HttpRequest&) const; + + private: + + std::atomic< bool > m_disableRequestProcessing; + + std::mutex m_requestProcessingSignalLock; + std::condition_variable m_requestProcessingSignal; + }; + + } // namespace Http +} // namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClientFactory.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClientFactory.h index a82a773c04..651275eb6c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClientFactory.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpClientFactory.h @@ -2,64 +2,64 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/http/HttpTypes.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> - -namespace Aws -{ - namespace Client - { - struct ClientConfiguration; - } // namespace Client - namespace Http - { - class URI; - class HttpClient; - class HttpRequest; - - /** - * Interface and default implementation of client for Http stack - */ - class AWS_CORE_API HttpClientFactory - { - public: - virtual ~HttpClientFactory() {} - - /** - * Creates a shared_ptr of HttpClient with the relevant settings from clientConfiguration - */ - virtual std::shared_ptr<HttpClient> CreateHttpClient(const Aws::Client::ClientConfiguration& clientConfiguration) const = 0; - /** - * Creates a shared_ptr of HttpRequest with uri, method, and closure for how to create a response stream. - */ - virtual std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) const = 0; - /** - * Creates a shared_ptr of HttpRequest with uri, method, and closure for how to create a response stream. - */ - virtual std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) const = 0; - - virtual void InitStaticState() {} - virtual void CleanupStaticState() {} - }; - - /** - * libCurl infects everything with its global state. If it is being used then we automatically initialize and clean it up. - * If this is a problem for you, set this to false. If you manually initialize libcurl please add the option CURL_GLOBAL_ALL to your init call. - */ - AWS_CORE_API void SetInitCleanupCurlFlag(bool initCleanupFlag); - AWS_CORE_API void SetInstallSigPipeHandlerFlag(bool installHandler); - AWS_CORE_API void InitHttp(); - AWS_CORE_API void CleanupHttp(); - AWS_CORE_API void SetHttpClientFactory(const std::shared_ptr<HttpClientFactory>& factory); - AWS_CORE_API std::shared_ptr<HttpClient> CreateHttpClient(const Aws::Client::ClientConfiguration& clientConfiguration); - AWS_CORE_API std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory); - AWS_CORE_API std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory); - - } // namespace Http -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/http/HttpTypes.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> + +namespace Aws +{ + namespace Client + { + struct ClientConfiguration; + } // namespace Client + namespace Http + { + class URI; + class HttpClient; + class HttpRequest; + + /** + * Interface and default implementation of client for Http stack + */ + class AWS_CORE_API HttpClientFactory + { + public: + virtual ~HttpClientFactory() {} + + /** + * Creates a shared_ptr of HttpClient with the relevant settings from clientConfiguration + */ + virtual std::shared_ptr<HttpClient> CreateHttpClient(const Aws::Client::ClientConfiguration& clientConfiguration) const = 0; + /** + * Creates a shared_ptr of HttpRequest with uri, method, and closure for how to create a response stream. + */ + virtual std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) const = 0; + /** + * Creates a shared_ptr of HttpRequest with uri, method, and closure for how to create a response stream. + */ + virtual std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) const = 0; + + virtual void InitStaticState() {} + virtual void CleanupStaticState() {} + }; + + /** + * libCurl infects everything with its global state. If it is being used then we automatically initialize and clean it up. + * If this is a problem for you, set this to false. If you manually initialize libcurl please add the option CURL_GLOBAL_ALL to your init call. + */ + AWS_CORE_API void SetInitCleanupCurlFlag(bool initCleanupFlag); + AWS_CORE_API void SetInstallSigPipeHandlerFlag(bool installHandler); + AWS_CORE_API void InitHttp(); + AWS_CORE_API void CleanupHttp(); + AWS_CORE_API void SetHttpClientFactory(const std::shared_ptr<HttpClientFactory>& factory); + AWS_CORE_API std::shared_ptr<HttpClient> CreateHttpClient(const Aws::Client::ClientConfiguration& clientConfiguration); + AWS_CORE_API std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory); + AWS_CORE_API std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory); + + } // namespace Http +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h index ab71a3a29b..a62f03c30f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpRequest.h @@ -2,24 +2,24 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/http/URI.h> -#include <aws/core/http/HttpTypes.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/stream/ResponseStream.h> -#include <aws/core/monitoring/HttpClientMetrics.h> -#include <memory> -#include <functional> - -namespace Aws -{ - namespace Http - { + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/http/URI.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/stream/ResponseStream.h> +#include <aws/core/monitoring/HttpClientMetrics.h> +#include <memory> +#include <functional> + +namespace Aws +{ + namespace Http + { extern AWS_CORE_API const char DATE_HEADER[]; extern AWS_CORE_API const char AWS_DATE_HEADER[]; extern AWS_CORE_API const char AWS_SECURITY_TOKEN[]; @@ -42,327 +42,327 @@ namespace Aws extern AWS_CORE_API const char SDK_INVOCATION_ID_HEADER[]; extern AWS_CORE_API const char SDK_REQUEST_HEADER[]; extern AWS_CORE_API const char CHUNKED_VALUE[]; - - class HttpRequest; - class HttpResponse; - - /** + + class HttpRequest; + class HttpResponse; + + /** * closure type for receiving notifications that data has been received. - */ - typedef std::function<void(const HttpRequest*, HttpResponse*, long long)> DataReceivedEventHandler; - /** - * closure type for receiving notifications that data has been sent. - */ - typedef std::function<void(const HttpRequest*, long long)> DataSentEventHandler; - /** - * Closure type for handling whether or not a request should be canceled. - */ - typedef std::function<bool(const HttpRequest*)> ContinueRequestHandler; - - /** - * Abstract class for representing an HttpRequest. - */ - class AWS_CORE_API HttpRequest - { - public: - /** - * Initializes an HttpRequest object with uri and http method. - */ - HttpRequest(const URI& uri, HttpMethod method) : + */ + typedef std::function<void(const HttpRequest*, HttpResponse*, long long)> DataReceivedEventHandler; + /** + * closure type for receiving notifications that data has been sent. + */ + typedef std::function<void(const HttpRequest*, long long)> DataSentEventHandler; + /** + * Closure type for handling whether or not a request should be canceled. + */ + typedef std::function<bool(const HttpRequest*)> ContinueRequestHandler; + + /** + * Abstract class for representing an HttpRequest. + */ + class AWS_CORE_API HttpRequest + { + public: + /** + * Initializes an HttpRequest object with uri and http method. + */ + HttpRequest(const URI& uri, HttpMethod method) : m_uri(uri), m_method(method), m_isEvenStreamRequest(false) - {} - - virtual ~HttpRequest() {} - - /** - * Get All headers for this request. - */ - virtual HeaderValueCollection GetHeaders() const = 0; - /** + {} + + virtual ~HttpRequest() {} + + /** + * Get All headers for this request. + */ + virtual HeaderValueCollection GetHeaders() const = 0; + /** * Get the value for a Header based on its name. (in default StandardHttpRequest implementation, an empty string will be returned if headerName doesn't exist) - */ - virtual const Aws::String& GetHeaderValue(const char* headerName) const = 0; - /** - * Add a header pair - */ - virtual void SetHeaderValue(const char* headerName, const Aws::String& headerValue) = 0; - /** - * Creates a shared_ptr of HttpRequest with uri, method, and closure for how to create a response stream. - */ - virtual void SetHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) = 0; - /** - * Deletes a header from the request by name. - */ - virtual void DeleteHeader(const char* headerName) = 0; - /** - * Adds a content body stream to the request. This stream will be used to send the body to the endpoint. - */ - virtual void AddContentBody(const std::shared_ptr<Aws::IOStream>& strContent) = 0; - /** - * Gets the content body stream that will be used for this request. - */ - virtual const std::shared_ptr<Aws::IOStream>& GetContentBody() const = 0; - /** - * Returns true if a header exists in the request with name - */ - virtual bool HasHeader(const char* name) const = 0; - /** - * Get size in bytes of the request when as it will be going accross the wire. - */ - virtual int64_t GetSize() const = 0; - /** - * Gets the factory for creating the stream that will be used in the http response. - */ - virtual const Aws::IOStreamFactory& GetResponseStreamFactory() const = 0; - /** - * Sets the factory for creating the stream that will be used in the http response. - */ - virtual void SetResponseStreamFactory(const Aws::IOStreamFactory& factory) = 0; - /** - * Gets underlying URI object with mutation access. - */ - inline URI& GetUri() - { - return m_uri; - } - /** - * Gets the underlying URI object. - */ - const URI& GetUri() const { return m_uri; } - /** - * Converts the URI into a string and returns it. If includeQueryString is set to true, the query string + */ + virtual const Aws::String& GetHeaderValue(const char* headerName) const = 0; + /** + * Add a header pair + */ + virtual void SetHeaderValue(const char* headerName, const Aws::String& headerValue) = 0; + /** + * Creates a shared_ptr of HttpRequest with uri, method, and closure for how to create a response stream. + */ + virtual void SetHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) = 0; + /** + * Deletes a header from the request by name. + */ + virtual void DeleteHeader(const char* headerName) = 0; + /** + * Adds a content body stream to the request. This stream will be used to send the body to the endpoint. + */ + virtual void AddContentBody(const std::shared_ptr<Aws::IOStream>& strContent) = 0; + /** + * Gets the content body stream that will be used for this request. + */ + virtual const std::shared_ptr<Aws::IOStream>& GetContentBody() const = 0; + /** + * Returns true if a header exists in the request with name + */ + virtual bool HasHeader(const char* name) const = 0; + /** + * Get size in bytes of the request when as it will be going accross the wire. + */ + virtual int64_t GetSize() const = 0; + /** + * Gets the factory for creating the stream that will be used in the http response. + */ + virtual const Aws::IOStreamFactory& GetResponseStreamFactory() const = 0; + /** + * Sets the factory for creating the stream that will be used in the http response. + */ + virtual void SetResponseStreamFactory(const Aws::IOStreamFactory& factory) = 0; + /** + * Gets underlying URI object with mutation access. + */ + inline URI& GetUri() + { + return m_uri; + } + /** + * Gets the underlying URI object. + */ + const URI& GetUri() const { return m_uri; } + /** + * Converts the URI into a string and returns it. If includeQueryString is set to true, the query string * will be included in the returned value. - */ - inline Aws::String GetURIString(bool includeQueryString = true) const - { - return m_uri.GetURIString(includeQueryString); - } - /** - * Get the http method for this request. - */ - inline HttpMethod GetMethod() const - { - return m_method; - } - /** - * Gets the query string from the URI on this request. - */ - inline const Aws::String& GetQueryString() const - { - return m_uri.GetQueryString(); - } - /** - * Normalizes the URI for use with signing. - */ - inline void CanonicalizeRequest() - { - m_uri.CanonicalizeQueryString(); - } - /** - * Gets the query string for the underlying URI as a key value mapping - */ - inline QueryStringParameterCollection GetQueryStringParameters() const - { - return m_uri.GetQueryStringParameters(); - } - /** - * Adds a query string parameter to the underlying URI by key and value. - */ - inline void AddQueryStringParameter(const char* key, const Aws::String& value) - { - m_uri.AddQueryStringParameter(key, value); - } - + */ + inline Aws::String GetURIString(bool includeQueryString = true) const + { + return m_uri.GetURIString(includeQueryString); + } + /** + * Get the http method for this request. + */ + inline HttpMethod GetMethod() const + { + return m_method; + } + /** + * Gets the query string from the URI on this request. + */ + inline const Aws::String& GetQueryString() const + { + return m_uri.GetQueryString(); + } + /** + * Normalizes the URI for use with signing. + */ + inline void CanonicalizeRequest() + { + m_uri.CanonicalizeQueryString(); + } + /** + * Gets the query string for the underlying URI as a key value mapping + */ + inline QueryStringParameterCollection GetQueryStringParameters() const + { + return m_uri.GetQueryStringParameters(); + } + /** + * Adds a query string parameter to the underlying URI by key and value. + */ + inline void AddQueryStringParameter(const char* key, const Aws::String& value) + { + m_uri.AddQueryStringParameter(key, value); + } + inline bool HasDate() const - { - return HasHeader(DATE_HEADER); - } - /** - * Gets date header. - */ - inline const Aws::String& GetDate() const - { - return GetHeaderValue(DATE_HEADER); - } - /** - * Gets date header. - */ - inline void SetDate(const Aws::String& value) - { - SetHeaderValue(DATE_HEADER, value); - } - - inline bool HasAccept() const - { - return HasHeader(ACCEPT_HEADER); - } - /** - * Gets accept header. - */ - inline const Aws::String& GetAccept() const - { - return GetHeaderValue(ACCEPT_HEADER); - } - /** - * Gets accept header. - */ - inline void SetAccept(const Aws::String& value) - { - SetHeaderValue(ACCEPT_HEADER, value); - } - - inline bool HasAcceptCharSet() const - { - return HasHeader(ACCEPT_CHAR_SET_HEADER); - } - /** - * Gets Accept CharSet header. - */ - inline const Aws::String& GetAcceptCharSet() const - { - return GetHeaderValue(ACCEPT_CHAR_SET_HEADER); - } - /** - * Sets Accept CharSet header. - */ - inline void SetAcceptCharSet(const Aws::String& value) - { - SetHeaderValue(ACCEPT_CHAR_SET_HEADER, value); - } - - inline bool HasAcceptEncoding() const - { - return HasHeader(ACCEPT_ENCODING_HEADER); - } - /** - * Gets accept encoding header. - */ - inline const Aws::String& GetAcceptEncoding() const - { - return GetHeaderValue(ACCEPT_ENCODING_HEADER); - } - /** - * Sets accept encoding header. - */ - inline void SetAcceptEncoding(const Aws::String& value) - { - SetHeaderValue(ACCEPT_ENCODING_HEADER, value); - } - - inline bool HasAuthorization() const - { - return HasHeader(AUTHORIZATION_HEADER); - } - /** - * Gets authorization encoding header. - */ - inline const Aws::String& GetAuthorization() const - { - return GetHeaderValue(AUTHORIZATION_HEADER); - } - /** - * Set authorization header. - */ - inline void SetAuthorization(const Aws::String& value) - { - SetHeaderValue(AUTHORIZATION_HEADER, value); - } - - inline bool HasAwsAuthorization() const - { - return HasHeader(AWS_AUTHORIZATION_HEADER); - } - /** - * Gets aws authorization header. - */ - inline const Aws::String& GetAwsAuthorization() const - { - return GetHeaderValue(AWS_AUTHORIZATION_HEADER); - } - /** - * Sets aws authorization header. - */ - inline void SetAwsAuthorization(const Aws::String& value) - { - SetHeaderValue(AWS_AUTHORIZATION_HEADER, value); - } - - inline bool HasAwsSessionToken() const - { - return HasHeader(AWS_SECURITY_TOKEN); - } - /** - * Gets session token header. - */ - inline const Aws::String& GetAwsSessionToken() const - { - return GetHeaderValue(AWS_SECURITY_TOKEN); - } - /** - * Sets session token header. - */ - inline void SetAwsSessionToken(const Aws::String& value) - { - SetHeaderValue(AWS_SECURITY_TOKEN, value); - } - - inline bool HasCookie() const - { - return HasHeader(COOKIE_HEADER); - } - /** - * Gets cookie header. - */ - inline const Aws::String& GetCookie() const - { - return GetHeaderValue(COOKIE_HEADER); - } - /** - * Sets cookie header. - */ - inline void SetCookie(const Aws::String& value) - { - SetHeaderValue(COOKIE_HEADER, value); - } - - inline bool HasContentLength() const - { - return HasHeader(CONTENT_LENGTH_HEADER); - } - /** - * Gets content-length header. - */ - inline const Aws::String& GetContentLength() const - { - return GetHeaderValue(CONTENT_LENGTH_HEADER); - } - /** - * Sets content-length header. - */ - inline void SetContentLength(const Aws::String& value) - { - SetHeaderValue(CONTENT_LENGTH_HEADER, value); - } - - inline bool HasContentType() const - { - return HasHeader(CONTENT_TYPE_HEADER); - } - /** - * Gets content-type header. - */ - inline const Aws::String& GetContentType() const - { - return GetHeaderValue(CONTENT_TYPE_HEADER); - } - /** - * sets content-type header. - */ - inline void SetContentType(const Aws::String& value) - { - SetHeaderValue(CONTENT_TYPE_HEADER, value); - } - + { + return HasHeader(DATE_HEADER); + } + /** + * Gets date header. + */ + inline const Aws::String& GetDate() const + { + return GetHeaderValue(DATE_HEADER); + } + /** + * Gets date header. + */ + inline void SetDate(const Aws::String& value) + { + SetHeaderValue(DATE_HEADER, value); + } + + inline bool HasAccept() const + { + return HasHeader(ACCEPT_HEADER); + } + /** + * Gets accept header. + */ + inline const Aws::String& GetAccept() const + { + return GetHeaderValue(ACCEPT_HEADER); + } + /** + * Gets accept header. + */ + inline void SetAccept(const Aws::String& value) + { + SetHeaderValue(ACCEPT_HEADER, value); + } + + inline bool HasAcceptCharSet() const + { + return HasHeader(ACCEPT_CHAR_SET_HEADER); + } + /** + * Gets Accept CharSet header. + */ + inline const Aws::String& GetAcceptCharSet() const + { + return GetHeaderValue(ACCEPT_CHAR_SET_HEADER); + } + /** + * Sets Accept CharSet header. + */ + inline void SetAcceptCharSet(const Aws::String& value) + { + SetHeaderValue(ACCEPT_CHAR_SET_HEADER, value); + } + + inline bool HasAcceptEncoding() const + { + return HasHeader(ACCEPT_ENCODING_HEADER); + } + /** + * Gets accept encoding header. + */ + inline const Aws::String& GetAcceptEncoding() const + { + return GetHeaderValue(ACCEPT_ENCODING_HEADER); + } + /** + * Sets accept encoding header. + */ + inline void SetAcceptEncoding(const Aws::String& value) + { + SetHeaderValue(ACCEPT_ENCODING_HEADER, value); + } + + inline bool HasAuthorization() const + { + return HasHeader(AUTHORIZATION_HEADER); + } + /** + * Gets authorization encoding header. + */ + inline const Aws::String& GetAuthorization() const + { + return GetHeaderValue(AUTHORIZATION_HEADER); + } + /** + * Set authorization header. + */ + inline void SetAuthorization(const Aws::String& value) + { + SetHeaderValue(AUTHORIZATION_HEADER, value); + } + + inline bool HasAwsAuthorization() const + { + return HasHeader(AWS_AUTHORIZATION_HEADER); + } + /** + * Gets aws authorization header. + */ + inline const Aws::String& GetAwsAuthorization() const + { + return GetHeaderValue(AWS_AUTHORIZATION_HEADER); + } + /** + * Sets aws authorization header. + */ + inline void SetAwsAuthorization(const Aws::String& value) + { + SetHeaderValue(AWS_AUTHORIZATION_HEADER, value); + } + + inline bool HasAwsSessionToken() const + { + return HasHeader(AWS_SECURITY_TOKEN); + } + /** + * Gets session token header. + */ + inline const Aws::String& GetAwsSessionToken() const + { + return GetHeaderValue(AWS_SECURITY_TOKEN); + } + /** + * Sets session token header. + */ + inline void SetAwsSessionToken(const Aws::String& value) + { + SetHeaderValue(AWS_SECURITY_TOKEN, value); + } + + inline bool HasCookie() const + { + return HasHeader(COOKIE_HEADER); + } + /** + * Gets cookie header. + */ + inline const Aws::String& GetCookie() const + { + return GetHeaderValue(COOKIE_HEADER); + } + /** + * Sets cookie header. + */ + inline void SetCookie(const Aws::String& value) + { + SetHeaderValue(COOKIE_HEADER, value); + } + + inline bool HasContentLength() const + { + return HasHeader(CONTENT_LENGTH_HEADER); + } + /** + * Gets content-length header. + */ + inline const Aws::String& GetContentLength() const + { + return GetHeaderValue(CONTENT_LENGTH_HEADER); + } + /** + * Sets content-length header. + */ + inline void SetContentLength(const Aws::String& value) + { + SetHeaderValue(CONTENT_LENGTH_HEADER, value); + } + + inline bool HasContentType() const + { + return HasHeader(CONTENT_TYPE_HEADER); + } + /** + * Gets content-type header. + */ + inline const Aws::String& GetContentType() const + { + return GetHeaderValue(CONTENT_TYPE_HEADER); + } + /** + * sets content-type header. + */ + inline void SetContentType(const Aws::String& value) + { + SetHeaderValue(CONTENT_TYPE_HEADER, value); + } + inline bool HasTransferEncoding() const { return HasHeader(TRANSFER_ENCODING_HEADER); @@ -382,45 +382,45 @@ namespace Aws SetHeaderValue(TRANSFER_ENCODING_HEADER, value); } - inline bool HasUserAgent() const - { - return HasHeader(USER_AGENT_HEADER); - } - /** - * Gets User Agent header. - */ - inline const Aws::String& GetUserAgent() const - { - return GetHeaderValue(USER_AGENT_HEADER); - } - /** - * Sets User Agent header. - */ - inline void SetUserAgent(const Aws::String& value) - { - SetHeaderValue(USER_AGENT_HEADER, value); - } - - inline bool HasVia() const - { - return HasHeader(VIA_HEADER); - } - /** - * Gets via header header. - */ - inline const Aws::String& GetVia() const - { - return GetHeaderValue(VIA_HEADER); - } - /** - * Sets via header. - */ - inline void SetVia(const Aws::String& value) - { - SetHeaderValue(VIA_HEADER, value); - } - - /** + inline bool HasUserAgent() const + { + return HasHeader(USER_AGENT_HEADER); + } + /** + * Gets User Agent header. + */ + inline const Aws::String& GetUserAgent() const + { + return GetHeaderValue(USER_AGENT_HEADER); + } + /** + * Sets User Agent header. + */ + inline void SetUserAgent(const Aws::String& value) + { + SetHeaderValue(USER_AGENT_HEADER, value); + } + + inline bool HasVia() const + { + return HasHeader(VIA_HEADER); + } + /** + * Gets via header header. + */ + inline const Aws::String& GetVia() const + { + return GetHeaderValue(VIA_HEADER); + } + /** + * Sets via header. + */ + inline void SetVia(const Aws::String& value) + { + SetHeaderValue(VIA_HEADER, value); + } + + /** * Has Api version header x-amz-api-version */ inline bool HasApiVersion() const @@ -444,76 +444,76 @@ namespace Aws } /** - * Sets the closure for receiving events when data is received from the server. - */ - inline void SetDataReceivedEventHandler(const DataReceivedEventHandler& dataReceivedEventHandler) { m_onDataReceived = dataReceivedEventHandler; } - /** - * Sets the closure for receiving events when data is received from the server. - */ - inline void SetDataReceivedEventHandler(DataReceivedEventHandler&& dataReceivedEventHandler) { m_onDataReceived = std::move(dataReceivedEventHandler); } - /** - * Sets the closure for receiving events when data is sent to the server. - */ - inline void SetDataSentEventHandler(const DataSentEventHandler& dataSentEventHandler) { m_onDataSent = dataSentEventHandler; } - /** - * Sets the closure for receiving events when data is sent to the server. - */ - inline void SetDataSentEventHandler(DataSentEventHandler&& dataSentEventHandler) { m_onDataSent = std::move(dataSentEventHandler); } - /** - * Sets the closure for handling whether or not to cancel a request. - */ - inline void SetContinueRequestHandle(const ContinueRequestHandler& continueRequestHandler) { m_continueRequest = continueRequestHandler; } - /** - * Sets the closure for handling whether or not to cancel a request. - */ - inline void SetContinueRequestHandle(ContinueRequestHandler&& continueRequestHandler) { m_continueRequest = std::move(continueRequestHandler); } - - /** - * Gets the closure for receiving events when data is received from the server. - */ - inline const DataReceivedEventHandler& GetDataReceivedEventHandler() const { return m_onDataReceived; } - /** - * Gets the closure for receiving events when data is sent to the server. - */ - inline const DataSentEventHandler& GetDataSentEventHandler() const { return m_onDataSent; } - - inline const ContinueRequestHandler& GetContinueRequestHandler() const { return m_continueRequest; } - - /** - * Gets the AWS Access Key if this HttpRequest is signed with Aws Access Key - */ - inline const Aws::String& GetSigningAccessKey() const { return m_signingAccessKey; } - /** - * Sets the Aws Access Key if this HttpRequest is signed with Aws Access Key - */ - inline void SetSigningAccessKey(const Aws::String& accessKey) { m_signingAccessKey = accessKey; } - - /** - * Gets the signing region if this request is signed. - */ - inline const Aws::String& GetSigningRegion() const { return m_signingRegion; } - /** - * Sets the signing region if this request is signed. - */ - inline void SetSigningRegion(const Aws::String& region) { m_signingRegion = region; } - - /** - * Add a request metric - * @param key, HttpClientMetricsKey defined in HttpClientMetrics.cpp - * @param value, the corresponding value of this key measured during http request. - */ - virtual void AddRequestMetric(const Aws::String& key, int64_t value) { m_httpRequestMetrics.emplace(key, value); } - - /** - * Sets the request metrics - */ + * Sets the closure for receiving events when data is received from the server. + */ + inline void SetDataReceivedEventHandler(const DataReceivedEventHandler& dataReceivedEventHandler) { m_onDataReceived = dataReceivedEventHandler; } + /** + * Sets the closure for receiving events when data is received from the server. + */ + inline void SetDataReceivedEventHandler(DataReceivedEventHandler&& dataReceivedEventHandler) { m_onDataReceived = std::move(dataReceivedEventHandler); } + /** + * Sets the closure for receiving events when data is sent to the server. + */ + inline void SetDataSentEventHandler(const DataSentEventHandler& dataSentEventHandler) { m_onDataSent = dataSentEventHandler; } + /** + * Sets the closure for receiving events when data is sent to the server. + */ + inline void SetDataSentEventHandler(DataSentEventHandler&& dataSentEventHandler) { m_onDataSent = std::move(dataSentEventHandler); } + /** + * Sets the closure for handling whether or not to cancel a request. + */ + inline void SetContinueRequestHandle(const ContinueRequestHandler& continueRequestHandler) { m_continueRequest = continueRequestHandler; } + /** + * Sets the closure for handling whether or not to cancel a request. + */ + inline void SetContinueRequestHandle(ContinueRequestHandler&& continueRequestHandler) { m_continueRequest = std::move(continueRequestHandler); } + + /** + * Gets the closure for receiving events when data is received from the server. + */ + inline const DataReceivedEventHandler& GetDataReceivedEventHandler() const { return m_onDataReceived; } + /** + * Gets the closure for receiving events when data is sent to the server. + */ + inline const DataSentEventHandler& GetDataSentEventHandler() const { return m_onDataSent; } + + inline const ContinueRequestHandler& GetContinueRequestHandler() const { return m_continueRequest; } + + /** + * Gets the AWS Access Key if this HttpRequest is signed with Aws Access Key + */ + inline const Aws::String& GetSigningAccessKey() const { return m_signingAccessKey; } + /** + * Sets the Aws Access Key if this HttpRequest is signed with Aws Access Key + */ + inline void SetSigningAccessKey(const Aws::String& accessKey) { m_signingAccessKey = accessKey; } + + /** + * Gets the signing region if this request is signed. + */ + inline const Aws::String& GetSigningRegion() const { return m_signingRegion; } + /** + * Sets the signing region if this request is signed. + */ + inline void SetSigningRegion(const Aws::String& region) { m_signingRegion = region; } + + /** + * Add a request metric + * @param key, HttpClientMetricsKey defined in HttpClientMetrics.cpp + * @param value, the corresponding value of this key measured during http request. + */ + virtual void AddRequestMetric(const Aws::String& key, int64_t value) { m_httpRequestMetrics.emplace(key, value); } + + /** + * Sets the request metrics + */ virtual void SetRequestMetrics(const Aws::Monitoring::HttpClientMetricsCollection& collection) { m_httpRequestMetrics = collection; } - - /** - * Gets the request metrics - */ + + /** + * Gets the request metrics + */ virtual const Aws::Monitoring::HttpClientMetricsCollection& GetRequestMetrics() const { return m_httpRequestMetrics; } - + /** * Returns the IP address of the remote host the request was made out to. * This value is populated after the request is made and when the HTTP client supports retrieving such @@ -525,18 +525,18 @@ namespace Aws bool IsEventStreamRequest() { return m_isEvenStreamRequest; } void SetEventStreamRequest(bool eventStreamRequest) { m_isEvenStreamRequest = eventStreamRequest; } - private: - URI m_uri; - HttpMethod m_method; + private: + URI m_uri; + HttpMethod m_method; bool m_isEvenStreamRequest; - DataReceivedEventHandler m_onDataReceived; - DataSentEventHandler m_onDataSent; - ContinueRequestHandler m_continueRequest; - Aws::String m_signingRegion; - Aws::String m_signingAccessKey; + DataReceivedEventHandler m_onDataReceived; + DataSentEventHandler m_onDataSent; + ContinueRequestHandler m_continueRequest; + Aws::String m_signingRegion; + Aws::String m_signingAccessKey; Aws::String m_resolvedRemoteHost; Aws::Monitoring::HttpClientMetricsCollection m_httpRequestMetrics; - }; - - } // namespace Http -} // namespace Aws + }; + + } // namespace Http +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h index 1db30d1730..ee6798e229 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpResponse.h @@ -2,198 +2,198 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/http/HttpTypes.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/http/HttpTypes.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> #include <aws/core/client/CoreErrors.h> - -namespace Aws -{ - namespace Utils - { - namespace Stream - { - class ResponseStream; - } - } - namespace Http - { - /** - * Enum of Http response Codes. The integer values of the response codes correspond to the values in the RFC. - */ - enum class HttpResponseCode - { - REQUEST_NOT_MADE = -1, - CONTINUE = 100, - SWITCHING_PROTOCOLS = 101, - PROCESSING = 102, - OK = 200, - CREATED = 201, - ACCEPTED = 202, - NON_AUTHORITATIVE_INFORMATION = 203, - NO_CONTENT = 204, - RESET_CONTENT = 205, - PARTIAL_CONTENT = 206, - MULTI_STATUS = 207, - ALREADY_REPORTED = 208, - IM_USED = 226, - MULTIPLE_CHOICES = 300, - MOVED_PERMANENTLY = 301, - FOUND = 302, - SEE_OTHER = 303, - NOT_MODIFIED = 304, - USE_PROXY = 305, - SWITCH_PROXY = 306, - TEMPORARY_REDIRECT = 307, - PERMANENT_REDIRECT = 308, - BAD_REQUEST = 400, - UNAUTHORIZED = 401, - PAYMENT_REQUIRED = 402, - FORBIDDEN = 403, - NOT_FOUND = 404, - METHOD_NOT_ALLOWED = 405, - NOT_ACCEPTABLE = 406, - PROXY_AUTHENTICATION_REQUIRED = 407, - REQUEST_TIMEOUT = 408, - CONFLICT = 409, - GONE = 410, - LENGTH_REQUIRED = 411, - PRECONDITION_FAILED = 412, - REQUEST_ENTITY_TOO_LARGE = 413, - REQUEST_URI_TOO_LONG = 414, - UNSUPPORTED_MEDIA_TYPE = 415, - REQUESTED_RANGE_NOT_SATISFIABLE = 416, - EXPECTATION_FAILED = 417, - IM_A_TEAPOT = 418, - AUTHENTICATION_TIMEOUT = 419, - METHOD_FAILURE = 420, - UNPROC_ENTITY = 422, - LOCKED = 423, - FAILED_DEPENDENCY = 424, - UPGRADE_REQUIRED = 426, - PRECONDITION_REQUIRED = 427, - TOO_MANY_REQUESTS = 429, - REQUEST_HEADER_FIELDS_TOO_LARGE = 431, - LOGIN_TIMEOUT = 440, - NO_RESPONSE = 444, - RETRY_WITH = 449, - BLOCKED = 450, - REDIRECT = 451, - REQUEST_HEADER_TOO_LARGE = 494, - CERT_ERROR = 495, - NO_CERT = 496, - HTTP_TO_HTTPS = 497, - CLIENT_CLOSED_TO_REQUEST = 499, - INTERNAL_SERVER_ERROR = 500, - NOT_IMPLEMENTED = 501, - BAD_GATEWAY = 502, - SERVICE_UNAVAILABLE = 503, - GATEWAY_TIMEOUT = 504, - HTTP_VERSION_NOT_SUPPORTED = 505, - VARIANT_ALSO_NEGOTIATES = 506, + +namespace Aws +{ + namespace Utils + { + namespace Stream + { + class ResponseStream; + } + } + namespace Http + { + /** + * Enum of Http response Codes. The integer values of the response codes correspond to the values in the RFC. + */ + enum class HttpResponseCode + { + REQUEST_NOT_MADE = -1, + CONTINUE = 100, + SWITCHING_PROTOCOLS = 101, + PROCESSING = 102, + OK = 200, + CREATED = 201, + ACCEPTED = 202, + NON_AUTHORITATIVE_INFORMATION = 203, + NO_CONTENT = 204, + RESET_CONTENT = 205, + PARTIAL_CONTENT = 206, + MULTI_STATUS = 207, + ALREADY_REPORTED = 208, + IM_USED = 226, + MULTIPLE_CHOICES = 300, + MOVED_PERMANENTLY = 301, + FOUND = 302, + SEE_OTHER = 303, + NOT_MODIFIED = 304, + USE_PROXY = 305, + SWITCH_PROXY = 306, + TEMPORARY_REDIRECT = 307, + PERMANENT_REDIRECT = 308, + BAD_REQUEST = 400, + UNAUTHORIZED = 401, + PAYMENT_REQUIRED = 402, + FORBIDDEN = 403, + NOT_FOUND = 404, + METHOD_NOT_ALLOWED = 405, + NOT_ACCEPTABLE = 406, + PROXY_AUTHENTICATION_REQUIRED = 407, + REQUEST_TIMEOUT = 408, + CONFLICT = 409, + GONE = 410, + LENGTH_REQUIRED = 411, + PRECONDITION_FAILED = 412, + REQUEST_ENTITY_TOO_LARGE = 413, + REQUEST_URI_TOO_LONG = 414, + UNSUPPORTED_MEDIA_TYPE = 415, + REQUESTED_RANGE_NOT_SATISFIABLE = 416, + EXPECTATION_FAILED = 417, + IM_A_TEAPOT = 418, + AUTHENTICATION_TIMEOUT = 419, + METHOD_FAILURE = 420, + UNPROC_ENTITY = 422, + LOCKED = 423, + FAILED_DEPENDENCY = 424, + UPGRADE_REQUIRED = 426, + PRECONDITION_REQUIRED = 427, + TOO_MANY_REQUESTS = 429, + REQUEST_HEADER_FIELDS_TOO_LARGE = 431, + LOGIN_TIMEOUT = 440, + NO_RESPONSE = 444, + RETRY_WITH = 449, + BLOCKED = 450, + REDIRECT = 451, + REQUEST_HEADER_TOO_LARGE = 494, + CERT_ERROR = 495, + NO_CERT = 496, + HTTP_TO_HTTPS = 497, + CLIENT_CLOSED_TO_REQUEST = 499, + INTERNAL_SERVER_ERROR = 500, + NOT_IMPLEMENTED = 501, + BAD_GATEWAY = 502, + SERVICE_UNAVAILABLE = 503, + GATEWAY_TIMEOUT = 504, + HTTP_VERSION_NOT_SUPPORTED = 505, + VARIANT_ALSO_NEGOTIATES = 506, INSUFFICIENT_STORAGE = 507, - LOOP_DETECTED = 508, - BANDWIDTH_LIMIT_EXCEEDED = 509, - NOT_EXTENDED = 510, - NETWORK_AUTHENTICATION_REQUIRED = 511, - NETWORK_READ_TIMEOUT = 598, - NETWORK_CONNECT_TIMEOUT = 599 - }; - - inline bool IsRetryableHttpResponseCode(HttpResponseCode responseCode) - { - switch (responseCode) - { - case HttpResponseCode::INTERNAL_SERVER_ERROR: - case HttpResponseCode::SERVICE_UNAVAILABLE: - case HttpResponseCode::TOO_MANY_REQUESTS: - case HttpResponseCode::BANDWIDTH_LIMIT_EXCEEDED: - case HttpResponseCode::REQUEST_TIMEOUT: - case HttpResponseCode::AUTHENTICATION_TIMEOUT: - case HttpResponseCode::LOGIN_TIMEOUT: - case HttpResponseCode::GATEWAY_TIMEOUT: - case HttpResponseCode::NETWORK_READ_TIMEOUT: - case HttpResponseCode::NETWORK_CONNECT_TIMEOUT: - return true; - default: - return false; - } - } - - /** - * Abstract class for representing an Http Response. - */ - class AWS_CORE_API HttpResponse - { - public: - /** - * Initializes an http response with the originalRequest and the response code. - */ + LOOP_DETECTED = 508, + BANDWIDTH_LIMIT_EXCEEDED = 509, + NOT_EXTENDED = 510, + NETWORK_AUTHENTICATION_REQUIRED = 511, + NETWORK_READ_TIMEOUT = 598, + NETWORK_CONNECT_TIMEOUT = 599 + }; + + inline bool IsRetryableHttpResponseCode(HttpResponseCode responseCode) + { + switch (responseCode) + { + case HttpResponseCode::INTERNAL_SERVER_ERROR: + case HttpResponseCode::SERVICE_UNAVAILABLE: + case HttpResponseCode::TOO_MANY_REQUESTS: + case HttpResponseCode::BANDWIDTH_LIMIT_EXCEEDED: + case HttpResponseCode::REQUEST_TIMEOUT: + case HttpResponseCode::AUTHENTICATION_TIMEOUT: + case HttpResponseCode::LOGIN_TIMEOUT: + case HttpResponseCode::GATEWAY_TIMEOUT: + case HttpResponseCode::NETWORK_READ_TIMEOUT: + case HttpResponseCode::NETWORK_CONNECT_TIMEOUT: + return true; + default: + return false; + } + } + + /** + * Abstract class for representing an Http Response. + */ + class AWS_CORE_API HttpResponse + { + public: + /** + * Initializes an http response with the originalRequest and the response code. + */ HttpResponse(const std::shared_ptr<const HttpRequest>& originatingRequest) : - m_httpRequest(originatingRequest), - m_responseCode(HttpResponseCode::REQUEST_NOT_MADE), + m_httpRequest(originatingRequest), + m_responseCode(HttpResponseCode::REQUEST_NOT_MADE), m_hasClientError(false) - {} - - virtual ~HttpResponse() = default; - - /** + {} + + virtual ~HttpResponse() = default; + + /** * Gets the request that originated this response - */ + */ virtual inline const HttpRequest& GetOriginatingRequest() const { return *m_httpRequest; } - - /** + + /** * Sets the request that originated this response */ virtual inline void SetOriginatingRequest(const std::shared_ptr<const HttpRequest>& httpRequest) { m_httpRequest = httpRequest; } - - /** - * Get the headers from this response - */ - virtual HeaderValueCollection GetHeaders() const = 0; - /** - * Returns true if the response contains a header by headerName - */ - virtual bool HasHeader(const char* headerName) const = 0; - /** - * Returns the value for a header at headerName if it exists. - */ - virtual const Aws::String& GetHeader(const Aws::String& headerName) const = 0; - /** - * Gets response code for this http response. - */ - virtual inline HttpResponseCode GetResponseCode() const { return m_responseCode; } - /** - * Sets the response code for this http response. - */ - virtual inline void SetResponseCode(HttpResponseCode httpResponseCode) { m_responseCode = httpResponseCode; } - /** - * Gets the content-type of the response body - */ - virtual const Aws::String& GetContentType() const { return GetHeader(Http::CONTENT_TYPE_HEADER); } - /** - * Gets the response body of the response. - */ - virtual Aws::IOStream& GetResponseBody() const = 0; - /** - * Gives full control of the memory of the ResponseBody over to the caller. At this point, it is the caller's - * responsibility to clean up this object. - */ - virtual Utils::Stream::ResponseStream&& SwapResponseStreamOwnership() = 0; - /** - * Adds a header to the http response object. - */ - virtual void AddHeader(const Aws::String&, const Aws::String&) = 0; - /** - * Sets the content type header on the http response object. - */ - virtual void SetContentType(const Aws::String& contentType) { AddHeader("content-type", contentType); } - + + /** + * Get the headers from this response + */ + virtual HeaderValueCollection GetHeaders() const = 0; + /** + * Returns true if the response contains a header by headerName + */ + virtual bool HasHeader(const char* headerName) const = 0; + /** + * Returns the value for a header at headerName if it exists. + */ + virtual const Aws::String& GetHeader(const Aws::String& headerName) const = 0; + /** + * Gets response code for this http response. + */ + virtual inline HttpResponseCode GetResponseCode() const { return m_responseCode; } + /** + * Sets the response code for this http response. + */ + virtual inline void SetResponseCode(HttpResponseCode httpResponseCode) { m_responseCode = httpResponseCode; } + /** + * Gets the content-type of the response body + */ + virtual const Aws::String& GetContentType() const { return GetHeader(Http::CONTENT_TYPE_HEADER); } + /** + * Gets the response body of the response. + */ + virtual Aws::IOStream& GetResponseBody() const = 0; + /** + * Gives full control of the memory of the ResponseBody over to the caller. At this point, it is the caller's + * responsibility to clean up this object. + */ + virtual Utils::Stream::ResponseStream&& SwapResponseStreamOwnership() = 0; + /** + * Adds a header to the http response object. + */ + virtual void AddHeader(const Aws::String&, const Aws::String&) = 0; + /** + * Sets the content type header on the http response object. + */ + virtual void SetContentType(const Aws::String& contentType) { AddHeader("content-type", contentType); } + inline bool HasClientError() const { return m_hasClientError; } inline void SetClientErrorType(Aws::Client::CoreErrors errorType) {m_hasClientError = true; m_clientErrorType = errorType;} inline Aws::Client::CoreErrors GetClientErrorType() { return m_clientErrorType; } @@ -201,19 +201,19 @@ namespace Aws inline const Aws::String &GetClientErrorMessage() const { return m_clientErrorMessage; } inline void SetClientErrorMessage(const Aws::String &error) { m_clientErrorMessage = error; } - private: - HttpResponse(const HttpResponse&); - HttpResponse& operator = (const HttpResponse&); - + private: + HttpResponse(const HttpResponse&); + HttpResponse& operator = (const HttpResponse&); + std::shared_ptr<const HttpRequest> m_httpRequest; - HttpResponseCode m_responseCode; + HttpResponseCode m_responseCode; // Error generated by http client, SDK or users, indicating non service error during http request bool m_hasClientError; Aws::Client::CoreErrors m_clientErrorType; Aws::String m_clientErrorMessage; - }; - - } // namespace Http -} // namespace Aws - - + }; + + } // namespace Http +} // namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpTypes.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpTypes.h index b8c993294a..f395f77972 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpTypes.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/HttpTypes.h @@ -2,56 +2,56 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSList.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSMap.h> - -#include <memory> - -namespace Aws -{ - namespace Http - { - /** - * Models Http methods. - */ - enum class HttpMethod - { - HTTP_GET, - HTTP_POST, - HTTP_DELETE, - HTTP_PUT, - HTTP_HEAD, - HTTP_PATCH - }; - - /** - * Possible default http factory vended http client implementations. - */ - enum class TransferLibType - { + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSList.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> + +#include <memory> + +namespace Aws +{ + namespace Http + { + /** + * Models Http methods. + */ + enum class HttpMethod + { + HTTP_GET, + HTTP_POST, + HTTP_DELETE, + HTTP_PUT, + HTTP_HEAD, + HTTP_PATCH + }; + + /** + * Possible default http factory vended http client implementations. + */ + enum class TransferLibType + { DEFAULT_CLIENT = 0, - CURL_CLIENT, - WIN_INET_CLIENT, - WIN_HTTP_CLIENT - }; - - namespace HttpMethodMapper - { - /** - * Gets the string value of an httpMethod. - */ - AWS_CORE_API const char* GetNameForHttpMethod(HttpMethod httpMethod); - } // namespace HttpMethodMapper - - typedef std::pair<Aws::String, Aws::String> HeaderValuePair; - typedef Aws::Map<Aws::String, Aws::String> HeaderValueCollection; - - } // namespace Http -} // namespace Aws - + CURL_CLIENT, + WIN_INET_CLIENT, + WIN_HTTP_CLIENT + }; + + namespace HttpMethodMapper + { + /** + * Gets the string value of an httpMethod. + */ + AWS_CORE_API const char* GetNameForHttpMethod(HttpMethod httpMethod); + } // namespace HttpMethodMapper + + typedef std::pair<Aws::String, Aws::String> HeaderValuePair; + typedef Aws::Map<Aws::String, Aws::String> HeaderValueCollection; + + } // namespace Http +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/Scheme.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/Scheme.h index a0ec88ad16..6c1dfa8a2e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/Scheme.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/Scheme.h @@ -2,37 +2,37 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Http - { - /** - * Enum representing URI scheme. - */ - enum class Scheme - { - HTTP, - HTTPS - }; - - namespace SchemeMapper - { - /** - * Converts a Scheme instance to a String. - */ - AWS_CORE_API const char* ToString(Scheme scheme); - /** - * Converts a string instance to a Scheme. Defaults to https. - */ - AWS_CORE_API Scheme FromString(const char* name); - } // namespace SchemeMapper - } // namespace Http -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Http + { + /** + * Enum representing URI scheme. + */ + enum class Scheme + { + HTTP, + HTTPS + }; + + namespace SchemeMapper + { + /** + * Converts a Scheme instance to a String. + */ + AWS_CORE_API const char* ToString(Scheme scheme); + /** + * Converts a string instance to a Scheme. Defaults to https. + */ + AWS_CORE_API Scheme FromString(const char* name); + } // namespace SchemeMapper + } // namespace Http +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h index d72e96b863..45879bb0c5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/URI.h @@ -2,170 +2,170 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/http/Scheme.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -#include <stdint.h> - -namespace Aws -{ - namespace Http - { - extern AWS_CORE_API const char* SEPARATOR; - static const uint16_t HTTP_DEFAULT_PORT = 80; - static const uint16_t HTTPS_DEFAULT_PORT = 443; - - //per https://tools.ietf.org/html/rfc3986#section-3.4 there is nothing preventing servers from allowing - //multiple values for the same key. So use a multimap instead of a map. - typedef Aws::MultiMap<Aws::String, Aws::String> QueryStringParameterCollection; - - /** - * class modeling universal resource identifier, but implemented for http - */ - class AWS_CORE_API URI - { - public: - /** - * Defaults to http and port 80 - */ - URI(); - /** - * Parses string and sets uri fields - */ - URI(const Aws::String&); - /** - * Parses string and sets uri fields - */ - URI(const char*); - - URI& operator = (const Aws::String&); - URI& operator = (const char*); - - bool operator == (const URI&) const; - bool operator == (const Aws::String&) const; - bool operator == (const char*) const; - bool operator != (const URI&) const; - bool operator != (const Aws::String&) const; - bool operator != (const char*) const; - - /** - * scheme or protocol e.g. http, https, ftp - */ - inline Scheme GetScheme() const { return m_scheme; } - - /** + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/http/Scheme.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +#include <stdint.h> + +namespace Aws +{ + namespace Http + { + extern AWS_CORE_API const char* SEPARATOR; + static const uint16_t HTTP_DEFAULT_PORT = 80; + static const uint16_t HTTPS_DEFAULT_PORT = 443; + + //per https://tools.ietf.org/html/rfc3986#section-3.4 there is nothing preventing servers from allowing + //multiple values for the same key. So use a multimap instead of a map. + typedef Aws::MultiMap<Aws::String, Aws::String> QueryStringParameterCollection; + + /** + * class modeling universal resource identifier, but implemented for http + */ + class AWS_CORE_API URI + { + public: + /** + * Defaults to http and port 80 + */ + URI(); + /** + * Parses string and sets uri fields + */ + URI(const Aws::String&); + /** + * Parses string and sets uri fields + */ + URI(const char*); + + URI& operator = (const Aws::String&); + URI& operator = (const char*); + + bool operator == (const URI&) const; + bool operator == (const Aws::String&) const; + bool operator == (const char*) const; + bool operator != (const URI&) const; + bool operator != (const Aws::String&) const; + bool operator != (const char*) const; + + /** + * scheme or protocol e.g. http, https, ftp + */ + inline Scheme GetScheme() const { return m_scheme; } + + /** * Sets scheme, if the port is incompatible with this scheme, the port will automatically be set as well. - */ - void SetScheme(Scheme value); - - /** - * Gets the domain portion of the uri - */ - inline const Aws::String& GetAuthority() const { return m_authority; } - - /** - * Sets the domain portion of the uri - */ - inline void SetAuthority(const Aws::String& value) { m_authority = value; } - - /** - * Gets the port portion of the uri, defaults to 22 for ftp, 80 for http and 443 for https - */ - inline uint16_t GetPort() const { return m_port; } - - /** - * Sets the port portion of the uri, normally you will not have to do this. If the scheme is set to ftp, http - * or https then the default ports will be set. - */ - inline void SetPort(uint16_t value) { m_port = value; } - - /** - * Gets the path portion of the uri e.g. the portion after the first slash after the authority and prior to the - * query string. This is not url encoded. - */ - inline const Aws::String& GetPath() const { return m_path; } - - /** - * Gets the path portion of the uri, url encodes it and returns it - */ - inline Aws::String GetURLEncodedPath() const { return URLEncodePath(m_path); } - - /** - * Sets the path portion of the uri. URL encodes it if needed - */ - void SetPath(const Aws::String& value); - - /** - * Gets the raw query string including the ? - */ - inline const Aws::String& GetQueryString() const { return m_queryString; } - - /** - * Resets the query string to the raw string. all query string manipulations made before this call will be lost - */ - void SetQueryString(const Aws::String& str); - - Aws::String GetFormParameters() const; - - /** + */ + void SetScheme(Scheme value); + + /** + * Gets the domain portion of the uri + */ + inline const Aws::String& GetAuthority() const { return m_authority; } + + /** + * Sets the domain portion of the uri + */ + inline void SetAuthority(const Aws::String& value) { m_authority = value; } + + /** + * Gets the port portion of the uri, defaults to 22 for ftp, 80 for http and 443 for https + */ + inline uint16_t GetPort() const { return m_port; } + + /** + * Sets the port portion of the uri, normally you will not have to do this. If the scheme is set to ftp, http + * or https then the default ports will be set. + */ + inline void SetPort(uint16_t value) { m_port = value; } + + /** + * Gets the path portion of the uri e.g. the portion after the first slash after the authority and prior to the + * query string. This is not url encoded. + */ + inline const Aws::String& GetPath() const { return m_path; } + + /** + * Gets the path portion of the uri, url encodes it and returns it + */ + inline Aws::String GetURLEncodedPath() const { return URLEncodePath(m_path); } + + /** + * Sets the path portion of the uri. URL encodes it if needed + */ + void SetPath(const Aws::String& value); + + /** + * Gets the raw query string including the ? + */ + inline const Aws::String& GetQueryString() const { return m_queryString; } + + /** + * Resets the query string to the raw string. all query string manipulations made before this call will be lost + */ + void SetQueryString(const Aws::String& str); + + Aws::String GetFormParameters() const; + + /** * Canonicalizes the query string. - */ - void CanonicalizeQueryString(); - - /** - * parses query string and returns url decoded key/value mappings from it. Spaces and all url encoded - * values will not be encoded. - */ - QueryStringParameterCollection GetQueryStringParameters(bool decode = true) const; - - /** - * Adds query string parameter to underlying query string. - */ - void AddQueryStringParameter(const char* key, const Aws::String& value); - - /** - * Adds multiple query string parameters to underlying query string. - */ - void AddQueryStringParameter(const Aws::Map<Aws::String, Aws::String>& queryStringPairs); - - /** - * Converts the URI to a String usable for its context. e.g. an http request. - */ - Aws::String GetURIString(bool includeQueryString = true) const; - - /** - * URLEncodes the path portions of path (doesn't encode the "/" portion) + */ + void CanonicalizeQueryString(); + + /** + * parses query string and returns url decoded key/value mappings from it. Spaces and all url encoded + * values will not be encoded. + */ + QueryStringParameterCollection GetQueryStringParameters(bool decode = true) const; + + /** + * Adds query string parameter to underlying query string. + */ + void AddQueryStringParameter(const char* key, const Aws::String& value); + + /** + * Adds multiple query string parameters to underlying query string. + */ + void AddQueryStringParameter(const Aws::Map<Aws::String, Aws::String>& queryStringPairs); + + /** + * Converts the URI to a String usable for its context. e.g. an http request. + */ + Aws::String GetURIString(bool includeQueryString = true) const; + + /** + * URLEncodes the path portions of path (doesn't encode the "/" portion) * Keeps the first and the last "/". - */ - static Aws::String URLEncodePath(const Aws::String& path); - - /** - * URLEncodes the path portion of the URI according to RFC3986 - */ - static Aws::String URLEncodePathRFC3986(const Aws::String& path); - - private: - void ParseURIParts(const Aws::String& uri); - void ExtractAndSetScheme(const Aws::String& uri); - void ExtractAndSetAuthority(const Aws::String& uri); - void ExtractAndSetPort(const Aws::String& uri); - void ExtractAndSetPath(const Aws::String& uri); - void ExtractAndSetQueryString(const Aws::String& uri); - bool CompareURIParts(const URI& other) const; - - Scheme m_scheme; - Aws::String m_authority; - uint16_t m_port; - Aws::String m_path; - Aws::String m_queryString; - }; - - } // namespace Http -} // namespace Aws - + */ + static Aws::String URLEncodePath(const Aws::String& path); + + /** + * URLEncodes the path portion of the URI according to RFC3986 + */ + static Aws::String URLEncodePathRFC3986(const Aws::String& path); + + private: + void ParseURIParts(const Aws::String& uri); + void ExtractAndSetScheme(const Aws::String& uri); + void ExtractAndSetAuthority(const Aws::String& uri); + void ExtractAndSetPort(const Aws::String& uri); + void ExtractAndSetPath(const Aws::String& uri); + void ExtractAndSetQueryString(const Aws::String& uri); + bool CompareURIParts(const URI& other) const; + + Scheme m_scheme; + Aws::String m_authority; + uint16_t m_port; + Aws::String m_path; + Aws::String m_queryString; + }; + + } // namespace Http +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h index c2745753eb..22d2a61955 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHandleContainer.h @@ -2,73 +2,73 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/utils/ResourceManager.h> - -#include <utility> -#include <curl/curl.h> - -namespace Aws -{ -namespace Http -{ - -/** - * Simple Connection pool manager for Curl. It maintains connections in a thread safe manner. You - * can call into acquire a handle, then put it back when finished. It is assumed that reusing an already - * initialized handle is preferable (especially for synchronous clients). The pool doubles in capacity as - * needed up to the maximum amount of connections. - */ -class CurlHandleContainer -{ -public: - /** - * Initializes an empty stack of CURL handles. If you are only making synchronous calls via your http client - * then a small size is best. For async support, a good value would be 6 * number of Processors. * - */ + +#pragma once + +#include <aws/core/utils/ResourceManager.h> + +#include <utility> +#include <curl/curl.h> + +namespace Aws +{ +namespace Http +{ + +/** + * Simple Connection pool manager for Curl. It maintains connections in a thread safe manner. You + * can call into acquire a handle, then put it back when finished. It is assumed that reusing an already + * initialized handle is preferable (especially for synchronous clients). The pool doubles in capacity as + * needed up to the maximum amount of connections. + */ +class CurlHandleContainer +{ +public: + /** + * Initializes an empty stack of CURL handles. If you are only making synchronous calls via your http client + * then a small size is best. For async support, a good value would be 6 * number of Processors. * + */ CurlHandleContainer(unsigned maxSize = 50, long httpRequestTimeout = 0, long connectTimeout = 1000, bool tcpKeepAlive = true, unsigned long tcpKeepAliveIntervalMs = 30000, long lowSpeedTime = 3000, unsigned long lowSpeedLimit = 1); - ~CurlHandleContainer(); - - /** - * Blocks until a curl handle from the pool is available for use. - */ - CURL* AcquireCurlHandle(); - /** - * Returns a handle to the pool for reuse. It is imperative that this is called - * after you are finished with the handle. - */ - void ReleaseCurlHandle(CURL* handle); - + ~CurlHandleContainer(); + + /** + * Blocks until a curl handle from the pool is available for use. + */ + CURL* AcquireCurlHandle(); + /** + * Returns a handle to the pool for reuse. It is imperative that this is called + * after you are finished with the handle. + */ + void ReleaseCurlHandle(CURL* handle); + /** * When the handle has bad DNS entries, problematic live connections, we need to destory the handle from pool. */ void DestroyCurlHandle(CURL* handle); -private: - CurlHandleContainer(const CurlHandleContainer&) = delete; - const CurlHandleContainer& operator = (const CurlHandleContainer&) = delete; - CurlHandleContainer(const CurlHandleContainer&&) = delete; - const CurlHandleContainer& operator = (const CurlHandleContainer&&) = delete; - +private: + CurlHandleContainer(const CurlHandleContainer&) = delete; + const CurlHandleContainer& operator = (const CurlHandleContainer&) = delete; + CurlHandleContainer(const CurlHandleContainer&&) = delete; + const CurlHandleContainer& operator = (const CurlHandleContainer&&) = delete; + CURL* CreateCurlHandleInPool(); - bool CheckAndGrowPool(); - void SetDefaultOptionsOnHandle(CURL* handle); - - Aws::Utils::ExclusiveOwnershipResourceManager<CURL*> m_handleContainer; - unsigned m_maxPoolSize; + bool CheckAndGrowPool(); + void SetDefaultOptionsOnHandle(CURL* handle); + + Aws::Utils::ExclusiveOwnershipResourceManager<CURL*> m_handleContainer; + unsigned m_maxPoolSize; unsigned long m_httpRequestTimeout; - unsigned long m_connectTimeout; + unsigned long m_connectTimeout; bool m_enableTcpKeepAlive; unsigned long m_tcpKeepAliveIntervalMs; unsigned long m_lowSpeedTime; unsigned long m_lowSpeedLimit; - unsigned m_poolSize; - std::mutex m_containerLock; -}; - -} // namespace Http -} // namespace Aws - + unsigned m_poolSize; + std::mutex m_containerLock; +}; + +} // namespace Http +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHttpClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHttpClient.h index 31f96befd5..9f174b9b26 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHttpClient.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/curl/CurlHttpClient.h @@ -2,44 +2,44 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ + + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/http/HttpClient.h> +#include <aws/core/http/curl/CurlHandleContainer.h> +#include <aws/core/client/ClientConfiguration.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <atomic> + +namespace Aws +{ +namespace Http +{ +namespace Standard +{ + class StandardHttpResponse; +} + +//Curl implementation of an http client. Right now it is only synchronous. +class AWS_CORE_API CurlHttpClient: public HttpClient +{ +public: + + using Base = HttpClient; + + //Creates client, initializes curl handle if it hasn't been created already. + CurlHttpClient(const Aws::Client::ClientConfiguration& clientConfig); - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/http/HttpClient.h> -#include <aws/core/http/curl/CurlHandleContainer.h> -#include <aws/core/client/ClientConfiguration.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <atomic> - -namespace Aws -{ -namespace Http -{ -namespace Standard -{ - class StandardHttpResponse; -} - -//Curl implementation of an http client. Right now it is only synchronous. -class AWS_CORE_API CurlHttpClient: public HttpClient -{ -public: - - using Base = HttpClient; - - //Creates client, initializes curl handle if it hasn't been created already. - CurlHttpClient(const Aws::Client::ClientConfiguration& clientConfig); - - //Makes request and receives response synchronously + //Makes request and receives response synchronously std::shared_ptr<HttpResponse> MakeRequest(const std::shared_ptr<HttpRequest>& request, Aws::Utils::RateLimits::RateLimiterInterface* readLimiter = nullptr, Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter = nullptr) const override; - - static void InitGlobalState(); - static void CleanupGlobalState(); - + + static void InitGlobalState(); + static void CleanupGlobalState(); + protected: /** * Override any configuration on CURL handle for each request before sending. @@ -47,31 +47,31 @@ protected: */ virtual void OverrideOptionsOnConnectionHandle(CURL*) const {} -private: - mutable CurlHandleContainer m_curlHandleContainer; - bool m_isUsingProxy; - Aws::String m_proxyUserName; - Aws::String m_proxyPassword; - Aws::String m_proxyScheme; - Aws::String m_proxyHost; +private: + mutable CurlHandleContainer m_curlHandleContainer; + bool m_isUsingProxy; + Aws::String m_proxyUserName; + Aws::String m_proxyPassword; + Aws::String m_proxyScheme; + Aws::String m_proxyHost; Aws::String m_proxySSLCertPath; Aws::String m_proxySSLCertType; Aws::String m_proxySSLKeyPath; Aws::String m_proxySSLKeyType; Aws::String m_proxyKeyPasswd; - unsigned m_proxyPort; - bool m_verifySSL; - Aws::String m_caPath; - Aws::String m_caFile; + unsigned m_proxyPort; + bool m_verifySSL; + Aws::String m_caPath; + Aws::String m_caFile; Aws::String m_proxyCaPath; Aws::String m_proxyCaFile; - bool m_disableExpectHeader; - bool m_allowRedirects; - static std::atomic<bool> isInit; -}; - -using PlatformHttpClient = CurlHttpClient; - -} // namespace Http -} // namespace Aws - + bool m_disableExpectHeader; + bool m_allowRedirects; + static std::atomic<bool> isInit; +}; + +using PlatformHttpClient = CurlHttpClient; + +} // namespace Http +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h index c9c0016ef5..3848f60765 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpRequest.h @@ -2,88 +2,88 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Http - { - namespace Standard - { - /** - * Simple STL container modeling of HttpRequest. Implementation of the HttpRequest interface. - */ - class AWS_CORE_API StandardHttpRequest : public HttpRequest - { - public: - /** - * Initializes an HttpRequest object with uri and http method. - */ - StandardHttpRequest(const URI& uri, HttpMethod method); - - /** - * Get All headers for this request. - */ - virtual HeaderValueCollection GetHeaders() const override; - /** - * Get the value for a Header based on its name. - * This function doesn't check the existence of headerName. - * So make sure you call HasHeader() first before calling this function, otherwise the behavior is undefined. + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Http + { + namespace Standard + { + /** + * Simple STL container modeling of HttpRequest. Implementation of the HttpRequest interface. + */ + class AWS_CORE_API StandardHttpRequest : public HttpRequest + { + public: + /** + * Initializes an HttpRequest object with uri and http method. + */ + StandardHttpRequest(const URI& uri, HttpMethod method); + + /** + * Get All headers for this request. + */ + virtual HeaderValueCollection GetHeaders() const override; + /** + * Get the value for a Header based on its name. + * This function doesn't check the existence of headerName. + * So make sure you call HasHeader() first before calling this function, otherwise the behavior is undefined. + */ + virtual const Aws::String& GetHeaderValue(const char* headerName) const override; + /** + * Add a header pair + */ + virtual void SetHeaderValue(const char* headerName, const Aws::String& headerValue) override; + /** + * Add a header pair + */ + virtual void SetHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) override; + /** + * delete pair by headerName + */ + virtual void DeleteHeader(const char* headerName) override; + /** + * Adds a content body stream to the request. This stream will be used to send the body to the endpoint. */ - virtual const Aws::String& GetHeaderValue(const char* headerName) const override; - /** - * Add a header pair - */ - virtual void SetHeaderValue(const char* headerName, const Aws::String& headerValue) override; - /** - * Add a header pair - */ - virtual void SetHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) override; - /** - * delete pair by headerName - */ - virtual void DeleteHeader(const char* headerName) override; - /** - * Adds a content body stream to the request. This stream will be used to send the body to the endpoint. - */ - virtual inline void AddContentBody(const std::shared_ptr<Aws::IOStream>& strContent) override { bodyStream = strContent; } - /** - * Gets the content body stream that will be used for this request. - */ - virtual inline const std::shared_ptr<Aws::IOStream>& GetContentBody() const override { return bodyStream; } - /** - * Returns true if a header exists in the request with name - */ - virtual bool HasHeader(const char*) const override; - /** - * Get size in bytes of the request when as it will be going accross the wire. - */ - virtual int64_t GetSize() const override; - /** - * Gets the factory for creating the stream that will be used in the http response. - */ - virtual const Aws::IOStreamFactory& GetResponseStreamFactory() const override; - /** - * Sets the factory for creating the stream that will be used in the http response. - */ - virtual void SetResponseStreamFactory(const Aws::IOStreamFactory& factory) override; - - private: - HeaderValueCollection headerMap; - std::shared_ptr<Aws::IOStream> bodyStream; - Aws::IOStreamFactory m_responseStreamFactory; - Aws::String m_emptyHeader; - }; - - } // namespace Standard - } // namespace Http -} // namespace Aws - - + virtual inline void AddContentBody(const std::shared_ptr<Aws::IOStream>& strContent) override { bodyStream = strContent; } + /** + * Gets the content body stream that will be used for this request. + */ + virtual inline const std::shared_ptr<Aws::IOStream>& GetContentBody() const override { return bodyStream; } + /** + * Returns true if a header exists in the request with name + */ + virtual bool HasHeader(const char*) const override; + /** + * Get size in bytes of the request when as it will be going accross the wire. + */ + virtual int64_t GetSize() const override; + /** + * Gets the factory for creating the stream that will be used in the http response. + */ + virtual const Aws::IOStreamFactory& GetResponseStreamFactory() const override; + /** + * Sets the factory for creating the stream that will be used in the http response. + */ + virtual void SetResponseStreamFactory(const Aws::IOStreamFactory& factory) override; + + private: + HeaderValueCollection headerMap; + std::shared_ptr<Aws::IOStream> bodyStream; + Aws::IOStreamFactory m_responseStreamFactory; + Aws::String m_emptyHeader; + }; + + } // namespace Standard + } // namespace Http +} // namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpResponse.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpResponse.h index 309206f1f3..80de073684 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpResponse.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/http/standard/StandardHttpResponse.h @@ -2,73 +2,73 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/http/HttpResponse.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/stream/ResponseStream.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Http - { - namespace Standard - { - /** - * Simple STL representation an Http Response, implements HttpResponse. - */ - class AWS_CORE_API StandardHttpResponse : public HttpResponse - { - public: - /** - * Initializes an http response with the originalRequest and the response code. - */ - StandardHttpResponse(const std::shared_ptr<const HttpRequest>& originatingRequest) : - HttpResponse(originatingRequest), - bodyStream(originatingRequest->GetResponseStreamFactory()) - {} - - ~StandardHttpResponse() = default; - - /** - * Get the headers from this response - */ - HeaderValueCollection GetHeaders() const; - /** - * Returns true if the response contains a header by headerName - */ - bool HasHeader(const char* headerName) const; - /** - * Returns the value for a header at headerName if it exists. - */ - const Aws::String& GetHeader(const Aws::String&) const; - /** - * Gets the response body of the response. - */ - inline Aws::IOStream& GetResponseBody() const { return bodyStream.GetUnderlyingStream(); } - /** - * Gives full control of the memory of the ResponseBody over to the caller. At this point, it is the caller's - * responsibility to clean up this object. - */ - inline Utils::Stream::ResponseStream&& SwapResponseStreamOwnership() { return std::move(bodyStream); } - /** - * Adds a header to the http response object. - */ - void AddHeader(const Aws::String&, const Aws::String&); - - private: + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/http/HttpResponse.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/stream/ResponseStream.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Http + { + namespace Standard + { + /** + * Simple STL representation an Http Response, implements HttpResponse. + */ + class AWS_CORE_API StandardHttpResponse : public HttpResponse + { + public: + /** + * Initializes an http response with the originalRequest and the response code. + */ + StandardHttpResponse(const std::shared_ptr<const HttpRequest>& originatingRequest) : + HttpResponse(originatingRequest), + bodyStream(originatingRequest->GetResponseStreamFactory()) + {} + + ~StandardHttpResponse() = default; + + /** + * Get the headers from this response + */ + HeaderValueCollection GetHeaders() const; + /** + * Returns true if the response contains a header by headerName + */ + bool HasHeader(const char* headerName) const; + /** + * Returns the value for a header at headerName if it exists. + */ + const Aws::String& GetHeader(const Aws::String&) const; + /** + * Gets the response body of the response. + */ + inline Aws::IOStream& GetResponseBody() const { return bodyStream.GetUnderlyingStream(); } + /** + * Gives full control of the memory of the ResponseBody over to the caller. At this point, it is the caller's + * responsibility to clean up this object. + */ + inline Utils::Stream::ResponseStream&& SwapResponseStreamOwnership() { return std::move(bodyStream); } + /** + * Adds a header to the http response object. + */ + void AddHeader(const Aws::String&, const Aws::String&); + + private: StandardHttpResponse(const StandardHttpResponse&); - - Aws::Map<Aws::String, Aws::String> headerMap; - Utils::Stream::ResponseStream bodyStream; - }; - - } // namespace Standard - } // namespace Http -} // namespace Aws - - + + Aws::Map<Aws::String, Aws::String> headerMap; + Utils::Stream::ResponseStream bodyStream; + }; + + } // namespace Standard + } // namespace Http +} // namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h index c58a1b70bf..4d879fc314 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/internal/AWSHttpResourceClient.h @@ -2,61 +2,61 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/client/ClientConfiguration.h> + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/client/ClientConfiguration.h> #include <aws/core/client/AWSErrorMarshaller.h> #include <aws/core/auth/AWSCredentials.h> #include <aws/core/AmazonWebServiceResult.h> #include <aws/core/utils/DateTime.h> -#include <memory> +#include <memory> #include <mutex> -namespace Aws -{ - namespace Http - { - class HttpClient; +namespace Aws +{ + namespace Http + { + class HttpClient; class HttpRequest; enum class HttpResponseCode; - } // namespace Http - - namespace Internal - { - /** - * Simple client for accessing the AWS remote data by Http. - * Currently we use it to access EC2 Metadata and ECS Credential. - */ - class AWS_CORE_API AWSHttpResourceClient - { - public: - /** - * Builds an AWSHttpResourceClient instance by using default http stack. - */ - AWSHttpResourceClient(const char* logtag = "AWSHttpResourceClient"); - AWSHttpResourceClient(const Client::ClientConfiguration& clientConfiguration, const char* logtag = "AWSHttpResourceClient"); - - AWSHttpResourceClient& operator =(const AWSHttpResourceClient& rhs) = delete; - AWSHttpResourceClient(const AWSHttpResourceClient& rhs) = delete; - AWSHttpResourceClient& operator =(const AWSHttpResourceClient&& rhs) = delete; - AWSHttpResourceClient(const AWSHttpResourceClient&& rhs) = delete; - - virtual ~AWSHttpResourceClient(); - - /** - * Connects to an HTTP endpoint to read the specified resource and returns the text contents. - * The resource URI = endpoint + resourcePath (e.g:http://domain/path/to/res) - * @param endpoint The HTTP resource to connect to. - * @param resourcePath A path appended to the endpoint to form the final URI. - * @param authToken An optional authorization token that will be passed as the value of the HTTP - * header 'Authorization'. - * @return The response from the HTTP endpoint as a string. - */ - virtual Aws::String GetResource(const char* endpoint, const char* resourcePath, const char* authToken) const; - + } // namespace Http + + namespace Internal + { + /** + * Simple client for accessing the AWS remote data by Http. + * Currently we use it to access EC2 Metadata and ECS Credential. + */ + class AWS_CORE_API AWSHttpResourceClient + { + public: + /** + * Builds an AWSHttpResourceClient instance by using default http stack. + */ + AWSHttpResourceClient(const char* logtag = "AWSHttpResourceClient"); + AWSHttpResourceClient(const Client::ClientConfiguration& clientConfiguration, const char* logtag = "AWSHttpResourceClient"); + + AWSHttpResourceClient& operator =(const AWSHttpResourceClient& rhs) = delete; + AWSHttpResourceClient(const AWSHttpResourceClient& rhs) = delete; + AWSHttpResourceClient& operator =(const AWSHttpResourceClient&& rhs) = delete; + AWSHttpResourceClient(const AWSHttpResourceClient&& rhs) = delete; + + virtual ~AWSHttpResourceClient(); + + /** + * Connects to an HTTP endpoint to read the specified resource and returns the text contents. + * The resource URI = endpoint + resourcePath (e.g:http://domain/path/to/res) + * @param endpoint The HTTP resource to connect to. + * @param resourcePath A path appended to the endpoint to form the final URI. + * @param authToken An optional authorization token that will be passed as the value of the HTTP + * header 'Authorization'. + * @return The response from the HTTP endpoint as a string. + */ + virtual Aws::String GetResource(const char* endpoint, const char* resourcePath, const char* authToken) const; + /** * Connects to an HTTP endpoint to read the specified resource and returns the text contents. * The resource URI = endpoint + resourcePath (e.g:http://domain/path/to/res) @@ -82,107 +82,107 @@ namespace Aws void SetErrorMarshaller(Aws::UniquePtr<Client::AWSErrorMarshaller> errorMarshaller) { m_errorMarshaller = std::move(errorMarshaller); } const Client::AWSErrorMarshaller* GetErrorMarshaller() const { return m_errorMarshaller.get(); } - protected: - Aws::String m_logtag; - - private: - std::shared_ptr<Client::RetryStrategy> m_retryStrategy; - std::shared_ptr<Http::HttpClient> m_httpClient; + protected: + Aws::String m_logtag; + + private: + std::shared_ptr<Client::RetryStrategy> m_retryStrategy; + std::shared_ptr<Http::HttpClient> m_httpClient; Aws::UniquePtr<Client::AWSErrorMarshaller> m_errorMarshaller; - }; - - /** - * Derived class to support retrieving of EC2 Metadata - */ - class AWS_CORE_API EC2MetadataClient : public AWSHttpResourceClient - { - public: - /** - * Build an instance with default EC2 Metadata service endpoint - */ - EC2MetadataClient(const char* endpoint = "http://169.254.169.254"); - EC2MetadataClient(const Client::ClientConfiguration& clientConfiguration, const char* endpoint = "http://169.254.169.254"); - - EC2MetadataClient& operator =(const EC2MetadataClient& rhs) = delete; - EC2MetadataClient(const EC2MetadataClient& rhs) = delete; - EC2MetadataClient& operator =(const EC2MetadataClient&& rhs) = delete; - EC2MetadataClient(const EC2MetadataClient&& rhs) = delete; - - virtual ~EC2MetadataClient(); - - using AWSHttpResourceClient::GetResource; - - /** - * Connects to the metadata service to read the specified resource and - * returns the text contents. The resource URI = m_endpoint + resourcePath. - */ - virtual Aws::String GetResource(const char* resourcePath) const; - - /** - * Connects to the Amazon EC2 Instance Metadata Service to retrieve the - * default credential information (if any). - */ - virtual Aws::String GetDefaultCredentials() const; - - /** + }; + + /** + * Derived class to support retrieving of EC2 Metadata + */ + class AWS_CORE_API EC2MetadataClient : public AWSHttpResourceClient + { + public: + /** + * Build an instance with default EC2 Metadata service endpoint + */ + EC2MetadataClient(const char* endpoint = "http://169.254.169.254"); + EC2MetadataClient(const Client::ClientConfiguration& clientConfiguration, const char* endpoint = "http://169.254.169.254"); + + EC2MetadataClient& operator =(const EC2MetadataClient& rhs) = delete; + EC2MetadataClient(const EC2MetadataClient& rhs) = delete; + EC2MetadataClient& operator =(const EC2MetadataClient&& rhs) = delete; + EC2MetadataClient(const EC2MetadataClient&& rhs) = delete; + + virtual ~EC2MetadataClient(); + + using AWSHttpResourceClient::GetResource; + + /** + * Connects to the metadata service to read the specified resource and + * returns the text contents. The resource URI = m_endpoint + resourcePath. + */ + virtual Aws::String GetResource(const char* resourcePath) const; + + /** + * Connects to the Amazon EC2 Instance Metadata Service to retrieve the + * default credential information (if any). + */ + virtual Aws::String GetDefaultCredentials() const; + + /** * Connects to the Amazon EC2 Instance Metadata Service to retrieve the * credential information (if any) in a more secure way. */ virtual Aws::String GetDefaultCredentialsSecurely() const; /** - * connects to the Amazon EC2 Instance metadata Service to retrieve the region - * the current EC2 instance is running in. - */ - virtual Aws::String GetCurrentRegion() const; - - private: - Aws::String m_endpoint; + * connects to the Amazon EC2 Instance metadata Service to retrieve the region + * the current EC2 instance is running in. + */ + virtual Aws::String GetCurrentRegion() const; + + private: + Aws::String m_endpoint; mutable std::recursive_mutex m_tokenMutex; mutable Aws::String m_token; mutable bool m_tokenRequired; mutable Aws::String m_region; - }; - + }; + void AWS_CORE_API InitEC2MetadataClient(); void AWS_CORE_API CleanupEC2MetadataClient(); std::shared_ptr<EC2MetadataClient> AWS_CORE_API GetEC2MetadataClient(); - /** + /** * Derived class to support retrieving of ECS Credentials - */ - class AWS_CORE_API ECSCredentialsClient : public AWSHttpResourceClient - { - public: - /** - * Build an instance with default ECS service endpoint - * @param resourcePath The path part of the metadata URL - * @param endpoint The URL authority to hit. Default is the IP address of the Task metadata service endpoint. - */ - ECSCredentialsClient(const char* resourcePath, const char* endpoint = "http://169.254.170.2", - const char* authToken = ""); - ECSCredentialsClient(const Client::ClientConfiguration& clientConfiguration, - const char* resourcePath, const char* endpoint = "http://169.254.170.2", - const char* authToken = ""); - - ECSCredentialsClient& operator =(ECSCredentialsClient& rhs) = delete; - ECSCredentialsClient(const ECSCredentialsClient& rhs) = delete; - ECSCredentialsClient& operator =(ECSCredentialsClient&& rhs) = delete; - ECSCredentialsClient(const ECSCredentialsClient&& rhs) = delete; - - /** - * Connects to the Amazon ECS service to retrieve the credential - */ - virtual Aws::String GetECSCredentials() const - { - return GetResource(m_endpoint.c_str(), m_resourcePath.c_str(), m_token.c_str()); - } - - private: - Aws::String m_resourcePath; - Aws::String m_endpoint; - Aws::String m_token; - }; + */ + class AWS_CORE_API ECSCredentialsClient : public AWSHttpResourceClient + { + public: + /** + * Build an instance with default ECS service endpoint + * @param resourcePath The path part of the metadata URL + * @param endpoint The URL authority to hit. Default is the IP address of the Task metadata service endpoint. + */ + ECSCredentialsClient(const char* resourcePath, const char* endpoint = "http://169.254.170.2", + const char* authToken = ""); + ECSCredentialsClient(const Client::ClientConfiguration& clientConfiguration, + const char* resourcePath, const char* endpoint = "http://169.254.170.2", + const char* authToken = ""); + + ECSCredentialsClient& operator =(ECSCredentialsClient& rhs) = delete; + ECSCredentialsClient(const ECSCredentialsClient& rhs) = delete; + ECSCredentialsClient& operator =(ECSCredentialsClient&& rhs) = delete; + ECSCredentialsClient(const ECSCredentialsClient&& rhs) = delete; + + /** + * Connects to the Amazon ECS service to retrieve the credential + */ + virtual Aws::String GetECSCredentials() const + { + return GetResource(m_endpoint.c_str(), m_resourcePath.c_str(), m_token.c_str()); + } + + private: + Aws::String m_resourcePath; + Aws::String m_endpoint; + Aws::String m_token; + }; /** * To support retrieving credentials from STS. @@ -221,5 +221,5 @@ namespace Aws private: Aws::String m_endpoint; }; - } // namespace Internal -} // namespace Aws + } // namespace Internal +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/CoreMetrics.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/CoreMetrics.h index 575a6003e2..409ab147fd 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/CoreMetrics.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/CoreMetrics.h @@ -1,27 +1,27 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/monitoring/HttpClientMetrics.h> - -namespace Aws -{ - namespace Monitoring - { - /** - * Metrics collected from AWS SDK Core include Http Client Metrics and other types of metrics. - */ - struct AWS_CORE_API CoreMetricsCollection - { - /** + */ + +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/monitoring/HttpClientMetrics.h> + +namespace Aws +{ + namespace Monitoring + { + /** + * Metrics collected from AWS SDK Core include Http Client Metrics and other types of metrics. + */ + struct AWS_CORE_API CoreMetricsCollection + { + /** * Metrics collected from underlying http client during execution of a request - */ - HttpClientMetricsCollection httpClientMetrics; - - // Add Other types of metrics here. - }; - } -} + */ + HttpClientMetricsCollection httpClientMetrics; + + // Add Other types of metrics here. + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/DefaultMonitoring.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/DefaultMonitoring.h index 148a3a23c5..1af1edb5db 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/DefaultMonitoring.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/DefaultMonitoring.h @@ -2,72 +2,72 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/client/AWSClient.h> -#include <aws/core/monitoring/MonitoringInterface.h> -#include <aws/core/monitoring/MonitoringFactory.h> -#include <aws/core/net/SimpleUDP.h> -namespace Aws -{ - namespace Monitoring - { - /** - * Default monitoring implementation definition - */ - class AWS_CORE_API DefaultMonitoring: public MonitoringInterface - { - public: - const static int DEFAULT_MONITORING_VERSION; - const static char DEFAULT_CSM_CONFIG_ENABLED[]; - const static char DEFAULT_CSM_CONFIG_CLIENT_ID[]; + +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/client/AWSClient.h> +#include <aws/core/monitoring/MonitoringInterface.h> +#include <aws/core/monitoring/MonitoringFactory.h> +#include <aws/core/net/SimpleUDP.h> +namespace Aws +{ + namespace Monitoring + { + /** + * Default monitoring implementation definition + */ + class AWS_CORE_API DefaultMonitoring: public MonitoringInterface + { + public: + const static int DEFAULT_MONITORING_VERSION; + const static char DEFAULT_CSM_CONFIG_ENABLED[]; + const static char DEFAULT_CSM_CONFIG_CLIENT_ID[]; const static char DEFAULT_CSM_CONFIG_HOST[]; - const static char DEFAULT_CSM_CONFIG_PORT[]; - const static char DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED[]; - const static char DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID[]; + const static char DEFAULT_CSM_CONFIG_PORT[]; + const static char DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED[]; + const static char DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID[]; const static char DEFAULT_CSM_ENVIRONMENT_VAR_HOST[]; - const static char DEFAULT_CSM_ENVIRONMENT_VAR_PORT[]; - - /** - * @brief Construct a default monitoring instance - * @param clientId, used to identify the application + const static char DEFAULT_CSM_ENVIRONMENT_VAR_PORT[]; + + /** + * @brief Construct a default monitoring instance + * @param clientId, used to identify the application * @param host, either the host name or the host ip address (could be ipv4 or ipv6). Note that "localhost" will be treated as host name and address look up will be performed. - * @param port, used to send collected metric to a local agent listen on this port. - */ + * @param port, used to send collected metric to a local agent listen on this port. + */ DefaultMonitoring(const Aws::String& clientId, const Aws::String& host, unsigned short port); - - void* OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) const override; - - void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const override; - - - void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const override; - + + void* OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) const override; + + void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const override; + + + void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const override; + void OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const override; - - + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const override; + + void OnFinish(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const override; - - static inline int GetVersion() { return DEFAULT_MONITORING_VERSION; } - private: + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const override; + + static inline int GetVersion() { return DEFAULT_MONITORING_VERSION; } + private: void CollectAndSendAttemptData(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Client::HttpResponseOutcome& outcome, - const CoreMetricsCollection& metricsFromCore, void* context) const; - - Aws::Net::SimpleUDP m_udp; - Aws::String m_clientId; - }; - - class AWS_CORE_API DefaultMonitoringFactory : public MonitoringFactory - { - public: - Aws::UniquePtr<MonitoringInterface> CreateMonitoringInstance() const override; - }; - } // namespace Monitoring + const CoreMetricsCollection& metricsFromCore, void* context) const; + + Aws::Net::SimpleUDP m_udp; + Aws::String m_clientId; + }; + + class AWS_CORE_API DefaultMonitoringFactory : public MonitoringFactory + { + public: + Aws::UniquePtr<MonitoringInterface> CreateMonitoringInstance() const override; + }; + } // namespace Monitoring } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/HttpClientMetrics.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/HttpClientMetrics.h index 2c2efa3ed5..73418dabf5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/HttpClientMetrics.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/HttpClientMetrics.h @@ -1,84 +1,84 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSMap.h> - -namespace Aws -{ - namespace Monitoring - { - /** - * Metrics definitions optional from HttpClient module inside AWS Sdk core. - */ - enum class HttpClientMetricsType - { + */ + +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> + +namespace Aws +{ + namespace Monitoring + { + /** + * Metrics definitions optional from HttpClient module inside AWS Sdk core. + */ + enum class HttpClientMetricsType + { /* - * Requires a successful DNS lookup, contains the (IPv4 or IPv6 as appropriate) numeric address of the connection endpoint to which the attempt was sent. - */ - DestinationIp = 0, - + * Requires a successful DNS lookup, contains the (IPv4 or IPv6 as appropriate) numeric address of the connection endpoint to which the attempt was sent. + */ + DestinationIp = 0, + /** * Requires the SDK to recognize that an existing connection was reused to make the request, - * contains the time interval (in milliseconds) between the construction of the http request and when a connection was successfully acquired from the connection pool. - */ - AcquireConnectionLatency, - - /** + * contains the time interval (in milliseconds) between the construction of the http request and when a connection was successfully acquired from the connection pool. + */ + AcquireConnectionLatency, + + /** * Requires the SDK to recognize whether or not an existing connection was used to make the request, - * contains 1 if an existing connection was used to perform the http request; contains 0 if a new connection was opened to perform the http request. - */ + * contains 1 if an existing connection was used to perform the http request; contains 0 if a new connection was opened to perform the http request. + */ ConnectionReused, - + /** * Requires the SDK to recognize that a new connection was established to make the request, * contains the time interval (in milliseconds) between the construction of the http request and when a connection was fully established. * If the SDK is able to estimate this time despite not having a perfectly accurate callback for the specific event, then it should. * For example, if the http client includes user-level data write functions that are guaranteed to be called shortly after connection establishment, - * then the first call could be used as a reasonable time marker for ConnectLatency - */ - ConnectLatency, - + * then the first call could be used as a reasonable time marker for ConnectLatency + */ + ConnectLatency, + /** * Requires the SDK to be able to mark the point in time where the request starts transmission, * contains the time interval (in milliseconds) between when the request begins transmission to the service and when a terminal error has occurred or the response has been parsed, - * excluding streaming payloads. Like ConnectLatency, if the SDK has access to an event that is a "close enough" marker in time, it should include this entry. - * The request here is a http level request, not a service level API request. - */ + * excluding streaming payloads. Like ConnectLatency, if the SDK has access to an event that is a "close enough" marker in time, it should include this entry. + * The request here is a http level request, not a service level API request. + */ RequestLatency, - - /** + + /** * Requires the SDK to have access to how long it took to perform DNS lookup, if it took place, - * contains the time (in milliseconds) it took to perform DNS lookup, during the Api Call attempt. - */ - DnsLatency, - - /** + * contains the time (in milliseconds) it took to perform DNS lookup, during the Api Call attempt. + */ + DnsLatency, + + /** * Requires the SDK to have access to how long it took to establish the underlying Tcp/Ip connection used for the request, - * contains the time (in milliseconds) it took to fully establish the TCP/IP connection used to make the request attempt. - */ - TcpLatency, - - /** + * contains the time (in milliseconds) it took to fully establish the TCP/IP connection used to make the request attempt. + */ + TcpLatency, + + /** * Requires the SDK to have access to how long it took to perform the SSL handshake for a secure request, - * contains the time (in milliseconds) it took to perform a SSL handshake over the established TCP/IP connection. - */ - SslLatency, - - /** - * Unknow Metrics Type - */ - Unknown - }; - - typedef Aws::Map<Aws::String, int64_t> HttpClientMetricsCollection; - + * contains the time (in milliseconds) it took to perform a SSL handshake over the established TCP/IP connection. + */ + SslLatency, + + /** + * Unknow Metrics Type + */ + Unknown + }; + + typedef Aws::Map<Aws::String, int64_t> HttpClientMetricsCollection; + AWS_CORE_API HttpClientMetricsType GetHttpClientMetricTypeByName(const Aws::String& name); - + AWS_CORE_API Aws::String GetHttpClientMetricNameByType(HttpClientMetricsType type); - } -} + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringFactory.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringFactory.h index 2d03efa712..22d9f6784b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringFactory.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringFactory.h @@ -1,26 +1,26 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once -#include <aws/core/Core_EXPORTS.h> - -namespace Aws -{ - namespace Monitoring - { - class MonitoringInterface; - - /** - * Factory to create monitoring instance. - */ - class AWS_CORE_API MonitoringFactory - { - public: - virtual ~MonitoringFactory() = default; - virtual Aws::UniquePtr<MonitoringInterface> CreateMonitoringInstance() const = 0; - }; - - } // namespace Monitoring -} // namespace Aws + */ + +#pragma once +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ + namespace Monitoring + { + class MonitoringInterface; + + /** + * Factory to create monitoring instance. + */ + class AWS_CORE_API MonitoringFactory + { + public: + virtual ~MonitoringFactory() = default; + virtual Aws::UniquePtr<MonitoringInterface> CreateMonitoringInstance() const = 0; + }; + + } // namespace Monitoring +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h index ebe50722c7..8613bae238 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringInterface.h @@ -1,89 +1,89 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/http/HttpResponse.h> -#include <aws/core/client/AWSError.h> -#include <aws/core/client/AWSClient.h> -#include <aws/core/monitoring/CoreMetrics.h> - -namespace Aws -{ - namespace Monitoring - { - /** - * Monitoring interface definition for SDK metrics collection. - */ - class AWS_CORE_API MonitoringInterface - { - public: - virtual ~MonitoringInterface() = default; - - /** + */ + +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/http/HttpResponse.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/client/AWSClient.h> +#include <aws/core/monitoring/CoreMetrics.h> + +namespace Aws +{ + namespace Monitoring + { + /** + * Monitoring interface definition for SDK metrics collection. + */ + class AWS_CORE_API MonitoringInterface + { + public: + virtual ~MonitoringInterface() = default; + + /** * @brief This function lets you do preparation work when a http attempt(request) starts. It returns a pointer to an implementation defined context which will be * passed down with the other facilities that completes the request's lifetime. This context can be used to track the lifetime of the request and record metrics - * specific to this particular request. You are responsible for deleteing the context during your OnFinish call. - * @param serviceName, the service client who initiates this http attempt. like "s3", "ec2", etc. - * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. - * @param request, the actual Http Request. - * @return implementation depends memory address of context. + * specific to this particular request. You are responsible for deleteing the context during your OnFinish call. + * @param serviceName, the service client who initiates this http attempt. like "s3", "ec2", etc. + * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. + * @param request, the actual Http Request. + * @return implementation depends memory address of context. */ virtual void* OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request) const = 0; - - /** + const std::shared_ptr<const Aws::Http::HttpRequest>& request) const = 0; + + /** * @brief Once a Http attempt finished and received "Succeeded" response, this function will be called. - * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. - * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. - * @param request, the actual Http Request. - * @param outcome, the outcome of the http attempt, you can access httpResponse and original httpRequest from it. - * @param metricsFromCore, metrics collected from core, such as detailed latencies during http connection. - * @param context parameter pointed to the same place returned by OnRequestStarted() function. - * @return void. - */ + * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. + * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. + * @param request, the actual Http Request. + * @param outcome, the outcome of the http attempt, you can access httpResponse and original httpRequest from it. + * @param metricsFromCore, metrics collected from core, such as detailed latencies during http connection. + * @param context parameter pointed to the same place returned by OnRequestStarted() function. + * @return void. + */ virtual void OnRequestSucceeded(const Aws::String& serviceName, - const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const = 0; - - /** - * @brief Once a Http request finished and received "Failed" response, this function will be called. - * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. - * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. - * @param request, the actual Http Request. - * @param outcome, the outcome of the http attempt, you can access httpResponse and original httpRequest from it. - * @param metricsFromCore, metrics collected from core, such as detailed latencies during http connection. - * @param context parameter pointed to the same place returned by OnRequestStarted() function. - * @return void. - */ + const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const = 0; + + /** + * @brief Once a Http request finished and received "Failed" response, this function will be called. + * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. + * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. + * @param request, the actual Http Request. + * @param outcome, the outcome of the http attempt, you can access httpResponse and original httpRequest from it. + * @param metricsFromCore, metrics collected from core, such as detailed latencies during http connection. + * @param context parameter pointed to the same place returned by OnRequestStarted() function. + * @return void. + */ virtual void OnRequestFailed(const Aws::String& serviceName, - const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const = 0; - - /** - * @brief Once an API call retried the attempt and send the request again, this function will be called. - * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. - * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. - * @param request, the actual Http Request. - * @param context parameter pointed to the same place returned by OnRequestStarted() function. - * @return void. - */ + const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const = 0; + + /** + * @brief Once an API call retried the attempt and send the request again, this function will be called. + * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. + * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. + * @param request, the actual Http Request. + * @param context parameter pointed to the same place returned by OnRequestStarted() function. + * @return void. + */ virtual void OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const = 0; - - /** - * @brief This function will always be called by the SDK to signal the implementer that this request is done. The implementer can safely delete the context. - * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. - * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. - * @param request, the actual Http Request. - * @param context parameter pointed to the same place returned by OnRequestStarted() function. - * @return void. - */ + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const = 0; + + /** + * @brief This function will always be called by the SDK to signal the implementer that this request is done. The implementer can safely delete the context. + * @param serviceName, the service client who initiate this http attempt. like "s3", "ec2", etc. + * @param requestName, the operation or API name of this http attempt, like "GetObject" in s3. + * @param request, the actual Http Request. + * @param context parameter pointed to the same place returned by OnRequestStarted() function. + * @return void. + */ virtual void OnFinish(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const = 0; - }; - } // namespace Monitoring + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const = 0; + }; + } // namespace Monitoring } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h index aaa5bca5d1..49bb8e00bf 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/monitoring/MonitoringManager.h @@ -1,64 +1,64 @@ - + /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <aws/core/client/AWSClient.h> -#include <aws/core/monitoring/CoreMetrics.h> - -namespace Aws -{ - namespace Monitoring - { - class MonitoringFactory; - /** - * Wrapper function of OnRequestStarted defined by all monitoring instances - */ - Aws::Vector<void*> OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request); - - /** - * Wrapper function of OnRequestSucceeded defined by all monitoring instances - */ - void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts); - - /** - * Wrapper function of OnRequestFailed defined by all monitoring instances - */ - void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts); - - /** - * Wrapper function of OnRequestRetry defined by all monitoring instances - */ + */ + +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/client/AWSClient.h> +#include <aws/core/monitoring/CoreMetrics.h> + +namespace Aws +{ + namespace Monitoring + { + class MonitoringFactory; + /** + * Wrapper function of OnRequestStarted defined by all monitoring instances + */ + Aws::Vector<void*> OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, + const std::shared_ptr<const Aws::Http::HttpRequest>& request); + + /** + * Wrapper function of OnRequestSucceeded defined by all monitoring instances + */ + void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts); + + /** + * Wrapper function of OnRequestFailed defined by all monitoring instances + */ + void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts); + + /** + * Wrapper function of OnRequestRetry defined by all monitoring instances + */ void OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts); - - /** - * Wrapper function of OnFinish defined by all monitoring instances - */ + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts); + + /** + * Wrapper function of OnFinish defined by all monitoring instances + */ void OnFinish(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts); - - typedef std::function<Aws::UniquePtr<MonitoringFactory>()> MonitoringFactoryCreateFunction; - - /** + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts); + + typedef std::function<Aws::UniquePtr<MonitoringFactory>()> MonitoringFactoryCreateFunction; + + /** * Init monitoring using supplied factories, monitoring can support multiple instances. - * We will try to (based on config resolution result) create a default client side monitoring listener instance defined in AWS SDK Core module. - * and create other instances from these factories. - * This function will be called during Aws::InitAPI call, argument is acquired from Aws::SDKOptions->MonitoringOptions - */ + * We will try to (based on config resolution result) create a default client side monitoring listener instance defined in AWS SDK Core module. + * and create other instances from these factories. + * This function will be called during Aws::InitAPI call, argument is acquired from Aws::SDKOptions->MonitoringOptions + */ AWS_CORE_API void InitMonitoring(const std::vector<MonitoringFactoryCreateFunction>& monitoringFactoryCreateFunctions); - - /** - * Clean up monitoring related global variables - */ + + /** + * Clean up monitoring related global variables + */ AWS_CORE_API void CleanupMonitoring(); - } -} + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/Net.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/Net.h index 00aca57e0a..25994a248a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/Net.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/Net.h @@ -1,23 +1,23 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -namespace Aws -{ - namespace Net - { - // Has network stack been initiated. - bool IsNetworkInitiated(); - - // Initiate network stack. - void InitNetwork(); - - // Cleanup network stack. - void CleanupNetwork(); - } -} + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ + namespace Net + { + // Has network stack been initiated. + bool IsNetworkInitiated(); + + // Initiate network stack. + void InitNetwork(); + + // Cleanup network stack. + void CleanupNetwork(); + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h index 2e96b509fb..4462331cb7 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/net/SimpleUDP.h @@ -1,47 +1,47 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> #include <aws/core/utils/memory/stl/AWSString.h> -#include <cstdint> -struct sockaddr; - -namespace Aws -{ - namespace Net - { - // 8K is aligned with default monitoring packet size. - const static size_t UDP_BUFFER_SIZE = 8192; - /** - * SimpleUDP definition. - */ - class AWS_CORE_API SimpleUDP - { - public: - /** - * @brief Constructor of SimpleUDP - * @param addressFamily, AF_INET for IPV4 or AF_INET6 for IPV6 - * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. +#include <cstdint> +struct sockaddr; + +namespace Aws +{ + namespace Net + { + // 8K is aligned with default monitoring packet size. + const static size_t UDP_BUFFER_SIZE = 8192; + /** + * SimpleUDP definition. + */ + class AWS_CORE_API SimpleUDP + { + public: + /** + * @brief Constructor of SimpleUDP + * @param addressFamily, AF_INET for IPV4 or AF_INET6 for IPV6 + * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. * @param receieveBufSize, if nonzero, try set socket's receive buffer size to this value. * @param nonBlocking, if it is true, implementation will try to create a non-blocking underlying UDP socket. - * Implementation should create and set the underlying udp socket. - */ - SimpleUDP(int addressFamily, size_t sendBufSize = UDP_BUFFER_SIZE, size_t receiveBufSize = UDP_BUFFER_SIZE, bool nonBlocking = true); - - /** - * @brief An easy constructor of an IPV4 or IPV6 SimpleUDP - * @param addressFamily, either AF_INET for IPV4 or AF_INET6 for IPV6 - * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. + * Implementation should create and set the underlying udp socket. + */ + SimpleUDP(int addressFamily, size_t sendBufSize = UDP_BUFFER_SIZE, size_t receiveBufSize = UDP_BUFFER_SIZE, bool nonBlocking = true); + + /** + * @brief An easy constructor of an IPV4 or IPV6 SimpleUDP + * @param addressFamily, either AF_INET for IPV4 or AF_INET6 for IPV6 + * @param sendBufSize, if nonzero, try set socket's send buffer size to this value. * @param receieveBufSize, if nonzero, try set socket's receive buffer size to this value. * @param nonBlocking, if it is true, implementation will try to create a non-blocking underlying UDP socket. - * Implementation should create and set the underlying udp socket. - */ - SimpleUDP(bool IPV4 = true, size_t sendBufSize = UDP_BUFFER_SIZE, size_t receiveBufSize = UDP_BUFFER_SIZE, bool nonBlocking = true); - + * Implementation should create and set the underlying udp socket. + */ + SimpleUDP(bool IPV4 = true, size_t sendBufSize = UDP_BUFFER_SIZE, size_t receiveBufSize = UDP_BUFFER_SIZE, bool nonBlocking = true); + /** * @brief An easy constructor of SimpleUDP based on host and port * @param host, the host that packets will be sent to, could be ipv4 or ipv6 address, or a hostname @@ -54,110 +54,110 @@ namespace Aws */ SimpleUDP(const char* host, unsigned short port, size_t sendBufSize = UDP_BUFFER_SIZE, size_t receiveBufSize = UDP_BUFFER_SIZE, bool nonBlocking = true); - ~SimpleUDP(); - - /** - * @brief Connect underlying udp socket to server specified in address. - * @param address, the server's address info. - * @param addressLength, length of address, structure of address can vary. - * @return 0 on success, -1 on error, check errno for detailed error information. - */ - int Connect(const sockaddr* address, size_t addressLength); - - /** + ~SimpleUDP(); + + /** + * @brief Connect underlying udp socket to server specified in address. + * @param address, the server's address info. + * @param addressLength, length of address, structure of address can vary. + * @return 0 on success, -1 on error, check errno for detailed error information. + */ + int Connect(const sockaddr* address, size_t addressLength); + + /** * @brief An easy way to connect to host * @param hostIP, a valid ipv4 or ipv6 address. The address type should match the m_addressFamily type settled during construction. * Otherwise the connection will fail. * @param port, the port that host listens on. - */ + */ int ConnectToHost(const char* hostIP, unsigned short port) const; - - /** + + /** * @brief An easy way to connect to 127.0.0.1 or ::1 based on m_addressFamily */ int ConnectToLocalHost(unsigned short port) const; /** - * @brief Bind underlying udp socket to an address. - * @param address, the server's address info. - * @param addressLength, length of address, structure of address can vary. - * @return 0 on success, -1 on error, check errno for detailed error information. - */ - int Bind(const sockaddr* address, size_t addressLength) const; - - /** - * @brief An easy way to bind to localhost - */ - int BindToLocalHost(unsigned short port) const; - - /** + * @brief Bind underlying udp socket to an address. + * @param address, the server's address info. + * @param addressLength, length of address, structure of address can vary. + * @return 0 on success, -1 on error, check errno for detailed error information. + */ + int Bind(const sockaddr* address, size_t addressLength) const; + + /** + * @brief An easy way to bind to localhost + */ + int BindToLocalHost(unsigned short port) const; + + /** * @brief Send data to server without specifying address, only usable if hostIP and port are available. - * @param data, the data you want to send. - * @param dataLen, the length of data you want to send. On Windows, dataLen larger than INT32_MAX will cause undefined behavior - * @return 0 on success, -1 on error, check errno for detailed error information. - */ - int SendData(const uint8_t* data, size_t dataLen) const; - - /** - * @brief Send data to server. - * @param address, the server's address info. - * @param addressLength, length of address, structure of address can vary. - * @param data, the memory address of the data you want to send. - * @param dataLen, the length of data you want to send. On Windows, dataLen larger than INT32_MAX will cause undefined behavior - * @return 0 on success, -1 on error check errno for detailed error information. - */ - int SendDataTo(const sockaddr* address, size_t addressLength, const uint8_t* data, size_t dataLen) const; - - /** - * @brief An easy way to send data to localhost, when the underlying udp is connected, call this function will - * send the data to where it connects to, not essentially to localhost. when it's not connected, it will send data - * to localhost, but this call will not connect underlying socket to localhost for you. - * @param data, the memory address of the data you want to send. - * @param dataLen, the length of data you want to send. On Windows, dataLen larger than INT32_MAX will cause undefined behavior - * @param port, port of localhost. - * @return 0 on success, -1 on error, check errno for detailed error information. - */ - int SendDataToLocalHost(const uint8_t* data, size_t dataLen, unsigned short port) const; - - /** - * @brief Receive data from unique address specified in ConnectWithServer call. - * this function is equivalent to call ReceiveDataFrom(nullptr, 0, data, dataLen, flags). - * @param buffer, the memory address where you want to store received data. - * @param bufferLen, the size of data buffer. - * @return -1 on failure, check errno for detailed error information, on success, returns the actual bytes of data received - */ - int ReceiveData(uint8_t* buffer, size_t bufferLen) const; - - /** - * @brief Receive data from network. - * @param address, if not null and underlying implementation supply the incoming data's source address, this will be filled with source address info. - * @param addressLength, the size of source adddress, should not be null. - * @param buffer, the memory address where you want to store received data. - * @param bufferLen, the size of data buffer. - * @return -1 on failure, check errno for detailed error information, on success, returns the actual bytes of data received. - */ - int ReceiveDataFrom(sockaddr* address, size_t* addressLength, uint8_t* buffer, size_t bufferLen) const; - - /** + * @param data, the data you want to send. + * @param dataLen, the length of data you want to send. On Windows, dataLen larger than INT32_MAX will cause undefined behavior + * @return 0 on success, -1 on error, check errno for detailed error information. + */ + int SendData(const uint8_t* data, size_t dataLen) const; + + /** + * @brief Send data to server. + * @param address, the server's address info. + * @param addressLength, length of address, structure of address can vary. + * @param data, the memory address of the data you want to send. + * @param dataLen, the length of data you want to send. On Windows, dataLen larger than INT32_MAX will cause undefined behavior + * @return 0 on success, -1 on error check errno for detailed error information. + */ + int SendDataTo(const sockaddr* address, size_t addressLength, const uint8_t* data, size_t dataLen) const; + + /** + * @brief An easy way to send data to localhost, when the underlying udp is connected, call this function will + * send the data to where it connects to, not essentially to localhost. when it's not connected, it will send data + * to localhost, but this call will not connect underlying socket to localhost for you. + * @param data, the memory address of the data you want to send. + * @param dataLen, the length of data you want to send. On Windows, dataLen larger than INT32_MAX will cause undefined behavior + * @param port, port of localhost. + * @return 0 on success, -1 on error, check errno for detailed error information. + */ + int SendDataToLocalHost(const uint8_t* data, size_t dataLen, unsigned short port) const; + + /** + * @brief Receive data from unique address specified in ConnectWithServer call. + * this function is equivalent to call ReceiveDataFrom(nullptr, 0, data, dataLen, flags). + * @param buffer, the memory address where you want to store received data. + * @param bufferLen, the size of data buffer. + * @return -1 on failure, check errno for detailed error information, on success, returns the actual bytes of data received + */ + int ReceiveData(uint8_t* buffer, size_t bufferLen) const; + + /** + * @brief Receive data from network. + * @param address, if not null and underlying implementation supply the incoming data's source address, this will be filled with source address info. + * @param addressLength, the size of source adddress, should not be null. + * @param buffer, the memory address where you want to store received data. + * @param bufferLen, the size of data buffer. + * @return -1 on failure, check errno for detailed error information, on success, returns the actual bytes of data received. + */ + int ReceiveDataFrom(sockaddr* address, size_t* addressLength, uint8_t* buffer, size_t bufferLen) const; + + /** * Gets the AddressFamily used for the underlying socket. E.g. AF_INET, AF_INET6 etc. - */ - inline int GetAddressFamily() const { return m_addressFamily; } - - /** - * Is the underlying socket connected with a remote address - */ - inline bool IsConnected() const { return m_connected; } - - private: - void CreateSocket(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking); - int GetUnderlyingSocket() const { return m_socket; } - void SetUnderlyingSocket(int socket) { m_socket = socket; } - int m_addressFamily; - // if not connected, you can't perform SendData, if connected, SendDataTo will call SendData + */ + inline int GetAddressFamily() const { return m_addressFamily; } + + /** + * Is the underlying socket connected with a remote address + */ + inline bool IsConnected() const { return m_connected; } + + private: + void CreateSocket(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking); + int GetUnderlyingSocket() const { return m_socket; } + void SetUnderlyingSocket(int socket) { m_socket = socket; } + int m_addressFamily; + // if not connected, you can't perform SendData, if connected, SendDataTo will call SendData mutable bool m_connected; - int m_socket; + int m_socket; unsigned short m_port; Aws::String m_hostIP; - }; - } -} + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Android.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Android.h index b012a49d50..7ff3c072ff 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Android.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Android.h @@ -2,28 +2,28 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#ifdef __ANDROID__ - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> - -#include <jni.h> - -namespace Aws -{ -namespace Platform -{ - -// must be called before any other native SDK functions when running on Android -AWS_CORE_API void InitAndroid(JNIEnv* env, jobject context); - -// helper functions for functionality requiring JNI calls; not valid until InitAndroid has been called -AWS_CORE_API JavaVM* GetJavaVM(); -AWS_CORE_API const char* GetCacheDirectory(); - -} //namespace Platform -} //namespace Aws - -#endif // __ANDROID__ + +#ifdef __ANDROID__ + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> + +#include <jni.h> + +namespace Aws +{ +namespace Platform +{ + +// must be called before any other native SDK functions when running on Android +AWS_CORE_API void InitAndroid(JNIEnv* env, jobject context); + +// helper functions for functionality requiring JNI calls; not valid until InitAndroid has been called +AWS_CORE_API JavaVM* GetJavaVM(); +AWS_CORE_API const char* GetCacheDirectory(); + +} //namespace Platform +} //namespace Aws + +#endif // __ANDROID__ diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Environment.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Environment.h index f522bf3a22..095f8ed8fc 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Environment.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Environment.h @@ -2,21 +2,21 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ -namespace Environment -{ - /** - * shim for getenv - */ - AWS_CORE_API Aws::String GetEnv(const char* name); - -} // namespace Environment -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ +namespace Environment +{ + /** + * shim for getenv + */ + AWS_CORE_API Aws::String GetEnv(const char* name); + +} // namespace Environment +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/FileSystem.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/FileSystem.h index 5eeacd2fbd..ad17749f22 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/FileSystem.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/FileSystem.h @@ -2,225 +2,225 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <functional> - -namespace Aws -{ - -namespace FileSystem -{ - struct DirectoryEntry; - class Directory; - - #ifdef _WIN32 - static const char PATH_DELIM = '\\'; - #else - static const char PATH_DELIM = '/'; - #endif - - /** - * Returns the directory path for the home dir env variable - */ - AWS_CORE_API Aws::String GetHomeDirectory(); - - /** - * Returns the directory path for the directory containing the currently running executable - */ - AWS_CORE_API Aws::String GetExecutableDirectory(); - - /** - * @brief Creates directory if it doesn't exist. Returns true if the directory was created or already exists. False for failure. - * @param path, the absolute path of the directory. - * @param createParentDirs, if true, then this function will create missing directories on the path like linux command: mkdir -p - */ - AWS_CORE_API bool CreateDirectoryIfNotExists(const char* path, bool createParentDirs = false); - - /** - * Creates directory if it doesn't exist. Returns true if the directory was created - * or already exists. False for failure. - */ - AWS_CORE_API bool RemoveDirectoryIfExists(const char* path); - - /** - * Deletes file if it exists. Returns true if file doesn't exist or on success. - */ - AWS_CORE_API bool RemoveFileIfExists(const char* fileName); - - /** - * Moves the file. Returns true on success - */ - AWS_CORE_API bool RelocateFileOrDirectory(const char* from, const char* to); - - /** - * Copies a directory and all of its contents. - */ - AWS_CORE_API bool DeepCopyDirectory(const char* from, const char* to); - - /** - * Deletes a directory and all of its contents. - */ - AWS_CORE_API bool DeepDeleteDirectory(const char* toDelete); - - /** - * Computes a unique tmp file path - */ - AWS_CORE_API Aws::String CreateTempFilePath(); - - /** - * Opens a directory for traversal. - */ - AWS_CORE_API Aws::UniquePtr<Directory> OpenDirectory(const Aws::String& path, const Aws::String& relativePath = ""); - - /** - * Joins the leftSegment and rightSegment of a path together using platform specific delimiter. - * e.g. C:\users\name\ and .aws becomes C:\users\name\.aws - */ - AWS_CORE_API Aws::String Join(const Aws::String& leftSegment, const Aws::String& rightSegment); - - /** - * Joins the leftSegment and rightSegment of a path together using the specified delimiter. - * e.g. with delimiter & C:\users\name\ and .aws becomes C:\users\name&.aws - */ - AWS_CORE_API Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment); - - /** - * Type of directory entry encountered. - */ - enum class FileType - { - None, - File, - Symlink, - Directory - }; - - struct DirectoryEntry - { - DirectoryEntry() : fileType(FileType::None), fileSize(0) {} - - operator bool() const { return !path.empty() && fileType != FileType::None; } - - Aws::String path; - Aws::String relativePath; - FileType fileType; - int64_t fileSize; - }; - - /** - * Base level representation of a directory. Provides the ability to iterate all entries in a directory and to descend into directories. - * We don't recommend you use this class directly. Instead see DirectoryTree. - */ - class AWS_CORE_API Directory - { - public: - virtual ~Directory() = default; - - /** - * Initialize a directory with it's absolute path. If the path is invalid, the bool operator will return false. - */ - Directory(const Aws::String& path, const Aws::String& relativePath); - - /** - * If this directory is valid for use. - */ - virtual operator bool() const { return m_directoryEntry.operator bool(); } - - /** - * Get the entry representing this current directory object. - */ - const DirectoryEntry& GetDirectoryEntry() const { return m_directoryEntry; } - - /** - * Get the current path of this directory object. - */ - const Aws::String& GetPath() const { return m_directoryEntry.path; } - - /** - * Get the next entry inside this directory. - */ - virtual DirectoryEntry Next() = 0; - - /** - * Descend into a directory if it is a directory. Returns a shared pointer to a Directory object which you can then call Next() and Descend on. - * The original Directory object you use is responsible for the memory this method allocates, so do not attempt to delete the return value. - */ - Aws::UniquePtr<Directory> Descend(const DirectoryEntry& directoryEntry); - - /** - * Recursively search directories with path as root directory, return all normal(non directory and non symlink) files' paths. - */ - static Aws::Vector<Aws::String> GetAllFilePathsInDirectory(const Aws::String& path); - - protected: - DirectoryEntry m_directoryEntry; - }; - - class DirectoryTree; - - /** - * Visitor for a Directory Tree traversal. Return true to continue the traversal, false to exit the traversal immediately. - */ - typedef std::function<bool(const DirectoryTree*, const DirectoryEntry&)> DirectoryEntryVisitor; - - /** - * Wrapper around directory. Currently provides a Depth-first and Breadth-first traversal of the provided path. This is most likely the class you are - * looking for. - */ - class AWS_CORE_API DirectoryTree - { - public: - /** - * Create a directory object for use with traversal using the provided path. - */ - DirectoryTree(const Aws::String& path); - - /** - * Returns true if the Directory Tree structures match. Otherwise false. - */ - bool operator==(DirectoryTree& other); - - /** - * Returns true if the Directory tree structure at path matches. Otherwise false. - */ - bool operator==(const Aws::String& path); - - /** - * Computes the difference between two directory trees based on their relative paths. - * File contents are not taken into account, only the tree structure. - * - * Returns the diff between the two trees where the key is the relative path. The Directory entry will - * contain the absolute path and file size. - */ - Aws::Map<Aws::String, DirectoryEntry> Diff(DirectoryTree& other); - - /** - * If the object is valid for use: true. Otherwise: false. - */ - operator bool() const; - - /** - * Performs a depth-first traversal of the directory tree. Upon encountering an entry, visitor will be invoked. - * If postOrder is true, a pre-order traversal will be used. otherwise pre-order will be used. - */ - void TraverseDepthFirst(const DirectoryEntryVisitor& visitor, bool postOrderTraversal = false); - - /** - * Performs a breadth-first traversal of the directory tree. Upon encountering an entry, visitor will be invoked. - */ - void TraverseBreadthFirst(const DirectoryEntryVisitor& visitor); - - private: - bool TraverseDepthFirst(Directory& dir, const DirectoryEntryVisitor& visitor, bool postOrder = false); - void TraverseBreadthFirst(Directory& dir, const DirectoryEntryVisitor& visitor); - - Aws::UniquePtr<Directory> m_dir; - }; - -} // namespace FileSystem -} // namespace Aws +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <functional> + +namespace Aws +{ + +namespace FileSystem +{ + struct DirectoryEntry; + class Directory; + + #ifdef _WIN32 + static const char PATH_DELIM = '\\'; + #else + static const char PATH_DELIM = '/'; + #endif + + /** + * Returns the directory path for the home dir env variable + */ + AWS_CORE_API Aws::String GetHomeDirectory(); + + /** + * Returns the directory path for the directory containing the currently running executable + */ + AWS_CORE_API Aws::String GetExecutableDirectory(); + + /** + * @brief Creates directory if it doesn't exist. Returns true if the directory was created or already exists. False for failure. + * @param path, the absolute path of the directory. + * @param createParentDirs, if true, then this function will create missing directories on the path like linux command: mkdir -p + */ + AWS_CORE_API bool CreateDirectoryIfNotExists(const char* path, bool createParentDirs = false); + + /** + * Creates directory if it doesn't exist. Returns true if the directory was created + * or already exists. False for failure. + */ + AWS_CORE_API bool RemoveDirectoryIfExists(const char* path); + + /** + * Deletes file if it exists. Returns true if file doesn't exist or on success. + */ + AWS_CORE_API bool RemoveFileIfExists(const char* fileName); + + /** + * Moves the file. Returns true on success + */ + AWS_CORE_API bool RelocateFileOrDirectory(const char* from, const char* to); + + /** + * Copies a directory and all of its contents. + */ + AWS_CORE_API bool DeepCopyDirectory(const char* from, const char* to); + + /** + * Deletes a directory and all of its contents. + */ + AWS_CORE_API bool DeepDeleteDirectory(const char* toDelete); + + /** + * Computes a unique tmp file path + */ + AWS_CORE_API Aws::String CreateTempFilePath(); + + /** + * Opens a directory for traversal. + */ + AWS_CORE_API Aws::UniquePtr<Directory> OpenDirectory(const Aws::String& path, const Aws::String& relativePath = ""); + + /** + * Joins the leftSegment and rightSegment of a path together using platform specific delimiter. + * e.g. C:\users\name\ and .aws becomes C:\users\name\.aws + */ + AWS_CORE_API Aws::String Join(const Aws::String& leftSegment, const Aws::String& rightSegment); + + /** + * Joins the leftSegment and rightSegment of a path together using the specified delimiter. + * e.g. with delimiter & C:\users\name\ and .aws becomes C:\users\name&.aws + */ + AWS_CORE_API Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment); + + /** + * Type of directory entry encountered. + */ + enum class FileType + { + None, + File, + Symlink, + Directory + }; + + struct DirectoryEntry + { + DirectoryEntry() : fileType(FileType::None), fileSize(0) {} + + operator bool() const { return !path.empty() && fileType != FileType::None; } + + Aws::String path; + Aws::String relativePath; + FileType fileType; + int64_t fileSize; + }; + + /** + * Base level representation of a directory. Provides the ability to iterate all entries in a directory and to descend into directories. + * We don't recommend you use this class directly. Instead see DirectoryTree. + */ + class AWS_CORE_API Directory + { + public: + virtual ~Directory() = default; + + /** + * Initialize a directory with it's absolute path. If the path is invalid, the bool operator will return false. + */ + Directory(const Aws::String& path, const Aws::String& relativePath); + + /** + * If this directory is valid for use. + */ + virtual operator bool() const { return m_directoryEntry.operator bool(); } + + /** + * Get the entry representing this current directory object. + */ + const DirectoryEntry& GetDirectoryEntry() const { return m_directoryEntry; } + + /** + * Get the current path of this directory object. + */ + const Aws::String& GetPath() const { return m_directoryEntry.path; } + + /** + * Get the next entry inside this directory. + */ + virtual DirectoryEntry Next() = 0; + + /** + * Descend into a directory if it is a directory. Returns a shared pointer to a Directory object which you can then call Next() and Descend on. + * The original Directory object you use is responsible for the memory this method allocates, so do not attempt to delete the return value. + */ + Aws::UniquePtr<Directory> Descend(const DirectoryEntry& directoryEntry); + + /** + * Recursively search directories with path as root directory, return all normal(non directory and non symlink) files' paths. + */ + static Aws::Vector<Aws::String> GetAllFilePathsInDirectory(const Aws::String& path); + + protected: + DirectoryEntry m_directoryEntry; + }; + + class DirectoryTree; + + /** + * Visitor for a Directory Tree traversal. Return true to continue the traversal, false to exit the traversal immediately. + */ + typedef std::function<bool(const DirectoryTree*, const DirectoryEntry&)> DirectoryEntryVisitor; + + /** + * Wrapper around directory. Currently provides a Depth-first and Breadth-first traversal of the provided path. This is most likely the class you are + * looking for. + */ + class AWS_CORE_API DirectoryTree + { + public: + /** + * Create a directory object for use with traversal using the provided path. + */ + DirectoryTree(const Aws::String& path); + + /** + * Returns true if the Directory Tree structures match. Otherwise false. + */ + bool operator==(DirectoryTree& other); + + /** + * Returns true if the Directory tree structure at path matches. Otherwise false. + */ + bool operator==(const Aws::String& path); + + /** + * Computes the difference between two directory trees based on their relative paths. + * File contents are not taken into account, only the tree structure. + * + * Returns the diff between the two trees where the key is the relative path. The Directory entry will + * contain the absolute path and file size. + */ + Aws::Map<Aws::String, DirectoryEntry> Diff(DirectoryTree& other); + + /** + * If the object is valid for use: true. Otherwise: false. + */ + operator bool() const; + + /** + * Performs a depth-first traversal of the directory tree. Upon encountering an entry, visitor will be invoked. + * If postOrder is true, a pre-order traversal will be used. otherwise pre-order will be used. + */ + void TraverseDepthFirst(const DirectoryEntryVisitor& visitor, bool postOrderTraversal = false); + + /** + * Performs a breadth-first traversal of the directory tree. Upon encountering an entry, visitor will be invoked. + */ + void TraverseBreadthFirst(const DirectoryEntryVisitor& visitor); + + private: + bool TraverseDepthFirst(Directory& dir, const DirectoryEntryVisitor& visitor, bool postOrder = false); + void TraverseBreadthFirst(Directory& dir, const DirectoryEntryVisitor& visitor); + + Aws::UniquePtr<Directory> m_dir; + }; + +} // namespace FileSystem +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/OSVersionInfo.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/OSVersionInfo.h index e9aa3ea1f0..785d909cb6 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/OSVersionInfo.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/OSVersionInfo.h @@ -2,26 +2,26 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ -namespace OSVersionInfo -{ - /** - * computing the version string for the current running operating system. - */ - AWS_CORE_API Aws::String ComputeOSVersionString(); - - /** - * runs a (shell) command string and returns the output; not needed on windows currently - */ - AWS_CORE_API Aws::String GetSysCommandOutput(const char* command); - -} // namespace OSVersionInfo -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ +namespace OSVersionInfo +{ + /** + * computing the version string for the current running operating system. + */ + AWS_CORE_API Aws::String ComputeOSVersionString(); + + /** + * runs a (shell) command string and returns the output; not needed on windows currently + */ + AWS_CORE_API Aws::String GetSysCommandOutput(const char* command); + +} // namespace OSVersionInfo +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Platform.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Platform.h index e1cae5262e..a3e4aae7b3 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Platform.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Platform.h @@ -2,8 +2,8 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/platform/Android.h> - + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/platform/Android.h> + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Security.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Security.h index d1533dd19f..edcd43f96a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Security.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Security.h @@ -2,23 +2,23 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <stddef.h> - -namespace Aws -{ -namespace Security -{ - - /* - * Securely clears a block of memory - */ - AWS_CORE_API void SecureMemClear(unsigned char *data, size_t length); - -} // namespace Security -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <stddef.h> + +namespace Aws +{ +namespace Security +{ + + /* + * Securely clears a block of memory + */ + AWS_CORE_API void SecureMemClear(unsigned char *data, size_t length); + +} // namespace Security +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Time.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Time.h index ecf802db66..17bd557cbe 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Time.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/platform/Time.h @@ -2,31 +2,31 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <ctime> - -namespace Aws -{ -namespace Time -{ - - /* - * A platform-agnostic implementation of the timegm function from gnu extensions - */ - AWS_CORE_API time_t TimeGM(tm* const t); - - /* - * Converts from a time value of std::time_t type to a C tm structure for easier date analysis - */ - AWS_CORE_API void LocalTime(tm* t, std::time_t time); - - /* - * Converts from a time value of std::time_t type to a C tm structure for easier date analysis - */ - AWS_CORE_API void GMTime(tm* t, std::time_t time); - -} // namespace Time -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <ctime> + +namespace Aws +{ +namespace Time +{ + + /* + * A platform-agnostic implementation of the timegm function from gnu extensions + */ + AWS_CORE_API time_t TimeGM(tm* const t); + + /* + * Converts from a time value of std::time_t type to a C tm structure for easier date analysis + */ + AWS_CORE_API void LocalTime(tm* t, std::time_t time); + + /* + * Converts from a time value of std::time_t type to a C tm structure for easier date analysis + */ + AWS_CORE_API void GMTime(tm* t, std::time_t time); + +} // namespace Time +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Array.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Array.h index 2b5bbc566d..5982831a94 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Array.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Array.h @@ -2,249 +2,249 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <memory> -#include <cassert> -#include <cstring> -#include <algorithm> - -#ifdef _WIN32 - -#include <iterator> - -#endif // _WIN32 - -namespace Aws -{ - namespace Utils - { - static const char* ARRAY_ALLOCATION_TAG = "Aws::Array"; - - /** - * Safe array class with move and copy semantics. - */ - template<typename T> - class Array - { - - public: - /** - * Create new empty array of size arraySize. Default argument is 0. If it is empty then no allocation happens. - */ - Array(size_t arraySize = 0) : - m_size(arraySize), - m_data(arraySize > 0 ? Aws::MakeUniqueArray<T>(arraySize, ARRAY_ALLOCATION_TAG) : nullptr) - { - } - - /** - * Create new array and initialize it to a raw array - */ - Array(const T* arrayToCopy, size_t arraySize) : - m_size(arraySize), - m_data(nullptr) - { - if (arrayToCopy != nullptr && m_size > 0) - { - m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); - -#ifdef _WIN32 - std::copy(arrayToCopy, arrayToCopy + arraySize, stdext::checked_array_iterator< T * >(m_data.get(), m_size)); -#else - std::copy(arrayToCopy, arrayToCopy + arraySize, m_data.get()); -#endif // MSVC - } - } - - /** - * Merge multiple arrays into one - */ - Array(Aws::Vector<Array*>&& toMerge) - { - size_t totalSize = 0; - for(auto& array : toMerge) - { - totalSize += array->m_size; - } - - m_size = totalSize; - m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); - - size_t location = 0; - for(auto& arr : toMerge) - { - if(arr->m_size > 0 && arr->m_data) - { - size_t arraySize = arr->m_size; -#ifdef _WIN32 - std::copy(arr->m_data.get(), arr->m_data.get() + arraySize, stdext::checked_array_iterator< T * >(m_data.get() + location, m_size)); -#else - std::copy(arr->m_data.get(), arr->m_data.get() + arraySize, m_data.get() + location); -#endif // MSVC - location += arraySize; - } - } - } - - Array(const Array& other) - { - m_size = other.m_size; - m_data = nullptr; - - if (m_size > 0) - { - m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); - -#ifdef _WIN32 - std::copy(other.m_data.get(), other.m_data.get() + other.m_size, stdext::checked_array_iterator< T * >(m_data.get(), m_size)); -#else - std::copy(other.m_data.get(), other.m_data.get() + other.m_size, m_data.get()); -#endif // MSVC - } - } - - //move c_tor - Array(Array&& other) : - m_size(other.m_size), - m_data(std::move(other.m_data)) - { - other.m_size = 0; - other.m_data = nullptr; - } - - virtual ~Array() = default; - - Array& operator=(const Array& other) - { - if (this == &other) - { - return *this; - } - - m_size = other.m_size; - m_data = nullptr; - - if (m_size > 0) - { - m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); - -#ifdef _WIN32 - std::copy(other.m_data.get(), other.m_data.get() + other.m_size, stdext::checked_array_iterator< T * >(m_data.get(), m_size)); -#else - std::copy(other.m_data.get(), other.m_data.get() + other.m_size, m_data.get()); -#endif // MSVC - } - - return *this; - } - - Array& operator=(Array&& other) - { - m_size = other.m_size; - m_data = std::move(other.m_data); - - return *this; - } - - bool operator==(const Array& other) const - { - if (this == &other) - return true; - - if (m_size == 0 && other.m_size == 0) - { - return true; - } - - if (m_size == other.m_size && m_data && other.m_data) - { - for (unsigned i = 0; i < m_size; ++i) - { - if (m_data.get()[i] != other.m_data.get()[i]) - return false; - } - - return true; - } - - return false; - } - - bool operator!=(const Array& other) const - { - return !(*this == other); - } - - T const& GetItem(size_t index) const - { - assert(index < m_size); - return m_data.get()[index]; - } - - T& GetItem(size_t index) - { - assert(index < m_size); - return m_data.get()[index]; - } - - T& operator[](size_t index) - { - return GetItem(index); - } - - T const& operator[](size_t index) const - { - return GetItem(index); - } - - inline size_t GetLength() const - { - return m_size; - } - - inline T* GetUnderlyingData() const - { - return m_data.get(); - } - - protected: - size_t m_size; - - Aws::UniqueArrayPtr<T> m_data; - }; - - typedef Array<unsigned char> ByteBuffer; - - /** - * Buffer for cryptographic operations. It zeroes itself back out upon deletion. Everything else is identical - * to byte buffer. - */ - class AWS_CORE_API CryptoBuffer : public ByteBuffer - { - public: - CryptoBuffer(size_t arraySize = 0) : ByteBuffer(arraySize) {} - CryptoBuffer(const unsigned char* arrayToCopy, size_t arraySize) : ByteBuffer(arrayToCopy, arraySize) {} - CryptoBuffer(Aws::Vector<ByteBuffer*>&& toMerge) : ByteBuffer(std::move(toMerge)) {} - CryptoBuffer(const ByteBuffer& other) : ByteBuffer(other) {} - CryptoBuffer(const CryptoBuffer& other) : ByteBuffer(other) {} - CryptoBuffer(CryptoBuffer&& other) : ByteBuffer(std::move(other)) {} - CryptoBuffer& operator=(const CryptoBuffer&) = default; - CryptoBuffer& operator=(CryptoBuffer&& other) { ByteBuffer::operator=(std::move(other)); return *this; } - bool operator==(const CryptoBuffer& other) const { return ByteBuffer::operator==(other); } - bool operator!=(const CryptoBuffer& other) const { return ByteBuffer::operator!=(other); } - - ~CryptoBuffer() { Zero(); } - - Array<CryptoBuffer> Slice(size_t sizeOfSlice) const; - CryptoBuffer& operator^(const CryptoBuffer& operand); - void Zero(); - }; - - } // namespace Utils -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <memory> +#include <cassert> +#include <cstring> +#include <algorithm> + +#ifdef _WIN32 + +#include <iterator> + +#endif // _WIN32 + +namespace Aws +{ + namespace Utils + { + static const char* ARRAY_ALLOCATION_TAG = "Aws::Array"; + + /** + * Safe array class with move and copy semantics. + */ + template<typename T> + class Array + { + + public: + /** + * Create new empty array of size arraySize. Default argument is 0. If it is empty then no allocation happens. + */ + Array(size_t arraySize = 0) : + m_size(arraySize), + m_data(arraySize > 0 ? Aws::MakeUniqueArray<T>(arraySize, ARRAY_ALLOCATION_TAG) : nullptr) + { + } + + /** + * Create new array and initialize it to a raw array + */ + Array(const T* arrayToCopy, size_t arraySize) : + m_size(arraySize), + m_data(nullptr) + { + if (arrayToCopy != nullptr && m_size > 0) + { + m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); + +#ifdef _WIN32 + std::copy(arrayToCopy, arrayToCopy + arraySize, stdext::checked_array_iterator< T * >(m_data.get(), m_size)); +#else + std::copy(arrayToCopy, arrayToCopy + arraySize, m_data.get()); +#endif // MSVC + } + } + + /** + * Merge multiple arrays into one + */ + Array(Aws::Vector<Array*>&& toMerge) + { + size_t totalSize = 0; + for(auto& array : toMerge) + { + totalSize += array->m_size; + } + + m_size = totalSize; + m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); + + size_t location = 0; + for(auto& arr : toMerge) + { + if(arr->m_size > 0 && arr->m_data) + { + size_t arraySize = arr->m_size; +#ifdef _WIN32 + std::copy(arr->m_data.get(), arr->m_data.get() + arraySize, stdext::checked_array_iterator< T * >(m_data.get() + location, m_size)); +#else + std::copy(arr->m_data.get(), arr->m_data.get() + arraySize, m_data.get() + location); +#endif // MSVC + location += arraySize; + } + } + } + + Array(const Array& other) + { + m_size = other.m_size; + m_data = nullptr; + + if (m_size > 0) + { + m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); + +#ifdef _WIN32 + std::copy(other.m_data.get(), other.m_data.get() + other.m_size, stdext::checked_array_iterator< T * >(m_data.get(), m_size)); +#else + std::copy(other.m_data.get(), other.m_data.get() + other.m_size, m_data.get()); +#endif // MSVC + } + } + + //move c_tor + Array(Array&& other) : + m_size(other.m_size), + m_data(std::move(other.m_data)) + { + other.m_size = 0; + other.m_data = nullptr; + } + + virtual ~Array() = default; + + Array& operator=(const Array& other) + { + if (this == &other) + { + return *this; + } + + m_size = other.m_size; + m_data = nullptr; + + if (m_size > 0) + { + m_data.reset(Aws::NewArray<T>(m_size, ARRAY_ALLOCATION_TAG)); + +#ifdef _WIN32 + std::copy(other.m_data.get(), other.m_data.get() + other.m_size, stdext::checked_array_iterator< T * >(m_data.get(), m_size)); +#else + std::copy(other.m_data.get(), other.m_data.get() + other.m_size, m_data.get()); +#endif // MSVC + } + + return *this; + } + + Array& operator=(Array&& other) + { + m_size = other.m_size; + m_data = std::move(other.m_data); + + return *this; + } + + bool operator==(const Array& other) const + { + if (this == &other) + return true; + + if (m_size == 0 && other.m_size == 0) + { + return true; + } + + if (m_size == other.m_size && m_data && other.m_data) + { + for (unsigned i = 0; i < m_size; ++i) + { + if (m_data.get()[i] != other.m_data.get()[i]) + return false; + } + + return true; + } + + return false; + } + + bool operator!=(const Array& other) const + { + return !(*this == other); + } + + T const& GetItem(size_t index) const + { + assert(index < m_size); + return m_data.get()[index]; + } + + T& GetItem(size_t index) + { + assert(index < m_size); + return m_data.get()[index]; + } + + T& operator[](size_t index) + { + return GetItem(index); + } + + T const& operator[](size_t index) const + { + return GetItem(index); + } + + inline size_t GetLength() const + { + return m_size; + } + + inline T* GetUnderlyingData() const + { + return m_data.get(); + } + + protected: + size_t m_size; + + Aws::UniqueArrayPtr<T> m_data; + }; + + typedef Array<unsigned char> ByteBuffer; + + /** + * Buffer for cryptographic operations. It zeroes itself back out upon deletion. Everything else is identical + * to byte buffer. + */ + class AWS_CORE_API CryptoBuffer : public ByteBuffer + { + public: + CryptoBuffer(size_t arraySize = 0) : ByteBuffer(arraySize) {} + CryptoBuffer(const unsigned char* arrayToCopy, size_t arraySize) : ByteBuffer(arrayToCopy, arraySize) {} + CryptoBuffer(Aws::Vector<ByteBuffer*>&& toMerge) : ByteBuffer(std::move(toMerge)) {} + CryptoBuffer(const ByteBuffer& other) : ByteBuffer(other) {} + CryptoBuffer(const CryptoBuffer& other) : ByteBuffer(other) {} + CryptoBuffer(CryptoBuffer&& other) : ByteBuffer(std::move(other)) {} + CryptoBuffer& operator=(const CryptoBuffer&) = default; + CryptoBuffer& operator=(CryptoBuffer&& other) { ByteBuffer::operator=(std::move(other)); return *this; } + bool operator==(const CryptoBuffer& other) const { return ByteBuffer::operator==(other); } + bool operator!=(const CryptoBuffer& other) const { return ByteBuffer::operator!=(other); } + + ~CryptoBuffer() { Zero(); } + + Array<CryptoBuffer> Slice(size_t sizeOfSlice) const; + CryptoBuffer& operator^(const CryptoBuffer& operand); + void Zero(); + }; + + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DNS.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DNS.h index 7472a386c0..efca36bbff 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DNS.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DNS.h @@ -2,17 +2,17 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Utils - { - AWS_CORE_API bool IsValidDnsLabel(const Aws::String& label); + +#pragma once + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Utils + { + AWS_CORE_API bool IsValidDnsLabel(const Aws::String& label); AWS_CORE_API bool IsValidHost(const Aws::String& host); - } -} + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h index a410279011..7235193ca8 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/DateTime.h @@ -2,249 +2,249 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <chrono> - -namespace Aws -{ - namespace Utils - { - enum class DateFormat - { - RFC822, //for http headers - ISO_8601, //for query and xml payloads + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <chrono> + +namespace Aws +{ + namespace Utils + { + enum class DateFormat + { + RFC822, //for http headers + ISO_8601, //for query and xml payloads ISO_8601_BASIC, // for retry headers and signers - AutoDetect - }; - - enum class Month - { - January = 0, - February, - March, - April, - May, - June, - July, - August, - September, - October, - November, - December - }; - - enum class DayOfWeek - { - Sunday = 0, - Monday, - Tuesday, - Wednesday, - Thursday, - Friday, - Saturday - }; - - /** + AutoDetect + }; + + enum class Month + { + January = 0, + February, + March, + April, + May, + June, + July, + August, + September, + October, + November, + December + }; + + enum class DayOfWeek + { + Sunday = 0, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday + }; + + /** * Wrapper for all the weird crap we need to do with timestamps. - */ - class AWS_CORE_API DateTime - { - public: - /** - * Initializes time point to epoch - */ - DateTime(); - - /** + */ + class AWS_CORE_API DateTime + { + public: + /** + * Initializes time point to epoch + */ + DateTime(); + + /** * Initializes time point to any other arbitrary timepoint - */ - DateTime(const std::chrono::system_clock::time_point& timepointToAssign); - - /** + */ + DateTime(const std::chrono::system_clock::time_point& timepointToAssign); + + /** * Initializes time point to millis Since epoch - */ - DateTime(int64_t millisSinceEpoch); - - /** - * Initializes time point to epoch time in seconds.millis - */ - DateTime(double epoch_millis); - - /** - * Initializes time point to value represented by timestamp and format. - */ - DateTime(const Aws::String& timestamp, DateFormat format); - - /** - * Initializes time point to value represented by timestamp and format. - */ - DateTime(const char* timestamp, DateFormat format); - - bool operator == (const DateTime& other) const; - bool operator < (const DateTime& other) const; - bool operator > (const DateTime& other) const; - bool operator != (const DateTime& other) const; - bool operator <= (const DateTime& other) const; - bool operator >= (const DateTime& other) const; - - DateTime operator+(const std::chrono::milliseconds& a) const; - DateTime operator-(const std::chrono::milliseconds& a) const; - - /** - * Assign from seconds.millis since epoch. - */ - DateTime& operator=(double secondsSinceEpoch); - - /** - * Assign from millis since epoch. - */ - DateTime& operator=(int64_t millisSinceEpoch); - - /** - * Assign from another time_point - */ - DateTime& operator=(const std::chrono::system_clock::time_point& timepointToAssign); - - /** - * Assign from an ISO8601 or RFC822 formatted string - */ - DateTime& operator=(const Aws::String& timestamp); - - /** - * Whether or not parsing the timestamp from string was successful. - */ - inline bool WasParseSuccessful() const { return m_valid; } - - /** - * Convert dateTime to local time string using predefined format. - */ - Aws::String ToLocalTimeString(DateFormat format) const; - - /** - * Convert dateTime to local time string using arbitrary format. - */ - Aws::String ToLocalTimeString(const char* formatStr) const; - - /** - * Convert dateTime to GMT time string using predefined format. - */ - Aws::String ToGmtString(DateFormat format) const; - - /** - * Convert dateTime to GMT time string using arbitrary format. - */ - Aws::String ToGmtString(const char* formatStr) const; - - /** - * Get the representation of this datetime as seconds.milliseconds since epoch - */ - double SecondsWithMSPrecision() const; - - /** - * Milliseconds since epoch of this datetime. - */ - int64_t Millis() const; - - /** - * In the likely case this class doesn't do everything you need to do, here's a copy of the time_point structure. Have fun. - */ - std::chrono::system_clock::time_point UnderlyingTimestamp() const; - - /** - * Get the Year portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - int GetYear(bool localTime = false) const; - - /** - * Get the Month portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - Month GetMonth(bool localTime = false) const; - - /** - * Get the Day of the Month portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - int GetDay(bool localTime = false) const; - - /** - * Get the Day of the Week portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - DayOfWeek GetDayOfWeek(bool localTime = false) const; - - /** - * Get the Hour portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - int GetHour(bool localTime = false) const; - - /** - * Get the Minute portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - int GetMinute(bool localTime = false) const; - - /** - * Get the Second portion of this dateTime. localTime if true, return local time, otherwise return UTC - */ - int GetSecond(bool localTime = false) const; - - /** - * Get whether or not this dateTime is in Daylight savings time. localTime if true, return local time, otherwise return UTC - */ - bool IsDST(bool localTime = false) const; - - /** - * Get an instance of DateTime representing this very instant. - */ - static DateTime Now(); - - /** - * Get the millis since epoch representing this very instant. - */ - static int64_t CurrentTimeMillis(); - - /** - * Calculates the current local timestamp, formats it and returns it as a string - */ - static Aws::String CalculateLocalTimestampAsString(const char* formatStr); - - /** - * Calculates the current gmt timestamp, formats it, and returns it as a string - */ - static Aws::String CalculateGmtTimestampAsString(const char* formatStr); - - /** - * Calculates the current hour of the day in localtime. - */ - static int CalculateCurrentHour(); - - /** - * The amazon timestamp format is a double with seconds.milliseconds - */ - static double ComputeCurrentTimestampInAmazonFormat(); - - /** + */ + DateTime(int64_t millisSinceEpoch); + + /** + * Initializes time point to epoch time in seconds.millis + */ + DateTime(double epoch_millis); + + /** + * Initializes time point to value represented by timestamp and format. + */ + DateTime(const Aws::String& timestamp, DateFormat format); + + /** + * Initializes time point to value represented by timestamp and format. + */ + DateTime(const char* timestamp, DateFormat format); + + bool operator == (const DateTime& other) const; + bool operator < (const DateTime& other) const; + bool operator > (const DateTime& other) const; + bool operator != (const DateTime& other) const; + bool operator <= (const DateTime& other) const; + bool operator >= (const DateTime& other) const; + + DateTime operator+(const std::chrono::milliseconds& a) const; + DateTime operator-(const std::chrono::milliseconds& a) const; + + /** + * Assign from seconds.millis since epoch. + */ + DateTime& operator=(double secondsSinceEpoch); + + /** + * Assign from millis since epoch. + */ + DateTime& operator=(int64_t millisSinceEpoch); + + /** + * Assign from another time_point + */ + DateTime& operator=(const std::chrono::system_clock::time_point& timepointToAssign); + + /** + * Assign from an ISO8601 or RFC822 formatted string + */ + DateTime& operator=(const Aws::String& timestamp); + + /** + * Whether or not parsing the timestamp from string was successful. + */ + inline bool WasParseSuccessful() const { return m_valid; } + + /** + * Convert dateTime to local time string using predefined format. + */ + Aws::String ToLocalTimeString(DateFormat format) const; + + /** + * Convert dateTime to local time string using arbitrary format. + */ + Aws::String ToLocalTimeString(const char* formatStr) const; + + /** + * Convert dateTime to GMT time string using predefined format. + */ + Aws::String ToGmtString(DateFormat format) const; + + /** + * Convert dateTime to GMT time string using arbitrary format. + */ + Aws::String ToGmtString(const char* formatStr) const; + + /** + * Get the representation of this datetime as seconds.milliseconds since epoch + */ + double SecondsWithMSPrecision() const; + + /** + * Milliseconds since epoch of this datetime. + */ + int64_t Millis() const; + + /** + * In the likely case this class doesn't do everything you need to do, here's a copy of the time_point structure. Have fun. + */ + std::chrono::system_clock::time_point UnderlyingTimestamp() const; + + /** + * Get the Year portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + int GetYear(bool localTime = false) const; + + /** + * Get the Month portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + Month GetMonth(bool localTime = false) const; + + /** + * Get the Day of the Month portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + int GetDay(bool localTime = false) const; + + /** + * Get the Day of the Week portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + DayOfWeek GetDayOfWeek(bool localTime = false) const; + + /** + * Get the Hour portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + int GetHour(bool localTime = false) const; + + /** + * Get the Minute portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + int GetMinute(bool localTime = false) const; + + /** + * Get the Second portion of this dateTime. localTime if true, return local time, otherwise return UTC + */ + int GetSecond(bool localTime = false) const; + + /** + * Get whether or not this dateTime is in Daylight savings time. localTime if true, return local time, otherwise return UTC + */ + bool IsDST(bool localTime = false) const; + + /** + * Get an instance of DateTime representing this very instant. + */ + static DateTime Now(); + + /** + * Get the millis since epoch representing this very instant. + */ + static int64_t CurrentTimeMillis(); + + /** + * Calculates the current local timestamp, formats it and returns it as a string + */ + static Aws::String CalculateLocalTimestampAsString(const char* formatStr); + + /** + * Calculates the current gmt timestamp, formats it, and returns it as a string + */ + static Aws::String CalculateGmtTimestampAsString(const char* formatStr); + + /** + * Calculates the current hour of the day in localtime. + */ + static int CalculateCurrentHour(); + + /** + * The amazon timestamp format is a double with seconds.milliseconds + */ + static double ComputeCurrentTimestampInAmazonFormat(); + + /** * Calculates the current time in GMT with millisecond precision using the format * "Year-month-day hours:minutes:seconds.milliseconds" */ static Aws::String CalculateGmtTimeWithMsPrecision(); /** - * Compute the difference between two timestamps. - */ - static std::chrono::milliseconds Diff(const DateTime& a, const DateTime& b); - + * Compute the difference between two timestamps. + */ + static std::chrono::milliseconds Diff(const DateTime& a, const DateTime& b); + std::chrono::milliseconds operator - (const DateTime& other) const; - private: - std::chrono::system_clock::time_point m_time; - bool m_valid; - - void ConvertTimestampStringToTimePoint(const char* timestamp, DateFormat format); - tm GetTimeStruct(bool localTime) const; - tm ConvertTimestampToLocalTimeStruct() const; + private: + std::chrono::system_clock::time_point m_time; + bool m_valid; + + void ConvertTimestampStringToTimePoint(const char* timestamp, DateFormat format); + tm GetTimeStruct(bool localTime) const; + tm ConvertTimestampToLocalTimeStruct() const; tm ConvertTimestampToGmtStruct() const; - }; - - } // namespace Utils -} // namespace Aws + }; + + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/EnumParseOverflowContainer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/EnumParseOverflowContainer.h index 0302e2bd36..6f1aca21e2 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/EnumParseOverflowContainer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/EnumParseOverflowContainer.h @@ -2,35 +2,35 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/threading/ReaderWriterLock.h> - -namespace Aws -{ - namespace Utils - { - /** - * This container is for storing unknown enum values that are encountered during parsing. - * This is to work around the round-tripping enums problem. It's really just a simple thread-safe - * hashmap. - */ - class AWS_CORE_API EnumParseOverflowContainer - { - public: - const Aws::String& RetrieveOverflow(int hashCode) const; - void StoreOverflow(int hashCode, const Aws::String& value); - - private: - mutable Aws::Utils::Threading::ReaderWriterLock m_overflowLock; - Aws::Map<int, Aws::String> m_overflowMap; - Aws::String m_emptyString; - }; - } -} - - + +#pragma once + +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/threading/ReaderWriterLock.h> + +namespace Aws +{ + namespace Utils + { + /** + * This container is for storing unknown enum values that are encountered during parsing. + * This is to work around the round-tripping enums problem. It's really just a simple thread-safe + * hashmap. + */ + class AWS_CORE_API EnumParseOverflowContainer + { + public: + const Aws::String& RetrieveOverflow(int hashCode) const; + void StoreOverflow(int hashCode, const Aws::String& value); + + private: + mutable Aws::Utils::Threading::ReaderWriterLock m_overflowLock; + Aws::Map<int, Aws::String> m_overflowMap; + Aws::String m_emptyString; + }; + } +} + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h index d62ff4c094..07b56a2e80 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/FileSystemUtils.h @@ -2,69 +2,69 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/platform/FileSystem.h> - -#include <fstream> - -namespace Aws -{ - namespace Utils - { - - class AWS_CORE_API FStreamWithFileName : public Aws::FStream - { - public: - FStreamWithFileName(const Aws::String& fileName, std::ios_base::openmode openFlags) : - Aws::FStream(fileName.c_str(), openFlags), m_fileName(fileName) {} - - virtual ~FStreamWithFileName() = default; - - const Aws::String& GetFileName() const { return m_fileName; } - protected: - Aws::String m_fileName; - }; - - /** - * Provides a fstream around a temporary file. This file gets deleted upon an instance of this class's destructor being called. - */ - class AWS_CORE_API TempFile : public Aws::Utils::FStreamWithFileName - { - public: - /** - * Creates a temporary file with [prefix][temp name][suffix] e.g. - * prefix of "foo" and suffix of ".bar" will generate foo[some random string].bar - */ - TempFile(const char* prefix, const char* suffix, std::ios_base::openmode openFlags); - /** - * Creates a temporary file with [prefix][temp name] e.g. - * prefix of "foo" will generate foo[some random string] - */ - TempFile(const char* prefix, std::ios_base::openmode openFlags); - /** - * Creates a temporary file with a randome string for the name. - */ - TempFile(std::ios_base::openmode openFlags); - - ~TempFile(); - }; - - class AWS_CORE_API PathUtils - { - public: - - /** - * Get file name from it's full path, e.g get "file1" from "/path/to/file1.ext"; get "file2" from "/path/to/file2" - */ - static Aws::String GetFileNameFromPathWithoutExt(const Aws::String& path); - - /** - * Get file name from it's full path, e.g get "file1.ext" from "/path/to/file1.ext"; get "file2" from "/path/to/file2" - */ - static Aws::String GetFileNameFromPathWithExt(const Aws::String& path); - }; - } -} +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/platform/FileSystem.h> + +#include <fstream> + +namespace Aws +{ + namespace Utils + { + + class AWS_CORE_API FStreamWithFileName : public Aws::FStream + { + public: + FStreamWithFileName(const Aws::String& fileName, std::ios_base::openmode openFlags) : + Aws::FStream(fileName.c_str(), openFlags), m_fileName(fileName) {} + + virtual ~FStreamWithFileName() = default; + + const Aws::String& GetFileName() const { return m_fileName; } + protected: + Aws::String m_fileName; + }; + + /** + * Provides a fstream around a temporary file. This file gets deleted upon an instance of this class's destructor being called. + */ + class AWS_CORE_API TempFile : public Aws::Utils::FStreamWithFileName + { + public: + /** + * Creates a temporary file with [prefix][temp name][suffix] e.g. + * prefix of "foo" and suffix of ".bar" will generate foo[some random string].bar + */ + TempFile(const char* prefix, const char* suffix, std::ios_base::openmode openFlags); + /** + * Creates a temporary file with [prefix][temp name] e.g. + * prefix of "foo" will generate foo[some random string] + */ + TempFile(const char* prefix, std::ios_base::openmode openFlags); + /** + * Creates a temporary file with a randome string for the name. + */ + TempFile(std::ios_base::openmode openFlags); + + ~TempFile(); + }; + + class AWS_CORE_API PathUtils + { + public: + + /** + * Get file name from it's full path, e.g get "file1" from "/path/to/file1.ext"; get "file2" from "/path/to/file2" + */ + static Aws::String GetFileNameFromPathWithoutExt(const Aws::String& path); + + /** + * Get file name from it's full path, e.g get "file1.ext" from "/path/to/file1.ext"; get "file2" from "/path/to/file2" + */ + static Aws::String GetFileNameFromPathWithExt(const Aws::String& path); + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/GetTheLights.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/GetTheLights.h index f42475c8e4..2d7875833b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/GetTheLights.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/GetTheLights.h @@ -2,34 +2,34 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSStack.h> -#include <functional> -#include <atomic> - -namespace Aws -{ - namespace Utils - { - /** - * Make initialization and cleanup of shared resources less painful. - * If you have this problem. Create a static instance of GetTheLights, - * have each actor call Enter the room with your callable. - * - * When you are finished with the shared resources call LeaveRoom(). The last caller will - * have its callable executed. - */ - class AWS_CORE_API GetTheLights - { - public: - GetTheLights(); - void EnterRoom(std::function<void()>&&); - void LeaveRoom(std::function<void()>&&); - private: - std::atomic<int> m_value; - }; - } -}
\ No newline at end of file + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSStack.h> +#include <functional> +#include <atomic> + +namespace Aws +{ + namespace Utils + { + /** + * Make initialization and cleanup of shared resources less painful. + * If you have this problem. Create a static instance of GetTheLights, + * have each actor call Enter the room with your callable. + * + * When you are finished with the shared resources call LeaveRoom(). The last caller will + * have its callable executed. + */ + class AWS_CORE_API GetTheLights + { + public: + GetTheLights(); + void EnterRoom(std::function<void()>&&); + void LeaveRoom(std::function<void()>&&); + private: + std::atomic<int> m_value; + }; + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h index 48c04daf59..986e2a247e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/HashingUtils.h @@ -2,85 +2,85 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/Array.h> - -namespace Aws -{ - namespace Utils - { - - /** - * Generic utils for hashing strings - */ - class AWS_CORE_API HashingUtils - { - public: - /** - * Base64 encodes string - */ - static Aws::String Base64Encode(const ByteBuffer& byteBuffer); - - /** - * Base64 decodes string - */ - static ByteBuffer Base64Decode(const Aws::String&); - - /** - * Hex encodes string - */ - static Aws::String HexEncode(const ByteBuffer& byteBuffer); - - /** - * Hex encodes string - */ - static ByteBuffer HexDecode(const Aws::String& str); - - /** - * Calculates a SHA256 HMAC digest (not hex encoded) - */ - static ByteBuffer CalculateSHA256HMAC(const ByteBuffer& toSign, const ByteBuffer& secret); - - /** - * Calculates a SHA256 Hash digest (not hex encoded) - */ - static ByteBuffer CalculateSHA256(const Aws::String& str); - - /** - * Calculates a SHA256 Hash digest on a stream (the entire stream is read, not hex encoded.) - */ - static ByteBuffer CalculateSHA256(Aws::IOStream& stream); - - /** - * Calculates a SHA256 Tree Hash digest (not hex encoded, see tree hash definition: http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html) - */ - static ByteBuffer CalculateSHA256TreeHash(const Aws::String& str); - - /** - * Calculates a SHA256 Tree Hash digest on a stream (the entire stream is read, not hex encoded.) - */ - static ByteBuffer CalculateSHA256TreeHash(Aws::IOStream& stream); - - /** - * Calculates a MD5 Hash value - */ - static ByteBuffer CalculateMD5(const Aws::String& str); - - /** - * Calculates a MD5 Hash value - */ - static ByteBuffer CalculateMD5(Aws::IOStream& stream); - - static int HashString(const char* strToHash); - - }; - - } // namespace Utils -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/Array.h> + +namespace Aws +{ + namespace Utils + { + + /** + * Generic utils for hashing strings + */ + class AWS_CORE_API HashingUtils + { + public: + /** + * Base64 encodes string + */ + static Aws::String Base64Encode(const ByteBuffer& byteBuffer); + + /** + * Base64 decodes string + */ + static ByteBuffer Base64Decode(const Aws::String&); + + /** + * Hex encodes string + */ + static Aws::String HexEncode(const ByteBuffer& byteBuffer); + + /** + * Hex encodes string + */ + static ByteBuffer HexDecode(const Aws::String& str); + + /** + * Calculates a SHA256 HMAC digest (not hex encoded) + */ + static ByteBuffer CalculateSHA256HMAC(const ByteBuffer& toSign, const ByteBuffer& secret); + + /** + * Calculates a SHA256 Hash digest (not hex encoded) + */ + static ByteBuffer CalculateSHA256(const Aws::String& str); + + /** + * Calculates a SHA256 Hash digest on a stream (the entire stream is read, not hex encoded.) + */ + static ByteBuffer CalculateSHA256(Aws::IOStream& stream); + + /** + * Calculates a SHA256 Tree Hash digest (not hex encoded, see tree hash definition: http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html) + */ + static ByteBuffer CalculateSHA256TreeHash(const Aws::String& str); + + /** + * Calculates a SHA256 Tree Hash digest on a stream (the entire stream is read, not hex encoded.) + */ + static ByteBuffer CalculateSHA256TreeHash(Aws::IOStream& stream); + + /** + * Calculates a MD5 Hash value + */ + static ByteBuffer CalculateMD5(const Aws::String& str); + + /** + * Calculates a MD5 Hash value + */ + static ByteBuffer CalculateMD5(Aws::IOStream& stream); + + static int HashString(const char* strToHash); + + }; + + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Outcome.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Outcome.h index 70e9e4be26..4b15c73977 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Outcome.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/Outcome.h @@ -2,52 +2,52 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + #include <cassert> -#include <utility> - -namespace Aws -{ - namespace Utils - { - - /** - * Template class representing the outcome of making a request. It will contain - * either a successful result or the failure error. The caller must check - * whether the outcome of the request was a success before attempting to access - * the result or the error. - */ - template<typename R, typename E> // Result, Error - class Outcome - { - public: - +#include <utility> + +namespace Aws +{ + namespace Utils + { + + /** + * Template class representing the outcome of making a request. It will contain + * either a successful result or the failure error. The caller must check + * whether the outcome of the request was a success before attempting to access + * the result or the error. + */ + template<typename R, typename E> // Result, Error + class Outcome + { + public: + Outcome() : result(), error(), success(false) - { + { } Outcome(const R& r) : result(r), error(), success(true) - { + { } Outcome(const E& e) : result(), error(e), success(false) - { + { } Outcome(R&& r) : result(std::forward<R>(r)), error(), success(true) - { + { } Outcome(E&& e) : result(), error(std::forward<E>(e)), success(false) - { - } - Outcome(const Outcome& o) : - result(o.result), - error(o.error), - success(o.success) - { - } - + { + } + Outcome(const Outcome& o) : + result(o.result), + error(o.error), + success(o.success) + { + } + template<typename RT, typename ET> friend class Outcome; @@ -94,77 +94,77 @@ namespace Aws { } - Outcome& operator=(const Outcome& o) - { - if (this != &o) - { - result = o.result; - error = o.error; - success = o.success; - } - - return *this; - } - - Outcome(Outcome&& o) : // Required to force Move Constructor - result(std::move(o.result)), - error(std::move(o.error)), - success(o.success) - { - } - - Outcome& operator=(Outcome&& o) - { - if (this != &o) - { - result = std::move(o.result); - error = std::move(o.error); - success = o.success; - } - - return *this; - } - - inline const R& GetResult() const - { - return result; - } - - inline R& GetResult() - { - return result; - } - - /** - * casts the underlying result to an r-value so that caller can take ownership of underlying resources. - * this is necessary when streams are involved. - */ - inline R&& GetResultWithOwnership() - { - return std::move(result); - } - - inline const E& GetError() const - { - return error; - } - + Outcome& operator=(const Outcome& o) + { + if (this != &o) + { + result = o.result; + error = o.error; + success = o.success; + } + + return *this; + } + + Outcome(Outcome&& o) : // Required to force Move Constructor + result(std::move(o.result)), + error(std::move(o.error)), + success(o.success) + { + } + + Outcome& operator=(Outcome&& o) + { + if (this != &o) + { + result = std::move(o.result); + error = std::move(o.error); + success = o.success; + } + + return *this; + } + + inline const R& GetResult() const + { + return result; + } + + inline R& GetResult() + { + return result; + } + + /** + * casts the underlying result to an r-value so that caller can take ownership of underlying resources. + * this is necessary when streams are involved. + */ + inline R&& GetResultWithOwnership() + { + return std::move(result); + } + + inline const E& GetError() const + { + return error; + } + template<typename T> inline T GetError() { return error.template GetModeledError<T>(); } - inline bool IsSuccess() const - { - return this->success; - } - - private: - R result; - E error; - bool success; - }; - - } // namespace Utils -} // namespace Aws + inline bool IsSuccess() const + { + return this->success; + } + + private: + R result; + E error; + bool success; + }; + + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h index 517f65d0fa..dec4a56c74 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ResourceManager.h @@ -2,121 +2,121 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <mutex> -#include <condition_variable> -#include <atomic> -#include <cassert> - -namespace Aws -{ - namespace Utils - { - /** - * Generic resource manager with Acquire/Release semantics. Acquire will block waiting on a an available resource. Release will - * cause one blocked acquisition to unblock. - * +#pragma once + +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <mutex> +#include <condition_variable> +#include <atomic> +#include <cassert> + +namespace Aws +{ + namespace Utils + { + /** + * Generic resource manager with Acquire/Release semantics. Acquire will block waiting on a an available resource. Release will + * cause one blocked acquisition to unblock. + * * You must call ShutdownAndWait() when finished with this container, this unblocks the listening thread and gives you a chance to * clean up the resource if needed. - * After calling ShutdownAndWait(), you must not call Acquire any more. - */ - template< typename RESOURCE_TYPE> - class ExclusiveOwnershipResourceManager - { - public: - ExclusiveOwnershipResourceManager() : m_shutdown(false) {} + * After calling ShutdownAndWait(), you must not call Acquire any more. + */ + template< typename RESOURCE_TYPE> + class ExclusiveOwnershipResourceManager + { + public: + ExclusiveOwnershipResourceManager() : m_shutdown(false) {} - /** - * Returns a resource with exclusive ownership. You must call Release on the resource when you are finished or other - * threads will block waiting to acquire it. - * - * @return instance of RESOURCE_TYPE - */ - RESOURCE_TYPE Acquire() - { - std::unique_lock<std::mutex> locker(m_queueLock); - while(!m_shutdown.load() && m_resources.size() == 0) - { + /** + * Returns a resource with exclusive ownership. You must call Release on the resource when you are finished or other + * threads will block waiting to acquire it. + * + * @return instance of RESOURCE_TYPE + */ + RESOURCE_TYPE Acquire() + { + std::unique_lock<std::mutex> locker(m_queueLock); + while(!m_shutdown.load() && m_resources.size() == 0) + { m_semaphore.wait(locker, [&](){ return m_shutdown.load() || m_resources.size() > 0; }); - } - - assert(!m_shutdown.load()); - - RESOURCE_TYPE resource = m_resources.back(); - m_resources.pop_back(); - - return resource; - } - - /** - * Returns whether or not resources are currently available for acquisition - * - * @return true means that at this instant some resources are available (though another thread may grab them from under you), - * this is only a hint. - */ - bool HasResourcesAvailable() - { - std::lock_guard<std::mutex> locker(m_queueLock); - return m_resources.size() > 0 && !m_shutdown.load(); - } - - /** - * Releases a resource back to the pool. This will unblock one waiting Acquire call if any are waiting. - * - * @param resource resource to release back to the pool - */ - void Release(RESOURCE_TYPE resource) - { - std::unique_lock<std::mutex> locker(m_queueLock); - m_resources.push_back(resource); - locker.unlock(); - m_semaphore.notify_one(); - } - - /** - * Does not block or even touch the semaphores. This is intended for setup only, do not use this after Acquire has been called for the first time. - * - * @param resource resource to be managed. - */ - void PutResource(RESOURCE_TYPE resource) - { - m_resources.push_back(resource); - } - - /** + } + + assert(!m_shutdown.load()); + + RESOURCE_TYPE resource = m_resources.back(); + m_resources.pop_back(); + + return resource; + } + + /** + * Returns whether or not resources are currently available for acquisition + * + * @return true means that at this instant some resources are available (though another thread may grab them from under you), + * this is only a hint. + */ + bool HasResourcesAvailable() + { + std::lock_guard<std::mutex> locker(m_queueLock); + return m_resources.size() > 0 && !m_shutdown.load(); + } + + /** + * Releases a resource back to the pool. This will unblock one waiting Acquire call if any are waiting. + * + * @param resource resource to release back to the pool + */ + void Release(RESOURCE_TYPE resource) + { + std::unique_lock<std::mutex> locker(m_queueLock); + m_resources.push_back(resource); + locker.unlock(); + m_semaphore.notify_one(); + } + + /** + * Does not block or even touch the semaphores. This is intended for setup only, do not use this after Acquire has been called for the first time. + * + * @param resource resource to be managed. + */ + void PutResource(RESOURCE_TYPE resource) + { + m_resources.push_back(resource); + } + + /** * Waits for all acquired resources to be released, then empties the queue. - * You must call ShutdownAndWait() when finished with this container, this unblocks the listening thread and gives you a chance to - * clean up the resource if needed. - * After calling ShutdownAndWait(), you must not call Acquire any more. - * + * You must call ShutdownAndWait() when finished with this container, this unblocks the listening thread and gives you a chance to + * clean up the resource if needed. + * After calling ShutdownAndWait(), you must not call Acquire any more. + * * @params resourceCount the number of resources you've added to the resource manager. - * @return the previously managed resources that are now available for cleanup. - */ - Aws::Vector<RESOURCE_TYPE> ShutdownAndWait(size_t resourceCount) - { - Aws::Vector<RESOURCE_TYPE> resources; - std::unique_lock<std::mutex> locker(m_queueLock); - m_shutdown = true; - + * @return the previously managed resources that are now available for cleanup. + */ + Aws::Vector<RESOURCE_TYPE> ShutdownAndWait(size_t resourceCount) + { + Aws::Vector<RESOURCE_TYPE> resources; + std::unique_lock<std::mutex> locker(m_queueLock); + m_shutdown = true; + //wait for all acquired resources to be released. - while (m_resources.size() < resourceCount) - { - m_semaphore.wait(locker, [&]() { return m_resources.size() == resourceCount; }); - } - - resources = m_resources; - m_resources.clear(); - - return resources; - } + while (m_resources.size() < resourceCount) + { + m_semaphore.wait(locker, [&]() { return m_resources.size() == resourceCount; }); + } + + resources = m_resources; + m_resources.clear(); - private: - Aws::Vector<RESOURCE_TYPE> m_resources; - std::mutex m_queueLock; - std::condition_variable m_semaphore; - std::atomic<bool> m_shutdown; - }; - } -} + return resources; + } + + private: + Aws::Vector<RESOURCE_TYPE> m_resources; + std::mutex m_queueLock; + std::condition_variable m_semaphore; + std::atomic<bool> m_shutdown; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h index 312342b86a..445e297f59 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/StringUtils.h @@ -2,71 +2,71 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - - - -namespace Aws -{ - namespace Utils - { - /** - * All the things the c++ stdlib is missing for string operations that I needed. - */ - class AWS_CORE_API StringUtils - { - public: - static void Replace(Aws::String& s, const char* search, const char* replace); - - - /** - * Converts a string to lower case. - */ - static Aws::String ToLower(const char* source); - - - /** - * Converts a string to upper case. - */ - static Aws::String ToUpper(const char* source); - - - /** - * Does a caseless comparison of two strings. - */ - static bool CaselessCompare(const char* value1, const char* value2); - - - /** - * URL encodes a string (uses %20 not + for spaces). - */ - static Aws::String URLEncode(const char* unsafe); - - /** - * Http Clients tend to escape some characters but not all. Escaping all of them causes problems, because the client - * will also try to escape them. - * So this only escapes non-ascii characters and the + character - */ - static Aws::String UTF8Escape(const char* unicodeString, const char* delimiter); - - /** - * URL encodes a double (if it ends up going to scientific notation) otherwise it just returns it as a string. - */ - static Aws::String URLEncode(double unsafe); - - - /** - * Decodes a URL encoded string (will handle both encoding schemes for spaces). - */ - static Aws::String URLDecode(const char* safe); - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + + + +namespace Aws +{ + namespace Utils + { + /** + * All the things the c++ stdlib is missing for string operations that I needed. + */ + class AWS_CORE_API StringUtils + { + public: + static void Replace(Aws::String& s, const char* search, const char* replace); + + + /** + * Converts a string to lower case. + */ + static Aws::String ToLower(const char* source); + + + /** + * Converts a string to upper case. + */ + static Aws::String ToUpper(const char* source); + + + /** + * Does a caseless comparison of two strings. + */ + static bool CaselessCompare(const char* value1, const char* value2); + + + /** + * URL encodes a string (uses %20 not + for spaces). + */ + static Aws::String URLEncode(const char* unsafe); + + /** + * Http Clients tend to escape some characters but not all. Escaping all of them causes problems, because the client + * will also try to escape them. + * So this only escapes non-ascii characters and the + character + */ + static Aws::String UTF8Escape(const char* unicodeString, const char* delimiter); + + /** + * URL encodes a double (if it ends up going to scientific notation) otherwise it just returns it as a string. + */ + static Aws::String URLEncode(double unsafe); + + + /** + * Decodes a URL encoded string (will handle both encoding schemes for spaces). + */ + static Aws::String URLDecode(const char* safe); + enum class SplitOptions { /** @@ -79,14 +79,14 @@ namespace Aws INCLUDE_EMPTY_ENTRIES }; - /** - * @brief Splits a string on a delimiter (empty items are excluded). - * @param toSplit, the original string to split - * @param splitOn, the delemiter you want to use. - */ - static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn); - - /** + /** + * @brief Splits a string on a delimiter (empty items are excluded). + * @param toSplit, the original string to split + * @param splitOn, the delemiter you want to use. + */ + static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn); + + /** * @brief Splits a string on a delimiter. * @param toSplit, the original string to split * @param splitOn, the delemiter you want to use. @@ -95,13 +95,13 @@ namespace Aws static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn, SplitOptions option); /** - * @brief Splits a string on a delimiter (empty items are excluded). - * @param toSplit, the original string to split - * @param splitOn, the delemiter you want to use. - * @param numOfTargetParts, how many target parts you want to get, if it is 0, as many as possible. - */ - static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts); - + * @brief Splits a string on a delimiter (empty items are excluded). + * @param toSplit, the original string to split + * @param splitOn, the delemiter you want to use. + * @param numOfTargetParts, how many target parts you want to get, if it is 0, as many as possible. + */ + static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts); + /** * @brief Splits a string on a delimiter. * @param toSplit, the original string to split @@ -110,77 +110,77 @@ namespace Aws * @param option, if INCLUDE_EMPTY_ENTRIES, includes empty entries in the result, otherwise removes empty entries. */ static Aws::Vector<Aws::String> Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts, SplitOptions option); - - /** - * Splits a string on new line characters. - */ - static Aws::Vector<Aws::String> SplitOnLine(const Aws::String& toSplit); - - - /** static Aws::Vector<Aws::String> SplitOnRegex(Aws::String regex); - * trim from start - */ - static Aws::String LTrim(const char* source); - - - /** - * trim from end - */ - static Aws::String RTrim(const char* source); - - /** - * trim from both ends - */ - static Aws::String Trim(const char* source); - - - /** - * convert to int 64 - */ - static long long ConvertToInt64(const char* source); - - - /** - * convert to int 32 - */ - static long ConvertToInt32(const char* source); - - - /** - * convert to bool - */ - static bool ConvertToBool(const char* source); - - - /** - * convert to double + + /** + * Splits a string on new line characters. + */ + static Aws::Vector<Aws::String> SplitOnLine(const Aws::String& toSplit); + + + /** static Aws::Vector<Aws::String> SplitOnRegex(Aws::String regex); + * trim from start + */ + static Aws::String LTrim(const char* source); + + + /** + * trim from end + */ + static Aws::String RTrim(const char* source); + + /** + * trim from both ends + */ + static Aws::String Trim(const char* source); + + + /** + * convert to int 64 + */ + static long long ConvertToInt64(const char* source); + + + /** + * convert to int 32 + */ + static long ConvertToInt32(const char* source); + + + /** + * convert to bool + */ + static bool ConvertToBool(const char* source); + + + /** + * convert to double + */ + static double ConvertToDouble(const char* source); + + +#ifdef _WIN32 + /** + * Converts a string to wstring. + */ + static Aws::WString ToWString(const char* source); + + /** + * Converts a wstring to string. + */ + static Aws::String FromWString(const wchar_t* source); +#endif + + /** + * not all platforms (Android) have std::to_string */ - static double ConvertToDouble(const char* source); - - -#ifdef _WIN32 - /** - * Converts a string to wstring. - */ - static Aws::WString ToWString(const char* source); - - /** - * Converts a wstring to string. - */ - static Aws::String FromWString(const wchar_t* source); -#endif - - /** - * not all platforms (Android) have std::to_string - */ - template< typename T > - static Aws::String to_string(T value) - { - Aws::OStringStream os; - os << value; - return os.str(); - } - + template< typename T > + static Aws::String to_string(T value) + { + Aws::OStringStream os; + os << value; + return os.str(); + } + /** * locale agnostic implementation of std::isalnum */ @@ -212,8 +212,8 @@ namespace Aws std::reverse(s.begin(), s.end()); return s; } - }; - - - } // namespace Utils + }; + + + } // namespace Utils } // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UUID.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UUID.h index e6320d14ef..b9b73d6e8e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UUID.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UUID.h @@ -2,51 +2,51 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/Array.h> - -namespace Aws -{ - namespace Utils - { - static const size_t UUID_BINARY_SIZE = 0x10; - - /** - * Class encapsulating a UUID. This is platform dependent. The method you are most likely interested in is RandomUUID(). - */ - class AWS_CORE_API UUID - { - public: - /** - * Parses a GUID string into the raw data. - */ - UUID(const Aws::String&); - /** - * Sets the raw uuid data - */ - UUID(const unsigned char uuid[UUID_BINARY_SIZE]); - - /** - * Returns the current UUID as a GUID string - */ - operator Aws::String() const; - /** - * Returns a copy of the raw uuid - */ - inline operator ByteBuffer() const { return ByteBuffer(m_uuid, sizeof(m_uuid)); } - - /** - * Generates a UUID. It will always try to prefer a random implementation from the entropy source on the machine. If none, is available, it will - * fallback to the mac address and timestamp implementation. - */ - static UUID RandomUUID(); - - private: - unsigned char m_uuid[UUID_BINARY_SIZE]; - }; - } -} + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/Array.h> + +namespace Aws +{ + namespace Utils + { + static const size_t UUID_BINARY_SIZE = 0x10; + + /** + * Class encapsulating a UUID. This is platform dependent. The method you are most likely interested in is RandomUUID(). + */ + class AWS_CORE_API UUID + { + public: + /** + * Parses a GUID string into the raw data. + */ + UUID(const Aws::String&); + /** + * Sets the raw uuid data + */ + UUID(const unsigned char uuid[UUID_BINARY_SIZE]); + + /** + * Returns the current UUID as a GUID string + */ + operator Aws::String() const; + /** + * Returns a copy of the raw uuid + */ + inline operator ByteBuffer() const { return ByteBuffer(m_uuid, sizeof(m_uuid)); } + + /** + * Generates a UUID. It will always try to prefer a random implementation from the entropy source on the machine. If none, is available, it will + * fallback to the mac address and timestamp implementation. + */ + static UUID RandomUUID(); + + private: + unsigned char m_uuid[UUID_BINARY_SIZE]; + }; + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UnreferencedParam.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UnreferencedParam.h index d1bb74467d..6997f6f79c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UnreferencedParam.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/UnreferencedParam.h @@ -2,17 +2,17 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -// taken from http://stackoverflow.com/questions/3020584/avoid-warning-unreferenced-formal-parameter, ugly but avoids having to #include the definition of an unreferenced struct/class - -#if defined (_MSC_VER) - - #define AWS_UNREFERENCED_PARAM(x) (&reinterpret_cast<const int &>(x)) - -#else - - #define AWS_UNREFERENCED_PARAM(x) ((void)(x)) - -#endif // _MSC_VER + +#pragma once + +// taken from http://stackoverflow.com/questions/3020584/avoid-warning-unreferenced-formal-parameter, ugly but avoids having to #include the definition of an unreferenced struct/class + +#if defined (_MSC_VER) + + #define AWS_UNREFERENCED_PARAM(x) (&reinterpret_cast<const int &>(x)) + +#else + + #define AWS_UNREFERENCED_PARAM(x) ((void)(x)) + +#endif // _MSC_VER diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/base64/Base64.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/base64/Base64.h index 454d20c262..c4953b4b51 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/base64/Base64.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/base64/Base64.h @@ -2,69 +2,69 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#ifdef __APPLE__ - -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif // __clang__ - -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif // __GNUC__ - -#endif // __APPLE__ - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/Array.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Utils - { - namespace Base64 - { - - /** - * interface for platform specific Base64 encoding/decoding. - */ - class AWS_CORE_API Base64 - { - public: - Base64(const char *encodingTable = nullptr); - - /** - * Encode a byte buffer into a base64 stream. - * - * throws Base64Exception if encoding fails. - */ - Aws::String Encode(const ByteBuffer&) const; - - /** - * Decode a base64 string into a byte buffer. - */ - ByteBuffer Decode(const Aws::String&) const; - - /** - * Calculates the required length of a base64 buffer after decoding the - * input string. - */ - static size_t CalculateBase64DecodedLength(const Aws::String& b64input); - /** - * Calculates the length of an encoded base64 string based on the buffer being encoded - */ - static size_t CalculateBase64EncodedLength(const ByteBuffer& buffer); - - private: - char m_mimeBase64EncodingTable[64]; - uint8_t m_mimeBase64DecodingTable[256]; - - }; - - } // namespace Base64 - } // namespace Utils -} // namespace Aws - + +#pragma once + +#ifdef __APPLE__ + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif // __clang__ + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#endif // __APPLE__ + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/Array.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Utils + { + namespace Base64 + { + + /** + * interface for platform specific Base64 encoding/decoding. + */ + class AWS_CORE_API Base64 + { + public: + Base64(const char *encodingTable = nullptr); + + /** + * Encode a byte buffer into a base64 stream. + * + * throws Base64Exception if encoding fails. + */ + Aws::String Encode(const ByteBuffer&) const; + + /** + * Decode a base64 string into a byte buffer. + */ + ByteBuffer Decode(const Aws::String&) const; + + /** + * Calculates the required length of a base64 buffer after decoding the + * input string. + */ + static size_t CalculateBase64DecodedLength(const Aws::String& b64input); + /** + * Calculates the length of an encoded base64 string based on the buffer being encoded + */ + static size_t CalculateBase64EncodedLength(const ByteBuffer& buffer); + + private: + char m_mimeBase64EncodingTable[64]; + uint8_t m_mimeBase64DecodingTable[256]; + + }; + + } // namespace Base64 + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Cipher.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Cipher.h index fb31628b0e..5cabba55cf 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Cipher.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Cipher.h @@ -2,205 +2,205 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/Array.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - static const size_t SYMMETRIC_KEY_LENGTH = 32; - static const size_t MIN_IV_LENGTH = 12; - - AWS_CORE_API CryptoBuffer IncrementCTRCounter(const CryptoBuffer& counter, uint32_t numberOfBlocks); - - /** - * Interface for symmetric encryption and decryption providers. An instance of this class is good for exactly one encryption or decryption run. - * It should not be used to encrypt or decrypt multiple messages. - */ - class AWS_CORE_API SymmetricCipher - { - public: - /** - * Initialize with key and an auto-generated initializationVector. Copies key. - * ivGenerationInCtrMode, if true, initializes the iv with a 4 byte counter at the end. - */ - SymmetricCipher(const CryptoBuffer& key, size_t ivSize, bool ivGenerationInCtrMode = false) : - m_key(key), - m_initializationVector(ivSize > 0 ? GenerateIV(ivSize, ivGenerationInCtrMode) : 0), - m_failure(false) - { - } - - /** - * Initialize with key and initializationVector, set tag for decryption of authenticated modes (makes copies of the buffers) - */ - SymmetricCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag = CryptoBuffer(0)) : - m_key(key), - m_initializationVector(initializationVector), - m_tag(tag), - m_failure(false) - { - } - - /** - * Initialize with key and initializationVector, set tag for decryption of authenticated modes (move the buffers) - */ - SymmetricCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag = CryptoBuffer(0)) : - m_key(std::move(key)), - m_initializationVector(std::move(initializationVector)), + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/Array.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + static const size_t SYMMETRIC_KEY_LENGTH = 32; + static const size_t MIN_IV_LENGTH = 12; + + AWS_CORE_API CryptoBuffer IncrementCTRCounter(const CryptoBuffer& counter, uint32_t numberOfBlocks); + + /** + * Interface for symmetric encryption and decryption providers. An instance of this class is good for exactly one encryption or decryption run. + * It should not be used to encrypt or decrypt multiple messages. + */ + class AWS_CORE_API SymmetricCipher + { + public: + /** + * Initialize with key and an auto-generated initializationVector. Copies key. + * ivGenerationInCtrMode, if true, initializes the iv with a 4 byte counter at the end. + */ + SymmetricCipher(const CryptoBuffer& key, size_t ivSize, bool ivGenerationInCtrMode = false) : + m_key(key), + m_initializationVector(ivSize > 0 ? GenerateIV(ivSize, ivGenerationInCtrMode) : 0), + m_failure(false) + { + } + + /** + * Initialize with key and initializationVector, set tag for decryption of authenticated modes (makes copies of the buffers) + */ + SymmetricCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag = CryptoBuffer(0)) : + m_key(key), + m_initializationVector(initializationVector), + m_tag(tag), + m_failure(false) + { + } + + /** + * Initialize with key and initializationVector, set tag for decryption of authenticated modes (move the buffers) + */ + SymmetricCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag = CryptoBuffer(0)) : + m_key(std::move(key)), + m_initializationVector(std::move(initializationVector)), m_tag(std::move(tag)), - m_failure(false) - { - } - - SymmetricCipher(const SymmetricCipher& other) = delete; - SymmetricCipher& operator=(const SymmetricCipher& other) = delete; - - /** - * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, - * so let's go ahead and optimize by defining default move operations. Implementors of this class - * need to be sure to define the move operations and call the base class. - */ - SymmetricCipher(SymmetricCipher&& toMove) : - m_key(std::move(toMove.m_key)), - m_initializationVector(std::move(toMove.m_initializationVector)), - m_tag(std::move(toMove.m_tag)), - m_failure(toMove.m_failure) - { - } - - /** - * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, - * so let's go ahead and optimize by defining default move operations. Implementors of this class - * need to be sure to define the move operations and call the base class. - */ - SymmetricCipher& operator=(SymmetricCipher&& toMove) - { - m_key = std::move(toMove.m_key); - m_initializationVector = std::move(toMove.m_initializationVector); - m_tag = std::move(toMove.m_tag); - m_failure = toMove.m_failure; - - return *this; - } - - virtual ~SymmetricCipher() = default; - - /** - * Whether or not the cipher is in a good state. If this ever returns false, throw away all buffers - * it has vended. - */ - virtual operator bool() const { return Good(); } - - /** + m_failure(false) + { + } + + SymmetricCipher(const SymmetricCipher& other) = delete; + SymmetricCipher& operator=(const SymmetricCipher& other) = delete; + + /** + * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, + * so let's go ahead and optimize by defining default move operations. Implementors of this class + * need to be sure to define the move operations and call the base class. + */ + SymmetricCipher(SymmetricCipher&& toMove) : + m_key(std::move(toMove.m_key)), + m_initializationVector(std::move(toMove.m_initializationVector)), + m_tag(std::move(toMove.m_tag)), + m_failure(toMove.m_failure) + { + } + + /** + * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, + * so let's go ahead and optimize by defining default move operations. Implementors of this class + * need to be sure to define the move operations and call the base class. + */ + SymmetricCipher& operator=(SymmetricCipher&& toMove) + { + m_key = std::move(toMove.m_key); + m_initializationVector = std::move(toMove.m_initializationVector); + m_tag = std::move(toMove.m_tag); + m_failure = toMove.m_failure; + + return *this; + } + + virtual ~SymmetricCipher() = default; + + /** + * Whether or not the cipher is in a good state. If this ever returns false, throw away all buffers + * it has vended. + */ + virtual operator bool() const { return Good(); } + + /** * Encrypt a buffer of data. Part of the contract for this interface is that intention that - * a user call this function multiple times for a large stream. As such, multiple calls to this function - * on the same instance should produce valid sequential output for an encrypted stream. - */ - virtual CryptoBuffer EncryptBuffer( const CryptoBuffer& unEncryptedData) = 0; - - /** - * Finalize Encryption, returns anything remaining in the last block - */ - virtual CryptoBuffer FinalizeEncryption () = 0; - - /** - * Decrypt a buffer of data. Part of the contract for this interface is that intention that - * a user call this function multiple times for a large stream. As such, multiple calls to this function - * on the same instance should produce valid sequential output from an encrypted stream. - */ - virtual CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) = 0; - - /** - * Finalize Decryption, returns anything remaining in the last block - */ - virtual CryptoBuffer FinalizeDecryption () = 0; - - virtual void Reset() = 0; - - /** - * IV used for encryption/decryption - */ - inline const CryptoBuffer& GetIV() const { return m_initializationVector; } - - /** - * Tag generated by encryption and used for the decryption. - * This will be set in an authenticated mode, otherwise empty - */ - inline const CryptoBuffer& GetTag() const { return m_tag; } - - inline bool Fail() const { return m_failure; } - inline bool Good() const { return !Fail(); } - - /** - * Generates a non-deterministic random IV. The first call is somewhat expensive but subsequent calls - * should be fast. If ctrMode is true, it will pad nonce in the first 1/4 of the iv and initialize - * the back 1/4 to 1. - */ - static CryptoBuffer GenerateIV(size_t ivLengthBytes, bool ctrMode = false); - - /** - * Generates a non-deterministic random symmetric key. Default (and minimum bar for security) is 256 bits. - */ + * a user call this function multiple times for a large stream. As such, multiple calls to this function + * on the same instance should produce valid sequential output for an encrypted stream. + */ + virtual CryptoBuffer EncryptBuffer( const CryptoBuffer& unEncryptedData) = 0; + + /** + * Finalize Encryption, returns anything remaining in the last block + */ + virtual CryptoBuffer FinalizeEncryption () = 0; + + /** + * Decrypt a buffer of data. Part of the contract for this interface is that intention that + * a user call this function multiple times for a large stream. As such, multiple calls to this function + * on the same instance should produce valid sequential output from an encrypted stream. + */ + virtual CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) = 0; + + /** + * Finalize Decryption, returns anything remaining in the last block + */ + virtual CryptoBuffer FinalizeDecryption () = 0; + + virtual void Reset() = 0; + + /** + * IV used for encryption/decryption + */ + inline const CryptoBuffer& GetIV() const { return m_initializationVector; } + + /** + * Tag generated by encryption and used for the decryption. + * This will be set in an authenticated mode, otherwise empty + */ + inline const CryptoBuffer& GetTag() const { return m_tag; } + + inline bool Fail() const { return m_failure; } + inline bool Good() const { return !Fail(); } + + /** + * Generates a non-deterministic random IV. The first call is somewhat expensive but subsequent calls + * should be fast. If ctrMode is true, it will pad nonce in the first 1/4 of the iv and initialize + * the back 1/4 to 1. + */ + static CryptoBuffer GenerateIV(size_t ivLengthBytes, bool ctrMode = false); + + /** + * Generates a non-deterministic random symmetric key. Default (and minimum bar for security) is 256 bits. + */ static CryptoBuffer GenerateKey(size_t keyLengthBytes = SYMMETRIC_KEY_LENGTH); - - protected: - - SymmetricCipher() : m_failure(false) {} - - CryptoBuffer m_key; - CryptoBuffer m_initializationVector; - CryptoBuffer m_tag; - bool m_failure; - }; - - /** - * Abstract factory class for Creating platform specific implementations of a Symmetric Cipher - */ - class SymmetricCipherFactory - { - public: - virtual ~SymmetricCipherFactory() {} - - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ - virtual std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const = 0; - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + + protected: + + SymmetricCipher() : m_failure(false) {} + + CryptoBuffer m_key; + CryptoBuffer m_initializationVector; + CryptoBuffer m_tag; + bool m_failure; + }; + + /** + * Abstract factory class for Creating platform specific implementations of a Symmetric Cipher + */ + class SymmetricCipherFactory + { + public: + virtual ~SymmetricCipherFactory() {} + + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ + virtual std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const = 0; + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ virtual std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer*) const { return CreateImplementation(key); } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ virtual std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag = CryptoBuffer(0), const CryptoBuffer& aad = CryptoBuffer(0)) const = 0; /** * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. */ virtual std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag = CryptoBuffer(0), CryptoBuffer&& aad = CryptoBuffer(0)) const = 0; - - /** - * Only called once per factory, your chance to make static library calls for setup. - * Default is no-op. - */ - virtual void InitStaticState() {} - - /** - * Only called once per factory, your chance to cleanup static library calls for setup. - * Default is no-op. - */ - virtual void CleanupStaticState() {} - }; - } - } + + /** + * Only called once per factory, your chance to make static library calls for setup. + * Default is no-op. + */ + virtual void InitStaticState() {} + + /** + * Only called once per factory, your chance to cleanup static library calls for setup. + * Default is no-op. + */ + virtual void CleanupStaticState() {} + }; + } + } } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoMaterial.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoMaterial.h index ea99798853..525a7ac972 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoMaterial.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoMaterial.h @@ -2,167 +2,167 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/Aws.h> -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/crypto/CryptoBuf.h> -#include <aws/core/utils/crypto/ContentCryptoScheme.h> -#include <aws/core/utils/crypto/KeyWrapAlgorithm.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - class AWS_CORE_API ContentCryptoMaterial - { - public: - /* - Default constructor. - */ - ContentCryptoMaterial(); - /* - Initialize content crypto material with content crypto scheme. Constructor will also generate the cek automatically. - Since the creation of the crypto content material will be within the S3 crypto modules, only the crypto scheme is needed for initialization. - The rest of the data will be set using the accessors below. - */ - ContentCryptoMaterial(ContentCryptoScheme contentCryptoScheme); - - /* +#pragma once + +#include <aws/core/Aws.h> +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/crypto/CryptoBuf.h> +#include <aws/core/utils/crypto/ContentCryptoScheme.h> +#include <aws/core/utils/crypto/KeyWrapAlgorithm.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + class AWS_CORE_API ContentCryptoMaterial + { + public: + /* + Default constructor. + */ + ContentCryptoMaterial(); + /* + Initialize content crypto material with content crypto scheme. Constructor will also generate the cek automatically. + Since the creation of the crypto content material will be within the S3 crypto modules, only the crypto scheme is needed for initialization. + The rest of the data will be set using the accessors below. + */ + ContentCryptoMaterial(ContentCryptoScheme contentCryptoScheme); + + /* Initialize with content encryption key (cek) and content crypto scheme. - */ - ContentCryptoMaterial(const Aws::Utils::CryptoBuffer& cek, ContentCryptoScheme contentCryptoScheme); - - /** - * Gets the underlying content encryption key. - */ - inline const Aws::Utils::CryptoBuffer& GetContentEncryptionKey() const - { - return m_contentEncryptionKey; - } - - /** - * Gets the underlying encrypted content encryption key. - */ - inline const Aws::Utils::CryptoBuffer& GetEncryptedContentEncryptionKey() const - { - return m_encryptedContentEncryptionKey; - } - - /** - * Gets the underlying initialization vector - */ - inline const Aws::Utils::CryptoBuffer& GetIV() const - { - return m_iv; - } - - /** - * Gets the underlying crypto tag length - */ - inline size_t GetCryptoTagLength() const - { - return m_cryptoTagLength; - } - - /** - * Gets the underlying materials description map. - */ - inline const Aws::Map<Aws::String, Aws::String>& GetMaterialsDescription() const - { - return m_materialsDescription; - } - - /* - * Gets the value of the key in the current materials description map. - */ - inline const Aws::String& GetMaterialsDescription(const Aws::String& key) const - { - return m_materialsDescription.at(key); - } - - /** - * Gets the underlying key wrap algorithm - */ - inline KeyWrapAlgorithm GetKeyWrapAlgorithm() const - { - return m_keyWrapAlgorithm; - } - - /** - * Gets the underlying content crypto scheme. - */ - inline ContentCryptoScheme GetContentCryptoScheme() const - { - return m_contentCryptoScheme; - } - - /** - * Sets the underlying content encryption key. Copies from parameter content encryption key. - */ - inline void SetContentEncryptionKey(const Aws::Utils::CryptoBuffer& contentEncryptionKey) - { - m_contentEncryptionKey = contentEncryptionKey; - } - - /** - * Sets the underlying encrypted content encryption key. Copies from parameter encrypted content encryption key. - */ - inline void SetEncryptedContentEncryptionKey(const Aws::Utils::CryptoBuffer& encryptedContentEncryptionKey) - { - m_encryptedContentEncryptionKey = encryptedContentEncryptionKey; - } - - /** - * Sets the underlying iv. Copies from parameter iv. - */ - inline void SetIV(const Aws::Utils::CryptoBuffer& iv) - { - m_iv = iv; - } - - /** - * Sets the underlying crypto Tag Length. Copies from parameter cryptoTagLength. - */ - inline void SetCryptoTagLength(size_t cryptoTagLength) - { - m_cryptoTagLength = cryptoTagLength; - } - - /** - * Adds to the current materials description map using a key and a value. - */ - inline void AddMaterialsDescription(const Aws::String& key, const Aws::String& value) - { - m_materialsDescription[key] = value; - } - - /** - * Sets the underlying materials description. Copies from parameter materials description. - */ - inline void SetMaterialsDescription(const Aws::Map<Aws::String, Aws::String>& materialsDescription) - { - m_materialsDescription = materialsDescription; - } - - /** - * Sets the underlying Key Wrap Algorithm. Copies from parameter keyWrapAlgorithm. - */ - inline void SetKeyWrapAlgorithm(KeyWrapAlgorithm keyWrapAlgorithm) - { - m_keyWrapAlgorithm = keyWrapAlgorithm; - } - - /** - * Sets the underlying content Crypto Scheme. Copies from parameter contentCryptoScheme. - */ - inline void SetContentCryptoScheme(ContentCryptoScheme contentCryptoScheme) - { - m_contentCryptoScheme = contentCryptoScheme; - } - + */ + ContentCryptoMaterial(const Aws::Utils::CryptoBuffer& cek, ContentCryptoScheme contentCryptoScheme); + + /** + * Gets the underlying content encryption key. + */ + inline const Aws::Utils::CryptoBuffer& GetContentEncryptionKey() const + { + return m_contentEncryptionKey; + } + + /** + * Gets the underlying encrypted content encryption key. + */ + inline const Aws::Utils::CryptoBuffer& GetEncryptedContentEncryptionKey() const + { + return m_encryptedContentEncryptionKey; + } + + /** + * Gets the underlying initialization vector + */ + inline const Aws::Utils::CryptoBuffer& GetIV() const + { + return m_iv; + } + + /** + * Gets the underlying crypto tag length + */ + inline size_t GetCryptoTagLength() const + { + return m_cryptoTagLength; + } + + /** + * Gets the underlying materials description map. + */ + inline const Aws::Map<Aws::String, Aws::String>& GetMaterialsDescription() const + { + return m_materialsDescription; + } + + /* + * Gets the value of the key in the current materials description map. + */ + inline const Aws::String& GetMaterialsDescription(const Aws::String& key) const + { + return m_materialsDescription.at(key); + } + + /** + * Gets the underlying key wrap algorithm + */ + inline KeyWrapAlgorithm GetKeyWrapAlgorithm() const + { + return m_keyWrapAlgorithm; + } + + /** + * Gets the underlying content crypto scheme. + */ + inline ContentCryptoScheme GetContentCryptoScheme() const + { + return m_contentCryptoScheme; + } + + /** + * Sets the underlying content encryption key. Copies from parameter content encryption key. + */ + inline void SetContentEncryptionKey(const Aws::Utils::CryptoBuffer& contentEncryptionKey) + { + m_contentEncryptionKey = contentEncryptionKey; + } + + /** + * Sets the underlying encrypted content encryption key. Copies from parameter encrypted content encryption key. + */ + inline void SetEncryptedContentEncryptionKey(const Aws::Utils::CryptoBuffer& encryptedContentEncryptionKey) + { + m_encryptedContentEncryptionKey = encryptedContentEncryptionKey; + } + + /** + * Sets the underlying iv. Copies from parameter iv. + */ + inline void SetIV(const Aws::Utils::CryptoBuffer& iv) + { + m_iv = iv; + } + + /** + * Sets the underlying crypto Tag Length. Copies from parameter cryptoTagLength. + */ + inline void SetCryptoTagLength(size_t cryptoTagLength) + { + m_cryptoTagLength = cryptoTagLength; + } + + /** + * Adds to the current materials description map using a key and a value. + */ + inline void AddMaterialsDescription(const Aws::String& key, const Aws::String& value) + { + m_materialsDescription[key] = value; + } + + /** + * Sets the underlying materials description. Copies from parameter materials description. + */ + inline void SetMaterialsDescription(const Aws::Map<Aws::String, Aws::String>& materialsDescription) + { + m_materialsDescription = materialsDescription; + } + + /** + * Sets the underlying Key Wrap Algorithm. Copies from parameter keyWrapAlgorithm. + */ + inline void SetKeyWrapAlgorithm(KeyWrapAlgorithm keyWrapAlgorithm) + { + m_keyWrapAlgorithm = keyWrapAlgorithm; + } + + /** + * Sets the underlying content Crypto Scheme. Copies from parameter contentCryptoScheme. + */ + inline void SetContentCryptoScheme(ContentCryptoScheme contentCryptoScheme) + { + m_contentCryptoScheme = contentCryptoScheme; + } + /** * Sets the underlying AAD for GCM if needed. */ @@ -223,22 +223,22 @@ namespace Aws return m_finalCEK; } - private: - Aws::Utils::CryptoBuffer m_contentEncryptionKey; - Aws::Utils::CryptoBuffer m_encryptedContentEncryptionKey; + private: + Aws::Utils::CryptoBuffer m_contentEncryptionKey; + Aws::Utils::CryptoBuffer m_encryptedContentEncryptionKey; /* if using AES_GCM key wrap algorithm, then final CEK is iv + encrypted_key + tag * otherwise it's the same as m_encryptedContentEncryptionKey */ Aws::Utils::CryptoBuffer m_finalCEK; - Aws::Utils::CryptoBuffer m_iv; + Aws::Utils::CryptoBuffer m_iv; Aws::Utils::CryptoBuffer m_cekIV; Aws::Utils::CryptoBuffer m_gcmAAD; Aws::Utils::CryptoBuffer m_cekGCMTag; - size_t m_cryptoTagLength; - Aws::Map<Aws::String, Aws::String> m_materialsDescription; - KeyWrapAlgorithm m_keyWrapAlgorithm; - ContentCryptoScheme m_contentCryptoScheme; - }; - } - } + size_t m_cryptoTagLength; + Aws::Map<Aws::String, Aws::String> m_materialsDescription; + KeyWrapAlgorithm m_keyWrapAlgorithm; + ContentCryptoScheme m_contentCryptoScheme; + }; + } + } } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoScheme.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoScheme.h index 605ad4e375..6d89da6585 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoScheme.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/ContentCryptoScheme.h @@ -2,31 +2,31 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - enum class ContentCryptoScheme - { - CBC, - CTR, - GCM, - NONE - }; - - namespace ContentCryptoSchemeMapper - { - AWS_CORE_API ContentCryptoScheme GetContentCryptoSchemeForName(const Aws::String& name); - - AWS_CORE_API Aws::String GetNameForContentCryptoScheme(ContentCryptoScheme enumValue); - } - } //namespace Crypto - - }//namespace Utils -}//namespace Aws
\ No newline at end of file +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + enum class ContentCryptoScheme + { + CBC, + CTR, + GCM, + NONE + }; + + namespace ContentCryptoSchemeMapper + { + AWS_CORE_API ContentCryptoScheme GetContentCryptoSchemeForName(const Aws::String& name); + + AWS_CORE_API Aws::String GetNameForContentCryptoScheme(ContentCryptoScheme enumValue); + } + } //namespace Crypto + + }//namespace Utils +}//namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoBuf.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoBuf.h index 1270c6b427..3d4b2b7436 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoBuf.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoBuf.h @@ -2,148 +2,148 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/utils/crypto/Cipher.h> -#include <aws/core/Core_EXPORTS.h> -#include <ios> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - typedef std::mbstate_t FPOS_TYPE; - static const size_t DEFAULT_BUF_SIZE = 1024; - static const size_t PUT_BACK_SIZE = 1; - - /** - * Which mode a cipher is being used for. Encryption or Decryption - */ - enum class CipherMode - { - Encrypt, - Decrypt - }; - - /** - * Generic base class for a streambuf that handles cryptography. - */ - class AWS_CORE_API CryptoBuf : public std::streambuf - { - public: - CryptoBuf() = default; - virtual ~CryptoBuf() = default; - CryptoBuf(const CryptoBuf&) = delete; - CryptoBuf(CryptoBuf&& rhs) = delete; - /** - * If the buffer needs to do a final push to the sink or needs to empty the cipher blocks etc... - */ - virtual void Finalize() {} - }; - - /** - * StreamBuf that takes data from an input stream, encrypts or decrypts it, and causes all input received from the stream that is using it - * to go through the cipher. A common use case is a file that is encrypted on disk being read via ifstream and then read decrypted into memory. - * Or you could send a plain text file through an iostream and have it encrypted when the stream is read. - * - * This streambuf is seekable, but it is very expensive to seek backwards since we have to reset the cipher and re-encrypt everything up to that point. - * So seeking should be avoided if at all possible. - */ - class AWS_CORE_API SymmetricCryptoBufSrc : public CryptoBuf - { - public: - /** - * stream to src from - * cipher to encrypt or decrypt the src stream with +#pragma once + +#include <aws/core/utils/crypto/Cipher.h> +#include <aws/core/Core_EXPORTS.h> +#include <ios> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + typedef std::mbstate_t FPOS_TYPE; + static const size_t DEFAULT_BUF_SIZE = 1024; + static const size_t PUT_BACK_SIZE = 1; + + /** + * Which mode a cipher is being used for. Encryption or Decryption + */ + enum class CipherMode + { + Encrypt, + Decrypt + }; + + /** + * Generic base class for a streambuf that handles cryptography. + */ + class AWS_CORE_API CryptoBuf : public std::streambuf + { + public: + CryptoBuf() = default; + virtual ~CryptoBuf() = default; + CryptoBuf(const CryptoBuf&) = delete; + CryptoBuf(CryptoBuf&& rhs) = delete; + /** + * If the buffer needs to do a final push to the sink or needs to empty the cipher blocks etc... + */ + virtual void Finalize() {} + }; + + /** + * StreamBuf that takes data from an input stream, encrypts or decrypts it, and causes all input received from the stream that is using it + * to go through the cipher. A common use case is a file that is encrypted on disk being read via ifstream and then read decrypted into memory. + * Or you could send a plain text file through an iostream and have it encrypted when the stream is read. + * + * This streambuf is seekable, but it is very expensive to seek backwards since we have to reset the cipher and re-encrypt everything up to that point. + * So seeking should be avoided if at all possible. + */ + class AWS_CORE_API SymmetricCryptoBufSrc : public CryptoBuf + { + public: + /** + * stream to src from + * cipher to encrypt or decrypt the src stream with * mode to use cipher in. Encryption or Decryption - * buffersize, the size of the src buffers to read at a time. Defaults to 1kb - */ - SymmetricCryptoBufSrc(Aws::IStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize = DEFAULT_BUF_SIZE); - - SymmetricCryptoBufSrc(const SymmetricCryptoBufSrc&) = delete; - SymmetricCryptoBufSrc(SymmetricCryptoBufSrc&&) = delete; - - SymmetricCryptoBufSrc& operator=(const SymmetricCryptoBufSrc&) = delete; - SymmetricCryptoBufSrc& operator=(SymmetricCryptoBufSrc&&) = delete; - - virtual ~SymmetricCryptoBufSrc() { FinalizeCipher(); } - - /** - * This call isn't necessary if you loop over the stream.read until you reach EOF, if you happen to read the exact - * amount as the in memory buffers and finish the stream, but never finish the finalize call you'll need to be sure - * to call this. This is automatically called by the destructor. - */ - void Finalize() override { FinalizeCipher(); } - - protected: - pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override; - pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override; - - private: - int_type underflow() override; - off_type ComputeAbsSeekPosition(off_type, std::ios_base::seekdir, std::fpos<FPOS_TYPE>); - void FinalizeCipher(); - - CryptoBuffer m_isBuf; - SymmetricCipher& m_cipher; - Aws::IStream& m_stream; - CipherMode m_cipherMode; - bool m_isFinalized; - size_t m_bufferSize; - size_t m_putBack; - }; - - /** - * Stream buf that takes it's input, encrypts or decrypts it using the cipher, and writes it to the sink stream. This is particularly useful - * when receiving an encrypted file over the internet and writing it decrypted to disk. Another case may be that you have an ofstream and you want - * to write text to it from your program but have it go encrypted to disk. - * - * This stream buf is not seekable. - */ - class AWS_CORE_API SymmetricCryptoBufSink : public CryptoBuf - { - public: - /** - * stream, sink to push the encrypted or decrypted data to. - * cipher, symmetric cipher to use to transform the input before sending it to the sink. - * cipherMode, encrypt or decrypt - * bufferSize, amount of data to encrypt/decrypt at a time. - */ - SymmetricCryptoBufSink(Aws::OStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize = DEFAULT_BUF_SIZE, int16_t blockOffset = 0); - SymmetricCryptoBufSink(const SymmetricCryptoBufSink&) = delete; - SymmetricCryptoBufSink(SymmetricCryptoBufSink&&) = delete; - - SymmetricCryptoBufSink& operator=(const SymmetricCryptoBufSink&) = delete; - /** - * Not move assignable since it contains reference members - */ - SymmetricCryptoBufSink& operator=(SymmetricCryptoBufSink&&) = delete; - - virtual ~SymmetricCryptoBufSink(); - - /** - * Finalizes the cipher and pushes all remaining data to the sink. Once this has been called, this streambuf cannot be used any further. - */ - void FinalizeCiphersAndFlushSink(); - /** - * Simply calls FinalizeCiphersAndFlushSink() - */ - void Finalize() override { FinalizeCiphersAndFlushSink(); } - - private: - int_type overflow(int_type ch) override; - int sync() override; - bool writeOutput(bool finalize); - - CryptoBuffer m_osBuf; - SymmetricCipher& m_cipher; - Aws::OStream& m_stream; - CipherMode m_cipherMode; - bool m_isFinalized; - int16_t m_blockOffset; - }; - } - } -} + * buffersize, the size of the src buffers to read at a time. Defaults to 1kb + */ + SymmetricCryptoBufSrc(Aws::IStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize = DEFAULT_BUF_SIZE); + + SymmetricCryptoBufSrc(const SymmetricCryptoBufSrc&) = delete; + SymmetricCryptoBufSrc(SymmetricCryptoBufSrc&&) = delete; + + SymmetricCryptoBufSrc& operator=(const SymmetricCryptoBufSrc&) = delete; + SymmetricCryptoBufSrc& operator=(SymmetricCryptoBufSrc&&) = delete; + + virtual ~SymmetricCryptoBufSrc() { FinalizeCipher(); } + + /** + * This call isn't necessary if you loop over the stream.read until you reach EOF, if you happen to read the exact + * amount as the in memory buffers and finish the stream, but never finish the finalize call you'll need to be sure + * to call this. This is automatically called by the destructor. + */ + void Finalize() override { FinalizeCipher(); } + + protected: + pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override; + pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out ) override; + + private: + int_type underflow() override; + off_type ComputeAbsSeekPosition(off_type, std::ios_base::seekdir, std::fpos<FPOS_TYPE>); + void FinalizeCipher(); + + CryptoBuffer m_isBuf; + SymmetricCipher& m_cipher; + Aws::IStream& m_stream; + CipherMode m_cipherMode; + bool m_isFinalized; + size_t m_bufferSize; + size_t m_putBack; + }; + + /** + * Stream buf that takes it's input, encrypts or decrypts it using the cipher, and writes it to the sink stream. This is particularly useful + * when receiving an encrypted file over the internet and writing it decrypted to disk. Another case may be that you have an ofstream and you want + * to write text to it from your program but have it go encrypted to disk. + * + * This stream buf is not seekable. + */ + class AWS_CORE_API SymmetricCryptoBufSink : public CryptoBuf + { + public: + /** + * stream, sink to push the encrypted or decrypted data to. + * cipher, symmetric cipher to use to transform the input before sending it to the sink. + * cipherMode, encrypt or decrypt + * bufferSize, amount of data to encrypt/decrypt at a time. + */ + SymmetricCryptoBufSink(Aws::OStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize = DEFAULT_BUF_SIZE, int16_t blockOffset = 0); + SymmetricCryptoBufSink(const SymmetricCryptoBufSink&) = delete; + SymmetricCryptoBufSink(SymmetricCryptoBufSink&&) = delete; + + SymmetricCryptoBufSink& operator=(const SymmetricCryptoBufSink&) = delete; + /** + * Not move assignable since it contains reference members + */ + SymmetricCryptoBufSink& operator=(SymmetricCryptoBufSink&&) = delete; + + virtual ~SymmetricCryptoBufSink(); + + /** + * Finalizes the cipher and pushes all remaining data to the sink. Once this has been called, this streambuf cannot be used any further. + */ + void FinalizeCiphersAndFlushSink(); + /** + * Simply calls FinalizeCiphersAndFlushSink() + */ + void Finalize() override { FinalizeCiphersAndFlushSink(); } + + private: + int_type overflow(int_type ch) override; + int sync() override; + bool writeOutput(bool finalize); + + CryptoBuffer m_osBuf; + SymmetricCipher& m_cipher; + Aws::OStream& m_stream; + CipherMode m_cipherMode; + bool m_isFinalized; + int16_t m_blockOffset; + }; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoStream.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoStream.h index 048d44392e..68178c32d4 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoStream.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/CryptoStream.h @@ -2,80 +2,80 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/utils/crypto/CryptoBuf.h> -#include <aws/core/Core_EXPORTS.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - /** - * IOStream that can either take a src buffer as an input stream and create a wrapper iostream that can be used to receive encrypted or decrypted - * input. - * - * A common use case is a file that is encrypted on disk being read via ifstream and then read decrypted into memory. - * Or you could send a plain text file through an iostream and have it encrypted when the stream is read. - * +#pragma once + +#include <aws/core/utils/crypto/CryptoBuf.h> +#include <aws/core/Core_EXPORTS.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + /** + * IOStream that can either take a src buffer as an input stream and create a wrapper iostream that can be used to receive encrypted or decrypted + * input. + * + * A common use case is a file that is encrypted on disk being read via ifstream and then read decrypted into memory. + * Or you could send a plain text file through an iostream and have it encrypted when the stream is read. + * * This stream is seekable, but it is very expensive to seek backwards since we have to reset the cipher and re-encrypt everything up to that point. - * So seeking should be avoided if at all possible. - * - * Or it can be used in the opposite direction where the stream is a sink and all input to the stream will be encrypted or decrypted and then sent to the - * sink stream. - * - * This is particularly useful - * when receiving an encrypted file over the internet and writing it decrypted to disk. Another case may be that you have an ofstream and you want - * to write text to it from your program but have it go encrypted to disk. - * - * In output mode, this stream is not seekable. - */ - class AWS_CORE_API SymmetricCryptoStream : public Aws::IOStream - { - public: - /** - * src stream to read from and encrypt or decrypt in transit - * mode of operation for cipher encryption or decryption - * cipher to use on the data - */ - SymmetricCryptoStream(Aws::IStream& src, CipherMode mode, SymmetricCipher& cipher, size_t bufLen = DEFAULT_BUF_SIZE); - /** - * sink stream to write the data to and encrypt or decrypt in transit - * mode of operation for cipher encryption or decryption - * cipher to use on the data - */ - SymmetricCryptoStream(Aws::OStream& sink, CipherMode mode, SymmetricCipher& cipher, size_t bufLen = DEFAULT_BUF_SIZE, int16_t blockOffset = 0 ); - /** - * bufSrc streambuf to use - */ - SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSrc& bufSrc); - /** - * bufSink streambuf to use - */ - SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSink& bufSink); - - SymmetricCryptoStream(const SymmetricCryptoStream&) = delete; - SymmetricCryptoStream(SymmetricCryptoStream&&) = delete; - - virtual ~SymmetricCryptoStream(); - - SymmetricCryptoStream& operator=(const SymmetricCryptoStream&) = delete; - SymmetricCryptoStream& operator=(SymmetricCryptoStream&&) = delete; - - - /** - * Call this in output stream mode when you want to flush the output to file. - * It will be called by the destructor, but if you want to sync before then, call this method. - * This stream is unusable after this method has been called. - */ - void Finalize(); - - private: - CryptoBuf* m_cryptoBuf; - bool m_hasOwnership; - }; - } - } -}
\ No newline at end of file + * So seeking should be avoided if at all possible. + * + * Or it can be used in the opposite direction where the stream is a sink and all input to the stream will be encrypted or decrypted and then sent to the + * sink stream. + * + * This is particularly useful + * when receiving an encrypted file over the internet and writing it decrypted to disk. Another case may be that you have an ofstream and you want + * to write text to it from your program but have it go encrypted to disk. + * + * In output mode, this stream is not seekable. + */ + class AWS_CORE_API SymmetricCryptoStream : public Aws::IOStream + { + public: + /** + * src stream to read from and encrypt or decrypt in transit + * mode of operation for cipher encryption or decryption + * cipher to use on the data + */ + SymmetricCryptoStream(Aws::IStream& src, CipherMode mode, SymmetricCipher& cipher, size_t bufLen = DEFAULT_BUF_SIZE); + /** + * sink stream to write the data to and encrypt or decrypt in transit + * mode of operation for cipher encryption or decryption + * cipher to use on the data + */ + SymmetricCryptoStream(Aws::OStream& sink, CipherMode mode, SymmetricCipher& cipher, size_t bufLen = DEFAULT_BUF_SIZE, int16_t blockOffset = 0 ); + /** + * bufSrc streambuf to use + */ + SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSrc& bufSrc); + /** + * bufSink streambuf to use + */ + SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSink& bufSink); + + SymmetricCryptoStream(const SymmetricCryptoStream&) = delete; + SymmetricCryptoStream(SymmetricCryptoStream&&) = delete; + + virtual ~SymmetricCryptoStream(); + + SymmetricCryptoStream& operator=(const SymmetricCryptoStream&) = delete; + SymmetricCryptoStream& operator=(SymmetricCryptoStream&&) = delete; + + + /** + * Call this in output stream mode when you want to flush the output to file. + * It will be called by the destructor, but if you want to sync before then, call this method. + * This stream is unusable after this method has been called. + */ + void Finalize(); + + private: + CryptoBuf* m_cryptoBuf; + bool m_hasOwnership; + }; + } + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/EncryptionMaterials.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/EncryptionMaterials.h index 0fbc77c6b4..22116c400f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/EncryptionMaterials.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/EncryptionMaterials.h @@ -2,45 +2,45 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/crypto/CryptoBuf.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/client/AWSError.h> -#include <aws/core/utils/crypto/ContentCryptoMaterial.h> -#include <aws/core/NoResult.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - enum class CryptoErrors - { - ENCRYPT_CONTENT_ENCRYPTION_KEY_FAILED, +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/crypto/CryptoBuf.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/utils/crypto/ContentCryptoMaterial.h> +#include <aws/core/NoResult.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + enum class CryptoErrors + { + ENCRYPT_CONTENT_ENCRYPTION_KEY_FAILED, DECRYPT_CONTENT_ENCRYPTION_KEY_FAILED, GENERATE_CONTENT_ENCRYPTION_KEY_FAILED - }; - - typedef Outcome<Aws::NoResult, Aws::Client::AWSError<CryptoErrors>> CryptoOutcome; - - class AWS_CORE_API EncryptionMaterials - { - public: - virtual ~EncryptionMaterials(); - - /* - * Override this method to control how to encrypt the content encryption key (CEK). This occurs in place. - */ - virtual CryptoOutcome EncryptCEK(ContentCryptoMaterial& contentCryptoMaterial) = 0; - - /* - * Override this method to control how to decrypt the content encryption key (CEK). This occurs in place. - */ - virtual CryptoOutcome DecryptCEK(ContentCryptoMaterial& contentCryptoMaterial) = 0; - }; - }//namespace Crypto - }//namespace Utils -}//namespace Aws + }; + + typedef Outcome<Aws::NoResult, Aws::Client::AWSError<CryptoErrors>> CryptoOutcome; + + class AWS_CORE_API EncryptionMaterials + { + public: + virtual ~EncryptionMaterials(); + + /* + * Override this method to control how to encrypt the content encryption key (CEK). This occurs in place. + */ + virtual CryptoOutcome EncryptCEK(ContentCryptoMaterial& contentCryptoMaterial) = 0; + + /* + * Override this method to control how to decrypt the content encryption key (CEK). This occurs in place. + */ + virtual CryptoOutcome DecryptCEK(ContentCryptoMaterial& contentCryptoMaterial) = 0; + }; + }//namespace Crypto + }//namespace Utils +}//namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h index b4c17b2a96..ff4eceb6eb 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Factories.h @@ -2,146 +2,146 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/Array.h> -#include <memory> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - class Hash; - class HMAC; - class SymmetricCipher; - class HashFactory; - class HMACFactory; - class SymmetricCipherFactory; - class SecureRandomBytes; - class SecureRandomFactory; - - /** - * You need to call this before using any of the cryptography libs. Should be called after setting the factories. - */ - AWS_CORE_API void InitCrypto(); - /** - * You need to call this upon program shutdown. - */ - AWS_CORE_API void CleanupCrypto(); - /** - * OpenSSL infects everything with its global state. If it is being used then we automatically initialize and clean it up. - * If this is a problem for you, set this to false. Be aware that if you don't use our init and cleanup and you are using - * crypto functionality, you are responsible for installing thread locking, and loading strings and error messages. - */ - AWS_CORE_API void SetInitCleanupOpenSSLFlag(bool initCleanupFlag); - - /** - * Create an MD5 Hash provider - */ - AWS_CORE_API std::shared_ptr<Hash> CreateMD5Implementation(); - /** - * Create a Sha256 Hash provider - */ - AWS_CORE_API std::shared_ptr<Hash> CreateSha256Implementation(); - /** - * Create a Sha256 HMACHash provider - */ - AWS_CORE_API std::shared_ptr<HMAC> CreateSha256HMACImplementation(); - - /** - * Create AES in CBC mode off of a 256 bit key. Auto Generates a 16 byte secure random IV - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CBCImplementation(const CryptoBuffer& key); - /** - * Create AES in CBC mode off of a 256 bit key and 16 byte IV - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CBCImplementation(const CryptoBuffer& key, const CryptoBuffer& iv); - /** - * Create AES in CBC mode off of a 256 bit key and 16 byte IV - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CBCImplementation(CryptoBuffer&& key, CryptoBuffer&& iv); - - /** - * Create AES in CTR mode off of a 256 bit key. Auto Generates a 16 byte IV in the format - * [nonce 4bytes ] [securely random iv 8 bytes] [ CTR init 4bytes ] - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CTRImplementation(const CryptoBuffer& key); - /** - * Create AES in CTR mode off of a 256 bit key and 16 byte IV - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CTRImplementation(const CryptoBuffer& key, const CryptoBuffer& iv); - /** - * Create AES in CTR mode off of a 256 bit key and 16 byte IV - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CTRImplementation(CryptoBuffer&& key, CryptoBuffer&& iv); - - /** + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/Array.h> +#include <memory> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + class Hash; + class HMAC; + class SymmetricCipher; + class HashFactory; + class HMACFactory; + class SymmetricCipherFactory; + class SecureRandomBytes; + class SecureRandomFactory; + + /** + * You need to call this before using any of the cryptography libs. Should be called after setting the factories. + */ + AWS_CORE_API void InitCrypto(); + /** + * You need to call this upon program shutdown. + */ + AWS_CORE_API void CleanupCrypto(); + /** + * OpenSSL infects everything with its global state. If it is being used then we automatically initialize and clean it up. + * If this is a problem for you, set this to false. Be aware that if you don't use our init and cleanup and you are using + * crypto functionality, you are responsible for installing thread locking, and loading strings and error messages. + */ + AWS_CORE_API void SetInitCleanupOpenSSLFlag(bool initCleanupFlag); + + /** + * Create an MD5 Hash provider + */ + AWS_CORE_API std::shared_ptr<Hash> CreateMD5Implementation(); + /** + * Create a Sha256 Hash provider + */ + AWS_CORE_API std::shared_ptr<Hash> CreateSha256Implementation(); + /** + * Create a Sha256 HMACHash provider + */ + AWS_CORE_API std::shared_ptr<HMAC> CreateSha256HMACImplementation(); + + /** + * Create AES in CBC mode off of a 256 bit key. Auto Generates a 16 byte secure random IV + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CBCImplementation(const CryptoBuffer& key); + /** + * Create AES in CBC mode off of a 256 bit key and 16 byte IV + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CBCImplementation(const CryptoBuffer& key, const CryptoBuffer& iv); + /** + * Create AES in CBC mode off of a 256 bit key and 16 byte IV + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CBCImplementation(CryptoBuffer&& key, CryptoBuffer&& iv); + + /** + * Create AES in CTR mode off of a 256 bit key. Auto Generates a 16 byte IV in the format + * [nonce 4bytes ] [securely random iv 8 bytes] [ CTR init 4bytes ] + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CTRImplementation(const CryptoBuffer& key); + /** + * Create AES in CTR mode off of a 256 bit key and 16 byte IV + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CTRImplementation(const CryptoBuffer& key, const CryptoBuffer& iv); + /** + * Create AES in CTR mode off of a 256 bit key and 16 byte IV + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_CTRImplementation(CryptoBuffer&& key, CryptoBuffer&& iv); + + /** * Create AES in GCM mode off of a 256 bit key. Auto Generates a 12 byte secure random IV. - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(const CryptoBuffer& key); - /** + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(const CryptoBuffer& key); + /** * Create AES in GCM mode off of a 256 bit key. Auto Generates a 12 byte secure random IV and aad. */ AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer* aad); /** * Create AES in GCM mode off of a 256 bit key, a 12 byte secure random IV, and an optional 16 byte Tag. If you are using this - * cipher to decrypt an encrypted payload, you must set the tag here. - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, + * cipher to decrypt an encrypted payload, you must set the tag here. + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag = CryptoBuffer(0), const CryptoBuffer& aad = CryptoBuffer(0)); - /** + /** * Create AES in GCM mode off of a 256 bit key, a 16 byte secure random IV, and an optional 16 byte Tag, as well an optional add. If you are using this - * cipher to decrypt an encrypted payload, you must set the tag here. - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, + * cipher to decrypt an encrypted payload, you must set the tag here. + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_GCMImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag = CryptoBuffer(0), CryptoBuffer&& aad = CryptoBuffer(0)); - /** - * Create AES in Key Wrap mode off of a 256 bit key. - */ - AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_KeyWrapImplementation(const CryptoBuffer& key); - - /** - * Create SecureRandomBytes instance - */ - AWS_CORE_API std::shared_ptr<SecureRandomBytes> CreateSecureRandomBytesImplementation(); - - /** - * Set the global factory for MD5 Hash providers - */ - AWS_CORE_API void SetMD5Factory(const std::shared_ptr<HashFactory>& factory); - /** - * Set the global factory for Sha256 Hash providers - */ - AWS_CORE_API void SetSha256Factory(const std::shared_ptr<HashFactory>& factory); - /** - * Set the global factory for Sha256 HMAC Hash providers - */ - AWS_CORE_API void SetSha256HMACFactory(const std::shared_ptr<HMACFactory>& factory); - /** - * Set the global factory for AES in CBC mode providers - */ - AWS_CORE_API void SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); - /** - * Set the global factory for AES in CTR mode providers - */ - AWS_CORE_API void SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); - /** - * Set the global factory for AES in GCM mode providers - */ - AWS_CORE_API void SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); - /** - * Set the global factory for AES in Key Wrap mode providers - */ - AWS_CORE_API void SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); - /** - * Set the global factory for secure random bytes - */ - AWS_CORE_API void SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory>& factory); - - } // namespace Crypto - } // namespace Utils -} // namespace Aws + /** + * Create AES in Key Wrap mode off of a 256 bit key. + */ + AWS_CORE_API std::shared_ptr<SymmetricCipher> CreateAES_KeyWrapImplementation(const CryptoBuffer& key); + + /** + * Create SecureRandomBytes instance + */ + AWS_CORE_API std::shared_ptr<SecureRandomBytes> CreateSecureRandomBytesImplementation(); + + /** + * Set the global factory for MD5 Hash providers + */ + AWS_CORE_API void SetMD5Factory(const std::shared_ptr<HashFactory>& factory); + /** + * Set the global factory for Sha256 Hash providers + */ + AWS_CORE_API void SetSha256Factory(const std::shared_ptr<HashFactory>& factory); + /** + * Set the global factory for Sha256 HMAC Hash providers + */ + AWS_CORE_API void SetSha256HMACFactory(const std::shared_ptr<HMACFactory>& factory); + /** + * Set the global factory for AES in CBC mode providers + */ + AWS_CORE_API void SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); + /** + * Set the global factory for AES in CTR mode providers + */ + AWS_CORE_API void SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); + /** + * Set the global factory for AES in GCM mode providers + */ + AWS_CORE_API void SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); + /** + * Set the global factory for AES in Key Wrap mode providers + */ + AWS_CORE_API void SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory>& factory); + /** + * Set the global factory for secure random bytes + */ + AWS_CORE_API void SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory>& factory); + + } // namespace Crypto + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HMAC.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HMAC.h index 450997c736..9caa5033d7 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HMAC.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HMAC.h @@ -2,67 +2,67 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - /* - * Interface for Sha256 encryptor and hmac - */ -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/Array.h> -#include <aws/core/utils/crypto/HashResult.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - /** - * Interface for HMAC hash providers. To implement an HMAC provider, inherit from this class and override Calculate. - */ - class AWS_CORE_API HMAC - { - public: - HMAC() {}; - virtual ~HMAC() {}; - - /** - * Calculates an HMAC digest - */ - virtual HashResult Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret) = 0; - - }; - - /** - * Simple abstract factory interface. Subclass this and create a factory if you want to control - * how HMAC Hash objects are created. - */ - class AWS_CORE_API HMACFactory - { - public: - virtual ~HMACFactory() {} - - /** - * Factory method. Returns hmac hash implementation. - */ - virtual std::shared_ptr<HMAC> CreateImplementation() const = 0; - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - virtual void InitStaticState() {} - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - virtual void CleanupStaticState() {} - }; - - } // namespace Crypto - } // namespace Utils -} // namespace Aws - + + /* + * Interface for Sha256 encryptor and hmac + */ +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/Array.h> +#include <aws/core/utils/crypto/HashResult.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + /** + * Interface for HMAC hash providers. To implement an HMAC provider, inherit from this class and override Calculate. + */ + class AWS_CORE_API HMAC + { + public: + HMAC() {}; + virtual ~HMAC() {}; + + /** + * Calculates an HMAC digest + */ + virtual HashResult Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret) = 0; + + }; + + /** + * Simple abstract factory interface. Subclass this and create a factory if you want to control + * how HMAC Hash objects are created. + */ + class AWS_CORE_API HMACFactory + { + public: + virtual ~HMACFactory() {} + + /** + * Factory method. Returns hmac hash implementation. + */ + virtual std::shared_ptr<HMAC> CreateImplementation() const = 0; + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + virtual void InitStaticState() {} + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + virtual void CleanupStaticState() {} + }; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h index 8ebbe009fc..a60b5eba7a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Hash.h @@ -2,72 +2,72 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/crypto/HashResult.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - /** - * Interface for computing hash codes using various hash algorithms - */ - class AWS_CORE_API Hash - { - public: - - Hash() {} - virtual ~Hash() {} - - /** - * Calculates a Hash digest - */ - virtual HashResult Calculate(const Aws::String& str) = 0; - - /** - * Calculates a Hash digest on a stream (the entire stream is read) - */ - virtual HashResult Calculate(Aws::IStream& stream) = 0; - - // when hashing streams, this is the size of our internal buffer we read the stream into - static const uint32_t INTERNAL_HASH_STREAM_BUFFER_SIZE = 8192; - }; - - /** - * Simple abstract factory interface. Subclass this and create a factory if you want to control - * how Hash objects are created. - */ - class AWS_CORE_API HashFactory - { - public: - virtual ~HashFactory() {} - - /** - * Factory method. Returns hash implementation. - */ - virtual std::shared_ptr<Hash> CreateImplementation() const = 0; - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - virtual void InitStaticState() {} - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - virtual void CleanupStaticState() {} - }; - - } // namespace Crypto - } // namespace Utils -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/crypto/HashResult.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + /** + * Interface for computing hash codes using various hash algorithms + */ + class AWS_CORE_API Hash + { + public: + + Hash() {} + virtual ~Hash() {} + + /** + * Calculates a Hash digest + */ + virtual HashResult Calculate(const Aws::String& str) = 0; + + /** + * Calculates a Hash digest on a stream (the entire stream is read) + */ + virtual HashResult Calculate(Aws::IStream& stream) = 0; + + // when hashing streams, this is the size of our internal buffer we read the stream into + static const uint32_t INTERNAL_HASH_STREAM_BUFFER_SIZE = 8192; + }; + + /** + * Simple abstract factory interface. Subclass this and create a factory if you want to control + * how Hash objects are created. + */ + class AWS_CORE_API HashFactory + { + public: + virtual ~HashFactory() {} + + /** + * Factory method. Returns hash implementation. + */ + virtual std::shared_ptr<Hash> CreateImplementation() const = 0; + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + virtual void InitStaticState() {} + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + virtual void CleanupStaticState() {} + }; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HashResult.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HashResult.h index 46b46d8095..0831e1c132 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HashResult.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/HashResult.h @@ -2,24 +2,24 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/Array.h> - -namespace Aws -{ - namespace Utils - { - - template< typename R, typename E > class Outcome; - - namespace Crypto - { - using HashResult = Outcome< ByteBuffer, bool >; - - } // namespace Crypto - } // namespace Utils -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/Array.h> + +namespace Aws +{ + namespace Utils + { + + template< typename R, typename E > class Outcome; + + namespace Crypto + { + using HashResult = Outcome< ByteBuffer, bool >; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/KeyWrapAlgorithm.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/KeyWrapAlgorithm.h index 0715f64740..6702f5625d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/KeyWrapAlgorithm.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/KeyWrapAlgorithm.h @@ -2,32 +2,32 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - enum class KeyWrapAlgorithm - { +#pragma once +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + enum class KeyWrapAlgorithm + { KMS, // Deprecated KMS_CONTEXT, AES_KEY_WRAP, // Deprecated AES_GCM, - NONE - }; - - namespace KeyWrapAlgorithmMapper - { - AWS_CORE_API KeyWrapAlgorithm GetKeyWrapAlgorithmForName(const Aws::String& name); - - AWS_CORE_API Aws::String GetNameForKeyWrapAlgorithm(KeyWrapAlgorithm enumValue); - } - } //namespace Crypto - - }//namespace Utils -}//namespace Aws + NONE + }; + + namespace KeyWrapAlgorithmMapper + { + AWS_CORE_API KeyWrapAlgorithm GetKeyWrapAlgorithmForName(const Aws::String& name); + + AWS_CORE_API Aws::String GetNameForKeyWrapAlgorithm(KeyWrapAlgorithm enumValue); + } + } //namespace Crypto + + }//namespace Utils +}//namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h index 59304a4a88..115213e928 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/MD5.h @@ -2,65 +2,65 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - /* - * Interface for Sha256 encryptor and hmac - */ -#pragma once - -#ifdef __APPLE__ - -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif // __clang__ - -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif // __GNUC__ - -#endif // __APPLE__ - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/crypto/Hash.h> -#include <aws/core/utils/Outcome.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - class WindowsHashImpl; - - /** - * Md5 hash implementation - */ - class AWS_CORE_API MD5 : public Hash - { - public: - /** + + /* + * Interface for Sha256 encryptor and hmac + */ +#pragma once + +#ifdef __APPLE__ + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif // __clang__ + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#endif // __APPLE__ + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/crypto/Hash.h> +#include <aws/core/utils/Outcome.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + class WindowsHashImpl; + + /** + * Md5 hash implementation + */ + class AWS_CORE_API MD5 : public Hash + { + public: + /** * Initializes platform crypto libs for md5 - */ - MD5(); - virtual ~MD5(); - - /** - * Calculates an MD5 hash - */ - virtual HashResult Calculate(const Aws::String& str) override; - - /** - * Calculates a Hash digest on a stream (the entire stream is read) - */ - virtual HashResult Calculate(Aws::IStream& stream) override; - - private: - - std::shared_ptr<Hash> m_hashImpl; - }; - - } // namespace Crypto - } // namespace Utils -} // namespace Aws - + */ + MD5(); + virtual ~MD5(); + + /** + * Calculates an MD5 hash + */ + virtual HashResult Calculate(const Aws::String& str) override; + + /** + * Calculates a Hash digest on a stream (the entire stream is read) + */ + virtual HashResult Calculate(Aws::IStream& stream) override; + + private: + + std::shared_ptr<Hash> m_hashImpl; + }; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/SecureRandom.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/SecureRandom.h index 7f48dc008d..4f5a372a01 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/SecureRandom.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/SecureRandom.h @@ -2,115 +2,115 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once -#include <type_traits> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - /** - * Interface for generating Random Bytes with guaranteed entropy for use with cryptographic functions. - * An instance is not guaranteed to be thread safe. This is intentional, that is needless overhead to - * pay for something you probably don't need. If you encounter a need for thread safety, you are responsible - * for memory fencing. - */ - class SecureRandomBytes - { - public: - SecureRandomBytes() : m_failure(false) - { - } - - virtual ~SecureRandomBytes() = default; - - /** - * fill in buffer of size bufferSize with random bytes - */ - virtual void GetBytes(unsigned char* buffer, size_t bufferSize) = 0; - - /** - * Always check this. If anything goes wrong, this tells you - */ - operator bool() const { return !m_failure; } - - protected: - bool m_failure; - }; - - /** - * Random Number generator for integral types. Guaranteed to have entropy or your program will crash. - */ - template <typename DataType = uint64_t> - class SecureRandom - { - public: - /** - * Initialize with the results of CreateSecureRandomBytesImplementation(). - * An instance is not guaranteed to be thread safe. This is intentional, that is needless overhead to - * pay for something you probably don't need. If you encounter a need for thread safety, you are responsible - * for memory fencing. - */ - SecureRandom(const std::shared_ptr<SecureRandomBytes>& entropySource) : m_entropy(entropySource) - { static_assert(std::is_unsigned<DataType>::value, "Type DataType must be integral"); } - - virtual ~SecureRandom() = default; - - virtual void Reset() {} - - /** - * Generate a random number of DataType - */ - virtual DataType operator()() - { - DataType value(0); - unsigned char buffer[sizeof(DataType)]; - m_entropy->GetBytes(buffer, sizeof(DataType)); - - assert(*m_entropy); - if(*m_entropy) - { - for (size_t i = 0; i < sizeof(DataType); ++i) - { - value <<= 8; - value |= buffer[i]; - - } - } - - return value; - } - - operator bool() const { return *m_entropy; } - - private: - std::shared_ptr<SecureRandomBytes> m_entropy; - }; - - class SecureRandomFactory - { - public: - virtual ~SecureRandomFactory() = default; - - /** - * Factory method. Returns SecureRandom implementation. - */ - virtual std::shared_ptr<SecureRandomBytes> CreateImplementation() const = 0; - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - virtual void InitStaticState() {} - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - virtual void CleanupStaticState() {} - }; - } - } -} +#pragma once +#include <type_traits> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + /** + * Interface for generating Random Bytes with guaranteed entropy for use with cryptographic functions. + * An instance is not guaranteed to be thread safe. This is intentional, that is needless overhead to + * pay for something you probably don't need. If you encounter a need for thread safety, you are responsible + * for memory fencing. + */ + class SecureRandomBytes + { + public: + SecureRandomBytes() : m_failure(false) + { + } + + virtual ~SecureRandomBytes() = default; + + /** + * fill in buffer of size bufferSize with random bytes + */ + virtual void GetBytes(unsigned char* buffer, size_t bufferSize) = 0; + + /** + * Always check this. If anything goes wrong, this tells you + */ + operator bool() const { return !m_failure; } + + protected: + bool m_failure; + }; + + /** + * Random Number generator for integral types. Guaranteed to have entropy or your program will crash. + */ + template <typename DataType = uint64_t> + class SecureRandom + { + public: + /** + * Initialize with the results of CreateSecureRandomBytesImplementation(). + * An instance is not guaranteed to be thread safe. This is intentional, that is needless overhead to + * pay for something you probably don't need. If you encounter a need for thread safety, you are responsible + * for memory fencing. + */ + SecureRandom(const std::shared_ptr<SecureRandomBytes>& entropySource) : m_entropy(entropySource) + { static_assert(std::is_unsigned<DataType>::value, "Type DataType must be integral"); } + + virtual ~SecureRandom() = default; + + virtual void Reset() {} + + /** + * Generate a random number of DataType + */ + virtual DataType operator()() + { + DataType value(0); + unsigned char buffer[sizeof(DataType)]; + m_entropy->GetBytes(buffer, sizeof(DataType)); + + assert(*m_entropy); + if(*m_entropy) + { + for (size_t i = 0; i < sizeof(DataType); ++i) + { + value <<= 8; + value |= buffer[i]; + + } + } + + return value; + } + + operator bool() const { return *m_entropy; } + + private: + std::shared_ptr<SecureRandomBytes> m_entropy; + }; + + class SecureRandomFactory + { + public: + virtual ~SecureRandomFactory() = default; + + /** + * Factory method. Returns SecureRandom implementation. + */ + virtual std::shared_ptr<SecureRandomBytes> CreateImplementation() const = 0; + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + virtual void InitStaticState() {} + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + virtual void CleanupStaticState() {} + }; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h index 441752b0a6..7fc46727f1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256.h @@ -2,64 +2,64 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - /* - * Interface for Sha256 encryptor and hmac - */ -#pragma once - -#ifdef __APPLE__ - -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif // __clang__ - -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif // __GNUC__ - -#endif // __APPLE__ - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/crypto/Hash.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - class WindowsHashImpl; - - /** - * Sha256 hash implementation. - */ - class AWS_CORE_API Sha256 : public Hash - { - public: - /** - * Initializes platform crypto libs. - */ - Sha256(); - virtual ~Sha256(); - - /** - * Calculates a SHA256 Hash digest (not hex encoded) - */ - virtual HashResult Calculate(const Aws::String& str) override; - - /** - * Calculates a Hash digest on a stream (the entire stream is read) - */ - virtual HashResult Calculate(Aws::IStream& stream) override; - - private: - - std::shared_ptr< Hash > m_hashImpl; - }; - - } // namespace Crypto - } // namespace Utils -} // namespace Aws - + + /* + * Interface for Sha256 encryptor and hmac + */ +#pragma once + +#ifdef __APPLE__ + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif // __clang__ + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#endif // __APPLE__ + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/crypto/Hash.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + class WindowsHashImpl; + + /** + * Sha256 hash implementation. + */ + class AWS_CORE_API Sha256 : public Hash + { + public: + /** + * Initializes platform crypto libs. + */ + Sha256(); + virtual ~Sha256(); + + /** + * Calculates a SHA256 Hash digest (not hex encoded) + */ + virtual HashResult Calculate(const Aws::String& str) override; + + /** + * Calculates a Hash digest on a stream (the entire stream is read) + */ + virtual HashResult Calculate(Aws::IStream& stream) override; + + private: + + std::shared_ptr< Hash > m_hashImpl; + }; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256HMAC.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256HMAC.h index d035b99da5..b78624186d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256HMAC.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/Sha256HMAC.h @@ -2,58 +2,58 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - /* - * Interface for Sha256 encryptor and hmac - */ -#pragma once - -#ifdef __APPLE__ - -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif // __clang__ - -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif // __GNUC__ - -#endif // __APPLE__ - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/crypto/HMAC.h> -#include <aws/core/utils/memory/AWSMemory.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - /** - * Sha256 HMAC implementation - */ - class AWS_CORE_API Sha256HMAC : public HMAC - { - public: - /** - * initializes platform specific libs. - */ - Sha256HMAC(); - virtual ~Sha256HMAC(); - - /** - * Calculates a SHA256 HMAC digest (not hex encoded) - */ - virtual HashResult Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret) override; - - private: - - std::shared_ptr< HMAC > m_hmacImpl; - }; - - } // namespace Sha256 - } // namespace Utils -} // namespace Aws - + + /* + * Interface for Sha256 encryptor and hmac + */ +#pragma once + +#ifdef __APPLE__ + +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif // __clang__ + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // __GNUC__ + +#endif // __APPLE__ + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/crypto/HMAC.h> +#include <aws/core/utils/memory/AWSMemory.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + /** + * Sha256 HMAC implementation + */ + class AWS_CORE_API Sha256HMAC : public HMAC + { + public: + /** + * initializes platform specific libs. + */ + Sha256HMAC(); + virtual ~Sha256HMAC(); + + /** + * Calculates a SHA256 HMAC digest (not hex encoded) + */ + virtual HashResult Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret) override; + + private: + + std::shared_ptr< HMAC > m_hmacImpl; + }; + + } // namespace Sha256 + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h index e3f37edda9..5c6980ae08 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/crypto/openssl/CryptoImpl.h @@ -2,277 +2,277 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#pragma once - -#include <aws/core/utils/crypto/Hash.h> -#include <aws/core/utils/crypto/HMAC.h> -#include <aws/core/utils/crypto/Cipher.h> -#include <aws/core/utils/crypto/SecureRandom.h> -#include <aws/core/utils/GetTheLights.h> -#include <openssl/ossl_typ.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> -#include <openssl/rand.h> -#include <atomic> -#include <mutex> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - namespace OpenSSL - { - extern GetTheLights getTheLights; - - void init_static_state(); - - void cleanup_static_state(); - - void locking_fn(int mode, int n, const char* file, int line); - - unsigned long id_fn(); - } - - /** - * OpenSSL implementation for SecureRandomBytes. +#pragma once + +#include <aws/core/utils/crypto/Hash.h> +#include <aws/core/utils/crypto/HMAC.h> +#include <aws/core/utils/crypto/Cipher.h> +#include <aws/core/utils/crypto/SecureRandom.h> +#include <aws/core/utils/GetTheLights.h> +#include <openssl/ossl_typ.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/rand.h> +#include <atomic> +#include <mutex> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + namespace OpenSSL + { + extern GetTheLights getTheLights; + + void init_static_state(); + + void cleanup_static_state(); + + void locking_fn(int mode, int n, const char* file, int line); + + unsigned long id_fn(); + } + + /** + * OpenSSL implementation for SecureRandomBytes. * Incidentally, this implementation is thread safe, though it is not - * on other platforms. You should treat an instance of SecureRandomBytes - * as needed to be memory fenced if you will be using accross multiple threads - */ - class SecureRandomBytes_OpenSSLImpl : public SecureRandomBytes - { - public: - SecureRandomBytes_OpenSSLImpl() - { } - - ~SecureRandomBytes_OpenSSLImpl() = default; - - /** - * Reads bufferSize bytes from RAND_bytes into buffer. - */ - void GetBytes(unsigned char* buffer, size_t bufferSize) override; - }; - - class MD5OpenSSLImpl : public Hash - { - public: - - MD5OpenSSLImpl() - { } - - virtual ~MD5OpenSSLImpl() = default; - - virtual HashResult Calculate(const Aws::String& str) override; - - virtual HashResult Calculate(Aws::IStream& stream) override; - - }; - - class Sha256OpenSSLImpl : public Hash - { - public: - Sha256OpenSSLImpl() - { } - - virtual ~Sha256OpenSSLImpl() = default; - - virtual HashResult Calculate(const Aws::String& str) override; - - virtual HashResult Calculate(Aws::IStream& stream) override; - }; - - class Sha256HMACOpenSSLImpl : public HMAC - { - public: - virtual ~Sha256HMACOpenSSLImpl() = default; - - virtual HashResult Calculate(const ByteBuffer& toSign, const ByteBuffer& secret) override; - }; - - /** - * OpenSSL implementation for SymmetricCipher - */ - class OpenSSLCipher : public SymmetricCipher - { - public: - /** - * Creates new OpenSSL based cipher for key, and autogenerates a secure IV of size ivSize - */ - OpenSSLCipher(const CryptoBuffer& key, size_t ivSize, bool ctrMode = false); - - /** - * Creates new OpenSSL based cipher for key, initializationVector, and optional tag. If this is an authenticated - * cipher being used for decryption. - */ - OpenSSLCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, - CryptoBuffer&& tag = CryptoBuffer(0)); - - /** - * Creates new OpenSSL based cipher for key, initializationVector, and optional tag. If this is an authenticated - * cipher being used for decryption. - */ - OpenSSLCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, - const CryptoBuffer& tag = CryptoBuffer(0)); - - OpenSSLCipher(const OpenSSLCipher& other) = delete; - - OpenSSLCipher& operator=(const OpenSSLCipher& other) = delete; - - /** - * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, - * so let's go ahead and optimize by defining default move operations. Implementors of this class - * need to be sure to define the move operations and call the base class. - */ - OpenSSLCipher(OpenSSLCipher&& toMove); - - /** - * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, - * so let's go ahead and optimize by defining default move operations. Implementors of this class - * need to be sure to define the move operations and call the base class. - */ - OpenSSLCipher& operator=(OpenSSLCipher&& toMove) = default; - - - virtual ~OpenSSLCipher(); - - /** - * Encrypt a buffer of data. Part of the contract for this interface is that intention that - * a user call this function multiple times for a large stream. As such, multiple calls to this function - * on the same instance should produce valid sequential output for an encrypted stream. - */ - CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override; - - /** - * Finalize Encryption, returns anything remaining in the last block - */ - CryptoBuffer FinalizeEncryption() override; - - /** - * Decrypt a buffer of data. Part of the contract for this interface is that intention that + * on other platforms. You should treat an instance of SecureRandomBytes + * as needed to be memory fenced if you will be using accross multiple threads + */ + class SecureRandomBytes_OpenSSLImpl : public SecureRandomBytes + { + public: + SecureRandomBytes_OpenSSLImpl() + { } + + ~SecureRandomBytes_OpenSSLImpl() = default; + + /** + * Reads bufferSize bytes from RAND_bytes into buffer. + */ + void GetBytes(unsigned char* buffer, size_t bufferSize) override; + }; + + class MD5OpenSSLImpl : public Hash + { + public: + + MD5OpenSSLImpl() + { } + + virtual ~MD5OpenSSLImpl() = default; + + virtual HashResult Calculate(const Aws::String& str) override; + + virtual HashResult Calculate(Aws::IStream& stream) override; + + }; + + class Sha256OpenSSLImpl : public Hash + { + public: + Sha256OpenSSLImpl() + { } + + virtual ~Sha256OpenSSLImpl() = default; + + virtual HashResult Calculate(const Aws::String& str) override; + + virtual HashResult Calculate(Aws::IStream& stream) override; + }; + + class Sha256HMACOpenSSLImpl : public HMAC + { + public: + virtual ~Sha256HMACOpenSSLImpl() = default; + + virtual HashResult Calculate(const ByteBuffer& toSign, const ByteBuffer& secret) override; + }; + + /** + * OpenSSL implementation for SymmetricCipher + */ + class OpenSSLCipher : public SymmetricCipher + { + public: + /** + * Creates new OpenSSL based cipher for key, and autogenerates a secure IV of size ivSize + */ + OpenSSLCipher(const CryptoBuffer& key, size_t ivSize, bool ctrMode = false); + + /** + * Creates new OpenSSL based cipher for key, initializationVector, and optional tag. If this is an authenticated + * cipher being used for decryption. + */ + OpenSSLCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, + CryptoBuffer&& tag = CryptoBuffer(0)); + + /** + * Creates new OpenSSL based cipher for key, initializationVector, and optional tag. If this is an authenticated + * cipher being used for decryption. + */ + OpenSSLCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, + const CryptoBuffer& tag = CryptoBuffer(0)); + + OpenSSLCipher(const OpenSSLCipher& other) = delete; + + OpenSSLCipher& operator=(const OpenSSLCipher& other) = delete; + + /** + * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, + * so let's go ahead and optimize by defining default move operations. Implementors of this class + * need to be sure to define the move operations and call the base class. + */ + OpenSSLCipher(OpenSSLCipher&& toMove); + + /** + * Normally we don't work around VS 2013 not auto-generating these, but they are kind of expensive, + * so let's go ahead and optimize by defining default move operations. Implementors of this class + * need to be sure to define the move operations and call the base class. + */ + OpenSSLCipher& operator=(OpenSSLCipher&& toMove) = default; + + + virtual ~OpenSSLCipher(); + + /** + * Encrypt a buffer of data. Part of the contract for this interface is that intention that + * a user call this function multiple times for a large stream. As such, multiple calls to this function + * on the same instance should produce valid sequential output for an encrypted stream. + */ + CryptoBuffer EncryptBuffer(const CryptoBuffer& unEncryptedData) override; + + /** + * Finalize Encryption, returns anything remaining in the last block + */ + CryptoBuffer FinalizeEncryption() override; + + /** + * Decrypt a buffer of data. Part of the contract for this interface is that intention that * a user call this function multiple times for a large stream. As such, multiple calls to this function - * on the same instance should produce valid sequential output from an encrypted stream. - */ - CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override; - - /** - * Finalize Decryption, returns anything remaining in the last block - */ - CryptoBuffer FinalizeDecryption() override; - - void Reset() override; - - protected: - virtual size_t GetBlockSizeBytes() const = 0; - virtual size_t GetKeyLengthBits() const = 0; + * on the same instance should produce valid sequential output from an encrypted stream. + */ + CryptoBuffer DecryptBuffer(const CryptoBuffer& encryptedData) override; + + /** + * Finalize Decryption, returns anything remaining in the last block + */ + CryptoBuffer FinalizeDecryption() override; + + void Reset() override; + + protected: + virtual size_t GetBlockSizeBytes() const = 0; + virtual size_t GetKeyLengthBits() const = 0; bool CheckKeyAndIVLength(size_t expectedKeyLength, size_t expectedIVLength); - - EVP_CIPHER_CTX* m_encryptor_ctx; - EVP_CIPHER_CTX* m_decryptor_ctx; - private: - void Init(); - void Cleanup(); + + EVP_CIPHER_CTX* m_encryptor_ctx; + EVP_CIPHER_CTX* m_decryptor_ctx; + private: + void Init(); + void Cleanup(); /* openssl has bug finalize decryption of an empty string */ bool m_emptyPlaintext; - }; - - /** - * OpenSSL implementation for AES in CBC mode - */ - class AES_CBC_Cipher_OpenSSL : public OpenSSLCipher - { - public: - /** - * Create AES in CBC mode off of a 256 bit key. Auto Generates a 16 byte secure random IV - */ - AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key); - - /** - * Create AES in CBC mode off of a 256 bit key and 16 byte IV - */ - AES_CBC_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector); - - /** - * Create AES in CBC mode off of a 256 bit key and 16 byte IV - */ - AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector); - - AES_CBC_Cipher_OpenSSL(const AES_CBC_Cipher_OpenSSL& other) = delete; - - AES_CBC_Cipher_OpenSSL& operator=(const AES_CBC_Cipher_OpenSSL& other) = delete; - - AES_CBC_Cipher_OpenSSL(AES_CBC_Cipher_OpenSSL&& toMove) = default; - + }; + + /** + * OpenSSL implementation for AES in CBC mode + */ + class AES_CBC_Cipher_OpenSSL : public OpenSSLCipher + { + public: + /** + * Create AES in CBC mode off of a 256 bit key. Auto Generates a 16 byte secure random IV + */ + AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key); + + /** + * Create AES in CBC mode off of a 256 bit key and 16 byte IV + */ + AES_CBC_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector); + + /** + * Create AES in CBC mode off of a 256 bit key and 16 byte IV + */ + AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector); + + AES_CBC_Cipher_OpenSSL(const AES_CBC_Cipher_OpenSSL& other) = delete; + + AES_CBC_Cipher_OpenSSL& operator=(const AES_CBC_Cipher_OpenSSL& other) = delete; + + AES_CBC_Cipher_OpenSSL(AES_CBC_Cipher_OpenSSL&& toMove) = default; + void Reset() override; - protected: - size_t GetBlockSizeBytes() const override; - - size_t GetKeyLengthBits() const override; - - private: - void InitCipher(); - - static size_t BlockSizeBytes; - static size_t KeyLengthBits; - }; - - /** - * OpenSSL implementation for AES in CTR mode - */ - class AES_CTR_Cipher_OpenSSL : public OpenSSLCipher - { - public: - /** - * Create AES in CTR mode off of a 256 bit key. Auto Generates a 16 byte IV in the format - * [nonce 4bytes ] [securely random iv 8 bytes] [ CTR init 4bytes ] - */ - AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key); - - /** - * Create AES in CTR mode off of a 256 bit key and 16 byte IV - */ - AES_CTR_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector); - - /** - * Create AES in CTR mode off of a 256 bit key and 16 byte IV - */ - AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector); - - AES_CTR_Cipher_OpenSSL(const AES_CTR_Cipher_OpenSSL& other) = delete; - - AES_CTR_Cipher_OpenSSL& operator=(const AES_CTR_Cipher_OpenSSL& other) = delete; - - AES_CTR_Cipher_OpenSSL(AES_CTR_Cipher_OpenSSL&& toMove) = default; - + protected: + size_t GetBlockSizeBytes() const override; + + size_t GetKeyLengthBits() const override; + + private: + void InitCipher(); + + static size_t BlockSizeBytes; + static size_t KeyLengthBits; + }; + + /** + * OpenSSL implementation for AES in CTR mode + */ + class AES_CTR_Cipher_OpenSSL : public OpenSSLCipher + { + public: + /** + * Create AES in CTR mode off of a 256 bit key. Auto Generates a 16 byte IV in the format + * [nonce 4bytes ] [securely random iv 8 bytes] [ CTR init 4bytes ] + */ + AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key); + + /** + * Create AES in CTR mode off of a 256 bit key and 16 byte IV + */ + AES_CTR_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector); + + /** + * Create AES in CTR mode off of a 256 bit key and 16 byte IV + */ + AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector); + + AES_CTR_Cipher_OpenSSL(const AES_CTR_Cipher_OpenSSL& other) = delete; + + AES_CTR_Cipher_OpenSSL& operator=(const AES_CTR_Cipher_OpenSSL& other) = delete; + + AES_CTR_Cipher_OpenSSL(AES_CTR_Cipher_OpenSSL&& toMove) = default; + void Reset() override; - protected: - size_t GetBlockSizeBytes() const override; - - size_t GetKeyLengthBits() const override; - - private: - void InitCipher(); - - static size_t BlockSizeBytes; - static size_t KeyLengthBits; - }; - - /** - * OpenSSL implementation for AES in GCM mode - */ - class AES_GCM_Cipher_OpenSSL : public OpenSSLCipher - { - public: - /** + protected: + size_t GetBlockSizeBytes() const override; + + size_t GetKeyLengthBits() const override; + + private: + void InitCipher(); + + static size_t BlockSizeBytes; + static size_t KeyLengthBits; + }; + + /** + * OpenSSL implementation for AES in GCM mode + */ + class AES_GCM_Cipher_OpenSSL : public OpenSSLCipher + { + public: + /** * Create AES in GCM mode off of a 256 bit key. Auto Generates a 12 byte secure random IV. - */ - AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key); - - /** + */ + AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key); + + /** * Create AES in GCM mode off of a 256 bit key and AAD. Auto Generates a 12 byte IV in the format */ AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer* aad); @@ -281,91 +281,91 @@ namespace Aws * Create AES in GCM mode off of a 256 bit key, a 12 byte secure random IV, and an optional 16 byte Tag and additional authentication data (AAD). * Note that tag could be acquired from encrypt mode and should only be set for decrypt mode. * If you are using this cipher to decrypt an encrypted payload, you must set the tag here. - */ - AES_GCM_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector, + */ + AES_GCM_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag = CryptoBuffer(0), CryptoBuffer&& aad = CryptoBuffer(0)); - - /** + + /** * Create AES in GCM mode off of a 256 bit key, a 12 byte secure random IV, and an optional 16 byte Tag and additional authentication data (AAD). * Note that tag could be acquired from encrypt mode and should only be set for decrypt mode. * If you are using this cipher to decrypt an encrypted payload, you must set the tag here. - */ - AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector, + */ + AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag = CryptoBuffer(0), const CryptoBuffer& aad = CryptoBuffer(0)); - - AES_GCM_Cipher_OpenSSL(const AES_GCM_Cipher_OpenSSL& other) = delete; - - AES_GCM_Cipher_OpenSSL& operator=(const AES_GCM_Cipher_OpenSSL& other) = delete; - - AES_GCM_Cipher_OpenSSL(AES_GCM_Cipher_OpenSSL&& toMove) = default; - - /** - * Calls base class first, then grabs the tag from the cipher and sets it on m_tag. - * After calling FinalizeEncryption, be sure to call GetTag() and do something with it - * or you will not be able to decrypt the payload. - */ - CryptoBuffer FinalizeEncryption() override; - + + AES_GCM_Cipher_OpenSSL(const AES_GCM_Cipher_OpenSSL& other) = delete; + + AES_GCM_Cipher_OpenSSL& operator=(const AES_GCM_Cipher_OpenSSL& other) = delete; + + AES_GCM_Cipher_OpenSSL(AES_GCM_Cipher_OpenSSL&& toMove) = default; + + /** + * Calls base class first, then grabs the tag from the cipher and sets it on m_tag. + * After calling FinalizeEncryption, be sure to call GetTag() and do something with it + * or you will not be able to decrypt the payload. + */ + CryptoBuffer FinalizeEncryption() override; + void Reset() override; - protected: - size_t GetBlockSizeBytes() const override; - - size_t GetKeyLengthBits() const override; - - size_t GetTagLengthBytes() const; - - private: - void InitCipher(); - + protected: + size_t GetBlockSizeBytes() const override; + + size_t GetKeyLengthBits() const override; + + size_t GetTagLengthBytes() const; + + private: + void InitCipher(); + CryptoBuffer m_aad; - static size_t BlockSizeBytes; - static size_t IVLengthBytes; - static size_t KeyLengthBits; - static size_t TagLengthBytes; - }; - - /** - * OpenSSL implementation for AES in Key Wrap mode. The key for the c_tor is the Kek, - * it either encrypts a CEK or decrypts it. - */ - class AES_KeyWrap_Cipher_OpenSSL : public OpenSSLCipher - { - public: - - /** - * Create AES in Key Wrap mode off of a 256 bit key. - */ - AES_KeyWrap_Cipher_OpenSSL(const CryptoBuffer& key); - - AES_KeyWrap_Cipher_OpenSSL(const AES_KeyWrap_Cipher_OpenSSL&) = delete; - - AES_KeyWrap_Cipher_OpenSSL& operator=(const AES_KeyWrap_Cipher_OpenSSL&) = delete; - - AES_KeyWrap_Cipher_OpenSSL(AES_KeyWrap_Cipher_OpenSSL&&) = default; - - CryptoBuffer EncryptBuffer(const CryptoBuffer&) override; - CryptoBuffer FinalizeEncryption() override; - - CryptoBuffer DecryptBuffer(const CryptoBuffer&) override; - CryptoBuffer FinalizeDecryption() override; - + static size_t BlockSizeBytes; + static size_t IVLengthBytes; + static size_t KeyLengthBits; + static size_t TagLengthBytes; + }; + + /** + * OpenSSL implementation for AES in Key Wrap mode. The key for the c_tor is the Kek, + * it either encrypts a CEK or decrypts it. + */ + class AES_KeyWrap_Cipher_OpenSSL : public OpenSSLCipher + { + public: + + /** + * Create AES in Key Wrap mode off of a 256 bit key. + */ + AES_KeyWrap_Cipher_OpenSSL(const CryptoBuffer& key); + + AES_KeyWrap_Cipher_OpenSSL(const AES_KeyWrap_Cipher_OpenSSL&) = delete; + + AES_KeyWrap_Cipher_OpenSSL& operator=(const AES_KeyWrap_Cipher_OpenSSL&) = delete; + + AES_KeyWrap_Cipher_OpenSSL(AES_KeyWrap_Cipher_OpenSSL&&) = default; + + CryptoBuffer EncryptBuffer(const CryptoBuffer&) override; + CryptoBuffer FinalizeEncryption() override; + + CryptoBuffer DecryptBuffer(const CryptoBuffer&) override; + CryptoBuffer FinalizeDecryption() override; + void Reset() override; - protected: - inline size_t GetBlockSizeBytes() const override { return BlockSizeBytes; } - - inline size_t GetKeyLengthBits() const override { return KeyLengthBits; } - - private: - void InitCipher(); - - static size_t BlockSizeBytes; - static size_t KeyLengthBits; - - CryptoBuffer m_workingKeyBuffer; - }; - - } // namespace Crypto - } // namespace Utils -} // namespace Aws + protected: + inline size_t GetBlockSizeBytes() const override { return BlockSizeBytes; } + + inline size_t GetKeyLengthBits() const override { return KeyLengthBits; } + + private: + void InitCipher(); + + static size_t BlockSizeBytes; + static size_t KeyLengthBits; + + CryptoBuffer m_workingKeyBuffer; + }; + + } // namespace Crypto + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h index 657ee6eff4..44987dbc7c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/json/JsonSerializer.h @@ -2,380 +2,380 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/Array.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/external/cjson/cJSON.h> - -#include <utility> - -namespace Aws -{ - namespace Utils - { - namespace Json - { - class JsonView; - /** - * JSON DOM manipulation class. - * To read or serialize use @ref View function. - */ - class AWS_CORE_API JsonValue - { - public: - /** - * Constructs empty JSON DOM. - */ - JsonValue(); - - /** - * Constructs a JSON DOM by parsing the input string. - */ - JsonValue(const Aws::String& value); - - /** - * Constructs a JSON DOM by parsing the text in the input stream. - */ - JsonValue(Aws::IStream& istream); - - /** - * Performs a deep copy of the JSON DOM parameter. - * Prefer using a @ref JsonView if copying is not needed. - */ - JsonValue(const JsonValue& value); - - /** - * Moves the ownership of the internal JSON DOM. - * No copying is performed. - */ - JsonValue(JsonValue&& value); - - ~JsonValue(); - - /** - * Performs a deep copy of the JSON DOM parameter. - */ - JsonValue& operator=(const JsonValue& other); - - /** - * Moves the ownership of the internal JSON DOM of the parameter to the current object. - * No copying is performed. - * A DOM currently owned by the object will be freed prior to copying. - * @warning This will result in invalidating any outstanding views of the current DOM. However, views - * to the moved-from DOM would still valid. - */ - JsonValue& operator=(JsonValue&& other); - - bool operator==(const JsonValue& other) const; - bool operator!=(const JsonValue& other) const; - - /** - * Adds a string to the top level of this node with key. - */ - JsonValue& WithString(const Aws::String& key, const Aws::String& value); - JsonValue& WithString(const char* key, const Aws::String& value); - - /** - * Converts the current JSON node to a string. - */ - JsonValue& AsString(const Aws::String& value); - - /** - * Adds a bool value with key to the top level of this node. - */ - JsonValue& WithBool(const Aws::String& key, bool value); - JsonValue& WithBool(const char* key, bool value); - - /** - * Converts the current JSON node to a bool. - */ - JsonValue& AsBool(bool value); - - /** - * Adds an integer value at key at the top level of this node. - */ - JsonValue& WithInteger(const Aws::String& key, int value); - JsonValue& WithInteger(const char* key, int value); - - /** - * Converts the current JSON node to an integer. - */ - JsonValue& AsInteger(int value); - - /** - * Adds a 64-bit integer value at key to the top level of this node. - */ - JsonValue& WithInt64(const Aws::String& key, long long value); - JsonValue& WithInt64(const char* key, long long value); - - /** - * Converts the current JSON node to a 64-bit integer. - */ - JsonValue& AsInt64(long long value); - - /** - * Adds a double value at key at the top level of this node. - */ - JsonValue& WithDouble(const Aws::String& key, double value); - JsonValue& WithDouble(const char* key, double value); - - /** - * Converts the current JSON node to a double. - */ - JsonValue& AsDouble(double value); - - /** - * Adds an array of strings to the top level of this node at key. - */ - JsonValue& WithArray(const Aws::String& key, const Array<Aws::String>& array); - JsonValue& WithArray(const char* key, const Array<Aws::String>& array); - - /** - * Adds an array of arbitrary JSON objects to the top level of this node at key. - * The values in the array parameter will be deep-copied. - */ - JsonValue& WithArray(const Aws::String& key, const Array<JsonValue>& array); - - /** - * Adds an array of arbitrary JSON objects to the top level of this node at key. - * The values in the array parameter will be moved-from. - */ - JsonValue& WithArray(const Aws::String& key, Array<JsonValue>&& array); - - /** - * Converts the current JSON node to an array whose values are deep-copied from the array parameter. - */ - JsonValue& AsArray(const Array<JsonValue>& array); - - /** - * Converts the current JSON node to an array whose values are moved from the array parameter. - */ - JsonValue& AsArray(Array<JsonValue>&& array); - - /** - * Adds a JSON object to the top level of this node at key. - * The object parameter is deep-copied. - */ - JsonValue& WithObject(const Aws::String& key, const JsonValue& value); - JsonValue& WithObject(const char* key, const JsonValue& value); - - /** - * Adds a JSON object to the top level of this node at key. - */ - JsonValue& WithObject(const Aws::String& key, JsonValue&& value); - JsonValue& WithObject(const char* key, JsonValue&& value); - - /** - * Converts the current JSON node to a JSON object by deep-copying the parameter. - */ - JsonValue& AsObject(const JsonValue& value); - - /** - * Converts the current JSON node to a JSON object by moving from the parameter. - */ - JsonValue& AsObject(JsonValue&& value); - - /** - * Returns true if the last parse request was successful. If this returns false, - * you can call GetErrorMessage() to find the cause. - */ - inline bool WasParseSuccessful() const - { - return m_wasParseSuccessful; - } - - /** - * Returns the last error message from a failed parse attempt. Returns empty string if no error. - */ - inline const Aws::String& GetErrorMessage() const - { - return m_errorMessage; - } - - /** - * Creates a view from the current root JSON node. - */ - JsonView View() const; - - private: - void Destroy(); - JsonValue(cJSON* value); - cJSON* m_value; - bool m_wasParseSuccessful; - Aws::String m_errorMessage; - friend class JsonView; - }; - - /** - * Provides read-only view to an existing JsonValue. This allows lightweight copying without making deep - * copies of the JsonValue. - * Note: This class does not extend the lifetime of the given JsonValue. It's your responsibility to ensure - * the lifetime of the JsonValue is extended beyond the lifetime of its view. - */ - class AWS_CORE_API JsonView - { - public: - /* constructors */ - JsonView(); - JsonView(const JsonValue& v); - JsonView& operator=(const JsonValue& v); - - /** - * Gets a string from this node by its key. - */ - Aws::String GetString(const Aws::String& key) const; - - /** - * Returns the value of this node as a string. - * The behavior is undefined if the node is _not_ of type string. - */ - Aws::String AsString() const; - - /** - * Gets a boolean value from this node by its key. - */ - bool GetBool(const Aws::String& key) const; - - /** - * Returns the value of this node as a boolean. - */ - bool AsBool() const; - - /** - * Gets an integer value from this node by its key. - * The integer is of the same size as an int on the machine. - */ - int GetInteger(const Aws::String& key) const; - - /** - * Returns the value of this node as an int. - */ - int AsInteger() const; - - /** - * Gets a 64-bit integer value from this node by its key. - * The value is 64-bit regardless of the platform/machine. - */ - int64_t GetInt64(const Aws::String& key) const; - - /** - * Returns the value of this node as 64-bit integer. - */ - int64_t AsInt64() const; - - /** - * Gets a double precision floating-point value from this node by its key. - */ - double GetDouble(const Aws::String& key) const; - - /** - * Returns the value of this node as a double precision floating-point. - */ - double AsDouble() const; - - /** - * Gets an array of JsonView objects from this node by its key. - */ - Array<JsonView> GetArray(const Aws::String& key) const; - - /** - * Returns the value of this node as an array of JsonView objects. - */ - Array<JsonView> AsArray() const; - - /** - * Gets a JsonView object from this node by its key. - */ - JsonView GetObject(const Aws::String& key) const; - - /** - * Returns the value of this node as a JsonView object. - */ - JsonView AsObject() const; - - /** - * Reads all json objects at the top level of this node (does not traverse the tree any further) - * along with their keys. - */ - Aws::Map<Aws::String, JsonView> GetAllObjects() const; - - /** - * Tests whether a value exists at the current node level for the given key. - * Returns true if a value has been found and its value is not null, false otherwise. - */ - bool ValueExists(const Aws::String& key) const; - - /** - * Tests whether a key exists at the current node level. - */ - bool KeyExists(const Aws::String& key) const; - - /** - * Tests whether the current value is a JSON object. - */ - bool IsObject() const; - - /** - * Tests whether the current value is a boolean. - */ - bool IsBool() const; - - /** - * Tests whether the current value is a string. - */ - bool IsString() const; - - /** - * Tests whether the current value is an int or int64_t. - * Returns false if the value is floating-point. - */ - bool IsIntegerType() const; - - /** - * Tests whether the current value is a floating-point. - */ - bool IsFloatingPointType() const; - - /** - * Tests whether the current value is a JSON array. - */ - bool IsListType() const; - - /** - * Tests whether the current value is NULL. - */ - bool IsNull() const; - - /** - * Writes the current JSON view without whitespace characters starting at the current level to a string. - * @param treatAsObject if the current value is empty, writes out '{}' rather than an empty string. - */ - Aws::String WriteCompact(bool treatAsObject = true) const; - - /** - * Writes the current JSON view to a string in a human friendly format. - * @param treatAsObject if the current value is empty, writes out '{}' rather than an empty string. - */ - Aws::String WriteReadable(bool treatAsObject = true) const; - - /** - * Creates a deep copy of the JSON value rooted in the current JSON view. - */ - JsonValue Materialize() const; - - private: - JsonView(cJSON* val); - JsonView& operator=(cJSON* val); - cJSON* m_value; - }; - - } // namespace Json - } // namespace Utils -} // namespace Aws - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/Array.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/external/cjson/cJSON.h> + +#include <utility> + +namespace Aws +{ + namespace Utils + { + namespace Json + { + class JsonView; + /** + * JSON DOM manipulation class. + * To read or serialize use @ref View function. + */ + class AWS_CORE_API JsonValue + { + public: + /** + * Constructs empty JSON DOM. + */ + JsonValue(); + + /** + * Constructs a JSON DOM by parsing the input string. + */ + JsonValue(const Aws::String& value); + + /** + * Constructs a JSON DOM by parsing the text in the input stream. + */ + JsonValue(Aws::IStream& istream); + + /** + * Performs a deep copy of the JSON DOM parameter. + * Prefer using a @ref JsonView if copying is not needed. + */ + JsonValue(const JsonValue& value); + + /** + * Moves the ownership of the internal JSON DOM. + * No copying is performed. + */ + JsonValue(JsonValue&& value); + + ~JsonValue(); + + /** + * Performs a deep copy of the JSON DOM parameter. + */ + JsonValue& operator=(const JsonValue& other); + + /** + * Moves the ownership of the internal JSON DOM of the parameter to the current object. + * No copying is performed. + * A DOM currently owned by the object will be freed prior to copying. + * @warning This will result in invalidating any outstanding views of the current DOM. However, views + * to the moved-from DOM would still valid. + */ + JsonValue& operator=(JsonValue&& other); + + bool operator==(const JsonValue& other) const; + bool operator!=(const JsonValue& other) const; + + /** + * Adds a string to the top level of this node with key. + */ + JsonValue& WithString(const Aws::String& key, const Aws::String& value); + JsonValue& WithString(const char* key, const Aws::String& value); + + /** + * Converts the current JSON node to a string. + */ + JsonValue& AsString(const Aws::String& value); + + /** + * Adds a bool value with key to the top level of this node. + */ + JsonValue& WithBool(const Aws::String& key, bool value); + JsonValue& WithBool(const char* key, bool value); + + /** + * Converts the current JSON node to a bool. + */ + JsonValue& AsBool(bool value); + + /** + * Adds an integer value at key at the top level of this node. + */ + JsonValue& WithInteger(const Aws::String& key, int value); + JsonValue& WithInteger(const char* key, int value); + + /** + * Converts the current JSON node to an integer. + */ + JsonValue& AsInteger(int value); + + /** + * Adds a 64-bit integer value at key to the top level of this node. + */ + JsonValue& WithInt64(const Aws::String& key, long long value); + JsonValue& WithInt64(const char* key, long long value); + + /** + * Converts the current JSON node to a 64-bit integer. + */ + JsonValue& AsInt64(long long value); + + /** + * Adds a double value at key at the top level of this node. + */ + JsonValue& WithDouble(const Aws::String& key, double value); + JsonValue& WithDouble(const char* key, double value); + + /** + * Converts the current JSON node to a double. + */ + JsonValue& AsDouble(double value); + + /** + * Adds an array of strings to the top level of this node at key. + */ + JsonValue& WithArray(const Aws::String& key, const Array<Aws::String>& array); + JsonValue& WithArray(const char* key, const Array<Aws::String>& array); + + /** + * Adds an array of arbitrary JSON objects to the top level of this node at key. + * The values in the array parameter will be deep-copied. + */ + JsonValue& WithArray(const Aws::String& key, const Array<JsonValue>& array); + + /** + * Adds an array of arbitrary JSON objects to the top level of this node at key. + * The values in the array parameter will be moved-from. + */ + JsonValue& WithArray(const Aws::String& key, Array<JsonValue>&& array); + + /** + * Converts the current JSON node to an array whose values are deep-copied from the array parameter. + */ + JsonValue& AsArray(const Array<JsonValue>& array); + + /** + * Converts the current JSON node to an array whose values are moved from the array parameter. + */ + JsonValue& AsArray(Array<JsonValue>&& array); + + /** + * Adds a JSON object to the top level of this node at key. + * The object parameter is deep-copied. + */ + JsonValue& WithObject(const Aws::String& key, const JsonValue& value); + JsonValue& WithObject(const char* key, const JsonValue& value); + + /** + * Adds a JSON object to the top level of this node at key. + */ + JsonValue& WithObject(const Aws::String& key, JsonValue&& value); + JsonValue& WithObject(const char* key, JsonValue&& value); + + /** + * Converts the current JSON node to a JSON object by deep-copying the parameter. + */ + JsonValue& AsObject(const JsonValue& value); + + /** + * Converts the current JSON node to a JSON object by moving from the parameter. + */ + JsonValue& AsObject(JsonValue&& value); + + /** + * Returns true if the last parse request was successful. If this returns false, + * you can call GetErrorMessage() to find the cause. + */ + inline bool WasParseSuccessful() const + { + return m_wasParseSuccessful; + } + + /** + * Returns the last error message from a failed parse attempt. Returns empty string if no error. + */ + inline const Aws::String& GetErrorMessage() const + { + return m_errorMessage; + } + + /** + * Creates a view from the current root JSON node. + */ + JsonView View() const; + + private: + void Destroy(); + JsonValue(cJSON* value); + cJSON* m_value; + bool m_wasParseSuccessful; + Aws::String m_errorMessage; + friend class JsonView; + }; + + /** + * Provides read-only view to an existing JsonValue. This allows lightweight copying without making deep + * copies of the JsonValue. + * Note: This class does not extend the lifetime of the given JsonValue. It's your responsibility to ensure + * the lifetime of the JsonValue is extended beyond the lifetime of its view. + */ + class AWS_CORE_API JsonView + { + public: + /* constructors */ + JsonView(); + JsonView(const JsonValue& v); + JsonView& operator=(const JsonValue& v); + + /** + * Gets a string from this node by its key. + */ + Aws::String GetString(const Aws::String& key) const; + + /** + * Returns the value of this node as a string. + * The behavior is undefined if the node is _not_ of type string. + */ + Aws::String AsString() const; + + /** + * Gets a boolean value from this node by its key. + */ + bool GetBool(const Aws::String& key) const; + + /** + * Returns the value of this node as a boolean. + */ + bool AsBool() const; + + /** + * Gets an integer value from this node by its key. + * The integer is of the same size as an int on the machine. + */ + int GetInteger(const Aws::String& key) const; + + /** + * Returns the value of this node as an int. + */ + int AsInteger() const; + + /** + * Gets a 64-bit integer value from this node by its key. + * The value is 64-bit regardless of the platform/machine. + */ + int64_t GetInt64(const Aws::String& key) const; + + /** + * Returns the value of this node as 64-bit integer. + */ + int64_t AsInt64() const; + + /** + * Gets a double precision floating-point value from this node by its key. + */ + double GetDouble(const Aws::String& key) const; + + /** + * Returns the value of this node as a double precision floating-point. + */ + double AsDouble() const; + + /** + * Gets an array of JsonView objects from this node by its key. + */ + Array<JsonView> GetArray(const Aws::String& key) const; + + /** + * Returns the value of this node as an array of JsonView objects. + */ + Array<JsonView> AsArray() const; + + /** + * Gets a JsonView object from this node by its key. + */ + JsonView GetObject(const Aws::String& key) const; + + /** + * Returns the value of this node as a JsonView object. + */ + JsonView AsObject() const; + + /** + * Reads all json objects at the top level of this node (does not traverse the tree any further) + * along with their keys. + */ + Aws::Map<Aws::String, JsonView> GetAllObjects() const; + + /** + * Tests whether a value exists at the current node level for the given key. + * Returns true if a value has been found and its value is not null, false otherwise. + */ + bool ValueExists(const Aws::String& key) const; + + /** + * Tests whether a key exists at the current node level. + */ + bool KeyExists(const Aws::String& key) const; + + /** + * Tests whether the current value is a JSON object. + */ + bool IsObject() const; + + /** + * Tests whether the current value is a boolean. + */ + bool IsBool() const; + + /** + * Tests whether the current value is a string. + */ + bool IsString() const; + + /** + * Tests whether the current value is an int or int64_t. + * Returns false if the value is floating-point. + */ + bool IsIntegerType() const; + + /** + * Tests whether the current value is a floating-point. + */ + bool IsFloatingPointType() const; + + /** + * Tests whether the current value is a JSON array. + */ + bool IsListType() const; + + /** + * Tests whether the current value is NULL. + */ + bool IsNull() const; + + /** + * Writes the current JSON view without whitespace characters starting at the current level to a string. + * @param treatAsObject if the current value is empty, writes out '{}' rather than an empty string. + */ + Aws::String WriteCompact(bool treatAsObject = true) const; + + /** + * Writes the current JSON view to a string in a human friendly format. + * @param treatAsObject if the current value is empty, writes out '{}' rather than an empty string. + */ + Aws::String WriteReadable(bool treatAsObject = true) const; + + /** + * Creates a deep copy of the JSON value rooted in the current JSON view. + */ + JsonValue Materialize() const; + + private: + JsonView(cJSON* val); + JsonView& operator=(cJSON* val); + cJSON* m_value; + }; + + } // namespace Json + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/AWSLogging.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/AWSLogging.h index be572ad23b..a238a2633a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/AWSLogging.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/AWSLogging.h @@ -2,49 +2,49 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <memory> - -namespace Aws -{ - namespace Utils - { - namespace Logging - { - class LogSystemInterface; - - // Standard interface - - /** - * Call this at the beginning of your program, prior to any AWS calls. - */ - AWS_CORE_API void InitializeAWSLogging(const std::shared_ptr<LogSystemInterface>& logSystem); - - /** - * Call this at the exit point of your program, after all calls have finished. - */ - AWS_CORE_API void ShutdownAWSLogging(void); - - /** - * Get currently configured log system instance. - */ - AWS_CORE_API LogSystemInterface* GetLogSystem(); - - // Testing interface - - /** - * Replaces the current logger with a new one, while pushing the old one onto a 1-deep stack; primarily for testing - */ - AWS_CORE_API void PushLogger(const std::shared_ptr<LogSystemInterface> &logSystem); - - /** - * Pops the logger off the logger stack and replaces the current logger with it. Disables logging if the top logger is actually a nullptr - */ - AWS_CORE_API void PopLogger(); - - } // namespace Logging - } // namespace Utils -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <memory> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + class LogSystemInterface; + + // Standard interface + + /** + * Call this at the beginning of your program, prior to any AWS calls. + */ + AWS_CORE_API void InitializeAWSLogging(const std::shared_ptr<LogSystemInterface>& logSystem); + + /** + * Call this at the exit point of your program, after all calls have finished. + */ + AWS_CORE_API void ShutdownAWSLogging(void); + + /** + * Get currently configured log system instance. + */ + AWS_CORE_API LogSystemInterface* GetLogSystem(); + + // Testing interface + + /** + * Replaces the current logger with a new one, while pushing the old one onto a 1-deep stack; primarily for testing + */ + AWS_CORE_API void PushLogger(const std::shared_ptr<LogSystemInterface> &logSystem); + + /** + * Pops the logger off the logger stack and replaces the current logger with it. Disables logging if the top logger is actually a nullptr + */ + AWS_CORE_API void PopLogger(); + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ConsoleLogSystem.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ConsoleLogSystem.h index b7fb714ed6..d6e3183743 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ConsoleLogSystem.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/ConsoleLogSystem.h @@ -2,44 +2,44 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/logging/FormattedLogSystem.h> - -namespace Aws -{ - namespace Utils - { - namespace Logging - { - /** - * Log system interface that logs to std::cout - */ - class AWS_CORE_API ConsoleLogSystem : public FormattedLogSystem - { - public: - - using Base = FormattedLogSystem; - - ConsoleLogSystem(LogLevel logLevel) : - Base(logLevel) - {} - - virtual ~ConsoleLogSystem() {} - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/logging/FormattedLogSystem.h> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + /** + * Log system interface that logs to std::cout + */ + class AWS_CORE_API ConsoleLogSystem : public FormattedLogSystem + { + public: + + using Base = FormattedLogSystem; + + ConsoleLogSystem(LogLevel logLevel) : + Base(logLevel) + {} + + virtual ~ConsoleLogSystem() {} + /** * Flushes buffered messages to stdout. */ void Flush() override; - protected: - - virtual void ProcessFormattedStatement(Aws::String&& statement) override; - }; - - } // namespace Logging - } // namespace Utils -} // namespace Aws + protected: + + virtual void ProcessFormattedStatement(Aws::String&& statement) override; + }; + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/DefaultLogSystem.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/DefaultLogSystem.h index dbeed83cb1..2b18fd59a5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/DefaultLogSystem.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/DefaultLogSystem.h @@ -2,89 +2,89 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/logging/FormattedLogSystem.h> -#include <aws/core/utils/logging/LogLevel.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> - -#include <thread> -#include <memory> -#include <mutex> -#include <atomic> -#include <condition_variable> - -namespace Aws -{ - namespace Utils - { - namespace Logging - { - /** - * Default behavior logger. It has a background thread that reads a log queue and prints the messages - * out to file as quickly as possible. This implementation also rolls the file every hour. - */ - class AWS_CORE_API DefaultLogSystem : public FormattedLogSystem - { - public: - using Base = FormattedLogSystem; - - /** - * Initialize the logging system to write to the supplied logfile output. Creates logging thread on construction. - */ - DefaultLogSystem(LogLevel logLevel, const std::shared_ptr<Aws::OStream>& logFile); - /** - * Initialize the logging system to write to a computed file path filenamePrefix + "timestamp.log". Creates logging thread - * on construction. - */ - DefaultLogSystem(LogLevel logLevel, const Aws::String& filenamePrefix); - - virtual ~DefaultLogSystem(); - - /** + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/logging/FormattedLogSystem.h> +#include <aws/core/utils/logging/LogLevel.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> + +#include <thread> +#include <memory> +#include <mutex> +#include <atomic> +#include <condition_variable> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + /** + * Default behavior logger. It has a background thread that reads a log queue and prints the messages + * out to file as quickly as possible. This implementation also rolls the file every hour. + */ + class AWS_CORE_API DefaultLogSystem : public FormattedLogSystem + { + public: + using Base = FormattedLogSystem; + + /** + * Initialize the logging system to write to the supplied logfile output. Creates logging thread on construction. + */ + DefaultLogSystem(LogLevel logLevel, const std::shared_ptr<Aws::OStream>& logFile); + /** + * Initialize the logging system to write to a computed file path filenamePrefix + "timestamp.log". Creates logging thread + * on construction. + */ + DefaultLogSystem(LogLevel logLevel, const Aws::String& filenamePrefix); + + virtual ~DefaultLogSystem(); + + /** * Flushes buffered messages to the file system. * This method is thread-safe. */ void Flush() override; /** - * Structure containing semaphores, queue etc... - */ - struct LogSynchronizationData - { - public: - LogSynchronizationData() : m_stopLogging(false) {} - - std::mutex m_logQueueMutex; - std::condition_variable m_queueSignal; - Aws::Vector<Aws::String> m_queuedLogMessages; + * Structure containing semaphores, queue etc... + */ + struct LogSynchronizationData + { + public: + LogSynchronizationData() : m_stopLogging(false) {} + + std::mutex m_logQueueMutex; + std::condition_variable m_queueSignal; + Aws::Vector<Aws::String> m_queuedLogMessages; bool m_stopLogging; - - private: - LogSynchronizationData(const LogSynchronizationData& rhs) = delete; - LogSynchronizationData& operator =(const LogSynchronizationData& rhs) = delete; - }; - - protected: - /** - * Pushes log onto the queue and notifies the background thread. - */ - virtual void ProcessFormattedStatement(Aws::String&& statement) override; - - private: - DefaultLogSystem(const DefaultLogSystem& rhs) = delete; - DefaultLogSystem& operator =(const DefaultLogSystem& rhs) = delete; - - LogSynchronizationData m_syncData; - - std::thread m_loggingThread; - }; - - } // namespace Logging - } // namespace Utils -} // namespace Aws + + private: + LogSynchronizationData(const LogSynchronizationData& rhs) = delete; + LogSynchronizationData& operator =(const LogSynchronizationData& rhs) = delete; + }; + + protected: + /** + * Pushes log onto the queue and notifies the background thread. + */ + virtual void ProcessFormattedStatement(Aws::String&& statement) override; + + private: + DefaultLogSystem(const DefaultLogSystem& rhs) = delete; + DefaultLogSystem& operator =(const DefaultLogSystem& rhs) = delete; + + LogSynchronizationData m_syncData; + + std::thread m_loggingThread; + }; + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/FormattedLogSystem.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/FormattedLogSystem.h index 6157c45528..80b068ead5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/FormattedLogSystem.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/FormattedLogSystem.h @@ -2,65 +2,65 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/logging/LogSystemInterface.h> -#include <aws/core/utils/logging/LogLevel.h> - -#include <atomic> - -namespace Aws -{ - namespace Utils - { - namespace Logging - { - /** - * Logger that formats log messages into [LEVEL] timestamp [threadid] message - */ - class AWS_CORE_API FormattedLogSystem : public LogSystemInterface - { - public: - using Base = LogSystemInterface; - - /** - * Initializes log system with logLevel - */ - FormattedLogSystem(LogLevel logLevel); - virtual ~FormattedLogSystem() = default; - - /** - * Gets the currently configured log level. - */ - virtual LogLevel GetLogLevel(void) const override { return m_logLevel; } - /** - * Set a new log level. This has the immediate effect of changing the log output to the new level. - */ - void SetLogLevel(LogLevel logLevel) { m_logLevel.store(logLevel); } - - /** - * Does a printf style output to ProcessFormattedStatement. Don't use this, it's unsafe. See LogStream - */ - virtual void Log(LogLevel logLevel, const char* tag, const char* formatStr, ...) override; - - /** - * Writes the stream to ProcessFormattedStatement. - */ - virtual void LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &messageStream) override; - - protected: - /** - * This is the method that most logger implementations will want to override. - * At this point the message is formatted and is ready to go to the output stream - */ - virtual void ProcessFormattedStatement(Aws::String&& statement) = 0; - - private: - std::atomic<LogLevel> m_logLevel; - }; - - } // namespace Logging - } // namespace Utils -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/logging/LogSystemInterface.h> +#include <aws/core/utils/logging/LogLevel.h> + +#include <atomic> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + /** + * Logger that formats log messages into [LEVEL] timestamp [threadid] message + */ + class AWS_CORE_API FormattedLogSystem : public LogSystemInterface + { + public: + using Base = LogSystemInterface; + + /** + * Initializes log system with logLevel + */ + FormattedLogSystem(LogLevel logLevel); + virtual ~FormattedLogSystem() = default; + + /** + * Gets the currently configured log level. + */ + virtual LogLevel GetLogLevel(void) const override { return m_logLevel; } + /** + * Set a new log level. This has the immediate effect of changing the log output to the new level. + */ + void SetLogLevel(LogLevel logLevel) { m_logLevel.store(logLevel); } + + /** + * Does a printf style output to ProcessFormattedStatement. Don't use this, it's unsafe. See LogStream + */ + virtual void Log(LogLevel logLevel, const char* tag, const char* formatStr, ...) override; + + /** + * Writes the stream to ProcessFormattedStatement. + */ + virtual void LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &messageStream) override; + + protected: + /** + * This is the method that most logger implementations will want to override. + * At this point the message is formatted and is ready to go to the output stream + */ + virtual void ProcessFormattedStatement(Aws::String&& statement) = 0; + + private: + std::atomic<LogLevel> m_logLevel; + }; + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogLevel.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogLevel.h index ff1dd36c0e..127eb19c69 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogLevel.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogLevel.h @@ -2,36 +2,36 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace Utils - { - namespace Logging - { - - /** - * LogLevel used to control verbosity of logging system. - */ - enum class LogLevel : int - { - Off = 0, - Fatal = 1, - Error = 2, - Warn = 3, - Info = 4, - Debug = 5, - Trace = 6 - }; - - AWS_CORE_API Aws::String GetLogLevelName(LogLevel logLevel); - - } // namespace Logging - } // namespace Utils -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + + /** + * LogLevel used to control verbosity of logging system. + */ + enum class LogLevel : int + { + Off = 0, + Fatal = 1, + Error = 2, + Warn = 3, + Info = 4, + Debug = 5, + Trace = 6 + }; + + AWS_CORE_API Aws::String GetLogLevelName(LogLevel logLevel); + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogMacros.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogMacros.h index b400340de4..a30bda089f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogMacros.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogMacros.h @@ -2,44 +2,44 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/logging/LogLevel.h> -#include <aws/core/utils/logging/AWSLogging.h> -#include <aws/core/utils/logging/LogSystemInterface.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - -// While macros are usually grotty, using them here lets us have a simple function call interface for logging that -// -// (1) Can be compiled out completely, so you don't even have to pay the cost to check the log level (which will be a virtual function call and a std::atomic<> read) if you don't want any AWS logging -// (2) If you use logging and the log statement doesn't pass the conditional log filter level, not only do you not pay the cost of building the log string, you don't pay the cost for allocating or -// getting any of the values used in building the log string, as they're in a scope (if-statement) that never gets entered. - -#ifdef DISABLE_AWS_LOGGING - - #define AWS_LOG(level, tag, ...) - #define AWS_LOG_FATAL(tag, ...) - #define AWS_LOG_ERROR(tag, ...) - #define AWS_LOG_WARN(tag, ...) - #define AWS_LOG_INFO(tag, ...) - #define AWS_LOG_DEBUG(tag, ...) - #define AWS_LOG_TRACE(tag, ...) + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/logging/LogLevel.h> +#include <aws/core/utils/logging/AWSLogging.h> +#include <aws/core/utils/logging/LogSystemInterface.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +// While macros are usually grotty, using them here lets us have a simple function call interface for logging that +// +// (1) Can be compiled out completely, so you don't even have to pay the cost to check the log level (which will be a virtual function call and a std::atomic<> read) if you don't want any AWS logging +// (2) If you use logging and the log statement doesn't pass the conditional log filter level, not only do you not pay the cost of building the log string, you don't pay the cost for allocating or +// getting any of the values used in building the log string, as they're in a scope (if-statement) that never gets entered. + +#ifdef DISABLE_AWS_LOGGING + + #define AWS_LOG(level, tag, ...) + #define AWS_LOG_FATAL(tag, ...) + #define AWS_LOG_ERROR(tag, ...) + #define AWS_LOG_WARN(tag, ...) + #define AWS_LOG_INFO(tag, ...) + #define AWS_LOG_DEBUG(tag, ...) + #define AWS_LOG_TRACE(tag, ...) #define AWS_LOG_FLUSH() - - #define AWS_LOGSTREAM(level, tag, streamExpression) - #define AWS_LOGSTREAM_FATAL(tag, streamExpression) - #define AWS_LOGSTREAM_ERROR(tag, streamExpression) - #define AWS_LOGSTREAM_WARN(tag, streamExpression) - #define AWS_LOGSTREAM_INFO(tag, streamExpression) - #define AWS_LOGSTREAM_DEBUG(tag, streamExpression) - #define AWS_LOGSTREAM_TRACE(tag, streamExpression) + + #define AWS_LOGSTREAM(level, tag, streamExpression) + #define AWS_LOGSTREAM_FATAL(tag, streamExpression) + #define AWS_LOGSTREAM_ERROR(tag, streamExpression) + #define AWS_LOGSTREAM_WARN(tag, streamExpression) + #define AWS_LOGSTREAM_INFO(tag, streamExpression) + #define AWS_LOGSTREAM_DEBUG(tag, streamExpression) + #define AWS_LOGSTREAM_TRACE(tag, streamExpression) #define AWS_LOGSTREAM_FLUSH() - -#else - + +#else + #define AWS_LOG_FLUSH() \ { \ Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ @@ -49,146 +49,146 @@ } \ } - #define AWS_LOG(level, tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= level ) \ - { \ - logSystem->Log(level, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOG_FATAL(tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Fatal ) \ - { \ - logSystem->Log(Aws::Utils::Logging::LogLevel::Fatal, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOG_ERROR(tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Error ) \ - { \ - logSystem->Log(Aws::Utils::Logging::LogLevel::Error, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOG_WARN(tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Warn ) \ - { \ - logSystem->Log(Aws::Utils::Logging::LogLevel::Warn, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOG_INFO(tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Info ) \ - { \ - logSystem->Log(Aws::Utils::Logging::LogLevel::Info, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOG_DEBUG(tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Debug ) \ - { \ - logSystem->Log(Aws::Utils::Logging::LogLevel::Debug, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOG_TRACE(tag, ...) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Trace ) \ - { \ - logSystem->Log(Aws::Utils::Logging::LogLevel::Trace, tag, __VA_ARGS__); \ - } \ - } - - #define AWS_LOGSTREAM(level, tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= level ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( logLevel, tag, logStream ); \ - } \ - } - - #define AWS_LOGSTREAM_FATAL(tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Fatal ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( Aws::Utils::Logging::LogLevel::Fatal, tag, logStream ); \ - } \ - } - - #define AWS_LOGSTREAM_ERROR(tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Error ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( Aws::Utils::Logging::LogLevel::Error, tag, logStream ); \ - } \ - } - - #define AWS_LOGSTREAM_WARN(tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Warn ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( Aws::Utils::Logging::LogLevel::Warn, tag, logStream ); \ - } \ - } - - #define AWS_LOGSTREAM_INFO(tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Info ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( Aws::Utils::Logging::LogLevel::Info, tag, logStream ); \ - } \ - } - - #define AWS_LOGSTREAM_DEBUG(tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Debug ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( Aws::Utils::Logging::LogLevel::Debug, tag, logStream ); \ - } \ - } - - #define AWS_LOGSTREAM_TRACE(tag, streamExpression) \ - { \ - Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ - if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Trace ) \ - { \ - Aws::OStringStream logStream; \ - logStream << streamExpression; \ - logSystem->LogStream( Aws::Utils::Logging::LogLevel::Trace, tag, logStream ); \ - } \ - } - + #define AWS_LOG(level, tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= level ) \ + { \ + logSystem->Log(level, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOG_FATAL(tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Fatal ) \ + { \ + logSystem->Log(Aws::Utils::Logging::LogLevel::Fatal, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOG_ERROR(tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Error ) \ + { \ + logSystem->Log(Aws::Utils::Logging::LogLevel::Error, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOG_WARN(tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Warn ) \ + { \ + logSystem->Log(Aws::Utils::Logging::LogLevel::Warn, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOG_INFO(tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Info ) \ + { \ + logSystem->Log(Aws::Utils::Logging::LogLevel::Info, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOG_DEBUG(tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Debug ) \ + { \ + logSystem->Log(Aws::Utils::Logging::LogLevel::Debug, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOG_TRACE(tag, ...) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Trace ) \ + { \ + logSystem->Log(Aws::Utils::Logging::LogLevel::Trace, tag, __VA_ARGS__); \ + } \ + } + + #define AWS_LOGSTREAM(level, tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= level ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( logLevel, tag, logStream ); \ + } \ + } + + #define AWS_LOGSTREAM_FATAL(tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Fatal ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( Aws::Utils::Logging::LogLevel::Fatal, tag, logStream ); \ + } \ + } + + #define AWS_LOGSTREAM_ERROR(tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Error ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( Aws::Utils::Logging::LogLevel::Error, tag, logStream ); \ + } \ + } + + #define AWS_LOGSTREAM_WARN(tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Warn ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( Aws::Utils::Logging::LogLevel::Warn, tag, logStream ); \ + } \ + } + + #define AWS_LOGSTREAM_INFO(tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Info ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( Aws::Utils::Logging::LogLevel::Info, tag, logStream ); \ + } \ + } + + #define AWS_LOGSTREAM_DEBUG(tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Debug ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( Aws::Utils::Logging::LogLevel::Debug, tag, logStream ); \ + } \ + } + + #define AWS_LOGSTREAM_TRACE(tag, streamExpression) \ + { \ + Aws::Utils::Logging::LogSystemInterface* logSystem = Aws::Utils::Logging::GetLogSystem(); \ + if ( logSystem && logSystem->GetLogLevel() >= Aws::Utils::Logging::LogLevel::Trace ) \ + { \ + Aws::OStringStream logStream; \ + logStream << streamExpression; \ + logSystem->LogStream( Aws::Utils::Logging::LogLevel::Trace, tag, logStream ); \ + } \ + } + #define AWS_LOGSTREAM_FLUSH() AWS_LOG_FLUSH() -#endif // DISABLE_AWS_LOGGING +#endif // DISABLE_AWS_LOGGING diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogSystemInterface.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogSystemInterface.h index 642d1c3022..3e83de729d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogSystemInterface.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/logging/LogSystemInterface.h @@ -2,50 +2,50 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - -namespace Aws -{ - namespace Utils - { - namespace Logging - { - enum class LogLevel : int; - - /** - * Interface for logging implementations. If you want to write your own logger, you can start here, though you may have more - * luck going down one more level to FormattedLogSystem. It does a bit more of the work for you and still gives you the ability - * to override the IO portion. - */ - class AWS_CORE_API LogSystemInterface - { - public: - virtual ~LogSystemInterface() = default; - - /** - * Gets the currently configured log level for this logger. - */ - virtual LogLevel GetLogLevel(void) const = 0; - /** - * Does a printf style output to the output stream. Don't use this, it's unsafe. See LogStream - */ - virtual void Log(LogLevel logLevel, const char* tag, const char* formatStr, ...) = 0; - /** - * Writes the stream to the output stream. - */ - virtual void LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &messageStream) = 0; + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +namespace Aws +{ + namespace Utils + { + namespace Logging + { + enum class LogLevel : int; + + /** + * Interface for logging implementations. If you want to write your own logger, you can start here, though you may have more + * luck going down one more level to FormattedLogSystem. It does a bit more of the work for you and still gives you the ability + * to override the IO portion. + */ + class AWS_CORE_API LogSystemInterface + { + public: + virtual ~LogSystemInterface() = default; + + /** + * Gets the currently configured log level for this logger. + */ + virtual LogLevel GetLogLevel(void) const = 0; + /** + * Does a printf style output to the output stream. Don't use this, it's unsafe. See LogStream + */ + virtual void Log(LogLevel logLevel, const char* tag, const char* formatStr, ...) = 0; + /** + * Writes the stream to the output stream. + */ + virtual void LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &messageStream) = 0; /** * Writes any buffered messages to the underlying device if the logger supports buffering. */ virtual void Flush() = 0; - }; - - } // namespace Logging - } // namespace Utils -} // namespace Aws + }; + + } // namespace Logging + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h index 5b1221917a..468a91766a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/AWSMemory.h @@ -1,291 +1,291 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/UnreferencedParam.h> -#include <aws/core/utils/memory/MemorySystemInterface.h> - -#include <memory> -#include <cstdlib> -#include <algorithm> -#include <type_traits> - + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/UnreferencedParam.h> +#include <aws/core/utils/memory/MemorySystemInterface.h> + +#include <memory> +#include <cstdlib> +#include <algorithm> +#include <type_traits> + struct aws_allocator; -namespace Aws -{ - namespace Utils - { - namespace Memory - { - /** - *InitializeAWSMemory should be called at the very start of your program - */ - AWS_CORE_API void InitializeAWSMemorySystem(MemorySystemInterface& memorySystem); - - /** - * ShutdownAWSMemory should be called the very end of your program - */ - AWS_CORE_API void ShutdownAWSMemorySystem(void); - - /** - * Get the globally install memory system, if it has been installed. - */ - AWS_CORE_API MemorySystemInterface* GetMemorySystem(); - - } // namespace Memory - } // namespace Utils - - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - AWS_CORE_API void* Malloc(const char* allocationTag, size_t allocationSize); - - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - AWS_CORE_API void Free(void* memoryPtr); - +namespace Aws +{ + namespace Utils + { + namespace Memory + { + /** + *InitializeAWSMemory should be called at the very start of your program + */ + AWS_CORE_API void InitializeAWSMemorySystem(MemorySystemInterface& memorySystem); + + /** + * ShutdownAWSMemory should be called the very end of your program + */ + AWS_CORE_API void ShutdownAWSMemorySystem(void); + + /** + * Get the globally install memory system, if it has been installed. + */ + AWS_CORE_API MemorySystemInterface* GetMemorySystem(); + + } // namespace Memory + } // namespace Utils + + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + AWS_CORE_API void* Malloc(const char* allocationTag, size_t allocationSize); + + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + AWS_CORE_API void Free(void* memoryPtr); + AWS_CORE_API aws_allocator* get_aws_allocator(); - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - template<typename T, typename ...ArgTypes> - T* New(const char* allocationTag, ArgTypes&&... args) - { - void *rawMemory = Malloc(allocationTag, sizeof(T)); - // http://stackoverflow.com/questions/6783993/placement-new-and-delete - T *constructedMemory = new (rawMemory) T(std::forward<ArgTypes>(args)...); - return constructedMemory; - } -/* - * dynamic_cast of all sorts do not work on MSVC if RTTI is turned off. - * This means that deleting an object via a pointer to one of its polymorphic base types that do not point to the - * address of their concrete class will result in undefined behavior. - * Example: - * struct Foo : InterfaceA, InterfaceB {}; - * Aws::Delete(pointerToInterfaceB); - */ -#if defined(_MSC_VER) && !defined(_CPPRTTI) - template<typename T> - void Delete(T* pointerToT) - { - if (pointerToT == nullptr) - { - return; - } - pointerToT->~T(); - Free(pointerToT); - } -#else - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - template<typename T> - typename std::enable_if<!std::is_polymorphic<T>::value>::type Delete(T* pointerToT) - { - if (pointerToT == nullptr) - { - return; - } - //http://stackoverflow.com/questions/6783993/placement-new-and-delete - pointerToT->~T(); - Free(pointerToT); - } - - template<typename T> - typename std::enable_if<std::is_polymorphic<T>::value>::type Delete(T* pointerToT) - { - if (pointerToT == nullptr) - { - return; - } - // deal with deleting objects that implement multiple interfaces - // see casting to pointer to void in http://en.cppreference.com/w/cpp/language/dynamic_cast - // https://stackoverflow.com/questions/8123776/are-there-practical-uses-for-dynamic-casting-to-void-pointer - // NOTE: on some compilers, calling the destructor before doing the dynamic_cast affects how calculation of - // the address of the most derived class. - void* mostDerivedT = dynamic_cast<void*>(pointerToT); - pointerToT->~T(); - Free(mostDerivedT); - } -#endif // _CPPRTTI - - template<typename T> - bool ShouldConstructArrayMembers() - { - return std::is_class<T>::value; - } - - template<typename T> - bool ShouldDestroyArrayMembers() - { - return !std::is_trivially_destructible<T>::value; - } - - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - template<typename T> - T* NewArray(std::size_t amount, const char* allocationTag) - { - if (amount > 0) - { - bool constructMembers = ShouldConstructArrayMembers<T>(); - bool trackMemberCount = ShouldDestroyArrayMembers<T>(); - - // if we need to remember the # of items in the array (because we need to call their destructors) then allocate extra memory and keep the # of items in the extra slot - std::size_t allocationSize = amount * sizeof(T); -#if defined(_MSC_VER) && _MSC_VER < 1900 - std::size_t headerSize = (std::max)(sizeof(std::size_t), __alignof(T)); -#else - std::size_t headerSize = (std::max)(sizeof(std::size_t), alignof(T)); -#endif - - if (trackMemberCount) - { - allocationSize += headerSize; - } - - void* rawMemory = Malloc(allocationTag, allocationSize); - T* pointerToT = nullptr; - - if (trackMemberCount) - { - std::size_t* pointerToAmount = reinterpret_cast<std::size_t*>(rawMemory); - *pointerToAmount = amount; - pointerToT = reinterpret_cast<T*>(reinterpret_cast<char*>(pointerToAmount) + headerSize); - - } - else - { - pointerToT = reinterpret_cast<T*>(rawMemory); - } - - if (constructMembers) - { - for (std::size_t i = 0; i < amount; ++i) - { - new (pointerToT + i) T; - } - } - - return pointerToT; - } - - return nullptr; - } - - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - template<typename T> - void DeleteArray(T* pointerToTArray) - { - if (pointerToTArray == nullptr) - { - return; - } - - bool destroyMembers = ShouldDestroyArrayMembers<T>(); - void* rawMemory = nullptr; - - if (destroyMembers) - { -#if defined(_MSC_VER) && _MSC_VER < 1900 - std::size_t headerSize = (std::max)(sizeof(std::size_t), __alignof(T)); -#else - std::size_t headerSize = (std::max)(sizeof(std::size_t), alignof(T)); -#endif - - std::size_t *pointerToAmount = reinterpret_cast<std::size_t*>(reinterpret_cast<char*>(pointerToTArray) - headerSize); - std::size_t amount = *pointerToAmount; - - for (std::size_t i = amount; i > 0; --i) - { - (pointerToTArray + i - 1)->~T(); - } - rawMemory = reinterpret_cast<void *>(pointerToAmount); - } - else - { - rawMemory = reinterpret_cast<void *>(pointerToTArray); - } - - Free(rawMemory); - } - - /** - * modeled from std::default_delete - */ - template<typename T> - struct Deleter - { - Deleter() {} - - template<class U, class = typename std::enable_if<std::is_convertible<U *, T *>::value, void>::type> - Deleter(const Deleter<U>&) - { - } - - void operator()(T *pointerToT) const - { - static_assert(0 < sizeof(T), "can't delete an incomplete type"); - Aws::Delete(pointerToT); - } - }; - - template< typename T > using UniquePtr = std::unique_ptr< T, Deleter< T > >; - - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - template<typename T, typename ...ArgTypes> - UniquePtr<T> MakeUnique(const char* allocationTag, ArgTypes&&... args) - { - return UniquePtr<T>(Aws::New<T>(allocationTag, std::forward<ArgTypes>(args)...)); - } - - template<typename T> - struct ArrayDeleter - { - ArrayDeleter() {} - - template<class U, class = typename std::enable_if<std::is_convertible<U *, T *>::value, void>::type> - ArrayDeleter(const ArrayDeleter<U>&) - { - } - - void operator()(T *pointerToTArray) const - { - static_assert(0 < sizeof(T), "can't delete an incomplete type"); - Aws::DeleteArray(pointerToTArray); - } - }; - - template< typename T > using UniqueArrayPtr = std::unique_ptr< T, ArrayDeleter< T > >; - - /** - * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code - * use these functions instead or Aws::MakeShared - */ - template<typename T, typename ...ArgTypes> - UniqueArrayPtr<T> MakeUniqueArray(std::size_t amount, const char* allocationTag, ArgTypes&&... args) - { - return UniqueArrayPtr<T>(Aws::NewArray<T>(amount, allocationTag, std::forward<ArgTypes>(args)...)); - } - -} // namespace Aws - + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + template<typename T, typename ...ArgTypes> + T* New(const char* allocationTag, ArgTypes&&... args) + { + void *rawMemory = Malloc(allocationTag, sizeof(T)); + // http://stackoverflow.com/questions/6783993/placement-new-and-delete + T *constructedMemory = new (rawMemory) T(std::forward<ArgTypes>(args)...); + return constructedMemory; + } +/* + * dynamic_cast of all sorts do not work on MSVC if RTTI is turned off. + * This means that deleting an object via a pointer to one of its polymorphic base types that do not point to the + * address of their concrete class will result in undefined behavior. + * Example: + * struct Foo : InterfaceA, InterfaceB {}; + * Aws::Delete(pointerToInterfaceB); + */ +#if defined(_MSC_VER) && !defined(_CPPRTTI) + template<typename T> + void Delete(T* pointerToT) + { + if (pointerToT == nullptr) + { + return; + } + pointerToT->~T(); + Free(pointerToT); + } +#else + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + template<typename T> + typename std::enable_if<!std::is_polymorphic<T>::value>::type Delete(T* pointerToT) + { + if (pointerToT == nullptr) + { + return; + } + //http://stackoverflow.com/questions/6783993/placement-new-and-delete + pointerToT->~T(); + Free(pointerToT); + } + + template<typename T> + typename std::enable_if<std::is_polymorphic<T>::value>::type Delete(T* pointerToT) + { + if (pointerToT == nullptr) + { + return; + } + // deal with deleting objects that implement multiple interfaces + // see casting to pointer to void in http://en.cppreference.com/w/cpp/language/dynamic_cast + // https://stackoverflow.com/questions/8123776/are-there-practical-uses-for-dynamic-casting-to-void-pointer + // NOTE: on some compilers, calling the destructor before doing the dynamic_cast affects how calculation of + // the address of the most derived class. + void* mostDerivedT = dynamic_cast<void*>(pointerToT); + pointerToT->~T(); + Free(mostDerivedT); + } +#endif // _CPPRTTI + + template<typename T> + bool ShouldConstructArrayMembers() + { + return std::is_class<T>::value; + } + + template<typename T> + bool ShouldDestroyArrayMembers() + { + return !std::is_trivially_destructible<T>::value; + } + + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + template<typename T> + T* NewArray(std::size_t amount, const char* allocationTag) + { + if (amount > 0) + { + bool constructMembers = ShouldConstructArrayMembers<T>(); + bool trackMemberCount = ShouldDestroyArrayMembers<T>(); + + // if we need to remember the # of items in the array (because we need to call their destructors) then allocate extra memory and keep the # of items in the extra slot + std::size_t allocationSize = amount * sizeof(T); +#if defined(_MSC_VER) && _MSC_VER < 1900 + std::size_t headerSize = (std::max)(sizeof(std::size_t), __alignof(T)); +#else + std::size_t headerSize = (std::max)(sizeof(std::size_t), alignof(T)); +#endif + + if (trackMemberCount) + { + allocationSize += headerSize; + } + + void* rawMemory = Malloc(allocationTag, allocationSize); + T* pointerToT = nullptr; + + if (trackMemberCount) + { + std::size_t* pointerToAmount = reinterpret_cast<std::size_t*>(rawMemory); + *pointerToAmount = amount; + pointerToT = reinterpret_cast<T*>(reinterpret_cast<char*>(pointerToAmount) + headerSize); + + } + else + { + pointerToT = reinterpret_cast<T*>(rawMemory); + } + + if (constructMembers) + { + for (std::size_t i = 0; i < amount; ++i) + { + new (pointerToT + i) T; + } + } + + return pointerToT; + } + + return nullptr; + } + + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + template<typename T> + void DeleteArray(T* pointerToTArray) + { + if (pointerToTArray == nullptr) + { + return; + } + + bool destroyMembers = ShouldDestroyArrayMembers<T>(); + void* rawMemory = nullptr; + + if (destroyMembers) + { +#if defined(_MSC_VER) && _MSC_VER < 1900 + std::size_t headerSize = (std::max)(sizeof(std::size_t), __alignof(T)); +#else + std::size_t headerSize = (std::max)(sizeof(std::size_t), alignof(T)); +#endif + + std::size_t *pointerToAmount = reinterpret_cast<std::size_t*>(reinterpret_cast<char*>(pointerToTArray) - headerSize); + std::size_t amount = *pointerToAmount; + + for (std::size_t i = amount; i > 0; --i) + { + (pointerToTArray + i - 1)->~T(); + } + rawMemory = reinterpret_cast<void *>(pointerToAmount); + } + else + { + rawMemory = reinterpret_cast<void *>(pointerToTArray); + } + + Free(rawMemory); + } + + /** + * modeled from std::default_delete + */ + template<typename T> + struct Deleter + { + Deleter() {} + + template<class U, class = typename std::enable_if<std::is_convertible<U *, T *>::value, void>::type> + Deleter(const Deleter<U>&) + { + } + + void operator()(T *pointerToT) const + { + static_assert(0 < sizeof(T), "can't delete an incomplete type"); + Aws::Delete(pointerToT); + } + }; + + template< typename T > using UniquePtr = std::unique_ptr< T, Deleter< T > >; + + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + template<typename T, typename ...ArgTypes> + UniquePtr<T> MakeUnique(const char* allocationTag, ArgTypes&&... args) + { + return UniquePtr<T>(Aws::New<T>(allocationTag, std::forward<ArgTypes>(args)...)); + } + + template<typename T> + struct ArrayDeleter + { + ArrayDeleter() {} + + template<class U, class = typename std::enable_if<std::is_convertible<U *, T *>::value, void>::type> + ArrayDeleter(const ArrayDeleter<U>&) + { + } + + void operator()(T *pointerToTArray) const + { + static_assert(0 < sizeof(T), "can't delete an incomplete type"); + Aws::DeleteArray(pointerToTArray); + } + }; + + template< typename T > using UniqueArrayPtr = std::unique_ptr< T, ArrayDeleter< T > >; + + /** + * ::new, ::delete, ::malloc, ::free, std::make_shared, and std::make_unique should not be used in SDK code + * use these functions instead or Aws::MakeShared + */ + template<typename T, typename ...ArgTypes> + UniqueArrayPtr<T> MakeUniqueArray(std::size_t amount, const char* allocationTag, ArgTypes&&... args) + { + return UniqueArrayPtr<T>(Aws::NewArray<T>(amount, allocationTag, std::forward<ArgTypes>(args)...)); + } + +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/MemorySystemInterface.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/MemorySystemInterface.h index 0a8341ff86..f5e089cd61 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/MemorySystemInterface.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/MemorySystemInterface.h @@ -1,50 +1,50 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <cstdlib> - -namespace Aws -{ - namespace Utils - { - namespace Memory - { - /** + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <cstdlib> + +namespace Aws +{ + namespace Utils + { + namespace Memory + { + /** * Central interface for memory management customizations. To create a custom memory manager, implement this interface and then - * call InitializeAWSMemorySystem(). - */ - class AWS_CORE_API MemorySystemInterface - { - public: - virtual ~MemorySystemInterface() = default; - - /** - * This is for initializing your memory manager in a static context. This can be empty if you don't need to do that. - */ - virtual void Begin() = 0; - /** - * This is for cleaning up your memory manager in a static context. This can be empty if you don't need to do that. - */ - virtual void End() = 0; - - /** + * call InitializeAWSMemorySystem(). + */ + class AWS_CORE_API MemorySystemInterface + { + public: + virtual ~MemorySystemInterface() = default; + + /** + * This is for initializing your memory manager in a static context. This can be empty if you don't need to do that. + */ + virtual void Begin() = 0; + /** + * This is for cleaning up your memory manager in a static context. This can be empty if you don't need to do that. + */ + virtual void End() = 0; + + /** * Allocate your memory inside this method. blocksize and alignment are exactly the same as the std::allocator interfaces. - * The allocationTag parameter is for memory tracking; you don't have to handle it. - */ - virtual void* AllocateMemory(std::size_t blockSize, std::size_t alignment, const char *allocationTag = nullptr) = 0; - - /** - * Free the memory pointed to by memoryPtr. - */ - virtual void FreeMemory(void* memoryPtr) = 0; - }; - - } // namespace Memory - } // namespace Utils -} // namespace Aws + * The allocationTag parameter is for memory tracking; you don't have to handle it. + */ + virtual void* AllocateMemory(std::size_t blockSize, std::size_t alignment, const char *allocationTag = nullptr) = 0; + + /** + * Free the memory pointed to by memoryPtr. + */ + virtual void FreeMemory(void* memoryPtr) = 0; + }; + + } // namespace Memory + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h index 932408b761..c54ee873d5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSAllocator.h @@ -1,100 +1,100 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/SDKConfig.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/MemorySystemInterface.h> - -#include <memory> -#include <cstdlib> - -namespace Aws -{ -#ifdef USE_AWS_MEMORY_MANAGEMENT - /** - * Std allocator interface that is used for all STL types in the event that Custom Memory Management is being used. - */ - template <typename T> - class Allocator : public std::allocator<T> - { - public: - - typedef std::allocator<T> Base; - - Allocator() throw() : - Base() - {} - - Allocator(const Allocator<T>& a) throw() : - Base(a) - {} - - template <class U> - Allocator(const Allocator<U>& a) throw() : - Base(a) - {} - - ~Allocator() throw() {} - - typedef std::size_t size_type; - - template<typename U> - struct rebind - { - typedef Allocator<U> other; - }; - - typename Base::pointer allocate(size_type n, const void *hint = nullptr) - { - AWS_UNREFERENCED_PARAM(hint); - - return reinterpret_cast<typename Base::pointer>(Malloc("AWSSTL", n * sizeof(T))); - } - - void deallocate(typename Base::pointer p, size_type n) - { - AWS_UNREFERENCED_PARAM(n); - - Free(p); - } - - }; - -#ifdef __ANDROID__ -#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 - template< typename T > - bool operator ==(const Allocator< T >& lhs, const Allocator< T >& rhs) - { - AWS_UNREFERENCED_PARAM(lhs); - AWS_UNREFERENCED_PARAM(rhs); - - return false; - } -#endif // _GLIBCXX_FULLY_DYNAMIC_STRING == 0 -#endif // __ANDROID__ - -#else - - template< typename T > using Allocator = std::allocator<T>; - -#endif // USE_AWS_MEMORY_MANAGEMENT - /** - * Creates a shared_ptr using AWS Allocator hooks. - * allocationTag is for memory tracking purposes. - */ - template<typename T, typename ...ArgTypes> - std::shared_ptr<T> MakeShared(const char* allocationTag, ArgTypes&&... args) - { - AWS_UNREFERENCED_PARAM(allocationTag); - - return std::allocate_shared<T, Aws::Allocator<T>>(Aws::Allocator<T>(), std::forward<ArgTypes>(args)...); - } - - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/SDKConfig.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/MemorySystemInterface.h> + +#include <memory> +#include <cstdlib> + +namespace Aws +{ +#ifdef USE_AWS_MEMORY_MANAGEMENT + /** + * Std allocator interface that is used for all STL types in the event that Custom Memory Management is being used. + */ + template <typename T> + class Allocator : public std::allocator<T> + { + public: + + typedef std::allocator<T> Base; + + Allocator() throw() : + Base() + {} + + Allocator(const Allocator<T>& a) throw() : + Base(a) + {} + + template <class U> + Allocator(const Allocator<U>& a) throw() : + Base(a) + {} + + ~Allocator() throw() {} + + typedef std::size_t size_type; + + template<typename U> + struct rebind + { + typedef Allocator<U> other; + }; + + typename Base::pointer allocate(size_type n, const void *hint = nullptr) + { + AWS_UNREFERENCED_PARAM(hint); + + return reinterpret_cast<typename Base::pointer>(Malloc("AWSSTL", n * sizeof(T))); + } + + void deallocate(typename Base::pointer p, size_type n) + { + AWS_UNREFERENCED_PARAM(n); + + Free(p); + } + + }; + +#ifdef __ANDROID__ +#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 + template< typename T > + bool operator ==(const Allocator< T >& lhs, const Allocator< T >& rhs) + { + AWS_UNREFERENCED_PARAM(lhs); + AWS_UNREFERENCED_PARAM(rhs); + + return false; + } +#endif // _GLIBCXX_FULLY_DYNAMIC_STRING == 0 +#endif // __ANDROID__ + +#else + + template< typename T > using Allocator = std::allocator<T>; + +#endif // USE_AWS_MEMORY_MANAGEMENT + /** + * Creates a shared_ptr using AWS Allocator hooks. + * allocationTag is for memory tracking purposes. + */ + template<typename T, typename ...ArgTypes> + std::shared_ptr<T> MakeShared(const char* allocationTag, ArgTypes&&... args) + { + AWS_UNREFERENCED_PARAM(allocationTag); + + return std::allocate_shared<T, Aws::Allocator<T>>(Aws::Allocator<T>(), std::forward<ArgTypes>(args)...); + } + + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSDeque.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSDeque.h index ed63b8e939..acb69ae68c 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSDeque.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSDeque.h @@ -1,19 +1,19 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <deque> - -namespace Aws -{ - -template< typename T > using Deque = std::deque< T, Aws::Allocator< T > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <deque> + +namespace Aws +{ + +template< typename T > using Deque = std::deque< T, Aws::Allocator< T > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSList.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSList.h index 49341325a8..e2163c26b0 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSList.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSList.h @@ -1,19 +1,19 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <list> - -namespace Aws -{ - -template< typename T > using List = std::list< T, Aws::Allocator< T > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <list> + +namespace Aws +{ + +template< typename T > using List = std::list< T, Aws::Allocator< T > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSMap.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSMap.h index 66dc98bb8f..566496ad40 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSMap.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSMap.h @@ -1,33 +1,33 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <map> -#include <unordered_map> -#include <cstring> - -namespace Aws -{ - -template< typename K, typename V > using Map = std::map< K, V, std::less< K >, Aws::Allocator< std::pair< const K, V > > >; -template< typename K, typename V > using UnorderedMap = std::unordered_map< K, V, std::hash< K >, std::equal_to< K >, Aws::Allocator< std::pair< const K, V > > >; -template< typename K, typename V > using MultiMap = std::multimap< K, V, std::less< K >, Aws::Allocator< std::pair< const K, V > > >; - -struct CompareStrings -{ - bool operator()(const char* a, const char* b) const - { - return std::strcmp(a, b) < 0; - } -}; - -template<typename V> using CStringMap = std::map<const char*, V, CompareStrings, Aws::Allocator<std::pair<const char*, V> > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <map> +#include <unordered_map> +#include <cstring> + +namespace Aws +{ + +template< typename K, typename V > using Map = std::map< K, V, std::less< K >, Aws::Allocator< std::pair< const K, V > > >; +template< typename K, typename V > using UnorderedMap = std::unordered_map< K, V, std::hash< K >, std::equal_to< K >, Aws::Allocator< std::pair< const K, V > > >; +template< typename K, typename V > using MultiMap = std::multimap< K, V, std::less< K >, Aws::Allocator< std::pair< const K, V > > >; + +struct CompareStrings +{ + bool operator()(const char* a, const char* b) const + { + return std::strcmp(a, b) < 0; + } +}; + +template<typename V> using CStringMap = std::map<const char*, V, CompareStrings, Aws::Allocator<std::pair<const char*, V> > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSQueue.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSQueue.h index d45b245ad0..5277947433 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSQueue.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSQueue.h @@ -1,21 +1,21 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> -#include <aws/core/utils/memory/stl/AWSDeque.h> - -#include <deque> -#include <queue> - -namespace Aws -{ - -template< typename T > using Queue = std::queue< T, Deque< T > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> +#include <aws/core/utils/memory/stl/AWSDeque.h> + +#include <deque> +#include <queue> + +namespace Aws +{ + +template< typename T > using Queue = std::queue< T, Deque< T > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h index 6aee204f39..64d99ae089 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSSet.h @@ -1,19 +1,19 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <set> - -namespace Aws -{ - -template< typename T > using Set = std::set< T, std::less< T >, Aws::Allocator< T > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <set> + +namespace Aws +{ + +template< typename T > using Set = std::set< T, std::less< T >, Aws::Allocator< T > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStack.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStack.h index 7a3f561244..6fdb350117 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStack.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStack.h @@ -1,21 +1,21 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> -#include <aws/core/utils/memory/stl/AWSDeque.h> - -#include <deque> -#include <stack> - -namespace Aws -{ - -template< typename T > using Stack = std::stack< T, Deque< T > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> +#include <aws/core/utils/memory/stl/AWSDeque.h> + +#include <deque> +#include <stack> + +namespace Aws +{ + +template< typename T > using Stack = std::stack< T, Deque< T > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStreamFwd.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStreamFwd.h index 335346a31b..cc0d0be7c3 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStreamFwd.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStreamFwd.h @@ -1,28 +1,28 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <iostream> -#include <functional> - -namespace Aws -{ - -// Serves no purpose other than to help my conversion process -typedef std::basic_ifstream< char, std::char_traits< char > > IFStream; -typedef std::basic_ofstream< char, std::char_traits< char > > OFStream; -typedef std::basic_fstream< char, std::char_traits< char > > FStream; -typedef std::basic_istream< char, std::char_traits< char > > IStream; -typedef std::basic_ostream< char, std::char_traits< char > > OStream; -typedef std::basic_iostream< char, std::char_traits< char > > IOStream; -typedef std::istreambuf_iterator< char, std::char_traits< char > > IStreamBufIterator; - -using IOStreamFactory = std::function< Aws::IOStream*(void) >; - - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <iostream> +#include <functional> + +namespace Aws +{ + +// Serves no purpose other than to help my conversion process +typedef std::basic_ifstream< char, std::char_traits< char > > IFStream; +typedef std::basic_ofstream< char, std::char_traits< char > > OFStream; +typedef std::basic_fstream< char, std::char_traits< char > > FStream; +typedef std::basic_istream< char, std::char_traits< char > > IStream; +typedef std::basic_ostream< char, std::char_traits< char > > OStream; +typedef std::basic_iostream< char, std::char_traits< char > > IOStream; +typedef std::istreambuf_iterator< char, std::char_traits< char > > IStreamBufIterator; + +using IOStreamFactory = std::function< Aws::IOStream*(void) >; + + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h index 3cd013e3f8..fd1fe725bf 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSString.h @@ -1,108 +1,108 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <functional> -#include <string> - -namespace Aws -{ - -#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) - -/* -using std::string with shared libraries is broken on android when using gnustl -due to the platform-level decision to set _GLIBCXX_FULLY_DYNAMIC_STRING to 0 - -The problem: - -(1) _GLIBCXX_FULLY_DYNAMIC_STRING is set to 0 in Android's c++config.h for gnustl -(2) The optimization that this enables is completely broken if using shared libraries and there is no way to opt out of using it. - An optimization that uses a comparison to a static memory address is death for shared libraries. - + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <functional> +#include <string> + +namespace Aws +{ + +#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) + +/* +using std::string with shared libraries is broken on android when using gnustl +due to the platform-level decision to set _GLIBCXX_FULLY_DYNAMIC_STRING to 0 + +The problem: + +(1) _GLIBCXX_FULLY_DYNAMIC_STRING is set to 0 in Android's c++config.h for gnustl +(2) The optimization that this enables is completely broken if using shared libraries and there is no way to opt out of using it. + An optimization that uses a comparison to a static memory address is death for shared libraries. + Supposing you have a shared library B that depends on another shared library A. There are a variety of innocuous scenarios where you end up crashing in the std::basic_string destructor because it's attempting to free a static memory address (&std::string::_Rep_Base::_S_empty_rep_storage -- you'll need to temporarily flip the struct to "public:" in order to take this address from your code). -If you take the address of this location, you will get two -different answers depending on whether you query it in library A or library B (oddly enough, if you look the symbol itself up, it only shows up as public weak in -libgnustl_shared.so). When the string destructor is run from the context of library B, the _Rep::_M_dispose function will end up attempting to free -an address that is static memory (from library A). - - -Lessons (with the empty string optimization forced on you): - (1) You can't move std::strings across shared libraries (as a part of another class, Outcome in our case) +If you take the address of this location, you will get two +different answers depending on whether you query it in library A or library B (oddly enough, if you look the symbol itself up, it only shows up as public weak in +libgnustl_shared.so). When the string destructor is run from the context of library B, the _Rep::_M_dispose function will end up attempting to free +an address that is static memory (from library A). + + +Lessons (with the empty string optimization forced on you): + (1) You can't move std::strings across shared libraries (as a part of another class, Outcome in our case) (2) If you default initialize a std::string member variable, you can't have a mismatched constructor/destructor pair such that one is in a cpp file and the other - is missing/implicit or defined in the header file - -Solutions: - -Use libc++ rather than gnustl - -For those who must use gnustl, we have provided a working solution by cobbling together a set of hacks: - -We prevent the empty string optimization from ever being run on our strings by: + is missing/implicit or defined in the header file + +Solutions: + +Use libc++ rather than gnustl + +For those who must use gnustl, we have provided a working solution by cobbling together a set of hacks: + +We prevent the empty string optimization from ever being run on our strings by: (1) Make Aws::Allocator always fail equality checks with itself; this check is part of the empty string optimization in several std::basic_string constructors - (2) All other cases are prevented by turning Aws::String into a subclass whose default constructor and move operations go to baseclass versions which will not - perform the empty string optimization - -Those changes prevent crashes, but lead to very poor performance when using a string stream; every character added will result in multiple copies of the entire -string (ie, quadratic). - -To fix the performance problems, we have put together a set of replacement classes, SimpleStreamBuf and SimpleStringStream, that -replace std::stringstream and std::stringbuf in SDK code. These replacements use raw buffers rather than strings in order to -avoid the performance issues. - -This solution is only enabled if using gnustl on Android. In all other situations, normal STL types are used. -*/ - -using AndroidBasicString = std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > >; - -class String : public AndroidBasicString -{ - public: - using Base = AndroidBasicString; - - String() : Base("") {} // allocator comparison failure will cause empty string optimisation to be skipped - String(const String& rhs ) : Base(rhs) {} - String(String&& rhs) : Base(rhs) {} // DO NOT CALL std::move, let this go to the const ref constructor - String(const AndroidBasicString& rhs) : Base(rhs) {} - String(AndroidBasicString&& rhs) : Base(rhs) {} // DO NOT CALL std::move, let this go to the const ref constructor - String(const char* str) : Base(str) {} - String(const char* str_begin, const char* str_end) : Base(str_begin, str_end) {} + (2) All other cases are prevented by turning Aws::String into a subclass whose default constructor and move operations go to baseclass versions which will not + perform the empty string optimization + +Those changes prevent crashes, but lead to very poor performance when using a string stream; every character added will result in multiple copies of the entire +string (ie, quadratic). + +To fix the performance problems, we have put together a set of replacement classes, SimpleStreamBuf and SimpleStringStream, that +replace std::stringstream and std::stringbuf in SDK code. These replacements use raw buffers rather than strings in order to +avoid the performance issues. + +This solution is only enabled if using gnustl on Android. In all other situations, normal STL types are used. +*/ + +using AndroidBasicString = std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > >; + +class String : public AndroidBasicString +{ + public: + using Base = AndroidBasicString; + + String() : Base("") {} // allocator comparison failure will cause empty string optimisation to be skipped + String(const String& rhs ) : Base(rhs) {} + String(String&& rhs) : Base(rhs) {} // DO NOT CALL std::move, let this go to the const ref constructor + String(const AndroidBasicString& rhs) : Base(rhs) {} + String(AndroidBasicString&& rhs) : Base(rhs) {} // DO NOT CALL std::move, let this go to the const ref constructor + String(const char* str) : Base(str) {} + String(const char* str_begin, const char* str_end) : Base(str_begin, str_end) {} String(const AndroidBasicString& str, size_type pos, size_type count) : Base(str, pos, count) {} - String(const String& str, size_type pos, size_type count) : Base(str, pos, count) {} - String(const char* str, size_type count) : Base(str, count) {} - String(size_type count, char c) : Base(count, c) {} - String(std::initializer_list<char> __l) : Base(__l) {} - - template<class _InputIterator> - String(_InputIterator __beg, _InputIterator __end) : Base(__beg, __end) {} - - String& operator=(const String& rhs) { Base::operator=(rhs); return *this; } - String& operator=(String&& rhs) { Base::operator=(rhs); return *this; } // might be ok to use std::move (base class uses swap) but let's be safe - String& operator=(const AndroidBasicString& rhs) { Base::operator=(rhs); return *this; } - String& operator=(AndroidBasicString&& rhs) { Base::operator=(rhs); return *this; } // might be ok to use std::move (base class uses swap) but let's be safe - String& operator=(const char* str) { Base::operator=(str); return *this; } -}; - -#else - -using String = std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > >; - -#ifdef _WIN32 -using WString = std::basic_string< wchar_t, std::char_traits< wchar_t >, Aws::Allocator< wchar_t > >; -#endif - -#endif // __ANDROID - -} // namespace Aws - - - + String(const String& str, size_type pos, size_type count) : Base(str, pos, count) {} + String(const char* str, size_type count) : Base(str, count) {} + String(size_type count, char c) : Base(count, c) {} + String(std::initializer_list<char> __l) : Base(__l) {} + + template<class _InputIterator> + String(_InputIterator __beg, _InputIterator __end) : Base(__beg, __end) {} + + String& operator=(const String& rhs) { Base::operator=(rhs); return *this; } + String& operator=(String&& rhs) { Base::operator=(rhs); return *this; } // might be ok to use std::move (base class uses swap) but let's be safe + String& operator=(const AndroidBasicString& rhs) { Base::operator=(rhs); return *this; } + String& operator=(AndroidBasicString&& rhs) { Base::operator=(rhs); return *this; } // might be ok to use std::move (base class uses swap) but let's be safe + String& operator=(const char* str) { Base::operator=(str); return *this; } +}; + +#else + +using String = std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > >; + +#ifdef _WIN32 +using WString = std::basic_string< wchar_t, std::char_traits< wchar_t >, Aws::Allocator< wchar_t > >; +#endif + +#endif // __ANDROID + +} // namespace Aws + + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStringStream.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStringStream.h index a5e6f4ae48..2ec3ee68d4 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStringStream.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSStringStream.h @@ -1,42 +1,42 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) - -#include <aws/core/utils/memory/stl/SimpleStringStream.h> - -#else - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <sstream> - -#endif - -namespace Aws -{ - -#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) - -// see the large comment block in AWSString.h for an explanation -typedef Aws::SimpleStringStream StringStream; -typedef Aws::SimpleIStringStream IStringStream; -typedef Aws::SimpleOStringStream OStringStream; -typedef Aws::Utils::Stream::SimpleStreamBuf StringBuf; - -#else - -typedef std::basic_stringstream< char, std::char_traits< char >, Aws::Allocator< char > > StringStream; -typedef std::basic_istringstream< char, std::char_traits< char >, Aws::Allocator< char > > IStringStream; -typedef std::basic_ostringstream< char, std::char_traits< char >, Aws::Allocator< char > > OStringStream; -typedef std::basic_stringbuf< char, std::char_traits< char >, Aws::Allocator< char > > StringBuf; - -#endif - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) + +#include <aws/core/utils/memory/stl/SimpleStringStream.h> + +#else + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <sstream> + +#endif + +namespace Aws +{ + +#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) + +// see the large comment block in AWSString.h for an explanation +typedef Aws::SimpleStringStream StringStream; +typedef Aws::SimpleIStringStream IStringStream; +typedef Aws::SimpleOStringStream OStringStream; +typedef Aws::Utils::Stream::SimpleStreamBuf StringBuf; + +#else + +typedef std::basic_stringstream< char, std::char_traits< char >, Aws::Allocator< char > > StringStream; +typedef std::basic_istringstream< char, std::char_traits< char >, Aws::Allocator< char > > IStringStream; +typedef std::basic_ostringstream< char, std::char_traits< char >, Aws::Allocator< char > > OStringStream; +typedef std::basic_stringbuf< char, std::char_traits< char >, Aws::Allocator< char > > StringBuf; + +#endif + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSVector.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSVector.h index d9f67825c7..4f3c62ba71 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSVector.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/AWSVector.h @@ -1,19 +1,19 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/memory/stl/AWSAllocator.h> - -#include <vector> - -namespace Aws -{ - -template< typename T > using Vector = std::vector< T, Aws::Allocator< T > >; - -} // namespace Aws + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/memory/stl/AWSAllocator.h> + +#include <vector> + +namespace Aws +{ + +template< typename T > using Vector = std::vector< T, Aws::Allocator< T > >; + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/SimpleStringStream.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/SimpleStringStream.h index 45c4d0a448..0be4fdc106 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/SimpleStringStream.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/memory/stl/SimpleStringStream.h @@ -1,126 +1,126 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/stream/SimpleStreamBuf.h> - -#include <iostream> - -namespace Aws -{ - -class AWS_CORE_API SimpleStringStream : public std::iostream -{ - public: - - using char_type = char; - using traits_type = std::char_traits<char>; - using allocator_type = Aws::Allocator<char>; - using int_type = int; - using pos_type = std::streampos; - using off_type = std::streamoff; - - using base = std::iostream; - - SimpleStringStream(); - SimpleStringStream(const Aws::String& value); - - virtual ~SimpleStringStream() {} - - // disabling copies of course - SimpleStringStream(const SimpleStringStream& rhs) = delete; - SimpleStringStream& operator=(const SimpleStringStream& rhs) = delete; - - // also disabling moves until there's a valid need - SimpleStringStream(SimpleStringStream&& rhs) = delete; - SimpleStringStream& operator=(SimpleStringStream&& rhs) = delete; - - Aws::Utils::Stream::SimpleStreamBuf* rdbuf() const { return const_cast<Aws::Utils::Stream::SimpleStreamBuf*>(&m_streamBuffer); } - + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/stream/SimpleStreamBuf.h> + +#include <iostream> + +namespace Aws +{ + +class AWS_CORE_API SimpleStringStream : public std::iostream +{ + public: + + using char_type = char; + using traits_type = std::char_traits<char>; + using allocator_type = Aws::Allocator<char>; + using int_type = int; + using pos_type = std::streampos; + using off_type = std::streamoff; + + using base = std::iostream; + + SimpleStringStream(); + SimpleStringStream(const Aws::String& value); + + virtual ~SimpleStringStream() {} + + // disabling copies of course + SimpleStringStream(const SimpleStringStream& rhs) = delete; + SimpleStringStream& operator=(const SimpleStringStream& rhs) = delete; + + // also disabling moves until there's a valid need + SimpleStringStream(SimpleStringStream&& rhs) = delete; + SimpleStringStream& operator=(SimpleStringStream&& rhs) = delete; + + Aws::Utils::Stream::SimpleStreamBuf* rdbuf() const { return const_cast<Aws::Utils::Stream::SimpleStreamBuf*>(&m_streamBuffer); } + Aws::String str() const { return m_streamBuffer.str(); } void str(const Aws::String& value); - - private: - - Aws::Utils::Stream::SimpleStreamBuf m_streamBuffer; -}; - -class AWS_CORE_API SimpleIStringStream : public std::istream -{ - public: - - using char_type = char; - using traits_type = std::char_traits<char>; - using allocator_type = Aws::Allocator<char>; - using int_type = int; - using pos_type = std::streampos; - using off_type = std::streamoff; - - using base = std::istream; - - SimpleIStringStream(); - SimpleIStringStream(const Aws::String& value); - - virtual ~SimpleIStringStream() {} - - // disabling copies of course - SimpleIStringStream(const SimpleIStringStream& rhs) = delete; - SimpleIStringStream& operator=(const SimpleIStringStream& rhs) = delete; - - // also disabling moves until there's a valid need - SimpleIStringStream(SimpleIStringStream&& rhs) = delete; - SimpleIStringStream& operator=(SimpleIStringStream&& rhs) = delete; - - Aws::Utils::Stream::SimpleStreamBuf* rdbuf() const { return const_cast<Aws::Utils::Stream::SimpleStreamBuf*>(&m_streamBuffer); } - + + private: + + Aws::Utils::Stream::SimpleStreamBuf m_streamBuffer; +}; + +class AWS_CORE_API SimpleIStringStream : public std::istream +{ + public: + + using char_type = char; + using traits_type = std::char_traits<char>; + using allocator_type = Aws::Allocator<char>; + using int_type = int; + using pos_type = std::streampos; + using off_type = std::streamoff; + + using base = std::istream; + + SimpleIStringStream(); + SimpleIStringStream(const Aws::String& value); + + virtual ~SimpleIStringStream() {} + + // disabling copies of course + SimpleIStringStream(const SimpleIStringStream& rhs) = delete; + SimpleIStringStream& operator=(const SimpleIStringStream& rhs) = delete; + + // also disabling moves until there's a valid need + SimpleIStringStream(SimpleIStringStream&& rhs) = delete; + SimpleIStringStream& operator=(SimpleIStringStream&& rhs) = delete; + + Aws::Utils::Stream::SimpleStreamBuf* rdbuf() const { return const_cast<Aws::Utils::Stream::SimpleStreamBuf*>(&m_streamBuffer); } + Aws::String str() const { return m_streamBuffer.str(); } void str(const Aws::String& value); - - private: - - Aws::Utils::Stream::SimpleStreamBuf m_streamBuffer; -}; - -class AWS_CORE_API SimpleOStringStream : public std::ostream -{ - public: - - using char_type = char; - using traits_type = std::char_traits<char>; - using allocator_type = Aws::Allocator<char>; - using int_type = int; - using pos_type = std::streampos; - using off_type = std::streamoff; - - using base = std::ostream; - - SimpleOStringStream(); - SimpleOStringStream(const Aws::String& value); - - virtual ~SimpleOStringStream() {} - - // disabling copies of course - SimpleOStringStream(const SimpleOStringStream& rhs) = delete; - SimpleOStringStream& operator=(const SimpleOStringStream& rhs) = delete; - - // also disabling moves until there's a valid need - SimpleOStringStream(SimpleOStringStream&& rhs) = delete; - SimpleOStringStream& operator=(SimpleOStringStream&& rhs) = delete; - - Aws::Utils::Stream::SimpleStreamBuf* rdbuf() const { return const_cast<Aws::Utils::Stream::SimpleStreamBuf*>(&m_streamBuffer); } - + + private: + + Aws::Utils::Stream::SimpleStreamBuf m_streamBuffer; +}; + +class AWS_CORE_API SimpleOStringStream : public std::ostream +{ + public: + + using char_type = char; + using traits_type = std::char_traits<char>; + using allocator_type = Aws::Allocator<char>; + using int_type = int; + using pos_type = std::streampos; + using off_type = std::streamoff; + + using base = std::ostream; + + SimpleOStringStream(); + SimpleOStringStream(const Aws::String& value); + + virtual ~SimpleOStringStream() {} + + // disabling copies of course + SimpleOStringStream(const SimpleOStringStream& rhs) = delete; + SimpleOStringStream& operator=(const SimpleOStringStream& rhs) = delete; + + // also disabling moves until there's a valid need + SimpleOStringStream(SimpleOStringStream&& rhs) = delete; + SimpleOStringStream& operator=(SimpleOStringStream&& rhs) = delete; + + Aws::Utils::Stream::SimpleStreamBuf* rdbuf() const { return const_cast<Aws::Utils::Stream::SimpleStreamBuf*>(&m_streamBuffer); } + Aws::String str() const { return m_streamBuffer.str(); } void str(const Aws::String& value); - - private: - - Aws::Utils::Stream::SimpleStreamBuf m_streamBuffer; -}; - -} // namespace Aws - + + private: + + Aws::Utils::Stream::SimpleStreamBuf m_streamBuffer; +}; + +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ratelimiter/RateLimiterInterface.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ratelimiter/RateLimiterInterface.h index 578c9ed844..44d71ee399 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ratelimiter/RateLimiterInterface.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/ratelimiter/RateLimiterInterface.h @@ -2,44 +2,44 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <stdint.h> -#include <chrono> - -namespace Aws -{ - namespace Utils - { - namespace RateLimits - { - /** - * Interface for bandwidth limiters. You likely don't want to implement your own as DefaultRateLimiter is probably what you need. - * If you need to implement one, then this is the interface to implement. - */ - class RateLimiterInterface - { - public: - using DelayType = std::chrono::milliseconds; - - virtual ~RateLimiterInterface() {} - /** - * Calculates time in milliseconds that should be delayed before letting anymore data through. - */ - virtual DelayType ApplyCost(int64_t cost) = 0; - /** - * Same as ApplyCost() but then goes ahead and sleeps the current thread. - */ - virtual void ApplyAndPayForCost(int64_t cost) = 0; - /** - * Update the bandwidth rate to allow. - */ - virtual void SetRate(int64_t rate, bool resetAccumulator = false) = 0; - }; - - } // namespace RateLimits - } // namespace Utils -} // namespace Aws
\ No newline at end of file + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <stdint.h> +#include <chrono> + +namespace Aws +{ + namespace Utils + { + namespace RateLimits + { + /** + * Interface for bandwidth limiters. You likely don't want to implement your own as DefaultRateLimiter is probably what you need. + * If you need to implement one, then this is the interface to implement. + */ + class RateLimiterInterface + { + public: + using DelayType = std::chrono::milliseconds; + + virtual ~RateLimiterInterface() {} + /** + * Calculates time in milliseconds that should be delayed before letting anymore data through. + */ + virtual DelayType ApplyCost(int64_t cost) = 0; + /** + * Same as ApplyCost() but then goes ahead and sleeps the current thread. + */ + virtual void ApplyAndPayForCost(int64_t cost) = 0; + /** + * Update the bandwidth rate to allow. + */ + virtual void SetRate(int64_t rate, bool resetAccumulator = false) = 0; + }; + + } // namespace RateLimits + } // namespace Utils +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/PreallocatedStreamBuf.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/PreallocatedStreamBuf.h index ad9dc2a929..3e36402fb5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/PreallocatedStreamBuf.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/PreallocatedStreamBuf.h @@ -1,56 +1,56 @@ - + /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/Array.h> -#include <streambuf> - -namespace Aws -{ - namespace Utils - { - namespace Stream - { - /** - * this is a stream buf to use with std::iostream that uses a preallocated buffer under the hood. - */ - class AWS_CORE_API PreallocatedStreamBuf : public std::streambuf - { - public: - /** - * Initialize the stream buffer with a pointer to your buffer. This class never takes ownership - * of the buffer. It is your responsibility to delete it once the stream is no longer in use. - * @param buffer buffer to initialize from. - * @param lengthToRead length in bytes to actually use in the buffer (e.g. you have a 1kb buffer, but only want the stream - * to see 500 b of it. - */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/Array.h> +#include <streambuf> + +namespace Aws +{ + namespace Utils + { + namespace Stream + { + /** + * this is a stream buf to use with std::iostream that uses a preallocated buffer under the hood. + */ + class AWS_CORE_API PreallocatedStreamBuf : public std::streambuf + { + public: + /** + * Initialize the stream buffer with a pointer to your buffer. This class never takes ownership + * of the buffer. It is your responsibility to delete it once the stream is no longer in use. + * @param buffer buffer to initialize from. + * @param lengthToRead length in bytes to actually use in the buffer (e.g. you have a 1kb buffer, but only want the stream + * to see 500 b of it. + */ PreallocatedStreamBuf(unsigned char* buffer, uint64_t lengthToRead); - - PreallocatedStreamBuf(const PreallocatedStreamBuf&) = delete; - PreallocatedStreamBuf& operator=(const PreallocatedStreamBuf&) = delete; - - PreallocatedStreamBuf(PreallocatedStreamBuf&& toMove) = delete; - PreallocatedStreamBuf& operator=(PreallocatedStreamBuf&&) = delete; - - /** - * Get the buffer that is being used by the stream buffer. - * @return Pointer to the underlying buffer (probably for a Aws::Delete() call). - */ + + PreallocatedStreamBuf(const PreallocatedStreamBuf&) = delete; + PreallocatedStreamBuf& operator=(const PreallocatedStreamBuf&) = delete; + + PreallocatedStreamBuf(PreallocatedStreamBuf&& toMove) = delete; + PreallocatedStreamBuf& operator=(PreallocatedStreamBuf&&) = delete; + + /** + * Get the buffer that is being used by the stream buffer. + * @return Pointer to the underlying buffer (probably for a Aws::Delete() call). + */ unsigned char* GetBuffer() { return m_underlyingBuffer; } - - protected: - pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; - pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; - - private: + + protected: + pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; + pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; + + private: unsigned char* m_underlyingBuffer; const uint64_t m_lengthToRead; - }; - } - } -} + }; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h index e82e6448cd..071541f2ab 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/ResponseStream.h @@ -2,73 +2,73 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> - -namespace Aws -{ - namespace Utils - { - namespace Stream - { - /** - * Encapsulates and manages ownership of custom response streams. This is a move only type. - */ - class AWS_CORE_API ResponseStream - { - public: - /** - * sets underlying stream to nullptr - */ - ResponseStream(); - /** - * moves the underlying stream - */ - ResponseStream(ResponseStream&&); - /** - * Uses factory to allocate underlying stream - */ - ResponseStream(const Aws::IOStreamFactory& factory); - /** - * Takes ownership of an underlying stream. - */ - ResponseStream(IOStream* underlyingStreamToManage); - ResponseStream(const ResponseStream&) = delete; - ~ResponseStream(); - - /** - * moves the underlying stream - */ - ResponseStream& operator=(ResponseStream&&); - ResponseStream& operator=(const ResponseStream&) = delete; - - /** - * Gives access to underlying stream, but keep in mind that this changes state of the stream - */ - inline Aws::IOStream& GetUnderlyingStream() const { return *m_underlyingStream; } - - private: - void ReleaseStream(); - - Aws::IOStream* m_underlyingStream; - }; - - class AWS_CORE_API DefaultUnderlyingStream : public Aws::IOStream - { - public: - using Base = Aws::IOStream; - - DefaultUnderlyingStream(); - DefaultUnderlyingStream(Aws::UniquePtr<std::streambuf> buf); - virtual ~DefaultUnderlyingStream(); - }; - - AWS_CORE_API Aws::IOStream* DefaultResponseStreamFactoryMethod(); - - } //namespace Stream - } //namespace Utils -} //namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> + +namespace Aws +{ + namespace Utils + { + namespace Stream + { + /** + * Encapsulates and manages ownership of custom response streams. This is a move only type. + */ + class AWS_CORE_API ResponseStream + { + public: + /** + * sets underlying stream to nullptr + */ + ResponseStream(); + /** + * moves the underlying stream + */ + ResponseStream(ResponseStream&&); + /** + * Uses factory to allocate underlying stream + */ + ResponseStream(const Aws::IOStreamFactory& factory); + /** + * Takes ownership of an underlying stream. + */ + ResponseStream(IOStream* underlyingStreamToManage); + ResponseStream(const ResponseStream&) = delete; + ~ResponseStream(); + + /** + * moves the underlying stream + */ + ResponseStream& operator=(ResponseStream&&); + ResponseStream& operator=(const ResponseStream&) = delete; + + /** + * Gives access to underlying stream, but keep in mind that this changes state of the stream + */ + inline Aws::IOStream& GetUnderlyingStream() const { return *m_underlyingStream; } + + private: + void ReleaseStream(); + + Aws::IOStream* m_underlyingStream; + }; + + class AWS_CORE_API DefaultUnderlyingStream : public Aws::IOStream + { + public: + using Base = Aws::IOStream; + + DefaultUnderlyingStream(); + DefaultUnderlyingStream(Aws::UniquePtr<std::streambuf> buf); + virtual ~DefaultUnderlyingStream(); + }; + + AWS_CORE_API Aws::IOStream* DefaultResponseStreamFactoryMethod(); + + } //namespace Stream + } //namespace Utils +} //namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/SimpleStreamBuf.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/SimpleStreamBuf.h index ef12c60ba3..35256ab633 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/SimpleStreamBuf.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/stream/SimpleStreamBuf.h @@ -1,64 +1,64 @@ - + /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <streambuf> - -namespace Aws -{ -namespace Utils -{ -namespace Stream -{ - /** - * A replacement for std::stringbuf when using Android and gnustl together - */ - class AWS_CORE_API SimpleStreamBuf : public std::streambuf - { - public: - - using base = std::streambuf; - - SimpleStreamBuf(); - explicit SimpleStreamBuf(const Aws::String& value); - - SimpleStreamBuf(const SimpleStreamBuf&) = delete; - SimpleStreamBuf& operator=(const SimpleStreamBuf&) = delete; - - SimpleStreamBuf(SimpleStreamBuf&& toMove) = delete; - SimpleStreamBuf& operator=(SimpleStreamBuf&&) = delete; - - virtual ~SimpleStreamBuf(); - + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <streambuf> + +namespace Aws +{ +namespace Utils +{ +namespace Stream +{ + /** + * A replacement for std::stringbuf when using Android and gnustl together + */ + class AWS_CORE_API SimpleStreamBuf : public std::streambuf + { + public: + + using base = std::streambuf; + + SimpleStreamBuf(); + explicit SimpleStreamBuf(const Aws::String& value); + + SimpleStreamBuf(const SimpleStreamBuf&) = delete; + SimpleStreamBuf& operator=(const SimpleStreamBuf&) = delete; + + SimpleStreamBuf(SimpleStreamBuf&& toMove) = delete; + SimpleStreamBuf& operator=(SimpleStreamBuf&&) = delete; + + virtual ~SimpleStreamBuf(); + Aws::String str() const; - void str(const Aws::String& value); - - void swap(SimpleStreamBuf& rhs); - - protected: - virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; - virtual std::streampos seekpos(std::streampos pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; - - virtual int overflow (int c = EOF) override; - virtual int underflow() override; - - virtual std::streamsize xsputn(const char* s, std::streamsize n) override; - - private: - - bool GrowBuffer(); - - char* m_buffer; - size_t m_bufferSize; - }; - -} -} -} + void str(const Aws::String& value); + + void swap(SimpleStreamBuf& rhs); + + protected: + virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; + virtual std::streampos seekpos(std::streampos pos, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override; + + virtual int overflow (int c = EOF) override; + virtual int underflow() override; + + virtual std::streamsize xsputn(const char* s, std::streamsize n) override; + + private: + + bool GrowBuffer(); + + char* m_buffer; + size_t m_bufferSize; + }; + +} +} +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h index 36975af513..b3917ac43b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Executor.h @@ -2,118 +2,118 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/memory/stl/AWSQueue.h> -#include <aws/core/utils/memory/stl/AWSVector.h> -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/threading/Semaphore.h> -#include <functional> -#include <future> -#include <mutex> -#include <atomic> - -namespace Aws -{ - namespace Utils - { - namespace Threading - { - class ThreadTask; - - /** - * Interface for implementing an Executor, to implement a custom thread execution strategy, inherit from this class - * and override SubmitToThread(). - */ - class AWS_CORE_API Executor - { - public: - virtual ~Executor() = default; - - /** - * Send function and its arguments to the SubmitToThread function. - */ - template<class Fn, class ... Args> - bool Submit(Fn&& fn, Args&& ... args) - { - std::function<void()> callable{ std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...) }; - return SubmitToThread(std::move(callable)); - } - - protected: - /** - * To implement your own executor implementation, then simply subclass Executor and implement this method. - */ - virtual bool SubmitToThread(std::function<void()>&&) = 0; - }; - - - /** - * Default Executor implementation. Simply spawns a thread and detaches it. - */ - class AWS_CORE_API DefaultExecutor : public Executor - { - public: - DefaultExecutor() : m_state(State::Free) {} - ~DefaultExecutor(); - protected: - enum class State - { - Free, Locked, Shutdown - }; - bool SubmitToThread(std::function<void()>&&) override; - void Detach(std::thread::id id); - std::atomic<State> m_state; - Aws::UnorderedMap<std::thread::id, std::thread> m_threads; - }; - - enum class OverflowPolicy - { - QUEUE_TASKS_EVENLY_ACCROSS_THREADS, - REJECT_IMMEDIATELY - }; - - /** - * Thread Pool Executor implementation. - */ - class AWS_CORE_API PooledThreadExecutor : public Executor - { - public: - PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy = OverflowPolicy::QUEUE_TASKS_EVENLY_ACCROSS_THREADS); - ~PooledThreadExecutor(); - - /** - * Rule of 5 stuff. - * Don't copy or move - */ - PooledThreadExecutor(const PooledThreadExecutor&) = delete; - PooledThreadExecutor& operator =(const PooledThreadExecutor&) = delete; - PooledThreadExecutor(PooledThreadExecutor&&) = delete; - PooledThreadExecutor& operator =(PooledThreadExecutor&&) = delete; - - protected: - bool SubmitToThread(std::function<void()>&&) override; - - private: - Aws::Queue<std::function<void()>*> m_tasks; - std::mutex m_queueLock; - Aws::Utils::Threading::Semaphore m_sync; - Aws::Vector<ThreadTask*> m_threadTaskHandles; - size_t m_poolSize; - OverflowPolicy m_overflowPolicy; - - /** - * Once you call this, you are responsible for freeing the memory pointed to by task. - */ - std::function<void()>* PopTask(); - bool HasTasks(); - - friend class ThreadTask; - }; - - - } // namespace Threading - } // namespace Utils -} // namespace Aws + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/memory/stl/AWSQueue.h> +#include <aws/core/utils/memory/stl/AWSVector.h> +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/threading/Semaphore.h> +#include <functional> +#include <future> +#include <mutex> +#include <atomic> + +namespace Aws +{ + namespace Utils + { + namespace Threading + { + class ThreadTask; + + /** + * Interface for implementing an Executor, to implement a custom thread execution strategy, inherit from this class + * and override SubmitToThread(). + */ + class AWS_CORE_API Executor + { + public: + virtual ~Executor() = default; + + /** + * Send function and its arguments to the SubmitToThread function. + */ + template<class Fn, class ... Args> + bool Submit(Fn&& fn, Args&& ... args) + { + std::function<void()> callable{ std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...) }; + return SubmitToThread(std::move(callable)); + } + + protected: + /** + * To implement your own executor implementation, then simply subclass Executor and implement this method. + */ + virtual bool SubmitToThread(std::function<void()>&&) = 0; + }; + + + /** + * Default Executor implementation. Simply spawns a thread and detaches it. + */ + class AWS_CORE_API DefaultExecutor : public Executor + { + public: + DefaultExecutor() : m_state(State::Free) {} + ~DefaultExecutor(); + protected: + enum class State + { + Free, Locked, Shutdown + }; + bool SubmitToThread(std::function<void()>&&) override; + void Detach(std::thread::id id); + std::atomic<State> m_state; + Aws::UnorderedMap<std::thread::id, std::thread> m_threads; + }; + + enum class OverflowPolicy + { + QUEUE_TASKS_EVENLY_ACCROSS_THREADS, + REJECT_IMMEDIATELY + }; + + /** + * Thread Pool Executor implementation. + */ + class AWS_CORE_API PooledThreadExecutor : public Executor + { + public: + PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy = OverflowPolicy::QUEUE_TASKS_EVENLY_ACCROSS_THREADS); + ~PooledThreadExecutor(); + + /** + * Rule of 5 stuff. + * Don't copy or move + */ + PooledThreadExecutor(const PooledThreadExecutor&) = delete; + PooledThreadExecutor& operator =(const PooledThreadExecutor&) = delete; + PooledThreadExecutor(PooledThreadExecutor&&) = delete; + PooledThreadExecutor& operator =(PooledThreadExecutor&&) = delete; + + protected: + bool SubmitToThread(std::function<void()>&&) override; + + private: + Aws::Queue<std::function<void()>*> m_tasks; + std::mutex m_queueLock; + Aws::Utils::Threading::Semaphore m_sync; + Aws::Vector<ThreadTask*> m_threadTaskHandles; + size_t m_poolSize; + OverflowPolicy m_overflowPolicy; + + /** + * Once you call this, you are responsible for freeing the memory pointed to by task. + */ + std::function<void()>* PopTask(); + bool HasTasks(); + + friend class ThreadTask; + }; + + + } // namespace Threading + } // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ReaderWriterLock.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ReaderWriterLock.h index 5d757dcecb..f736918960 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ReaderWriterLock.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ReaderWriterLock.h @@ -2,115 +2,115 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <aws/core/utils/threading/Semaphore.h> -#include <mutex> -#include <atomic> -#include <condition_variable> -#include <cstdint> - -namespace Aws -{ - namespace Utils - { - namespace Threading - { - /** - * This lock is optimized for frequent reads and infrequent writes. - * However, writers get priority to the lock. - */ - class AWS_CORE_API ReaderWriterLock - { - public: - ReaderWriterLock(); - /** - * Enters the lock in Reader-mode. - * This call blocks until no writers are acquiring the lock. - */ - void LockReader(); - - /** - * Decrements the readers count by one and if the count is zero, signals any waiting writers to acquire - * the lock. - * NOTE: Calling this function without a matching LockReader results in undefined behavior. - */ - void UnlockReader(); - - /** - * Enters the lock in Writer-mode. - * This call blocks until no readers nor writers are acquiring the lock. - */ - void LockWriter(); - - /** - * Decrements the number of writers by one and signals any waiting readers or writers to acquire the - * lock. - * NOTE: Calling this function without a matching LockWriter results in undefined behavior. - */ - void UnlockWriter(); - private: - std::atomic<int64_t> m_readers; - std::atomic<int64_t> m_holdouts; - Semaphore m_readerSem; - Semaphore m_writerSem; - std::mutex m_writerLock; - }; - - class AWS_CORE_API ReaderLockGuard - { - public: - explicit ReaderLockGuard(ReaderWriterLock& rwl) : m_rwlock(rwl), m_upgraded(false) - { - m_rwlock.LockReader(); - } - - void UpgradeToWriterLock() - { - m_rwlock.UnlockReader(); - m_rwlock.LockWriter(); - m_upgraded = true; - } - - ~ReaderLockGuard() - { - if(m_upgraded) - { - m_rwlock.UnlockWriter(); - } - else - { - m_rwlock.UnlockReader(); - } - } - // for VS2013 - ReaderLockGuard(const ReaderLockGuard&) = delete; - ReaderLockGuard& operator=(const ReaderLockGuard&) = delete; - private: - ReaderWriterLock& m_rwlock; - bool m_upgraded; - }; - - class AWS_CORE_API WriterLockGuard - { - public: - explicit WriterLockGuard(ReaderWriterLock& rwl) : m_rwlock(rwl) - { - m_rwlock.LockWriter(); - } - - ~WriterLockGuard() - { - m_rwlock.UnlockWriter(); - } - // for VS2013 - WriterLockGuard(const WriterLockGuard&) = delete; - WriterLockGuard& operator=(const WriterLockGuard&) = delete; - private: - ReaderWriterLock& m_rwlock; - }; - } - } -} + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <aws/core/utils/threading/Semaphore.h> +#include <mutex> +#include <atomic> +#include <condition_variable> +#include <cstdint> + +namespace Aws +{ + namespace Utils + { + namespace Threading + { + /** + * This lock is optimized for frequent reads and infrequent writes. + * However, writers get priority to the lock. + */ + class AWS_CORE_API ReaderWriterLock + { + public: + ReaderWriterLock(); + /** + * Enters the lock in Reader-mode. + * This call blocks until no writers are acquiring the lock. + */ + void LockReader(); + + /** + * Decrements the readers count by one and if the count is zero, signals any waiting writers to acquire + * the lock. + * NOTE: Calling this function without a matching LockReader results in undefined behavior. + */ + void UnlockReader(); + + /** + * Enters the lock in Writer-mode. + * This call blocks until no readers nor writers are acquiring the lock. + */ + void LockWriter(); + + /** + * Decrements the number of writers by one and signals any waiting readers or writers to acquire the + * lock. + * NOTE: Calling this function without a matching LockWriter results in undefined behavior. + */ + void UnlockWriter(); + private: + std::atomic<int64_t> m_readers; + std::atomic<int64_t> m_holdouts; + Semaphore m_readerSem; + Semaphore m_writerSem; + std::mutex m_writerLock; + }; + + class AWS_CORE_API ReaderLockGuard + { + public: + explicit ReaderLockGuard(ReaderWriterLock& rwl) : m_rwlock(rwl), m_upgraded(false) + { + m_rwlock.LockReader(); + } + + void UpgradeToWriterLock() + { + m_rwlock.UnlockReader(); + m_rwlock.LockWriter(); + m_upgraded = true; + } + + ~ReaderLockGuard() + { + if(m_upgraded) + { + m_rwlock.UnlockWriter(); + } + else + { + m_rwlock.UnlockReader(); + } + } + // for VS2013 + ReaderLockGuard(const ReaderLockGuard&) = delete; + ReaderLockGuard& operator=(const ReaderLockGuard&) = delete; + private: + ReaderWriterLock& m_rwlock; + bool m_upgraded; + }; + + class AWS_CORE_API WriterLockGuard + { + public: + explicit WriterLockGuard(ReaderWriterLock& rwl) : m_rwlock(rwl) + { + m_rwlock.LockWriter(); + } + + ~WriterLockGuard() + { + m_rwlock.UnlockWriter(); + } + // for VS2013 + WriterLockGuard(const WriterLockGuard&) = delete; + WriterLockGuard& operator=(const WriterLockGuard&) = delete; + private: + ReaderWriterLock& m_rwlock; + }; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Semaphore.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Semaphore.h index bad50532dd..4f83a2f6ea 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Semaphore.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/Semaphore.h @@ -1,45 +1,45 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <mutex> -#include <condition_variable> - -namespace Aws -{ - namespace Utils - { - namespace Threading - { - class AWS_CORE_API Semaphore { - public: - /** - * Initializes a new instance of Semaphore class specifying the initial number of entries and - * the maximum number of concurrent entries. - */ - Semaphore(size_t initialCount, size_t maxCount); - /** - * Blocks the current thread until it receives a signal. - */ - void WaitOne(); - /** - * Exits the semaphore once. - */ - void Release(); - /** - * Exit the semaphore up to the maximum number of entries available. - */ - void ReleaseAll(); - private: - size_t m_count; - const size_t m_maxCount; - std::mutex m_mutex; - std::condition_variable m_syncPoint; - }; - } - } -} + */ + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <mutex> +#include <condition_variable> + +namespace Aws +{ + namespace Utils + { + namespace Threading + { + class AWS_CORE_API Semaphore { + public: + /** + * Initializes a new instance of Semaphore class specifying the initial number of entries and + * the maximum number of concurrent entries. + */ + Semaphore(size_t initialCount, size_t maxCount); + /** + * Blocks the current thread until it receives a signal. + */ + void WaitOne(); + /** + * Exits the semaphore once. + */ + void Release(); + /** + * Exit the semaphore up to the maximum number of entries available. + */ + void ReleaseAll(); + private: + size_t m_count; + const size_t m_maxCount; + std::mutex m_mutex; + std::condition_variable m_syncPoint; + }; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ThreadTask.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ThreadTask.h index 79326b3a15..a8060ad852 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ThreadTask.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/threading/ThreadTask.h @@ -2,47 +2,47 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> -#include <functional> -#include <thread> -#include <atomic> - -namespace Aws -{ - namespace Utils - { - namespace Threading - { - class PooledThreadExecutor; - - class AWS_CORE_API ThreadTask - { - public: - ThreadTask(PooledThreadExecutor& executor); - ~ThreadTask(); - - /** - * Rule of 5 stuff. - * Don't copy or move - */ - ThreadTask(const ThreadTask&) = delete; - ThreadTask& operator =(const ThreadTask&) = delete; - ThreadTask(ThreadTask&&) = delete; - ThreadTask& operator =(ThreadTask&&) = delete; - - void StopProcessingWork(); - - protected: - void MainTaskRunner(); - - private: - std::atomic<bool> m_continue; - PooledThreadExecutor& m_executor; - std::thread m_thread; - }; - } - } -} + +#pragma once + +#include <aws/core/Core_EXPORTS.h> +#include <functional> +#include <thread> +#include <atomic> + +namespace Aws +{ + namespace Utils + { + namespace Threading + { + class PooledThreadExecutor; + + class AWS_CORE_API ThreadTask + { + public: + ThreadTask(PooledThreadExecutor& executor); + ~ThreadTask(); + + /** + * Rule of 5 stuff. + * Don't copy or move + */ + ThreadTask(const ThreadTask&) = delete; + ThreadTask& operator =(const ThreadTask&) = delete; + ThreadTask(ThreadTask&&) = delete; + ThreadTask& operator =(ThreadTask&&) = delete; + + void StopProcessingWork(); + + protected: + void MainTaskRunner(); + + private: + std::atomic<bool> m_continue; + PooledThreadExecutor& m_executor; + std::thread m_thread; + }; + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h index d1ca79ffab..0e910c90ab 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include/aws/core/utils/xml/XmlSerializer.h @@ -2,217 +2,217 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#pragma once - -#include <aws/core/Core_EXPORTS.h> - -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/memory/stl/AWSString.h> - -namespace Aws -{ - namespace External - { - namespace tinyxml2 - { - class XMLNode; - - class XMLDocument; - } // namespace tinyxml2 - } // namespace External -} // namespace Aws - -namespace Aws -{ - template<typename PAYLOAD_TYPE> - class AmazonWebServiceResult; - namespace Client - { - enum class CoreErrors; - template<typename ERROR_TYPE> - class AWSError; - class AWSXMLClient; - } // namespace Client - namespace Utils - { - namespace Xml - { - /** - * Converts escaped xml text back to the original characters (e.g. < ! > = etc...) - */ - AWS_CORE_API Aws::String DecodeEscapedXmlText(const Aws::String& textToDecode); - - class XmlDocument; - - /** - * Node in an Xml Document - */ - class AWS_CORE_API XmlNode - { - public: - /** - * copies node and document over. - */ - XmlNode(const XmlNode& other); - /** - * copies node and document over. - */ - XmlNode& operator=(const XmlNode& other); - /** - * Get the name of the node. - */ - const Aws::String GetName() const; - /** - * Set the name of the node. - */ - void SetName(const Aws::String& name); - /** - * Get Value of an attribute specified by name. - */ - const Aws::String GetAttributeValue(const Aws::String& name) const; - /** - * Set an attribute at name to value - */ - void SetAttributeValue(const Aws::String& name, const Aws::String& value); - /** - * Get the inner text of the node (potentially includes other nodes) - */ - Aws::String GetText() const; - /** - * Set the inner text of the node - */ - void SetText(const Aws::String& textValue); - /** - * returns true if this node has another sibling. - */ - bool HasNextNode() const; - /** - * returns the next sibling. - */ - XmlNode NextNode() const; - /** - * returns the next sibling that matches node name. - */ - XmlNode NextNode(const char* name) const; - /** - * returns the next sibling that matches node name. - */ - XmlNode NextNode(const Aws::String& name) const; - /** - * return the first child node of this node. - */ - XmlNode FirstChild() const; - /** - * returns the first child node of this node that has name. - */ - XmlNode FirstChild(const char* name) const; - /** - * returns the first child node of this node that has name. - */ - XmlNode FirstChild(const Aws::String& name) const; - /** - * returns true if this node has child nodes. - */ - bool HasChildren() const; - /** - * returns the parent of this node. - */ - XmlNode Parent() const; - /** - * Creates a new child element to this with name - */ - XmlNode CreateChildElement(const Aws::String& name); - /** - * Creates a new child element to this with name - */ - XmlNode CreateSiblingElement(const Aws::String& name); - /** - * If current node is valid. - */ - bool IsNull(); - - private: - XmlNode(Aws::External::tinyxml2::XMLNode* node, const XmlDocument& document) : - m_node(node), m_doc(&document) - { - } - - //we do not own these.... I just had to change it from ref because the compiler was - //confused about which assignment operator to call. Do not... I repeat... do not delete - //these pointers in your destructor. - Aws::External::tinyxml2::XMLNode* m_node; - const XmlDocument* m_doc; - - friend class XmlDocument; - }; - - /** - * Container for Xml Document as a whole. All nodes have a reference to their parent document. Any changes + +#pragma once + +#include <aws/core/Core_EXPORTS.h> + +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/memory/stl/AWSString.h> + +namespace Aws +{ + namespace External + { + namespace tinyxml2 + { + class XMLNode; + + class XMLDocument; + } // namespace tinyxml2 + } // namespace External +} // namespace Aws + +namespace Aws +{ + template<typename PAYLOAD_TYPE> + class AmazonWebServiceResult; + namespace Client + { + enum class CoreErrors; + template<typename ERROR_TYPE> + class AWSError; + class AWSXMLClient; + } // namespace Client + namespace Utils + { + namespace Xml + { + /** + * Converts escaped xml text back to the original characters (e.g. < ! > = etc...) + */ + AWS_CORE_API Aws::String DecodeEscapedXmlText(const Aws::String& textToDecode); + + class XmlDocument; + + /** + * Node in an Xml Document + */ + class AWS_CORE_API XmlNode + { + public: + /** + * copies node and document over. + */ + XmlNode(const XmlNode& other); + /** + * copies node and document over. + */ + XmlNode& operator=(const XmlNode& other); + /** + * Get the name of the node. + */ + const Aws::String GetName() const; + /** + * Set the name of the node. + */ + void SetName(const Aws::String& name); + /** + * Get Value of an attribute specified by name. + */ + const Aws::String GetAttributeValue(const Aws::String& name) const; + /** + * Set an attribute at name to value + */ + void SetAttributeValue(const Aws::String& name, const Aws::String& value); + /** + * Get the inner text of the node (potentially includes other nodes) + */ + Aws::String GetText() const; + /** + * Set the inner text of the node + */ + void SetText(const Aws::String& textValue); + /** + * returns true if this node has another sibling. + */ + bool HasNextNode() const; + /** + * returns the next sibling. + */ + XmlNode NextNode() const; + /** + * returns the next sibling that matches node name. + */ + XmlNode NextNode(const char* name) const; + /** + * returns the next sibling that matches node name. + */ + XmlNode NextNode(const Aws::String& name) const; + /** + * return the first child node of this node. + */ + XmlNode FirstChild() const; + /** + * returns the first child node of this node that has name. + */ + XmlNode FirstChild(const char* name) const; + /** + * returns the first child node of this node that has name. + */ + XmlNode FirstChild(const Aws::String& name) const; + /** + * returns true if this node has child nodes. + */ + bool HasChildren() const; + /** + * returns the parent of this node. + */ + XmlNode Parent() const; + /** + * Creates a new child element to this with name + */ + XmlNode CreateChildElement(const Aws::String& name); + /** + * Creates a new child element to this with name + */ + XmlNode CreateSiblingElement(const Aws::String& name); + /** + * If current node is valid. + */ + bool IsNull(); + + private: + XmlNode(Aws::External::tinyxml2::XMLNode* node, const XmlDocument& document) : + m_node(node), m_doc(&document) + { + } + + //we do not own these.... I just had to change it from ref because the compiler was + //confused about which assignment operator to call. Do not... I repeat... do not delete + //these pointers in your destructor. + Aws::External::tinyxml2::XMLNode* m_node; + const XmlDocument* m_doc; + + friend class XmlDocument; + }; + + /** + * Container for Xml Document as a whole. All nodes have a reference to their parent document. Any changes * you make to the nodes will be reflected here. - */ - class AWS_CORE_API XmlDocument - { - public: - /** - * move document memory - */ + */ + class AWS_CORE_API XmlDocument + { + public: + /** + * move document memory + */ XmlDocument(const XmlDocument& other); XmlDocument(XmlDocument&& doc); - + XmlDocument& operator=(const XmlDocument& other); XmlDocument& operator=(XmlDocument&& other); - ~XmlDocument(); - - /** - * Get root element of the document - */ - XmlNode GetRootElement() const; - /** - * Convert entire document to string. Use this if you for example, want to save the document to a file. - */ - Aws::String ConvertToString() const; - /** - * Returns true if the call to CreateFromXml* was successful, otherwise false. - * if this returns false, you can call GetErrorMessage() to see details. - */ - bool WasParseSuccessful() const; - /** + ~XmlDocument(); + + /** + * Get root element of the document + */ + XmlNode GetRootElement() const; + /** + * Convert entire document to string. Use this if you for example, want to save the document to a file. + */ + Aws::String ConvertToString() const; + /** + * Returns true if the call to CreateFromXml* was successful, otherwise false. + * if this returns false, you can call GetErrorMessage() to see details. + */ + bool WasParseSuccessful() const; + /** * Returns the error message if the call to CreateFromXml* failed. - */ - Aws::String GetErrorMessage() const; - /** - * Parses the stream into an XMLDocument - */ - static XmlDocument CreateFromXmlStream(Aws::IOStream&); - /** - * Parses the string into an XMLDocument - */ - static XmlDocument CreateFromXmlString(const Aws::String&); - /** - * Creates an empty document with root node name - */ - static XmlDocument CreateWithRootNode(const Aws::String&); - - private: - XmlDocument(); + */ + Aws::String GetErrorMessage() const; + /** + * Parses the stream into an XMLDocument + */ + static XmlDocument CreateFromXmlStream(Aws::IOStream&); + /** + * Parses the string into an XMLDocument + */ + static XmlDocument CreateFromXmlString(const Aws::String&); + /** + * Creates an empty document with root node name + */ + static XmlDocument CreateWithRootNode(const Aws::String&); + + private: + XmlDocument(); void InitDoc(); - - Aws::External::tinyxml2::XMLDocument* m_doc; - - friend class XmlNode; - - //allow outcome call the default constructor to handle it's error case. - friend class Aws::Utils::Outcome<Aws::AmazonWebServiceResult<Aws::Utils::Xml::XmlDocument>, Aws::Client::AWSError<Aws::Client::CoreErrors>>; - friend class Aws::AmazonWebServiceResult<Aws::Utils::Xml::XmlDocument>; + + Aws::External::tinyxml2::XMLDocument* m_doc; + + friend class XmlNode; + + //allow outcome call the default constructor to handle it's error case. + friend class Aws::Utils::Outcome<Aws::AmazonWebServiceResult<Aws::Utils::Xml::XmlDocument>, Aws::Client::AWSError<Aws::Client::CoreErrors>>; + friend class Aws::AmazonWebServiceResult<Aws::Utils::Xml::XmlDocument>; template<typename T> friend class Client::AWSError; - friend class Client::AWSXMLClient; - }; - - } // namespace Xml - } // namespace Utils -} // namespace Aws - + friend class Client::AWSXMLClient; + }; + + } // namespace Xml + } // namespace Utils +} // namespace Aws + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp index 0c401b01b2..dc0f38b4dc 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonSerializableWebServiceRequest.cpp @@ -2,23 +2,23 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/AmazonSerializableWebServiceRequest.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - -using namespace Aws; - -std::shared_ptr<Aws::IOStream> AmazonSerializableWebServiceRequest::GetBody() const -{ - Aws::String&& payload = SerializePayload(); - std::shared_ptr<Aws::IOStream> payloadBody; - - if (!payload.empty()) - { - payloadBody = Aws::MakeShared<Aws::StringStream>("AmazonSerializableWebServiceRequest"); - *payloadBody << payload; - } - - return payloadBody; -} - + +#include <aws/core/AmazonSerializableWebServiceRequest.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +using namespace Aws; + +std::shared_ptr<Aws::IOStream> AmazonSerializableWebServiceRequest::GetBody() const +{ + Aws::String&& payload = SerializePayload(); + std::shared_ptr<Aws::IOStream> payloadBody; + + if (!payload.empty()) + { + payloadBody = Aws::MakeShared<Aws::StringStream>("AmazonSerializableWebServiceRequest"); + *payloadBody << payload; + } + + return payloadBody; +} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonStreamingWebServiceRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonStreamingWebServiceRequest.cpp index 92e61c7ad4..fae0ea1c11 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonStreamingWebServiceRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonStreamingWebServiceRequest.cpp @@ -2,11 +2,11 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/AmazonStreamingWebServiceRequest.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - -using namespace Aws; - -AmazonStreamingWebServiceRequest::~AmazonStreamingWebServiceRequest() {} - + +#include <aws/core/AmazonStreamingWebServiceRequest.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +using namespace Aws; + +AmazonStreamingWebServiceRequest::~AmazonStreamingWebServiceRequest() {} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp index a6b0406683..a0007c6d23 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/AmazonWebServiceRequest.cpp @@ -2,19 +2,19 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/AmazonWebServiceRequest.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - -using namespace Aws; - -AmazonWebServiceRequest::AmazonWebServiceRequest() : - m_responseStreamFactory(Aws::Utils::Stream::DefaultResponseStreamFactoryMethod), - m_onDataReceived(nullptr), + +#include <aws/core/AmazonWebServiceRequest.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +using namespace Aws; + +AmazonWebServiceRequest::AmazonWebServiceRequest() : + m_responseStreamFactory(Aws::Utils::Stream::DefaultResponseStreamFactoryMethod), + m_onDataReceived(nullptr), m_onDataSent(nullptr), m_continueRequest(nullptr), m_onRequestSigned(nullptr), m_requestRetryHandler(nullptr) -{ -} - +{ +} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp index 1eaa477fca..16099d7123 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Aws.cpp @@ -2,133 +2,133 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/Version.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/Aws.h> +#include <aws/core/Version.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/Aws.h> #include <aws/core/client/CoreErrors.h> -#include <aws/core/utils/logging/AWSLogging.h> -#include <aws/core/utils/logging/DefaultLogSystem.h> -#include <aws/core/Globals.h> -#include <aws/core/external/cjson/cJSON.h> -#include <aws/core/monitoring/MonitoringManager.h> -#include <aws/core/net/Net.h> +#include <aws/core/utils/logging/AWSLogging.h> +#include <aws/core/utils/logging/DefaultLogSystem.h> +#include <aws/core/Globals.h> +#include <aws/core/external/cjson/cJSON.h> +#include <aws/core/monitoring/MonitoringManager.h> +#include <aws/core/net/Net.h> #include <aws/core/config/AWSProfileConfigLoader.h> #include <aws/core/internal/AWSHttpResourceClient.h> - -namespace Aws -{ - static const char* ALLOCATION_TAG = "Aws_Init_Cleanup"; - - void InitAPI(const SDKOptions &options) - { -#ifdef USE_AWS_MEMORY_MANAGEMENT - if(options.memoryManagementOptions.memoryManager) - { - Aws::Utils::Memory::InitializeAWSMemorySystem(*options.memoryManagementOptions.memoryManager); - } -#endif // USE_AWS_MEMORY_MANAGEMENT + +namespace Aws +{ + static const char* ALLOCATION_TAG = "Aws_Init_Cleanup"; + + void InitAPI(const SDKOptions &options) + { +#ifdef USE_AWS_MEMORY_MANAGEMENT + if(options.memoryManagementOptions.memoryManager) + { + Aws::Utils::Memory::InitializeAWSMemorySystem(*options.memoryManagementOptions.memoryManager); + } +#endif // USE_AWS_MEMORY_MANAGEMENT Aws::Client::CoreErrorsMapper::InitCoreErrorsMapper(); - if(options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) - { - if(options.loggingOptions.logger_create_fn) - { - Aws::Utils::Logging::InitializeAWSLogging(options.loggingOptions.logger_create_fn()); - } - else - { - Aws::Utils::Logging::InitializeAWSLogging( - Aws::MakeShared<Aws::Utils::Logging::DefaultLogSystem>(ALLOCATION_TAG, options.loggingOptions.logLevel, options.loggingOptions.defaultLogPrefix)); - } - // For users to better debugging in case multiple versions of SDK installed - AWS_LOGSTREAM_INFO(ALLOCATION_TAG, "Initiate AWS SDK for C++ with Version:" << Aws::String(Aws::Version::GetVersionString())); - } - + if(options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) + { + if(options.loggingOptions.logger_create_fn) + { + Aws::Utils::Logging::InitializeAWSLogging(options.loggingOptions.logger_create_fn()); + } + else + { + Aws::Utils::Logging::InitializeAWSLogging( + Aws::MakeShared<Aws::Utils::Logging::DefaultLogSystem>(ALLOCATION_TAG, options.loggingOptions.logLevel, options.loggingOptions.defaultLogPrefix)); + } + // For users to better debugging in case multiple versions of SDK installed + AWS_LOGSTREAM_INFO(ALLOCATION_TAG, "Initiate AWS SDK for C++ with Version:" << Aws::String(Aws::Version::GetVersionString())); + } + Aws::Config::InitConfigAndCredentialsCacheManager(); if (options.cryptoOptions.aes_CBCFactory_create_fn) - { - Aws::Utils::Crypto::SetAES_CBCFactory(options.cryptoOptions.aes_CBCFactory_create_fn()); - } - - if(options.cryptoOptions.aes_CTRFactory_create_fn) - { - Aws::Utils::Crypto::SetAES_CTRFactory(options.cryptoOptions.aes_CTRFactory_create_fn()); - } - - if(options.cryptoOptions.aes_GCMFactory_create_fn) - { - Aws::Utils::Crypto::SetAES_GCMFactory(options.cryptoOptions.aes_GCMFactory_create_fn()); - } - - if(options.cryptoOptions.md5Factory_create_fn) - { - Aws::Utils::Crypto::SetMD5Factory(options.cryptoOptions.md5Factory_create_fn()); - } - - if(options.cryptoOptions.sha256Factory_create_fn) - { - Aws::Utils::Crypto::SetSha256Factory(options.cryptoOptions.sha256Factory_create_fn()); - } - - if(options.cryptoOptions.sha256HMACFactory_create_fn) - { - Aws::Utils::Crypto::SetSha256HMACFactory(options.cryptoOptions.sha256HMACFactory_create_fn()); - } - - if (options.cryptoOptions.aes_KeyWrapFactory_create_fn) - { - Aws::Utils::Crypto::SetAES_KeyWrapFactory(options.cryptoOptions.aes_KeyWrapFactory_create_fn()); - } - - if(options.cryptoOptions.secureRandomFactory_create_fn) - { - Aws::Utils::Crypto::SetSecureRandomFactory(options.cryptoOptions.secureRandomFactory_create_fn()); - } - - Aws::Utils::Crypto::SetInitCleanupOpenSSLFlag(options.cryptoOptions.initAndCleanupOpenSSL); - Aws::Utils::Crypto::InitCrypto(); - - if(options.httpOptions.httpClientFactory_create_fn) - { - Aws::Http::SetHttpClientFactory(options.httpOptions.httpClientFactory_create_fn()); - } - - Aws::Http::SetInitCleanupCurlFlag(options.httpOptions.initAndCleanupCurl); - Aws::Http::SetInstallSigPipeHandlerFlag(options.httpOptions.installSigPipeHandler); - Aws::Http::InitHttp(); - Aws::InitializeEnumOverflowContainer(); - cJSON_Hooks hooks; - hooks.malloc_fn = [](size_t sz) { return Aws::Malloc("cJSON_Tag", sz); }; - hooks.free_fn = Aws::Free; - cJSON_InitHooks(&hooks); - Aws::Net::InitNetwork(); + { + Aws::Utils::Crypto::SetAES_CBCFactory(options.cryptoOptions.aes_CBCFactory_create_fn()); + } + + if(options.cryptoOptions.aes_CTRFactory_create_fn) + { + Aws::Utils::Crypto::SetAES_CTRFactory(options.cryptoOptions.aes_CTRFactory_create_fn()); + } + + if(options.cryptoOptions.aes_GCMFactory_create_fn) + { + Aws::Utils::Crypto::SetAES_GCMFactory(options.cryptoOptions.aes_GCMFactory_create_fn()); + } + + if(options.cryptoOptions.md5Factory_create_fn) + { + Aws::Utils::Crypto::SetMD5Factory(options.cryptoOptions.md5Factory_create_fn()); + } + + if(options.cryptoOptions.sha256Factory_create_fn) + { + Aws::Utils::Crypto::SetSha256Factory(options.cryptoOptions.sha256Factory_create_fn()); + } + + if(options.cryptoOptions.sha256HMACFactory_create_fn) + { + Aws::Utils::Crypto::SetSha256HMACFactory(options.cryptoOptions.sha256HMACFactory_create_fn()); + } + + if (options.cryptoOptions.aes_KeyWrapFactory_create_fn) + { + Aws::Utils::Crypto::SetAES_KeyWrapFactory(options.cryptoOptions.aes_KeyWrapFactory_create_fn()); + } + + if(options.cryptoOptions.secureRandomFactory_create_fn) + { + Aws::Utils::Crypto::SetSecureRandomFactory(options.cryptoOptions.secureRandomFactory_create_fn()); + } + + Aws::Utils::Crypto::SetInitCleanupOpenSSLFlag(options.cryptoOptions.initAndCleanupOpenSSL); + Aws::Utils::Crypto::InitCrypto(); + + if(options.httpOptions.httpClientFactory_create_fn) + { + Aws::Http::SetHttpClientFactory(options.httpOptions.httpClientFactory_create_fn()); + } + + Aws::Http::SetInitCleanupCurlFlag(options.httpOptions.initAndCleanupCurl); + Aws::Http::SetInstallSigPipeHandlerFlag(options.httpOptions.installSigPipeHandler); + Aws::Http::InitHttp(); + Aws::InitializeEnumOverflowContainer(); + cJSON_Hooks hooks; + hooks.malloc_fn = [](size_t sz) { return Aws::Malloc("cJSON_Tag", sz); }; + hooks.free_fn = Aws::Free; + cJSON_InitHooks(&hooks); + Aws::Net::InitNetwork(); Aws::Internal::InitEC2MetadataClient(); - Aws::Monitoring::InitMonitoring(options.monitoringOptions.customizedMonitoringFactory_create_fn); - } - - void ShutdownAPI(const SDKOptions& options) - { - Aws::Monitoring::CleanupMonitoring(); + Aws::Monitoring::InitMonitoring(options.monitoringOptions.customizedMonitoringFactory_create_fn); + } + + void ShutdownAPI(const SDKOptions& options) + { + Aws::Monitoring::CleanupMonitoring(); Aws::Internal::CleanupEC2MetadataClient(); - Aws::Net::CleanupNetwork(); - Aws::CleanupEnumOverflowContainer(); - Aws::Http::CleanupHttp(); - Aws::Utils::Crypto::CleanupCrypto(); - + Aws::Net::CleanupNetwork(); + Aws::CleanupEnumOverflowContainer(); + Aws::Http::CleanupHttp(); + Aws::Utils::Crypto::CleanupCrypto(); + Aws::Config::CleanupConfigAndCredentialsCacheManager(); - if(options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) - { - Aws::Utils::Logging::ShutdownAWSLogging(); - } + if(options.loggingOptions.logLevel != Aws::Utils::Logging::LogLevel::Off) + { + Aws::Utils::Logging::ShutdownAWSLogging(); + } Aws::Client::CoreErrorsMapper::CleanupCoreErrorsMapper(); - -#ifdef USE_AWS_MEMORY_MANAGEMENT - if(options.memoryManagementOptions.memoryManager) - { - Aws::Utils::Memory::ShutdownAWSMemorySystem(); - } -#endif // USE_AWS_MEMORY_MANAGEMENT - } -} + +#ifdef USE_AWS_MEMORY_MANAGEMENT + if(options.memoryManagementOptions.memoryManager) + { + Aws::Utils::Memory::ShutdownAWSMemorySystem(); + } +#endif // USE_AWS_MEMORY_MANAGEMENT + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp index 55f2ee9220..6dc9ebd139 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Globals.cpp @@ -2,27 +2,27 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/Globals.h> -#include <aws/core/utils/EnumParseOverflowContainer.h> -#include <aws/core/utils/memory/AWSMemory.h> - -namespace Aws -{ - static const char TAG[] = "GlobalEnumOverflowContainer"; - static Utils::EnumParseOverflowContainer* g_enumOverflow; - - Utils::EnumParseOverflowContainer* GetEnumOverflowContainer() - { - return g_enumOverflow; - } - - void InitializeEnumOverflowContainer() - { - g_enumOverflow = Aws::New<Aws::Utils::EnumParseOverflowContainer>(TAG); - } - - void CleanupEnumOverflowContainer() - { - Aws::Delete(g_enumOverflow); - } -} +#include <aws/core/Globals.h> +#include <aws/core/utils/EnumParseOverflowContainer.h> +#include <aws/core/utils/memory/AWSMemory.h> + +namespace Aws +{ + static const char TAG[] = "GlobalEnumOverflowContainer"; + static Utils::EnumParseOverflowContainer* g_enumOverflow; + + Utils::EnumParseOverflowContainer* GetEnumOverflowContainer() + { + return g_enumOverflow; + } + + void InitializeEnumOverflowContainer() + { + g_enumOverflow = Aws::New<Aws::Utils::EnumParseOverflowContainer>(TAG); + } + + void CleanupEnumOverflowContainer() + { + Aws::Delete(g_enumOverflow); + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp index 35291906b7..b379330738 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/Version.cpp @@ -2,52 +2,52 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/Version.h> -#include <aws/core/VersionConfig.h> - -namespace Aws -{ -namespace Version -{ - const char* GetVersionString() - { - return AWS_SDK_VERSION_STRING; - } - - unsigned GetVersionMajor() - { - return AWS_SDK_VERSION_MAJOR; - } - - unsigned GetVersionMinor() - { - return AWS_SDK_VERSION_MINOR; - } - - unsigned GetVersionPatch() - { - return AWS_SDK_VERSION_PATCH; - } - - - const char* GetCompilerVersionString() - { -#define xstr(s) str(s) -#define str(s) #s -#if defined(_MSC_VER) - return "MSVC/" xstr(_MSC_VER); -#elif defined(__clang__) - return "Clang/" xstr(__clang_major__) "." xstr(__clang_minor__) "." xstr(__clang_patchlevel__); -#elif defined(__GNUC__) - return "GCC/" xstr(__GNUC__) "." xstr(__GNUC_MINOR__) "." xstr(__GNUC_PATCHLEVEL__); -#else - return "UnknownCompiler"; -#endif -#undef str -#undef xstr - } -} //namespace Version -} //namespace Aws - - + +#include <aws/core/Version.h> +#include <aws/core/VersionConfig.h> + +namespace Aws +{ +namespace Version +{ + const char* GetVersionString() + { + return AWS_SDK_VERSION_STRING; + } + + unsigned GetVersionMajor() + { + return AWS_SDK_VERSION_MAJOR; + } + + unsigned GetVersionMinor() + { + return AWS_SDK_VERSION_MINOR; + } + + unsigned GetVersionPatch() + { + return AWS_SDK_VERSION_PATCH; + } + + + const char* GetCompilerVersionString() + { +#define xstr(s) str(s) +#define str(s) #s +#if defined(_MSC_VER) + return "MSVC/" xstr(_MSC_VER); +#elif defined(__clang__) + return "Clang/" xstr(__clang_major__) "." xstr(__clang_minor__) "." xstr(__clang_patchlevel__); +#elif defined(__GNUC__) + return "GCC/" xstr(__GNUC__) "." xstr(__GNUC_MINOR__) "." xstr(__GNUC_PATCHLEVEL__); +#else + return "UnknownCompiler"; +#endif +#undef str +#undef xstr + } +} //namespace Version +} //namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp index de4826fa5b..fa3f5583d5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp @@ -2,536 +2,536 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/auth/AWSAuthSigner.h> - -#include <aws/core/auth/AWSCredentialsProvider.h> -#include <aws/core/client/ClientConfiguration.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/http/HttpResponse.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/crypto/Sha256.h> -#include <aws/core/utils/crypto/Sha256HMAC.h> + +#include <aws/core/auth/AWSAuthSigner.h> + +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/client/ClientConfiguration.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/http/HttpResponse.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/crypto/Sha256.h> +#include <aws/core/utils/crypto/Sha256HMAC.h> #include <aws/core/utils/stream/PreallocatedStreamBuf.h> #include <aws/core/utils/event/EventMessage.h> #include <aws/core/utils/event/EventHeader.h> - -#include <cstdio> -#include <iomanip> -#include <math.h> + +#include <cstdio> +#include <iomanip> +#include <math.h> #include <cstring> - -using namespace Aws; -using namespace Aws::Client; -using namespace Aws::Auth; -using namespace Aws::Http; -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; - -static const char* EQ = "="; -static const char* AWS_HMAC_SHA256 = "AWS4-HMAC-SHA256"; + +using namespace Aws; +using namespace Aws::Client; +using namespace Aws::Auth; +using namespace Aws::Http; +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +static const char* EQ = "="; +static const char* AWS_HMAC_SHA256 = "AWS4-HMAC-SHA256"; static const char* EVENT_STREAM_CONTENT_SHA256 = "STREAMING-AWS4-HMAC-SHA256-EVENTS"; static const char* EVENT_STREAM_PAYLOAD = "AWS4-HMAC-SHA256-PAYLOAD"; -static const char* AWS4_REQUEST = "aws4_request"; -static const char* SIGNED_HEADERS = "SignedHeaders"; -static const char* CREDENTIAL = "Credential"; -static const char* NEWLINE = "\n"; -static const char* X_AMZ_SIGNED_HEADERS = "X-Amz-SignedHeaders"; -static const char* X_AMZ_ALGORITHM = "X-Amz-Algorithm"; -static const char* X_AMZ_CREDENTIAL = "X-Amz-Credential"; -static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD"; -static const char* X_AMZ_SIGNATURE = "X-Amz-Signature"; +static const char* AWS4_REQUEST = "aws4_request"; +static const char* SIGNED_HEADERS = "SignedHeaders"; +static const char* CREDENTIAL = "Credential"; +static const char* NEWLINE = "\n"; +static const char* X_AMZ_SIGNED_HEADERS = "X-Amz-SignedHeaders"; +static const char* X_AMZ_ALGORITHM = "X-Amz-Algorithm"; +static const char* X_AMZ_CREDENTIAL = "X-Amz-Credential"; +static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD"; +static const char* X_AMZ_SIGNATURE = "X-Amz-Signature"; static const char* X_AMZN_TRACE_ID = "x-amzn-trace-id"; static const char* X_AMZ_CONTENT_SHA256 = "x-amz-content-sha256"; static const char* USER_AGENT = "user-agent"; -static const char* SIGNING_KEY = "AWS4"; -static const char* SIMPLE_DATE_FORMAT_STR = "%Y%m%d"; -static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; - +static const char* SIGNING_KEY = "AWS4"; +static const char* SIMPLE_DATE_FORMAT_STR = "%Y%m%d"; +static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; + static const char v4LogTag[] = "AWSAuthV4Signer"; static const char v4StreamingLogTag[] = "AWSAuthEventStreamV4Signer"; - -namespace Aws -{ - namespace Auth - { + +namespace Aws +{ + namespace Auth + { const char SIGNATURE[] = "Signature"; - const char SIGV4_SIGNER[] = "SignatureV4"; + const char SIGV4_SIGNER[] = "SignatureV4"; const char EVENTSTREAM_SIGV4_SIGNER[] = "EventStreamSignatureV4"; const char EVENTSTREAM_SIGNATURE_HEADER[] = ":chunk-signature"; const char EVENTSTREAM_DATE_HEADER[] = ":date"; - const char NULL_SIGNER[] = "NullSigner"; - } -} - -static Aws::String CanonicalizeRequestSigningString(HttpRequest& request, bool urlEscapePath) -{ - request.CanonicalizeRequest(); - Aws::StringStream signingStringStream; - signingStringStream << HttpMethodMapper::GetNameForHttpMethod(request.GetMethod()); - - URI uriCpy = request.GetUri(); - // Many AWS services do not decode the URL before calculating SignatureV4 on their end. - // This results in the signature getting calculated with a double encoded URL. - // That means we have to double encode it here for the signature to match on the service side. - if(urlEscapePath) - { - // RFC3986 is how we encode the URL before sending it on the wire. - auto rfc3986EncodedPath = URI::URLEncodePathRFC3986(uriCpy.GetPath()); - uriCpy.SetPath(rfc3986EncodedPath); - // However, SignatureV4 uses this URL encoding scheme - signingStringStream << NEWLINE << uriCpy.GetURLEncodedPath() << NEWLINE; - } - else - { - // For the services that DO decode the URL first; we don't need to double encode it. - uriCpy.SetPath(uriCpy.GetURLEncodedPath()); - signingStringStream << NEWLINE << uriCpy.GetPath() << NEWLINE; - } - + const char NULL_SIGNER[] = "NullSigner"; + } +} + +static Aws::String CanonicalizeRequestSigningString(HttpRequest& request, bool urlEscapePath) +{ + request.CanonicalizeRequest(); + Aws::StringStream signingStringStream; + signingStringStream << HttpMethodMapper::GetNameForHttpMethod(request.GetMethod()); + + URI uriCpy = request.GetUri(); + // Many AWS services do not decode the URL before calculating SignatureV4 on their end. + // This results in the signature getting calculated with a double encoded URL. + // That means we have to double encode it here for the signature to match on the service side. + if(urlEscapePath) + { + // RFC3986 is how we encode the URL before sending it on the wire. + auto rfc3986EncodedPath = URI::URLEncodePathRFC3986(uriCpy.GetPath()); + uriCpy.SetPath(rfc3986EncodedPath); + // However, SignatureV4 uses this URL encoding scheme + signingStringStream << NEWLINE << uriCpy.GetURLEncodedPath() << NEWLINE; + } + else + { + // For the services that DO decode the URL first; we don't need to double encode it. + uriCpy.SetPath(uriCpy.GetURLEncodedPath()); + signingStringStream << NEWLINE << uriCpy.GetPath() << NEWLINE; + } + if (request.GetQueryString().find('=') != std::string::npos) - { - signingStringStream << request.GetQueryString().substr(1) << NEWLINE; - } - else if (request.GetQueryString().size() > 1) - { - signingStringStream << request.GetQueryString().substr(1) << "=" << NEWLINE; - } - else - { - signingStringStream << NEWLINE; - } - - return signingStringStream.str(); -} - -static Http::HeaderValueCollection CanonicalizeHeaders(Http::HeaderValueCollection&& headers) -{ - Http::HeaderValueCollection canonicalHeaders; - for (const auto& header : headers) - { - auto trimmedHeaderName = StringUtils::Trim(header.first.c_str()); - auto trimmedHeaderValue = StringUtils::Trim(header.second.c_str()); - - //multiline gets converted to line1,line2,etc... - auto headerMultiLine = StringUtils::SplitOnLine(trimmedHeaderValue); - Aws::String headerValue = headerMultiLine.size() == 0 ? "" : headerMultiLine[0]; - - if (headerMultiLine.size() > 1) - { - for(size_t i = 1; i < headerMultiLine.size(); ++i) - { - headerValue += ","; - headerValue += StringUtils::Trim(headerMultiLine[i].c_str()); - } - } - - //duplicate spaces need to be converted to one. - Aws::String::iterator new_end = - std::unique(headerValue.begin(), headerValue.end(), - [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); } - ); - headerValue.erase(new_end, headerValue.end()); - + { + signingStringStream << request.GetQueryString().substr(1) << NEWLINE; + } + else if (request.GetQueryString().size() > 1) + { + signingStringStream << request.GetQueryString().substr(1) << "=" << NEWLINE; + } + else + { + signingStringStream << NEWLINE; + } + + return signingStringStream.str(); +} + +static Http::HeaderValueCollection CanonicalizeHeaders(Http::HeaderValueCollection&& headers) +{ + Http::HeaderValueCollection canonicalHeaders; + for (const auto& header : headers) + { + auto trimmedHeaderName = StringUtils::Trim(header.first.c_str()); + auto trimmedHeaderValue = StringUtils::Trim(header.second.c_str()); + + //multiline gets converted to line1,line2,etc... + auto headerMultiLine = StringUtils::SplitOnLine(trimmedHeaderValue); + Aws::String headerValue = headerMultiLine.size() == 0 ? "" : headerMultiLine[0]; + + if (headerMultiLine.size() > 1) + { + for(size_t i = 1; i < headerMultiLine.size(); ++i) + { + headerValue += ","; + headerValue += StringUtils::Trim(headerMultiLine[i].c_str()); + } + } + + //duplicate spaces need to be converted to one. + Aws::String::iterator new_end = + std::unique(headerValue.begin(), headerValue.end(), + [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); } + ); + headerValue.erase(new_end, headerValue.end()); + canonicalHeaders[trimmedHeaderName] = headerValue; - } - - return canonicalHeaders; -} - -AWSAuthV4Signer::AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, - const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy, bool urlEscapePath) : - m_includeSha256HashHeader(true), - m_credentialsProvider(credentialsProvider), - m_serviceName(serviceName), - m_region(region), - m_hash(Aws::MakeUnique<Aws::Utils::Crypto::Sha256>(v4LogTag)), - m_HMAC(Aws::MakeUnique<Aws::Utils::Crypto::Sha256HMAC>(v4LogTag)), + } + + return canonicalHeaders; +} + +AWSAuthV4Signer::AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, + const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy, bool urlEscapePath) : + m_includeSha256HashHeader(true), + m_credentialsProvider(credentialsProvider), + m_serviceName(serviceName), + m_region(region), + m_hash(Aws::MakeUnique<Aws::Utils::Crypto::Sha256>(v4LogTag)), + m_HMAC(Aws::MakeUnique<Aws::Utils::Crypto::Sha256HMAC>(v4LogTag)), m_unsignedHeaders({USER_AGENT, X_AMZN_TRACE_ID}), - m_payloadSigningPolicy(signingPolicy), - m_urlEscapePath(urlEscapePath) -{ - //go ahead and warm up the signing cache. + m_payloadSigningPolicy(signingPolicy), + m_urlEscapePath(urlEscapePath) +{ + //go ahead and warm up the signing cache. ComputeHash(credentialsProvider->GetAWSCredentials().GetAWSSecretKey(), DateTime::CalculateGmtTimestampAsString(SIMPLE_DATE_FORMAT_STR), region, m_serviceName); -} - -AWSAuthV4Signer::~AWSAuthV4Signer() -{ +} + +AWSAuthV4Signer::~AWSAuthV4Signer() +{ // empty destructor in .cpp file to keep from needing the implementation of (AWSCredentialsProvider, Sha256, Sha256HMAC) in the header file -} - - -bool AWSAuthV4Signer::ShouldSignHeader(const Aws::String& header) const -{ - return m_unsignedHeaders.find(Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend(); -} - +} + + +bool AWSAuthV4Signer::ShouldSignHeader(const Aws::String& header) const +{ + return m_unsignedHeaders.find(Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend(); +} + bool AWSAuthV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const -{ - AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); - - //don't sign anonymous requests - if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) - { - return true; - } - - if (!credentials.GetSessionToken().empty()) - { - request.SetAwsSessionToken(credentials.GetSessionToken()); - } - - Aws::String payloadHash(UNSIGNED_PAYLOAD); - switch(m_payloadSigningPolicy) - { - case PayloadSigningPolicy::Always: - signBody = true; - break; - case PayloadSigningPolicy::Never: - signBody = false; - break; - case PayloadSigningPolicy::RequestDependent: - // respect the request setting - default: - break; - } - - if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS) - { +{ + AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); + + //don't sign anonymous requests + if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) + { + return true; + } + + if (!credentials.GetSessionToken().empty()) + { + request.SetAwsSessionToken(credentials.GetSessionToken()); + } + + Aws::String payloadHash(UNSIGNED_PAYLOAD); + switch(m_payloadSigningPolicy) + { + case PayloadSigningPolicy::Always: + signBody = true; + break; + case PayloadSigningPolicy::Never: + signBody = false; + break; + case PayloadSigningPolicy::RequestDependent: + // respect the request setting + default: + break; + } + + if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS) + { payloadHash = ComputePayloadHash(request); - if (payloadHash.empty()) - { - return false; - } - } - else - { - AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody - << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme())); - } - - if(m_includeSha256HashHeader) - { + if (payloadHash.empty()) + { + return false; + } + } + else + { + AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody + << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme())); + } + + if(m_includeSha256HashHeader) + { request.SetHeaderValue(X_AMZ_CONTENT_SHA256, payloadHash); - } - - //calculate date header to use in internal signature (this also goes into date header). - DateTime now = GetSigningTimestamp(); + } + + //calculate date header to use in internal signature (this also goes into date header). + DateTime now = GetSigningTimestamp(); Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); - request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); - - Aws::StringStream headersStream; - Aws::StringStream signedHeadersStream; - - for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) - { - if(ShouldSignHeader(header.first)) - { - headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; - signedHeadersStream << header.first.c_str() << ";"; - } - } - - Aws::String canonicalHeadersString = headersStream.str(); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); - - //calculate signed headers parameter - Aws::String signedHeadersValue = signedHeadersStream.str(); - //remove that last semi-colon - if (!signedHeadersValue.empty()) - { + request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue); + + Aws::StringStream headersStream; + Aws::StringStream signedHeadersStream; + + for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) + { + if(ShouldSignHeader(header.first)) + { + headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; + signedHeadersStream << header.first.c_str() << ";"; + } + } + + Aws::String canonicalHeadersString = headersStream.str(); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); + + //calculate signed headers parameter + Aws::String signedHeadersValue = signedHeadersStream.str(); + //remove that last semi-colon + if (!signedHeadersValue.empty()) + { signedHeadersValue.pop_back(); - } - - AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue); - - //generate generalized canonicalized request string. - Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); - - //append v4 stuff to the canonical request string. - canonicalRequestString.append(canonicalHeadersString); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(signedHeadersValue); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(payloadHash); - - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); - - //now compute sha256 on that request string - auto hashResult = m_hash->Calculate(canonicalRequestString); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); - return false; - } - - auto sha256Digest = hashResult.GetResult(); + } + + AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue); + + //generate generalized canonicalized request string. + Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); + + //append v4 stuff to the canonical request string. + canonicalRequestString.append(canonicalHeadersString); + canonicalRequestString.append(NEWLINE); + canonicalRequestString.append(signedHeadersValue); + canonicalRequestString.append(NEWLINE); + canonicalRequestString.append(payloadHash); + + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); + + //now compute sha256 on that request string + auto hashResult = m_hash->Calculate(canonicalRequestString); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); + return false; + } + + auto sha256Digest = hashResult.GetResult(); Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); - Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); - + Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); + Aws::String signingRegion = region ? region : m_region; Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); - - Aws::StringStream ss; - ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate + + Aws::StringStream ss; + ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST << ", " << SIGNED_HEADERS << EQ - << signedHeadersValue << ", " << SIGNATURE << EQ << finalSignature; - - auto awsAuthString = ss.str(); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString); - request.SetAwsAuthorization(awsAuthString); - request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); + << signedHeadersValue << ", " << SIGNATURE << EQ << finalSignature; + + auto awsAuthString = ss.str(); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString); + request.SetAwsAuthorization(awsAuthString); + request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); request.SetSigningRegion(signingRegion); - return true; -} - -bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, long long expirationTimeInSeconds) const -{ - return PresignRequest(request, m_region.c_str(), expirationTimeInSeconds); -} - -bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds) const -{ - return PresignRequest(request, region, m_serviceName.c_str(), expirationInSeconds); -} - -bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationTimeInSeconds) const -{ - AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); - - //don't sign anonymous requests - if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) - { - return true; - } - - Aws::StringStream intConversionStream; - intConversionStream << expirationTimeInSeconds; - request.AddQueryStringParameter(Http::X_AMZ_EXPIRES_HEADER, intConversionStream.str()); - - if (!credentials.GetSessionToken().empty()) - { - request.AddQueryStringParameter(Http::AWS_SECURITY_TOKEN, credentials.GetSessionToken()); - } - - //calculate date header to use in internal signature (this also goes into date header). - DateTime now = GetSigningTimestamp(); + return true; +} + +bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, long long expirationTimeInSeconds) const +{ + return PresignRequest(request, m_region.c_str(), expirationTimeInSeconds); +} + +bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds) const +{ + return PresignRequest(request, region, m_serviceName.c_str(), expirationInSeconds); +} + +bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationTimeInSeconds) const +{ + AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials(); + + //don't sign anonymous requests + if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty()) + { + return true; + } + + Aws::StringStream intConversionStream; + intConversionStream << expirationTimeInSeconds; + request.AddQueryStringParameter(Http::X_AMZ_EXPIRES_HEADER, intConversionStream.str()); + + if (!credentials.GetSessionToken().empty()) + { + request.AddQueryStringParameter(Http::AWS_SECURITY_TOKEN, credentials.GetSessionToken()); + } + + //calculate date header to use in internal signature (this also goes into date header). + DateTime now = GetSigningTimestamp(); Aws::String dateQueryValue = now.ToGmtString(DateFormat::ISO_8601_BASIC); - request.AddQueryStringParameter(Http::AWS_DATE_HEADER, dateQueryValue); - - Aws::StringStream headersStream; - Aws::StringStream signedHeadersStream; - for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) - { - if(ShouldSignHeader(header.first)) - { - headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; - signedHeadersStream << header.first.c_str() << ";"; - } - } - - Aws::String canonicalHeadersString = headersStream.str(); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); - - //calculate signed headers parameter - Aws::String signedHeadersValue(signedHeadersStream.str()); - //remove that last semi-colon - if (!signedHeadersValue.empty()) - { - signedHeadersValue.pop_back(); - } - - request.AddQueryStringParameter(X_AMZ_SIGNED_HEADERS, signedHeadersValue); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value: " << signedHeadersValue); - - Aws::StringStream ss; + request.AddQueryStringParameter(Http::AWS_DATE_HEADER, dateQueryValue); + + Aws::StringStream headersStream; + Aws::StringStream signedHeadersStream; + for (const auto& header : CanonicalizeHeaders(request.GetHeaders())) + { + if(ShouldSignHeader(header.first)) + { + headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE; + signedHeadersStream << header.first.c_str() << ";"; + } + } + + Aws::String canonicalHeadersString = headersStream.str(); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString); + + //calculate signed headers parameter + Aws::String signedHeadersValue(signedHeadersStream.str()); + //remove that last semi-colon + if (!signedHeadersValue.empty()) + { + signedHeadersValue.pop_back(); + } + + request.AddQueryStringParameter(X_AMZ_SIGNED_HEADERS, signedHeadersValue); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value: " << signedHeadersValue); + + Aws::StringStream ss; Aws::String signingRegion = region ? region : m_region; Aws::String signingServiceName = serviceName ? serviceName : m_serviceName; - Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); - ss << credentials.GetAWSAccessKeyId() << "/" << simpleDate + Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR); + ss << credentials.GetAWSAccessKeyId() << "/" << simpleDate << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST; - - request.AddQueryStringParameter(X_AMZ_ALGORITHM, AWS_HMAC_SHA256); - request.AddQueryStringParameter(X_AMZ_CREDENTIAL, ss.str()); - ss.str(""); - - request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); + + request.AddQueryStringParameter(X_AMZ_ALGORITHM, AWS_HMAC_SHA256); + request.AddQueryStringParameter(X_AMZ_CREDENTIAL, ss.str()); + ss.str(""); + + request.SetSigningAccessKey(credentials.GetAWSAccessKeyId()); request.SetSigningRegion(signingRegion); - - //generate generalized canonicalized request string. - Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); - - //append v4 stuff to the canonical request string. - canonicalRequestString.append(canonicalHeadersString); - canonicalRequestString.append(NEWLINE); - canonicalRequestString.append(signedHeadersValue); - canonicalRequestString.append(NEWLINE); + + //generate generalized canonicalized request string. + Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath); + + //append v4 stuff to the canonical request string. + canonicalRequestString.append(canonicalHeadersString); + canonicalRequestString.append(NEWLINE); + canonicalRequestString.append(signedHeadersValue); + canonicalRequestString.append(NEWLINE); if (ServiceRequireUnsignedPayload(signingServiceName)) { - canonicalRequestString.append(UNSIGNED_PAYLOAD); + canonicalRequestString.append(UNSIGNED_PAYLOAD); } else { - canonicalRequestString.append(EMPTY_STRING_SHA256); - } - AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); - - //now compute sha256 on that request string - auto hashResult = m_hash->Calculate(canonicalRequestString); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); - return false; - } - - auto sha256Digest = hashResult.GetResult(); + canonicalRequestString.append(EMPTY_STRING_SHA256); + } + AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString); + + //now compute sha256 on that request string + auto hashResult = m_hash->Calculate(canonicalRequestString); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\""); + return false; + } + + auto sha256Digest = hashResult.GetResult(); auto canonicalRequestHash = HashingUtils::HexEncode(sha256Digest); - + auto stringToSign = GenerateStringToSign(dateQueryValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName); auto finalSigningHash = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName); - if (finalSigningHash.empty()) - { - return false; - } - + if (finalSigningHash.empty()) + { + return false; + } + //add that the signature to the query string - request.AddQueryStringParameter(X_AMZ_SIGNATURE, finalSigningHash); - - return true; -} - -bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceName) const -{ - // S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here: - // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html - // this is true for PUT, POST, GET, DELETE and HEAD operations. - // However, other services (for example RDS) implement the specification as outlined here: - // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - // which states that body-less requests should use the empty-string SHA256 hash. - return "s3" == serviceName; -} - -Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const -{ - auto key = ComputeHash(credentials.GetAWSSecretKey(), simpleDate, region, serviceName); - return GenerateSignature(stringToSign, key); -} - -Aws::String AWSAuthV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const -{ - AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign); - - Aws::StringStream ss; - - auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The final string is: \"" << stringToSign << "\""); + request.AddQueryStringParameter(X_AMZ_SIGNATURE, finalSigningHash); + + return true; +} + +bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceName) const +{ + // S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here: + // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html + // this is true for PUT, POST, GET, DELETE and HEAD operations. + // However, other services (for example RDS) implement the specification as outlined here: + // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + // which states that body-less requests should use the empty-string SHA256 hash. + return "s3" == serviceName; +} + +Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const +{ + auto key = ComputeHash(credentials.GetAWSSecretKey(), simpleDate, region, serviceName); + return GenerateSignature(stringToSign, key); +} + +Aws::String AWSAuthV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const +{ + AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign); + + Aws::StringStream ss; + + auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The final string is: \"" << stringToSign << "\""); return {}; - } - - //now we finally sign our request string with our hex encoded derived hash. - auto finalSigningDigest = hashResult.GetResult(); - - auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash); - - return finalSigningHash; -} - -Aws::String AWSAuthV4Signer::ComputePayloadHash(Aws::Http::HttpRequest& request) const -{ - if (!request.GetContentBody()) - { - AWS_LOGSTREAM_DEBUG(v4LogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty."); - return EMPTY_STRING_SHA256; - } - - //compute hash on payload if it exists. - auto hashResult = m_hash->Calculate(*request.GetContentBody()); - - if(request.GetContentBody()) - { - request.GetContentBody()->clear(); - request.GetContentBody()->seekg(0); - } - - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hash (sha256) request body"); + } + + //now we finally sign our request string with our hex encoded derived hash. + auto finalSigningDigest = hashResult.GetResult(); + + auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash); + + return finalSigningHash; +} + +Aws::String AWSAuthV4Signer::ComputePayloadHash(Aws::Http::HttpRequest& request) const +{ + if (!request.GetContentBody()) + { + AWS_LOGSTREAM_DEBUG(v4LogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty."); + return EMPTY_STRING_SHA256; + } + + //compute hash on payload if it exists. + auto hashResult = m_hash->Calculate(*request.GetContentBody()); + + if(request.GetContentBody()) + { + request.GetContentBody()->clear(); + request.GetContentBody()->seekg(0); + } + + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hash (sha256) request body"); return {}; - } - - auto sha256Digest = hashResult.GetResult(); - - Aws::String payloadHash(HashingUtils::HexEncode(sha256Digest)); - AWS_LOGSTREAM_DEBUG(v4LogTag, "Calculated sha256 " << payloadHash << " for payload."); - return payloadHash; -} - -Aws::String AWSAuthV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, - const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const -{ - //generate the actual string we will use in signing the final request. - Aws::StringStream ss; - - ss << AWS_HMAC_SHA256 << NEWLINE << dateValue << NEWLINE << simpleDate << "/" << region << "/" - << serviceName << "/" << AWS4_REQUEST << NEWLINE << canonicalRequestHash; - - return ss.str(); -} - -Aws::Utils::ByteBuffer AWSAuthV4Signer::ComputeHash(const Aws::String& secretKey, - const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const -{ - Aws::String signingKey(SIGNING_KEY); - signingKey.append(secretKey); - auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), - ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); - - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\""); - return {}; - } - - auto kDate = hashResult.GetResult(); - hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) region string \"" << region << "\""); - return {}; - } - - auto kRegion = hashResult.GetResult(); - hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\""); - return {}; - } - - auto kService = hashResult.GetResult(); - hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService); - if (!hashResult.IsSuccess()) - { - AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to HMAC (SHA256) request string"); - AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << AWS4_REQUEST << "\""); - return {}; - } - return hashResult.GetResult(); -} + } + + auto sha256Digest = hashResult.GetResult(); + + Aws::String payloadHash(HashingUtils::HexEncode(sha256Digest)); + AWS_LOGSTREAM_DEBUG(v4LogTag, "Calculated sha256 " << payloadHash << " for payload."); + return payloadHash; +} + +Aws::String AWSAuthV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate, + const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const +{ + //generate the actual string we will use in signing the final request. + Aws::StringStream ss; + + ss << AWS_HMAC_SHA256 << NEWLINE << dateValue << NEWLINE << simpleDate << "/" << region << "/" + << serviceName << "/" << AWS4_REQUEST << NEWLINE << canonicalRequestHash; + + return ss.str(); +} + +Aws::Utils::ByteBuffer AWSAuthV4Signer::ComputeHash(const Aws::String& secretKey, + const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const +{ + Aws::String signingKey(SIGNING_KEY); + signingKey.append(secretKey); + auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()), + ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length())); + + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\""); + return {}; + } + + auto kDate = hashResult.GetResult(); + hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) region string \"" << region << "\""); + return {}; + } + + auto kRegion = hashResult.GetResult(); + hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\""); + return {}; + } + + auto kService = hashResult.GetResult(); + hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService); + if (!hashResult.IsSuccess()) + { + AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to HMAC (SHA256) request string"); + AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << AWS4_REQUEST << "\""); + return {}; + } + return hashResult.GetResult(); +} AWSAuthEventStreamV4Signer::AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, const char* serviceName, const Aws::String& region) : diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp index 31fd6c006b..bd005b73b7 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp @@ -2,16 +2,16 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/auth/AWSAuthSignerProvider.h> -#include <aws/core/auth/AWSAuthSigner.h> + +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/auth/AWSAuthSignerProvider.h> +#include <aws/core/auth/AWSAuthSigner.h> #include <aws/core/auth/AWSCredentialsProvider.h> #include <aws/core/utils/memory/stl/AWSAllocator.h> - -const char CLASS_TAG[] = "AuthSignerProvider"; - -using namespace Aws::Auth; + +const char CLASS_TAG[] = "AuthSignerProvider"; + +using namespace Aws::Auth; DefaultAuthSignerProvider::DefaultAuthSignerProvider(const std::shared_ptr<AWSCredentialsProvider>& credentialsProvider, const Aws::String& serviceName, const Aws::String& region) @@ -21,28 +21,28 @@ DefaultAuthSignerProvider::DefaultAuthSignerProvider(const std::shared_ptr<AWSCr m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(CLASS_TAG)); } -DefaultAuthSignerProvider::DefaultAuthSignerProvider(const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) -{ - m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(CLASS_TAG)); - if(signer) - { - m_signers.emplace_back(signer); - } -} - -std::shared_ptr<Aws::Client::AWSAuthSigner> DefaultAuthSignerProvider::GetSigner(const Aws::String& signerName) const -{ - for(const auto& signer : m_signers) - { - if(signer->GetName() == signerName) - { - return signer; - } - } - AWS_LOGSTREAM_ERROR(CLASS_TAG, "Request's signer: '" << signerName << "' is not found in the signer's map."); - assert(false); - return nullptr; -} +DefaultAuthSignerProvider::DefaultAuthSignerProvider(const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) +{ + m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(CLASS_TAG)); + if(signer) + { + m_signers.emplace_back(signer); + } +} + +std::shared_ptr<Aws::Client::AWSAuthSigner> DefaultAuthSignerProvider::GetSigner(const Aws::String& signerName) const +{ + for(const auto& signer : m_signers) + { + if(signer->GetName() == signerName) + { + return signer; + } + } + AWS_LOGSTREAM_ERROR(CLASS_TAG, "Request's signer: '" << signerName << "' is not found in the signer's map."); + assert(false); + return nullptr; +} void DefaultAuthSignerProvider::AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer) { diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp index 31e28b996f..b7029eb832 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp @@ -2,104 +2,104 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/auth/AWSCredentialsProvider.h> - -#include <aws/core/config/AWSProfileConfigLoader.h> -#include <aws/core/platform/Environment.h> -#include <aws/core/platform/FileSystem.h> + + +#include <aws/core/auth/AWSCredentialsProvider.h> + +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/platform/FileSystem.h> #include <aws/core/platform/OSVersionInfo.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/json/JsonSerializer.h> -#include <aws/core/utils/FileSystemUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <aws/core/utils/FileSystemUtils.h> #include <aws/core/client/AWSError.h> #include <aws/core/utils/StringUtils.h> #include <aws/core/utils/xml/XmlSerializer.h> -#include <cstdlib> -#include <fstream> -#include <string.h> -#include <climits> - - -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; -using namespace Aws::Auth; -using namespace Aws::Internal; +#include <cstdlib> +#include <fstream> +#include <string.h> +#include <climits> + + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; +using namespace Aws::Auth; +using namespace Aws::Internal; using namespace Aws::FileSystem; using namespace Aws::Utils::Xml; using namespace Aws::Client; -using Aws::Utils::Threading::ReaderLockGuard; -using Aws::Utils::Threading::WriterLockGuard; - -static const char ACCESS_KEY_ENV_VAR[] = "AWS_ACCESS_KEY_ID"; -static const char SECRET_KEY_ENV_VAR[] = "AWS_SECRET_ACCESS_KEY"; -static const char SESSION_TOKEN_ENV_VAR[] = "AWS_SESSION_TOKEN"; -static const char DEFAULT_PROFILE[] = "default"; -static const char AWS_PROFILE_ENV_VAR[] = "AWS_PROFILE"; -static const char AWS_PROFILE_DEFAULT_ENV_VAR[] = "AWS_DEFAULT_PROFILE"; - +using Aws::Utils::Threading::ReaderLockGuard; +using Aws::Utils::Threading::WriterLockGuard; + +static const char ACCESS_KEY_ENV_VAR[] = "AWS_ACCESS_KEY_ID"; +static const char SECRET_KEY_ENV_VAR[] = "AWS_SECRET_ACCESS_KEY"; +static const char SESSION_TOKEN_ENV_VAR[] = "AWS_SESSION_TOKEN"; +static const char DEFAULT_PROFILE[] = "default"; +static const char AWS_PROFILE_ENV_VAR[] = "AWS_PROFILE"; +static const char AWS_PROFILE_DEFAULT_ENV_VAR[] = "AWS_DEFAULT_PROFILE"; + static const char AWS_CREDENTIALS_FILE[] = "AWS_SHARED_CREDENTIALS_FILE"; extern const char AWS_CONFIG_FILE[] = "AWS_CONFIG_FILE"; - + extern const char PROFILE_DIRECTORY[] = ".aws"; static const char DEFAULT_CREDENTIALS_FILE[] = "credentials"; extern const char DEFAULT_CONFIG_FILE[] = "config"; - - -static const int EXPIRATION_GRACE_PERIOD = 5 * 1000; - -void AWSCredentialsProvider::Reload() -{ - m_lastLoadedMs = DateTime::Now().Millis(); -} - -bool AWSCredentialsProvider::IsTimeToRefresh(long reloadFrequency) -{ - if (DateTime::Now().Millis() - m_lastLoadedMs > reloadFrequency) - { - return true; - } - return false; -} - - -static const char* ENVIRONMENT_LOG_TAG = "EnvironmentAWSCredentialsProvider"; - - -AWSCredentials EnvironmentAWSCredentialsProvider::GetAWSCredentials() -{ - auto accessKey = Aws::Environment::GetEnv(ACCESS_KEY_ENV_VAR); + + +static const int EXPIRATION_GRACE_PERIOD = 5 * 1000; + +void AWSCredentialsProvider::Reload() +{ + m_lastLoadedMs = DateTime::Now().Millis(); +} + +bool AWSCredentialsProvider::IsTimeToRefresh(long reloadFrequency) +{ + if (DateTime::Now().Millis() - m_lastLoadedMs > reloadFrequency) + { + return true; + } + return false; +} + + +static const char* ENVIRONMENT_LOG_TAG = "EnvironmentAWSCredentialsProvider"; + + +AWSCredentials EnvironmentAWSCredentialsProvider::GetAWSCredentials() +{ + auto accessKey = Aws::Environment::GetEnv(ACCESS_KEY_ENV_VAR); AWSCredentials credentials; - - if (!accessKey.empty()) - { - credentials.SetAWSAccessKeyId(accessKey); - - AWS_LOGSTREAM_DEBUG(ENVIRONMENT_LOG_TAG, "Found credential in environment with access key id " << accessKey); - auto secretKey = Aws::Environment::GetEnv(SECRET_KEY_ENV_VAR); - - if (!secretKey.empty()) - { - credentials.SetAWSSecretKey(secretKey); - AWS_LOGSTREAM_INFO(ENVIRONMENT_LOG_TAG, "Found secret key"); - } - - auto sessionToken = Aws::Environment::GetEnv(SESSION_TOKEN_ENV_VAR); - - if(!sessionToken.empty()) - { - credentials.SetSessionToken(sessionToken); - AWS_LOGSTREAM_INFO(ENVIRONMENT_LOG_TAG, "Found sessionToken"); - } - } - - return credentials; -} - + + if (!accessKey.empty()) + { + credentials.SetAWSAccessKeyId(accessKey); + + AWS_LOGSTREAM_DEBUG(ENVIRONMENT_LOG_TAG, "Found credential in environment with access key id " << accessKey); + auto secretKey = Aws::Environment::GetEnv(SECRET_KEY_ENV_VAR); + + if (!secretKey.empty()) + { + credentials.SetAWSSecretKey(secretKey); + AWS_LOGSTREAM_INFO(ENVIRONMENT_LOG_TAG, "Found secret key"); + } + + auto sessionToken = Aws::Environment::GetEnv(SESSION_TOKEN_ENV_VAR); + + if(!sessionToken.empty()) + { + credentials.SetSessionToken(sessionToken); + AWS_LOGSTREAM_INFO(ENVIRONMENT_LOG_TAG, "Found sessionToken"); + } + } + + return credentials; +} + Aws::String Aws::Auth::GetConfigProfileFilename() -{ +{ auto configFileNameFromVar = Aws::Environment::GetEnv(AWS_CONFIG_FILE); if (!configFileNameFromVar.empty()) { @@ -109,8 +109,8 @@ Aws::String Aws::Auth::GetConfigProfileFilename() { return Aws::FileSystem::GetHomeDirectory() + PROFILE_DIRECTORY + PATH_DELIM + DEFAULT_CONFIG_FILE; } -} - +} + Aws::String Aws::Auth::GetConfigProfileName() { auto profileFromVar = Aws::Environment::GetEnv(AWS_PROFILE_DEFAULT_ENV_VAR); @@ -130,231 +130,231 @@ Aws::String Aws::Auth::GetConfigProfileName() } static const char* PROFILE_LOG_TAG = "ProfileConfigFileAWSCredentialsProvider"; - -Aws::String ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename() -{ + +Aws::String ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename() +{ auto credentialsFileNameFromVar = Aws::Environment::GetEnv(AWS_CREDENTIALS_FILE); - + if (credentialsFileNameFromVar.empty()) - { + { return Aws::FileSystem::GetHomeDirectory() + PROFILE_DIRECTORY + PATH_DELIM + DEFAULT_CREDENTIALS_FILE; - } - else - { + } + else + { return credentialsFileNameFromVar; - } -} - -Aws::String ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory() -{ + } +} + +Aws::String ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory() +{ Aws::String credentialsFileName = GetCredentialsProfileFilename(); auto lastSeparator = credentialsFileName.find_last_of(PATH_DELIM); - if (lastSeparator != std::string::npos) - { + if (lastSeparator != std::string::npos) + { return credentialsFileName.substr(0, lastSeparator); - } - else - { + } + else + { return {}; - } -} - -ProfileConfigFileAWSCredentialsProvider::ProfileConfigFileAWSCredentialsProvider(long refreshRateMs) : + } +} + +ProfileConfigFileAWSCredentialsProvider::ProfileConfigFileAWSCredentialsProvider(long refreshRateMs) : m_profileToUse(Aws::Auth::GetConfigProfileName()), m_credentialsFileLoader(GetCredentialsProfileFilename()), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(PROFILE_LOG_TAG, "Setting provider to read credentials from " << GetCredentialsProfileFilename() << " for credentials file" - << " and " << GetConfigProfileFilename() << " for the config file " - << ", for use with profile " << m_profileToUse); -} - -ProfileConfigFileAWSCredentialsProvider::ProfileConfigFileAWSCredentialsProvider(const char* profile, long refreshRateMs) : +{ + AWS_LOGSTREAM_INFO(PROFILE_LOG_TAG, "Setting provider to read credentials from " << GetCredentialsProfileFilename() << " for credentials file" + << " and " << GetConfigProfileFilename() << " for the config file " + << ", for use with profile " << m_profileToUse); +} + +ProfileConfigFileAWSCredentialsProvider::ProfileConfigFileAWSCredentialsProvider(const char* profile, long refreshRateMs) : m_profileToUse(profile), m_credentialsFileLoader(GetCredentialsProfileFilename()), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(PROFILE_LOG_TAG, "Setting provider to read credentials from " << GetCredentialsProfileFilename() << " for credentials file" - << " and " << GetConfigProfileFilename() << " for the config file " - << ", for use with profile " << m_profileToUse); -} - -AWSCredentials ProfileConfigFileAWSCredentialsProvider::GetAWSCredentials() -{ - RefreshIfExpired(); - ReaderLockGuard guard(m_reloadLock); +{ + AWS_LOGSTREAM_INFO(PROFILE_LOG_TAG, "Setting provider to read credentials from " << GetCredentialsProfileFilename() << " for credentials file" + << " and " << GetConfigProfileFilename() << " for the config file " + << ", for use with profile " << m_profileToUse); +} + +AWSCredentials ProfileConfigFileAWSCredentialsProvider::GetAWSCredentials() +{ + RefreshIfExpired(); + ReaderLockGuard guard(m_reloadLock); auto credsFileProfileIter = m_credentialsFileLoader.GetProfiles().find(m_profileToUse); - + if(credsFileProfileIter != m_credentialsFileLoader.GetProfiles().end()) - { - return credsFileProfileIter->second.GetCredentials(); - } - - return AWSCredentials(); -} - - -void ProfileConfigFileAWSCredentialsProvider::Reload() -{ + { + return credsFileProfileIter->second.GetCredentials(); + } + + return AWSCredentials(); +} + + +void ProfileConfigFileAWSCredentialsProvider::Reload() +{ m_credentialsFileLoader.Load(); - AWSCredentialsProvider::Reload(); -} - -void ProfileConfigFileAWSCredentialsProvider::RefreshIfExpired() -{ - ReaderLockGuard guard(m_reloadLock); - if (!IsTimeToRefresh(m_loadFrequencyMs)) - { - return; - } - - guard.UpgradeToWriterLock(); - if (!IsTimeToRefresh(m_loadFrequencyMs)) // double-checked lock to avoid refreshing twice - { - return; - } - - Reload(); -} - -static const char* INSTANCE_LOG_TAG = "InstanceProfileCredentialsProvider"; - -InstanceProfileCredentialsProvider::InstanceProfileCredentialsProvider(long refreshRateMs) : + AWSCredentialsProvider::Reload(); +} + +void ProfileConfigFileAWSCredentialsProvider::RefreshIfExpired() +{ + ReaderLockGuard guard(m_reloadLock); + if (!IsTimeToRefresh(m_loadFrequencyMs)) + { + return; + } + + guard.UpgradeToWriterLock(); + if (!IsTimeToRefresh(m_loadFrequencyMs)) // double-checked lock to avoid refreshing twice + { + return; + } + + Reload(); +} + +static const char* INSTANCE_LOG_TAG = "InstanceProfileCredentialsProvider"; + +InstanceProfileCredentialsProvider::InstanceProfileCredentialsProvider(long refreshRateMs) : m_ec2MetadataConfigLoader(Aws::MakeShared<Aws::Config::EC2InstanceProfileConfigLoader>(INSTANCE_LOG_TAG)), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Creating Instance with default EC2MetadataClient and refresh rate " << refreshRateMs); -} - - +{ + AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Creating Instance with default EC2MetadataClient and refresh rate " << refreshRateMs); +} + + InstanceProfileCredentialsProvider::InstanceProfileCredentialsProvider(const std::shared_ptr<Aws::Config::EC2InstanceProfileConfigLoader>& loader, long refreshRateMs) : m_ec2MetadataConfigLoader(loader), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Creating Instance with injected EC2MetadataClient and refresh rate " << refreshRateMs); -} - - -AWSCredentials InstanceProfileCredentialsProvider::GetAWSCredentials() -{ - RefreshIfExpired(); - ReaderLockGuard guard(m_reloadLock); - auto profileIter = m_ec2MetadataConfigLoader->GetProfiles().find(Aws::Config::INSTANCE_PROFILE_KEY); - - if(profileIter != m_ec2MetadataConfigLoader->GetProfiles().end()) - { - return profileIter->second.GetCredentials(); - } - - return AWSCredentials(); -} - -void InstanceProfileCredentialsProvider::Reload() -{ - AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Credentials have expired attempting to repull from EC2 Metadata Service."); - m_ec2MetadataConfigLoader->Load(); - AWSCredentialsProvider::Reload(); -} - -void InstanceProfileCredentialsProvider::RefreshIfExpired() -{ - AWS_LOGSTREAM_DEBUG(INSTANCE_LOG_TAG, "Checking if latest credential pull has expired."); - ReaderLockGuard guard(m_reloadLock); - if (!IsTimeToRefresh(m_loadFrequencyMs)) - { +{ + AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Creating Instance with injected EC2MetadataClient and refresh rate " << refreshRateMs); +} + + +AWSCredentials InstanceProfileCredentialsProvider::GetAWSCredentials() +{ + RefreshIfExpired(); + ReaderLockGuard guard(m_reloadLock); + auto profileIter = m_ec2MetadataConfigLoader->GetProfiles().find(Aws::Config::INSTANCE_PROFILE_KEY); + + if(profileIter != m_ec2MetadataConfigLoader->GetProfiles().end()) + { + return profileIter->second.GetCredentials(); + } + + return AWSCredentials(); +} + +void InstanceProfileCredentialsProvider::Reload() +{ + AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Credentials have expired attempting to repull from EC2 Metadata Service."); + m_ec2MetadataConfigLoader->Load(); + AWSCredentialsProvider::Reload(); +} + +void InstanceProfileCredentialsProvider::RefreshIfExpired() +{ + AWS_LOGSTREAM_DEBUG(INSTANCE_LOG_TAG, "Checking if latest credential pull has expired."); + ReaderLockGuard guard(m_reloadLock); + if (!IsTimeToRefresh(m_loadFrequencyMs)) + { + return; + } + + guard.UpgradeToWriterLock(); + if (!IsTimeToRefresh(m_loadFrequencyMs)) // double-checked lock to avoid refreshing twice + { return; - } - - guard.UpgradeToWriterLock(); - if (!IsTimeToRefresh(m_loadFrequencyMs)) // double-checked lock to avoid refreshing twice - { - return; - } - Reload(); -} - -static const char TASK_ROLE_LOG_TAG[] = "TaskRoleCredentialsProvider"; - -TaskRoleCredentialsProvider::TaskRoleCredentialsProvider(const char* URI, long refreshRateMs) : - m_ecsCredentialsClient(Aws::MakeShared<Aws::Internal::ECSCredentialsClient>(TASK_ROLE_LOG_TAG, URI)), + } + Reload(); +} + +static const char TASK_ROLE_LOG_TAG[] = "TaskRoleCredentialsProvider"; + +TaskRoleCredentialsProvider::TaskRoleCredentialsProvider(const char* URI, long refreshRateMs) : + m_ecsCredentialsClient(Aws::MakeShared<Aws::Internal::ECSCredentialsClient>(TASK_ROLE_LOG_TAG, URI)), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Creating TaskRole with default ECSCredentialsClient and refresh rate " << refreshRateMs); -} - -TaskRoleCredentialsProvider::TaskRoleCredentialsProvider(const char* endpoint, const char* token, long refreshRateMs) : +{ + AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Creating TaskRole with default ECSCredentialsClient and refresh rate " << refreshRateMs); +} + +TaskRoleCredentialsProvider::TaskRoleCredentialsProvider(const char* endpoint, const char* token, long refreshRateMs) : m_ecsCredentialsClient(Aws::MakeShared<Aws::Internal::ECSCredentialsClient>(TASK_ROLE_LOG_TAG, ""/*resourcePath*/, endpoint, token)), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Creating TaskRole with default ECSCredentialsClient and refresh rate " << refreshRateMs); -} - -TaskRoleCredentialsProvider::TaskRoleCredentialsProvider( - const std::shared_ptr<Aws::Internal::ECSCredentialsClient>& client, long refreshRateMs) : - m_ecsCredentialsClient(client), +{ + AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Creating TaskRole with default ECSCredentialsClient and refresh rate " << refreshRateMs); +} + +TaskRoleCredentialsProvider::TaskRoleCredentialsProvider( + const std::shared_ptr<Aws::Internal::ECSCredentialsClient>& client, long refreshRateMs) : + m_ecsCredentialsClient(client), m_loadFrequencyMs(refreshRateMs) -{ - AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Creating TaskRole with default ECSCredentialsClient and refresh rate " << refreshRateMs); -} - -AWSCredentials TaskRoleCredentialsProvider::GetAWSCredentials() -{ - RefreshIfExpired(); - ReaderLockGuard guard(m_reloadLock); - return m_credentials; -} - -bool TaskRoleCredentialsProvider::ExpiresSoon() const -{ +{ + AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Creating TaskRole with default ECSCredentialsClient and refresh rate " << refreshRateMs); +} + +AWSCredentials TaskRoleCredentialsProvider::GetAWSCredentials() +{ + RefreshIfExpired(); + ReaderLockGuard guard(m_reloadLock); + return m_credentials; +} + +bool TaskRoleCredentialsProvider::ExpiresSoon() const +{ return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < EXPIRATION_GRACE_PERIOD); -} - -void TaskRoleCredentialsProvider::Reload() -{ - AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Credentials have expired or will expire, attempting to repull from ECS IAM Service."); - - auto credentialsStr = m_ecsCredentialsClient->GetECSCredentials(); - if (credentialsStr.empty()) return; - - Json::JsonValue credentialsDoc(credentialsStr); +} + +void TaskRoleCredentialsProvider::Reload() +{ + AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Credentials have expired or will expire, attempting to repull from ECS IAM Service."); + + auto credentialsStr = m_ecsCredentialsClient->GetECSCredentials(); + if (credentialsStr.empty()) return; + + Json::JsonValue credentialsDoc(credentialsStr); if (!credentialsDoc.WasParseSuccessful()) - { + { AWS_LOGSTREAM_ERROR(TASK_ROLE_LOG_TAG, "Failed to parse output from ECSCredentialService."); - return; - } - - Aws::String accessKey, secretKey, token; - Utils::Json::JsonView credentialsView(credentialsDoc); - accessKey = credentialsView.GetString("AccessKeyId"); - secretKey = credentialsView.GetString("SecretAccessKey"); - token = credentialsView.GetString("Token"); - AWS_LOGSTREAM_DEBUG(TASK_ROLE_LOG_TAG, "Successfully pulled credentials from metadata service with access key " << accessKey); - - m_credentials.SetAWSAccessKeyId(accessKey); - m_credentials.SetAWSSecretKey(secretKey); - m_credentials.SetSessionToken(token); + return; + } + + Aws::String accessKey, secretKey, token; + Utils::Json::JsonView credentialsView(credentialsDoc); + accessKey = credentialsView.GetString("AccessKeyId"); + secretKey = credentialsView.GetString("SecretAccessKey"); + token = credentialsView.GetString("Token"); + AWS_LOGSTREAM_DEBUG(TASK_ROLE_LOG_TAG, "Successfully pulled credentials from metadata service with access key " << accessKey); + + m_credentials.SetAWSAccessKeyId(accessKey); + m_credentials.SetAWSSecretKey(secretKey); + m_credentials.SetSessionToken(token); m_credentials.SetExpiration(Aws::Utils::DateTime(credentialsView.GetString("Expiration"), DateFormat::ISO_8601)); - AWSCredentialsProvider::Reload(); -} - -void TaskRoleCredentialsProvider::RefreshIfExpired() -{ - AWS_LOGSTREAM_DEBUG(TASK_ROLE_LOG_TAG, "Checking if latest credential pull has expired."); - ReaderLockGuard guard(m_reloadLock); + AWSCredentialsProvider::Reload(); +} + +void TaskRoleCredentialsProvider::RefreshIfExpired() +{ + AWS_LOGSTREAM_DEBUG(TASK_ROLE_LOG_TAG, "Checking if latest credential pull has expired."); + ReaderLockGuard guard(m_reloadLock); if (!m_credentials.IsEmpty() && !IsTimeToRefresh(m_loadFrequencyMs) && !ExpiresSoon()) - { - return; - } - - guard.UpgradeToWriterLock(); - + { + return; + } + + guard.UpgradeToWriterLock(); + if (!m_credentials.IsEmpty() && !IsTimeToRefresh(m_loadFrequencyMs) && !ExpiresSoon()) - { - return; - } - - Reload(); -} + { + return; + } + + Reload(); +} static const char PROCESS_LOG_TAG[] = "ProcessCredentialsProvider"; ProcessCredentialsProvider::ProcessCredentialsProvider() : diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp index 373136d96a..299f288210 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp @@ -2,76 +2,76 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/auth/AWSCredentialsProviderChain.h> + +#include <aws/core/auth/AWSCredentialsProviderChain.h> #include <aws/core/auth/STSCredentialsProvider.h> -#include <aws/core/platform/Environment.h> -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/logging/LogMacros.h> - -using namespace Aws::Auth; - -static const char AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI[] = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"; -static const char AWS_ECS_CONTAINER_CREDENTIALS_FULL_URI[] = "AWS_CONTAINER_CREDENTIALS_FULL_URI"; -static const char AWS_ECS_CONTAINER_AUTHORIZATION_TOKEN[] = "AWS_CONTAINER_AUTHORIZATION_TOKEN"; -static const char AWS_EC2_METADATA_DISABLED[] = "AWS_EC2_METADATA_DISABLED"; -static const char DefaultCredentialsProviderChainTag[] = "DefaultAWSCredentialsProviderChain"; - -AWSCredentials AWSCredentialsProviderChain::GetAWSCredentials() -{ +#include <aws/core/platform/Environment.h> +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> + +using namespace Aws::Auth; + +static const char AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI[] = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"; +static const char AWS_ECS_CONTAINER_CREDENTIALS_FULL_URI[] = "AWS_CONTAINER_CREDENTIALS_FULL_URI"; +static const char AWS_ECS_CONTAINER_AUTHORIZATION_TOKEN[] = "AWS_CONTAINER_AUTHORIZATION_TOKEN"; +static const char AWS_EC2_METADATA_DISABLED[] = "AWS_EC2_METADATA_DISABLED"; +static const char DefaultCredentialsProviderChainTag[] = "DefaultAWSCredentialsProviderChain"; + +AWSCredentials AWSCredentialsProviderChain::GetAWSCredentials() +{ for (auto&& credentialsProvider : m_providerChain) - { - AWSCredentials credentials = credentialsProvider->GetAWSCredentials(); - if (!credentials.GetAWSAccessKeyId().empty() && !credentials.GetAWSSecretKey().empty()) - { - return credentials; - } - } - + { + AWSCredentials credentials = credentialsProvider->GetAWSCredentials(); + if (!credentials.GetAWSAccessKeyId().empty() && !credentials.GetAWSSecretKey().empty()) + { + return credentials; + } + } + return AWSCredentials(); -} - -DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain() : AWSCredentialsProviderChain() -{ - AddProvider(Aws::MakeShared<EnvironmentAWSCredentialsProvider>(DefaultCredentialsProviderChainTag)); - AddProvider(Aws::MakeShared<ProfileConfigFileAWSCredentialsProvider>(DefaultCredentialsProviderChainTag)); +} + +DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain() : AWSCredentialsProviderChain() +{ + AddProvider(Aws::MakeShared<EnvironmentAWSCredentialsProvider>(DefaultCredentialsProviderChainTag)); + AddProvider(Aws::MakeShared<ProfileConfigFileAWSCredentialsProvider>(DefaultCredentialsProviderChainTag)); AddProvider(Aws::MakeShared<ProcessCredentialsProvider>(DefaultCredentialsProviderChainTag)); AddProvider(Aws::MakeShared<STSAssumeRoleWebIdentityCredentialsProvider>(DefaultCredentialsProviderChainTag)); - //ECS TaskRole Credentials only available when ENVIRONMENT VARIABLE is set - const auto relativeUri = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI); - AWS_LOGSTREAM_DEBUG(DefaultCredentialsProviderChainTag, "The environment variable value " << AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI - << " is " << relativeUri); - - const auto absoluteUri = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_CREDENTIALS_FULL_URI); - AWS_LOGSTREAM_DEBUG(DefaultCredentialsProviderChainTag, "The environment variable value " << AWS_ECS_CONTAINER_CREDENTIALS_FULL_URI - << " is " << absoluteUri); - - const auto ec2MetadataDisabled = Aws::Environment::GetEnv(AWS_EC2_METADATA_DISABLED); - AWS_LOGSTREAM_DEBUG(DefaultCredentialsProviderChainTag, "The environment variable value " << AWS_EC2_METADATA_DISABLED - << " is " << ec2MetadataDisabled); - - if (!relativeUri.empty()) - { - AddProvider(Aws::MakeShared<TaskRoleCredentialsProvider>(DefaultCredentialsProviderChainTag, relativeUri.c_str())); - AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added ECS metadata service credentials provider with relative path: [" - << relativeUri << "] to the provider chain."); - } - else if (!absoluteUri.empty()) - { - const auto token = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_AUTHORIZATION_TOKEN); - AddProvider(Aws::MakeShared<TaskRoleCredentialsProvider>(DefaultCredentialsProviderChainTag, - absoluteUri.c_str(), token.c_str())); - - //DO NOT log the value of the authorization token for security purposes. - AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added ECS credentials provider with URI: [" - << absoluteUri << "] to the provider chain with a" << (token.empty() ? "n empty " : " non-empty ") - << "authorization token."); - } - else if (Aws::Utils::StringUtils::ToLower(ec2MetadataDisabled.c_str()) != "true") - { - AddProvider(Aws::MakeShared<InstanceProfileCredentialsProvider>(DefaultCredentialsProviderChainTag)); - AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added EC2 metadata service credentials provider to the provider chain."); - } -} + //ECS TaskRole Credentials only available when ENVIRONMENT VARIABLE is set + const auto relativeUri = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI); + AWS_LOGSTREAM_DEBUG(DefaultCredentialsProviderChainTag, "The environment variable value " << AWS_ECS_CONTAINER_CREDENTIALS_RELATIVE_URI + << " is " << relativeUri); + + const auto absoluteUri = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_CREDENTIALS_FULL_URI); + AWS_LOGSTREAM_DEBUG(DefaultCredentialsProviderChainTag, "The environment variable value " << AWS_ECS_CONTAINER_CREDENTIALS_FULL_URI + << " is " << absoluteUri); + + const auto ec2MetadataDisabled = Aws::Environment::GetEnv(AWS_EC2_METADATA_DISABLED); + AWS_LOGSTREAM_DEBUG(DefaultCredentialsProviderChainTag, "The environment variable value " << AWS_EC2_METADATA_DISABLED + << " is " << ec2MetadataDisabled); + + if (!relativeUri.empty()) + { + AddProvider(Aws::MakeShared<TaskRoleCredentialsProvider>(DefaultCredentialsProviderChainTag, relativeUri.c_str())); + AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added ECS metadata service credentials provider with relative path: [" + << relativeUri << "] to the provider chain."); + } + else if (!absoluteUri.empty()) + { + const auto token = Aws::Environment::GetEnv(AWS_ECS_CONTAINER_AUTHORIZATION_TOKEN); + AddProvider(Aws::MakeShared<TaskRoleCredentialsProvider>(DefaultCredentialsProviderChainTag, + absoluteUri.c_str(), token.c_str())); + + //DO NOT log the value of the authorization token for security purposes. + AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added ECS credentials provider with URI: [" + << absoluteUri << "] to the provider chain with a" << (token.empty() ? "n empty " : " non-empty ") + << "authorization token."); + } + else if (Aws::Utils::StringUtils::ToLower(ec2MetadataDisabled.c_str()) != "true") + { + AddProvider(Aws::MakeShared<InstanceProfileCredentialsProvider>(DefaultCredentialsProviderChainTag)); + AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added EC2 metadata service credentials provider to the provider chain."); + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp index e1ff064840..0a1d9e6388 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSClient.cpp @@ -1,75 +1,75 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/client/AWSClient.h> -#include <aws/core/AmazonWebServiceRequest.h> -#include <aws/core/auth/AWSAuthSigner.h> -#include <aws/core/auth/AWSAuthSignerProvider.h> -#include <aws/core/client/AWSError.h> -#include <aws/core/client/AWSErrorMarshaller.h> -#include <aws/core/client/ClientConfiguration.h> -#include <aws/core/client/CoreErrors.h> -#include <aws/core/client/RetryStrategy.h> -#include <aws/core/http/HttpClient.h> -#include <aws/core/http/HttpClientFactory.h> -#include <aws/core/http/HttpResponse.h> -#include <aws/core/http/standard/StandardHttpResponse.h> + */ + +#include <aws/core/client/AWSClient.h> +#include <aws/core/AmazonWebServiceRequest.h> +#include <aws/core/auth/AWSAuthSigner.h> +#include <aws/core/auth/AWSAuthSignerProvider.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/client/AWSErrorMarshaller.h> +#include <aws/core/client/ClientConfiguration.h> +#include <aws/core/client/CoreErrors.h> +#include <aws/core/client/RetryStrategy.h> +#include <aws/core/http/HttpClient.h> +#include <aws/core/http/HttpClientFactory.h> +#include <aws/core/http/HttpResponse.h> +#include <aws/core/http/standard/StandardHttpResponse.h> #include <aws/core/http/URI.h> -#include <aws/core/utils/stream/ResponseStream.h> -#include <aws/core/utils/json/JsonSerializer.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/xml/XmlSerializer.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/Globals.h> -#include <aws/core/utils/EnumParseOverflowContainer.h> -#include <aws/core/utils/crypto/MD5.h> -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/utils/crypto/Factories.h> +#include <aws/core/utils/stream/ResponseStream.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/xml/XmlSerializer.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/Globals.h> +#include <aws/core/utils/EnumParseOverflowContainer.h> +#include <aws/core/utils/crypto/MD5.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/crypto/Factories.h> #include <aws/core/utils/event/EventStream.h> #include <aws/core/utils/UUID.h> -#include <aws/core/monitoring/MonitoringManager.h> +#include <aws/core/monitoring/MonitoringManager.h> #include <aws/core/Region.h> #include <aws/core/utils/DNS.h> #include <aws/core/Version.h> #include <aws/core/platform/OSVersionInfo.h> - + #include <cstring> #include <cassert> -using namespace Aws; -using namespace Aws::Client; -using namespace Aws::Http; -using namespace Aws::Utils; -using namespace Aws::Utils::Json; -using namespace Aws::Utils::Xml; - -static const int SUCCESS_RESPONSE_MIN = 200; -static const int SUCCESS_RESPONSE_MAX = 299; - -static const char AWS_CLIENT_LOG_TAG[] = "AWSClient"; -//4 Minutes +using namespace Aws; +using namespace Aws::Client; +using namespace Aws::Http; +using namespace Aws::Utils; +using namespace Aws::Utils::Json; +using namespace Aws::Utils::Xml; + +static const int SUCCESS_RESPONSE_MIN = 200; +static const int SUCCESS_RESPONSE_MAX = 299; + +static const char AWS_CLIENT_LOG_TAG[] = "AWSClient"; +//4 Minutes static const std::chrono::milliseconds TIME_DIFF_MAX = std::chrono::minutes(4); -//-4 Minutes -static const std::chrono::milliseconds TIME_DIFF_MIN = std::chrono::minutes(-4); - -static CoreErrors GuessBodylessErrorType(Aws::Http::HttpResponseCode responseCode) -{ - switch (responseCode) - { - case HttpResponseCode::FORBIDDEN: - case HttpResponseCode::UNAUTHORIZED: - return CoreErrors::ACCESS_DENIED; - case HttpResponseCode::NOT_FOUND: - return CoreErrors::RESOURCE_NOT_FOUND; - default: - return CoreErrors::UNKNOWN; +//-4 Minutes +static const std::chrono::milliseconds TIME_DIFF_MIN = std::chrono::minutes(-4); + +static CoreErrors GuessBodylessErrorType(Aws::Http::HttpResponseCode responseCode) +{ + switch (responseCode) + { + case HttpResponseCode::FORBIDDEN: + case HttpResponseCode::UNAUTHORIZED: + return CoreErrors::ACCESS_DENIED; + case HttpResponseCode::NOT_FOUND: + return CoreErrors::RESOURCE_NOT_FOUND; + default: + return CoreErrors::UNKNOWN; } -} - +} + struct RequestInfo { Aws::Utils::DateTime ttl; @@ -93,44 +93,44 @@ struct RequestInfo } }; -AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : +AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : m_region(configuration.region), - m_httpClient(CreateHttpClient(configuration)), - m_signerProvider(Aws::MakeUnique<Aws::Auth::DefaultAuthSignerProvider>(AWS_CLIENT_LOG_TAG, signer)), - m_errorMarshaller(errorMarshaller), - m_retryStrategy(configuration.retryStrategy), - m_writeRateLimiter(configuration.writeRateLimiter), - m_readRateLimiter(configuration.readRateLimiter), - m_userAgent(configuration.userAgent), + m_httpClient(CreateHttpClient(configuration)), + m_signerProvider(Aws::MakeUnique<Aws::Auth::DefaultAuthSignerProvider>(AWS_CLIENT_LOG_TAG, signer)), + m_errorMarshaller(errorMarshaller), + m_retryStrategy(configuration.retryStrategy), + m_writeRateLimiter(configuration.writeRateLimiter), + m_readRateLimiter(configuration.readRateLimiter), + m_userAgent(configuration.userAgent), m_customizedUserAgent(!m_userAgent.empty()), - m_hash(Aws::Utils::Crypto::CreateMD5Implementation()), + m_hash(Aws::Utils::Crypto::CreateMD5Implementation()), m_requestTimeoutMs(configuration.requestTimeoutMs), - m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment) -{ + m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment) +{ SetServiceClientName("AWSBaseClient"); -} - -AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : +} + +AWSClient::AWSClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : m_region(configuration.region), - m_httpClient(CreateHttpClient(configuration)), - m_signerProvider(signerProvider), - m_errorMarshaller(errorMarshaller), - m_retryStrategy(configuration.retryStrategy), - m_writeRateLimiter(configuration.writeRateLimiter), - m_readRateLimiter(configuration.readRateLimiter), - m_userAgent(configuration.userAgent), + m_httpClient(CreateHttpClient(configuration)), + m_signerProvider(signerProvider), + m_errorMarshaller(errorMarshaller), + m_retryStrategy(configuration.retryStrategy), + m_writeRateLimiter(configuration.writeRateLimiter), + m_readRateLimiter(configuration.readRateLimiter), + m_userAgent(configuration.userAgent), m_customizedUserAgent(!m_userAgent.empty()), - m_hash(Aws::Utils::Crypto::CreateMD5Implementation()), + m_hash(Aws::Utils::Crypto::CreateMD5Implementation()), m_requestTimeoutMs(configuration.requestTimeoutMs), - m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment) -{ + m_enableClockSkewAdjustment(configuration.enableClockSkewAdjustment) +{ SetServiceClientName("AWSBaseClient"); -} - +} + void AWSClient::SetServiceClientName(const Aws::String& name) { m_serviceName = name; @@ -141,8 +141,8 @@ void AWSClient::SetServiceClientName(const Aws::String& name) << " " << Version::GetCompilerVersionString(); m_userAgent = ss.str(); } -} - +} + void AWSClient::DisableRequestProcessing() { m_httpClient->DisableRequestProcessing(); @@ -150,15 +150,15 @@ void AWSClient::DisableRequestProcessing() void AWSClient::EnableRequestProcessing() { - m_httpClient->EnableRequestProcessing(); -} - -Aws::Client::AWSAuthSigner* AWSClient::GetSignerByName(const char* name) const -{ - const auto& signer = m_signerProvider->GetSigner(name); - return signer ? signer.get() : nullptr; -} - + m_httpClient->EnableRequestProcessing(); +} + +Aws::Client::AWSAuthSigner* AWSClient::GetSignerByName(const char* name) const +{ + const auto& signer = m_signerProvider->GetSigner(name); + return signer ? signer.get() : nullptr; +} + static DateTime GetServerTimeFromError(const AWSError<CoreErrors> error) { const Http::HeaderValueCollection& headers = error.GetResponseHeaders(); @@ -178,60 +178,60 @@ static DateTime GetServerTimeFromError(const AWSError<CoreErrors> error) } } -bool AWSClient::AdjustClockSkew(HttpResponseOutcome& outcome, const char* signerName) const -{ - if (m_enableClockSkewAdjustment) - { - auto signer = GetSignerByName(signerName); +bool AWSClient::AdjustClockSkew(HttpResponseOutcome& outcome, const char* signerName) const +{ + if (m_enableClockSkewAdjustment) + { + auto signer = GetSignerByName(signerName); //detect clock skew and try to correct. - AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "If the signature check failed. This could be because of a time skew. Attempting to adjust the signer."); - + AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "If the signature check failed. This could be because of a time skew. Attempting to adjust the signer."); + DateTime serverTime = GetServerTimeFromError(outcome.GetError()); - const auto signingTimestamp = signer->GetSigningTimestamp(); - if (!serverTime.WasParseSuccessful() || serverTime == DateTime()) - { - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Date header was not found in the response, can't attempt to detect clock skew"); - return false; - } - - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Server time is " << serverTime.ToGmtString(DateFormat::RFC822) << ", while client time is " << DateTime::Now().ToGmtString(DateFormat::RFC822)); - auto diff = DateTime::Diff(serverTime, signingTimestamp); - //only try again if clock skew was the cause of the error. - if (diff >= TIME_DIFF_MAX || diff <= TIME_DIFF_MIN) - { - diff = DateTime::Diff(serverTime, DateTime::Now()); - AWS_LOGSTREAM_INFO(AWS_CLIENT_LOG_TAG, "Computed time difference as " << diff.count() << " milliseconds. Adjusting signer with the skew."); - signer->SetClockSkew(diff); + const auto signingTimestamp = signer->GetSigningTimestamp(); + if (!serverTime.WasParseSuccessful() || serverTime == DateTime()) + { + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Date header was not found in the response, can't attempt to detect clock skew"); + return false; + } + + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Server time is " << serverTime.ToGmtString(DateFormat::RFC822) << ", while client time is " << DateTime::Now().ToGmtString(DateFormat::RFC822)); + auto diff = DateTime::Diff(serverTime, signingTimestamp); + //only try again if clock skew was the cause of the error. + if (diff >= TIME_DIFF_MAX || diff <= TIME_DIFF_MIN) + { + diff = DateTime::Diff(serverTime, DateTime::Now()); + AWS_LOGSTREAM_INFO(AWS_CLIENT_LOG_TAG, "Computed time difference as " << diff.count() << " milliseconds. Adjusting signer with the skew."); + signer->SetClockSkew(diff); AWSError<CoreErrors> newError( - outcome.GetError().GetErrorType(), outcome.GetError().GetExceptionName(), outcome.GetError().GetMessage(), true); - newError.SetResponseHeaders(outcome.GetError().GetResponseHeaders()); - newError.SetResponseCode(outcome.GetError().GetResponseCode()); + outcome.GetError().GetErrorType(), outcome.GetError().GetExceptionName(), outcome.GetError().GetMessage(), true); + newError.SetResponseHeaders(outcome.GetError().GetResponseHeaders()); + newError.SetResponseCode(outcome.GetError().GetResponseCode()); outcome = std::move(newError); - return true; - } - } - return false; -} - -HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - HttpMethod method, + return true; + } + } + return false; +} + +HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + HttpMethod method, const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ if (!Aws::Utils::IsValidHost(uri.GetAuthority())) { return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::VALIDATION, "", "Invalid DNS Label found in URI host", false/*retryable*/)); } - std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(uri, method, request.GetResponseStreamFactory())); - HttpResponseOutcome outcome; + std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(uri, method, request.GetResponseStreamFactory())); + HttpResponseOutcome outcome; AWSError<CoreErrors> lastError; - Aws::Monitoring::CoreMetricsCollection coreMetrics; - auto contexts = Aws::Monitoring::OnRequestStarted(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest); + Aws::Monitoring::CoreMetricsCollection coreMetrics; + auto contexts = Aws::Monitoring::OnRequestStarted(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest); const char* signerRegion = signerRegionOverride; Aws::String regionFromResponse; - + Aws::String invocationId = UUID::RandomUUID(); RequestInfo requestInfo; requestInfo.attempt = 1; @@ -239,8 +239,8 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, httpRequest->SetHeaderValue(Http::SDK_INVOCATION_ID_HEADER, invocationId); httpRequest->SetHeaderValue(Http::SDK_REQUEST_HEADER, requestInfo); - for (long retries = 0;; retries++) - { + for (long retries = 0;; retries++) + { m_retryStrategy->GetSendToken(); httpRequest->SetEventStreamRequest(request.IsEventStreamRequest()); @@ -253,26 +253,26 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, { m_retryStrategy->RequestBookkeeping(outcome, lastError); } - coreMetrics.httpClientMetrics = httpRequest->GetRequestMetrics(); - if (outcome.IsSuccess()) - { - Aws::Monitoring::OnRequestSucceeded(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, outcome, coreMetrics, contexts); - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request successful returning."); - break; - } + coreMetrics.httpClientMetrics = httpRequest->GetRequestMetrics(); + if (outcome.IsSuccess()) + { + Aws::Monitoring::OnRequestSucceeded(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, outcome, coreMetrics, contexts); + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request successful returning."); + break; + } lastError = outcome.GetError(); - + DateTime serverTime = GetServerTimeFromError(outcome.GetError()); auto clockSkew = DateTime::Diff(serverTime, DateTime::Now()); - Aws::Monitoring::OnRequestFailed(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, outcome, coreMetrics, contexts); - - if (!m_httpClient->IsRequestProcessingEnabled()) - { - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request was cancelled externally."); - break; - } - + Aws::Monitoring::OnRequestFailed(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, outcome, coreMetrics, contexts); + + if (!m_httpClient->IsRequestProcessingEnabled()) + { + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request was cancelled externally."); + break; + } + // Adjust region bool retryWithCorrectRegion = false; HttpResponseCode httpResponseCode = outcome.GetError().GetResponseCode(); @@ -289,32 +289,32 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, } } - long sleepMillis = m_retryStrategy->CalculateDelayBeforeNextRetry(outcome.GetError(), retries); - //AdjustClockSkew returns true means clock skew was the problem and skew was adjusted, false otherwise. + long sleepMillis = m_retryStrategy->CalculateDelayBeforeNextRetry(outcome.GetError(), retries); + //AdjustClockSkew returns true means clock skew was the problem and skew was adjusted, false otherwise. //sleep if clock skew and region was NOT the problem. AdjustClockSkew may update error inside outcome. bool shouldSleep = !AdjustClockSkew(outcome, signerName) && !retryWithCorrectRegion; - + if (!retryWithCorrectRegion && !m_retryStrategy->ShouldRetry(outcome.GetError(), retries)) - { - break; - } - - AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "Request failed, now waiting " << sleepMillis << " ms before attempting again."); - if(request.GetBody()) - { - request.GetBody()->clear(); - request.GetBody()->seekg(0); - } - - if (request.GetRequestRetryHandler()) - { - request.GetRequestRetryHandler()(request); - } - - if (shouldSleep) - { - m_httpClient->RetryRequestSleep(std::chrono::milliseconds(sleepMillis)); - } + { + break; + } + + AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "Request failed, now waiting " << sleepMillis << " ms before attempting again."); + if(request.GetBody()) + { + request.GetBody()->clear(); + request.GetBody()->seekg(0); + } + + if (request.GetRequestRetryHandler()) + { + request.GetRequestRetryHandler()(request); + } + + if (shouldSleep) + { + m_httpClient->RetryRequestSleep(std::chrono::milliseconds(sleepMillis)); + } Aws::Http::URI newUri = uri; Aws::String newEndpoint = GetErrorMarshaller()->ExtractEndpoint(outcome.GetError()); @@ -332,32 +332,32 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, requestInfo.attempt ++; requestInfo.maxAttempts = m_retryStrategy->GetMaxAttempts(); httpRequest->SetHeaderValue(Http::SDK_REQUEST_HEADER, requestInfo); - Aws::Monitoring::OnRequestRetry(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, contexts); - } - Aws::Monitoring::OnFinish(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, contexts); - return outcome; -} - + Aws::Monitoring::OnRequestRetry(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, contexts); + } + Aws::Monitoring::OnFinish(this->GetServiceClientName(), request.GetServiceRequestName(), httpRequest, contexts); + return outcome; +} + HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, HttpMethod method, const char* signerName, const char* requestName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ if (!Aws::Utils::IsValidHost(uri.GetAuthority())) { return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::VALIDATION, "", "Invalid DNS Label found in URI host", false/*retryable*/)); } - std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod)); - HttpResponseOutcome outcome; + std::shared_ptr<HttpRequest> httpRequest(CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod)); + HttpResponseOutcome outcome; AWSError<CoreErrors> lastError; - Aws::Monitoring::CoreMetricsCollection coreMetrics; - auto contexts = Aws::Monitoring::OnRequestStarted(this->GetServiceClientName(), requestName, httpRequest); + Aws::Monitoring::CoreMetricsCollection coreMetrics; + auto contexts = Aws::Monitoring::OnRequestStarted(this->GetServiceClientName(), requestName, httpRequest); const char* signerRegion = signerRegionOverride; Aws::String regionFromResponse; - + Aws::String invocationId = UUID::RandomUUID(); RequestInfo requestInfo; requestInfo.attempt = 1; @@ -365,8 +365,8 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, httpRequest->SetHeaderValue(Http::SDK_INVOCATION_ID_HEADER, invocationId); httpRequest->SetHeaderValue(Http::SDK_REQUEST_HEADER, requestInfo); - for (long retries = 0;; retries++) - { + for (long retries = 0;; retries++) + { m_retryStrategy->GetSendToken(); outcome = AttemptOneRequest(httpRequest, signerName, requestName, signerRegion, signerServiceNameOverride); if (retries == 0) @@ -377,26 +377,26 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, { m_retryStrategy->RequestBookkeeping(outcome, lastError); } - coreMetrics.httpClientMetrics = httpRequest->GetRequestMetrics(); - if (outcome.IsSuccess()) - { - Aws::Monitoring::OnRequestSucceeded(this->GetServiceClientName(), requestName, httpRequest, outcome, coreMetrics, contexts); - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request successful returning."); - break; - } + coreMetrics.httpClientMetrics = httpRequest->GetRequestMetrics(); + if (outcome.IsSuccess()) + { + Aws::Monitoring::OnRequestSucceeded(this->GetServiceClientName(), requestName, httpRequest, outcome, coreMetrics, contexts); + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request successful returning."); + break; + } lastError = outcome.GetError(); - + DateTime serverTime = GetServerTimeFromError(outcome.GetError()); auto clockSkew = DateTime::Diff(serverTime, DateTime::Now()); - Aws::Monitoring::OnRequestFailed(this->GetServiceClientName(), requestName, httpRequest, outcome, coreMetrics, contexts); - - if (!m_httpClient->IsRequestProcessingEnabled()) - { - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request was cancelled externally."); - break; - } - + Aws::Monitoring::OnRequestFailed(this->GetServiceClientName(), requestName, httpRequest, outcome, coreMetrics, contexts); + + if (!m_httpClient->IsRequestProcessingEnabled()) + { + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Request was cancelled externally."); + break; + } + // Adjust region bool retryWithCorrectRegion = false; HttpResponseCode httpResponseCode = outcome.GetError().GetResponseCode(); @@ -413,22 +413,22 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, } } - long sleepMillis = m_retryStrategy->CalculateDelayBeforeNextRetry(outcome.GetError(), retries); - //AdjustClockSkew returns true means clock skew was the problem and skew was adjusted, false otherwise. + long sleepMillis = m_retryStrategy->CalculateDelayBeforeNextRetry(outcome.GetError(), retries); + //AdjustClockSkew returns true means clock skew was the problem and skew was adjusted, false otherwise. //sleep if clock skew and region was NOT the problem. AdjustClockSkew may update error inside outcome. bool shouldSleep = !AdjustClockSkew(outcome, signerName) && !retryWithCorrectRegion; - + if (!retryWithCorrectRegion && !m_retryStrategy->ShouldRetry(outcome.GetError(), retries)) - { - break; - } - - AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "Request failed, now waiting " << sleepMillis << " ms before attempting again."); - - if (shouldSleep) - { - m_httpClient->RetryRequestSleep(std::chrono::milliseconds(sleepMillis)); - } + { + break; + } + + AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "Request failed, now waiting " << sleepMillis << " ms before attempting again."); + + if (shouldSleep) + { + m_httpClient->RetryRequestSleep(std::chrono::milliseconds(sleepMillis)); + } Aws::Http::URI newUri = uri; Aws::String newEndpoint = GetErrorMarshaller()->ExtractEndpoint(outcome.GetError()); @@ -446,120 +446,120 @@ HttpResponseOutcome AWSClient::AttemptExhaustively(const Aws::Http::URI& uri, requestInfo.attempt ++; requestInfo.maxAttempts = m_retryStrategy->GetMaxAttempts(); httpRequest->SetHeaderValue(Http::SDK_REQUEST_HEADER, requestInfo); - Aws::Monitoring::OnRequestRetry(this->GetServiceClientName(), requestName, httpRequest, contexts); - } - Aws::Monitoring::OnFinish(this->GetServiceClientName(), requestName, httpRequest, contexts); - return outcome; -} - -static bool DoesResponseGenerateError(const std::shared_ptr<HttpResponse>& response) -{ + Aws::Monitoring::OnRequestRetry(this->GetServiceClientName(), requestName, httpRequest, contexts); + } + Aws::Monitoring::OnFinish(this->GetServiceClientName(), requestName, httpRequest, contexts); + return outcome; +} + +static bool DoesResponseGenerateError(const std::shared_ptr<HttpResponse>& response) +{ if (response->HasClientError()) return true; - - int responseCode = static_cast<int>(response->GetResponseCode()); - return responseCode < SUCCESS_RESPONSE_MIN || responseCode > SUCCESS_RESPONSE_MAX; - -} - + + int responseCode = static_cast<int>(response->GetResponseCode()); + return responseCode < SUCCESS_RESPONSE_MIN || responseCode > SUCCESS_RESPONSE_MAX; + +} + HttpResponseOutcome AWSClient::AttemptOneRequest(const std::shared_ptr<HttpRequest>& httpRequest, const Aws::AmazonWebServiceRequest& request, const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ - BuildHttpRequest(request, httpRequest); - auto signer = GetSignerByName(signerName); +{ + BuildHttpRequest(request, httpRequest); + auto signer = GetSignerByName(signerName); if (!signer->SignRequest(*httpRequest, signerRegionOverride, signerServiceNameOverride, request.SignBody())) - { - AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Request signing failed. Returning error."); - return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::CLIENT_SIGNING_FAILURE, "", "SDK failed to sign the request", false/*retryable*/)); - } - + { + AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Request signing failed. Returning error."); + return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::CLIENT_SIGNING_FAILURE, "", "SDK failed to sign the request", false/*retryable*/)); + } + if (request.GetRequestSignedHandler()) { request.GetRequestSignedHandler()(*httpRequest); } - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request Successfully signed"); - std::shared_ptr<HttpResponse> httpResponse( - m_httpClient->MakeRequest(httpRequest, m_readRateLimiter.get(), m_writeRateLimiter.get())); - - if (DoesResponseGenerateError(httpResponse)) - { - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response"); + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request Successfully signed"); + std::shared_ptr<HttpResponse> httpResponse( + m_httpClient->MakeRequest(httpRequest, m_readRateLimiter.get(), m_writeRateLimiter.get())); + + if (DoesResponseGenerateError(httpResponse)) + { + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response"); auto error = BuildAWSError(httpResponse); return HttpResponseOutcome(std::move(error)); - } - - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned successful response."); - + } + + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned successful response."); + return HttpResponseOutcome(std::move(httpResponse)); -} - +} + HttpResponseOutcome AWSClient::AttemptOneRequest(const std::shared_ptr<HttpRequest>& httpRequest, const char* signerName, const char* requestName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ - AWS_UNREFERENCED_PARAM(requestName); - - auto signer = GetSignerByName(signerName); +{ + AWS_UNREFERENCED_PARAM(requestName); + + auto signer = GetSignerByName(signerName); if (!signer->SignRequest(*httpRequest, signerRegionOverride, signerServiceNameOverride, true)) - { - AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Request signing failed. Returning error."); - return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::CLIENT_SIGNING_FAILURE, "", "SDK failed to sign the request", false/*retryable*/)); - } - - //user agent and headers like that shouldn't be signed for the sake of compatibility with proxies which MAY mutate that header. - AddCommonHeaders(*httpRequest); - - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request Successfully signed"); - std::shared_ptr<HttpResponse> httpResponse( - m_httpClient->MakeRequest(httpRequest, m_readRateLimiter.get(), m_writeRateLimiter.get())); - - if (DoesResponseGenerateError(httpResponse)) - { - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response"); + { + AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Request signing failed. Returning error."); + return HttpResponseOutcome(AWSError<CoreErrors>(CoreErrors::CLIENT_SIGNING_FAILURE, "", "SDK failed to sign the request", false/*retryable*/)); + } + + //user agent and headers like that shouldn't be signed for the sake of compatibility with proxies which MAY mutate that header. + AddCommonHeaders(*httpRequest); + + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request Successfully signed"); + std::shared_ptr<HttpResponse> httpResponse( + m_httpClient->MakeRequest(httpRequest, m_readRateLimiter.get(), m_writeRateLimiter.get())); + + if (DoesResponseGenerateError(httpResponse)) + { + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned error. Attempting to generate appropriate error codes from response"); auto error = BuildAWSError(httpResponse); return HttpResponseOutcome(std::move(error)); - } - - AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned successful response."); - + } + + AWS_LOGSTREAM_DEBUG(AWS_CLIENT_LOG_TAG, "Request returned successful response."); + return HttpResponseOutcome(std::move(httpResponse)); -} - -StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method, +} + +StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method, const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ HttpResponseOutcome httpResponseOutcome = AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride); - if (httpResponseOutcome.IsSuccess()) - { - return StreamOutcome(AmazonWebServiceResult<Stream::ResponseStream>( - httpResponseOutcome.GetResult()->SwapResponseStreamOwnership(), - httpResponseOutcome.GetResult()->GetHeaders(), httpResponseOutcome.GetResult()->GetResponseCode())); - } - + if (httpResponseOutcome.IsSuccess()) + { + return StreamOutcome(AmazonWebServiceResult<Stream::ResponseStream>( + httpResponseOutcome.GetResult()->SwapResponseStreamOwnership(), + httpResponseOutcome.GetResult()->GetHeaders(), httpResponseOutcome.GetResult()->GetResponseCode())); + } + return StreamOutcome(std::move(httpResponseOutcome)); -} - +} + StreamOutcome AWSClient::MakeRequestWithUnparsedResponse(const Aws::Http::URI& uri, Http::HttpMethod method, const char* signerName, const char* requestName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ HttpResponseOutcome httpResponseOutcome = AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride); - if (httpResponseOutcome.IsSuccess()) - { - return StreamOutcome(AmazonWebServiceResult<Stream::ResponseStream>( - httpResponseOutcome.GetResult()->SwapResponseStreamOwnership(), - httpResponseOutcome.GetResult()->GetHeaders(), httpResponseOutcome.GetResult()->GetResponseCode())); - } - + if (httpResponseOutcome.IsSuccess()) + { + return StreamOutcome(AmazonWebServiceResult<Stream::ResponseStream>( + httpResponseOutcome.GetResult()->SwapResponseStreamOwnership(), + httpResponseOutcome.GetResult()->GetHeaders(), httpResponseOutcome.GetResult()->GetResponseCode())); + } + return StreamOutcome(std::move(httpResponseOutcome)); -} - +} + XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::Http::URI& uri, const Aws::AmazonWebServiceRequest& request, Http::HttpMethod method, @@ -592,80 +592,80 @@ XmlOutcome AWSXMLClient::MakeRequestWithEventStream(const Aws::Http::URI& uri, return XmlOutcome(std::move(httpOutcome)); } -void AWSClient::AddHeadersToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, - const Http::HeaderValueCollection& headerValues) const -{ - for (auto const& headerValue : headerValues) - { - httpRequest->SetHeaderValue(headerValue.first, headerValue.second); - } - - AddCommonHeaders(*httpRequest); -} - -void AWSClient::AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, +void AWSClient::AddHeadersToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, + const Http::HeaderValueCollection& headerValues) const +{ + for (auto const& headerValue : headerValues) + { + httpRequest->SetHeaderValue(headerValue.first, headerValue.second); + } + + AddCommonHeaders(*httpRequest); +} + +void AWSClient::AddContentBodyToRequest(const std::shared_ptr<Aws::Http::HttpRequest>& httpRequest, const std::shared_ptr<Aws::IOStream>& body, bool needsContentMd5, bool isChunked) const -{ - httpRequest->AddContentBody(body); - - //If there is no body, we have a content length of 0 - //note: we also used to remove content-type, but S3 actually needs content-type on InitiateMultipartUpload and it isn't - //forbiden by the spec. If we start getting weird errors related to this, make sure it isn't caused by this removal. - if (!body) - { - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "No content body, content-length headers"); - - if(httpRequest->GetMethod() == HttpMethod::HTTP_POST || httpRequest->GetMethod() == HttpMethod::HTTP_PUT) +{ + httpRequest->AddContentBody(body); + + //If there is no body, we have a content length of 0 + //note: we also used to remove content-type, but S3 actually needs content-type on InitiateMultipartUpload and it isn't + //forbiden by the spec. If we start getting weird errors related to this, make sure it isn't caused by this removal. + if (!body) + { + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "No content body, content-length headers"); + + if(httpRequest->GetMethod() == HttpMethod::HTTP_POST || httpRequest->GetMethod() == HttpMethod::HTTP_PUT) { httpRequest->SetHeaderValue(Http::CONTENT_LENGTH_HEADER, "0"); - } - else - { - httpRequest->DeleteHeader(Http::CONTENT_LENGTH_HEADER); - } - } - + } + else + { + httpRequest->DeleteHeader(Http::CONTENT_LENGTH_HEADER); + } + } + //Add transfer-encoding:chunked to header if (body && isChunked) { httpRequest->SetTransferEncoding(CHUNKED_VALUE); } - //in the scenario where we are adding a content body as a stream, the request object likely already - //has a content-length header set and we don't want to seek the stream just to find this information. + //in the scenario where we are adding a content body as a stream, the request object likely already + //has a content-length header set and we don't want to seek the stream just to find this information. else if (body && !httpRequest->HasHeader(Http::CONTENT_LENGTH_HEADER)) - { + { if (!m_httpClient->SupportsChunkedTransferEncoding()) { AWS_LOGSTREAM_WARN(AWS_CLIENT_LOG_TAG, "This http client doesn't support transfer-encoding:chunked. " << "The request may fail if it's not a seekable stream."); } - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Found body, but content-length has not been set, attempting to compute content-length"); - body->seekg(0, body->end); - auto streamSize = body->tellg(); - body->seekg(0, body->beg); - Aws::StringStream ss; - ss << streamSize; - httpRequest->SetContentLength(ss.str()); - } - - if (needsContentMd5 && body && !httpRequest->HasHeader(Http::CONTENT_MD5_HEADER)) - { - AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Found body, and content-md5 needs to be set" << - ", attempting to compute content-md5"); - - //changing the internal state of the hash computation is not a logical state - //change as far as constness goes for this class. Due to the platform specificness - //of hash computations, we can't control the fact that computing a hash mutates - //state on some platforms such as windows (but that isn't a concern of this class. - auto md5HashResult = const_cast<AWSClient*>(this)->m_hash->Calculate(*body); - body->clear(); - if (md5HashResult.IsSuccess()) - { - httpRequest->SetHeaderValue(Http::CONTENT_MD5_HEADER, HashingUtils::Base64Encode(md5HashResult.GetResult())); - } - } -} - + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Found body, but content-length has not been set, attempting to compute content-length"); + body->seekg(0, body->end); + auto streamSize = body->tellg(); + body->seekg(0, body->beg); + Aws::StringStream ss; + ss << streamSize; + httpRequest->SetContentLength(ss.str()); + } + + if (needsContentMd5 && body && !httpRequest->HasHeader(Http::CONTENT_MD5_HEADER)) + { + AWS_LOGSTREAM_TRACE(AWS_CLIENT_LOG_TAG, "Found body, and content-md5 needs to be set" << + ", attempting to compute content-md5"); + + //changing the internal state of the hash computation is not a logical state + //change as far as constness goes for this class. Due to the platform specificness + //of hash computations, we can't control the fact that computing a hash mutates + //state on some platforms such as windows (but that isn't a concern of this class. + auto md5HashResult = const_cast<AWSClient*>(this)->m_hash->Calculate(*body); + body->clear(); + if (md5HashResult.IsSuccess()) + { + httpRequest->SetHeaderValue(Http::CONTENT_MD5_HEADER, HashingUtils::Base64Encode(md5HashResult.GetResult())); + } + } +} + Aws::String Aws::Client::GetAuthorizationHeader(const Aws::Http::HttpRequest& httpRequest) { // Extract the hex-encoded signature from the authorization header rather than recalculating it. @@ -697,47 +697,47 @@ void AWSClient::BuildHttpRequest(const Aws::AmazonWebServiceRequest& request, AddContentBodyToRequest(httpRequest, request.GetBody(), request.ShouldComputeContentMd5(), request.IsStreaming() && request.IsChunked() && m_httpClient->SupportsChunkedTransferEncoding()); } - // Pass along handlers for processing data sent/received in bytes - httpRequest->SetDataReceivedEventHandler(request.GetDataReceivedEventHandler()); - httpRequest->SetDataSentEventHandler(request.GetDataSentEventHandler()); - httpRequest->SetContinueRequestHandle(request.GetContinueRequestHandler()); - - request.AddQueryStringParameters(httpRequest->GetUri()); -} - -void AWSClient::AddCommonHeaders(HttpRequest& httpRequest) const -{ - httpRequest.SetUserAgent(m_userAgent); -} - -Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, long long expirationInSeconds) -{ - std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); - if (signer->PresignRequest(*request, expirationInSeconds)) - { - return request->GetURIString(); - } - + // Pass along handlers for processing data sent/received in bytes + httpRequest->SetDataReceivedEventHandler(request.GetDataReceivedEventHandler()); + httpRequest->SetDataSentEventHandler(request.GetDataSentEventHandler()); + httpRequest->SetContinueRequestHandle(request.GetContinueRequestHandler()); + + request.AddQueryStringParameters(httpRequest->GetUri()); +} + +void AWSClient::AddCommonHeaders(HttpRequest& httpRequest) const +{ + httpRequest.SetUserAgent(m_userAgent); +} + +Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, long long expirationInSeconds) +{ + std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + if (signer->PresignRequest(*request, expirationInSeconds)) + { + return request->GetURIString(); + } + return {}; -} - -Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds) -{ - std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); - for (const auto& it: customizedHeaders) - { - request->SetHeaderValue(it.first.c_str(), it.second); - } - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); - if (signer->PresignRequest(*request, expirationInSeconds)) - { - return request->GetURIString(); - } - +} + +Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds) +{ + std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); + for (const auto& it: customizedHeaders) + { + request->SetHeaderValue(it.first.c_str(), it.second); + } + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + if (signer->PresignRequest(*request, expirationInSeconds)) + { + return request->GetURIString(); + } + return {}; -} - +} + Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const char* region, long long expirationInSeconds) const { std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); @@ -766,165 +766,165 @@ Aws::String AWSClient::GeneratePresignedUrl(URI& uri, HttpMethod method, const c return {}; } -Aws::String AWSClient::GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds) const -{ - std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); - if (signer->PresignRequest(*request, region, serviceName, expirationInSeconds)) - { - return request->GetURIString(); - } - +Aws::String AWSClient::GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, long long expirationInSeconds) const +{ + std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + if (signer->PresignRequest(*request, region, serviceName, expirationInSeconds)) + { + return request->GetURIString(); + } + return {}; -} - +} + Aws::String AWSClient::GeneratePresignedUrl(Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, const Aws::Http::HeaderValueCollection& customizedHeaders, long long expirationInSeconds) -{ - std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); +{ + std::shared_ptr<HttpRequest> request = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); for (const auto& it: customizedHeaders) { request->SetHeaderValue(it.first.c_str(), it.second); } - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); if (signer->PresignRequest(*request, region, serviceName, expirationInSeconds)) - { - return request->GetURIString(); - } - + { + return request->GetURIString(); + } + return {}; -} - -Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, - const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const -{ - std::shared_ptr<HttpRequest> httpRequest = - ConvertToRequestForPresigning(request, uri, method, extraParams); - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); - if (signer->PresignRequest(*httpRequest, region, expirationInSeconds)) - { - return httpRequest->GetURIString(); - } - +} + +Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, + const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const +{ + std::shared_ptr<HttpRequest> httpRequest = + ConvertToRequestForPresigning(request, uri, method, extraParams); + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + if (signer->PresignRequest(*httpRequest, region, expirationInSeconds)) + { + return httpRequest->GetURIString(); + } + return {}; -} - -Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, -const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const -{ - std::shared_ptr<HttpRequest> httpRequest = - ConvertToRequestForPresigning(request, uri, method, extraParams); - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); - if (signer->PresignRequest(*httpRequest, region, serviceName, expirationInSeconds)) - { - return httpRequest->GetURIString(); - } - +} + +Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, const char* region, const char* serviceName, +const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const +{ + std::shared_ptr<HttpRequest> httpRequest = + ConvertToRequestForPresigning(request, uri, method, extraParams); + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + if (signer->PresignRequest(*httpRequest, region, serviceName, expirationInSeconds)) + { + return httpRequest->GetURIString(); + } + return {}; -} - -Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, - const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const -{ - std::shared_ptr<HttpRequest> httpRequest = - ConvertToRequestForPresigning(request, uri, method, extraParams); - auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); - if (signer->PresignRequest(*httpRequest, expirationInSeconds)) - { - return httpRequest->GetURIString(); - } - +} + +Aws::String AWSClient::GeneratePresignedUrl(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, Aws::Http::HttpMethod method, + const Aws::Http::QueryStringParameterCollection& extraParams, long long expirationInSeconds) const +{ + std::shared_ptr<HttpRequest> httpRequest = + ConvertToRequestForPresigning(request, uri, method, extraParams); + auto signer = GetSignerByName(Aws::Auth::SIGV4_SIGNER); + if (signer->PresignRequest(*httpRequest, expirationInSeconds)) + { + return httpRequest->GetURIString(); + } + return {}; -} - -std::shared_ptr<Aws::Http::HttpRequest> AWSClient::ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, - Aws::Http::HttpMethod method, const Aws::Http::QueryStringParameterCollection& extraParams) const -{ - request.PutToPresignedUrl(uri); - std::shared_ptr<HttpRequest> httpRequest = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); - - for (auto& param : extraParams) - { - httpRequest->AddQueryStringParameter(param.first.c_str(), param.second); - } - - return httpRequest; -} - +} + +std::shared_ptr<Aws::Http::HttpRequest> AWSClient::ConvertToRequestForPresigning(const Aws::AmazonWebServiceRequest& request, Aws::Http::URI& uri, + Aws::Http::HttpMethod method, const Aws::Http::QueryStringParameterCollection& extraParams) const +{ + request.PutToPresignedUrl(uri); + std::shared_ptr<HttpRequest> httpRequest = CreateHttpRequest(uri, method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod); + + for (auto& param : extraParams) + { + httpRequest->AddQueryStringParameter(param.first.c_str(), param.second); + } + + return httpRequest; +} + std::shared_ptr<Aws::Http::HttpResponse> AWSClient::MakeHttpRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const { return m_httpClient->MakeRequest(request, m_readRateLimiter.get(), m_writeRateLimiter.get()); } - - -//////////////////////////////////////////////////////////////////////////// -AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : - BASECLASS(configuration, signer, errorMarshaller) -{ -} - -AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : - BASECLASS(configuration, signerProvider, errorMarshaller) -{ -} - - -JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method, + + +//////////////////////////////////////////////////////////////////////////// +AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : + BASECLASS(configuration, signer, errorMarshaller) +{ +} + +AWSJsonClient::AWSJsonClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : + BASECLASS(configuration, signerProvider, errorMarshaller) +{ +} + + +JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method, const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride)); - if (!httpOutcome.IsSuccess()) - { + if (!httpOutcome.IsSuccess()) + { return JsonOutcome(std::move(httpOutcome)); - } - - if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) - //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint. - return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(httpOutcome.GetResult()->GetResponseBody()), - httpOutcome.GetResult()->GetHeaders(), - httpOutcome.GetResult()->GetResponseCode())); - - else - return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders())); -} - -JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri, - Http::HttpMethod method, - const char* signerName, + } + + if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) + //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint. + return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(httpOutcome.GetResult()->GetResponseBody()), + httpOutcome.GetResult()->GetHeaders(), + httpOutcome.GetResult()->GetResponseCode())); + + else + return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders())); +} + +JsonOutcome AWSJsonClient::MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method, + const char* signerName, const char* requestName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride)); - if (!httpOutcome.IsSuccess()) - { + if (!httpOutcome.IsSuccess()) + { return JsonOutcome(std::move(httpOutcome)); - } - - if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) - { - JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody()); - if (!jsonValue.WasParseSuccessful()) - { - return JsonOutcome(AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Json Parser Error", jsonValue.GetErrorMessage(), false)); - } - - //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint. - return JsonOutcome(AmazonWebServiceResult<JsonValue>(std::move(jsonValue), - httpOutcome.GetResult()->GetHeaders(), - httpOutcome.GetResult()->GetResponseCode())); - } - - return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders())); -} - + } + + if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) + { + JsonValue jsonValue(httpOutcome.GetResult()->GetResponseBody()); + if (!jsonValue.WasParseSuccessful()) + { + return JsonOutcome(AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Json Parser Error", jsonValue.GetErrorMessage(), false)); + } + + //this is stupid, but gcc doesn't pick up the covariant on the dereference so we have to give it a little hint. + return JsonOutcome(AmazonWebServiceResult<JsonValue>(std::move(jsonValue), + httpOutcome.GetResult()->GetHeaders(), + httpOutcome.GetResult()->GetResponseCode())); + } + + return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders())); +} + JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::HttpRequest>& request) const { // request is assumed to be signed @@ -958,141 +958,141 @@ JsonOutcome AWSJsonClient::MakeEventStreamRequest(std::shared_ptr<Aws::Http::Htt return JsonOutcome(AmazonWebServiceResult<JsonValue>(JsonValue(), httpOutcome.GetResult()->GetHeaders())); } -AWSError<CoreErrors> AWSJsonClient::BuildAWSError( - const std::shared_ptr<Aws::Http::HttpResponse>& httpResponse) const -{ - AWSError<CoreErrors> error; +AWSError<CoreErrors> AWSJsonClient::BuildAWSError( + const std::shared_ptr<Aws::Http::HttpResponse>& httpResponse) const +{ + AWSError<CoreErrors> error; if (httpResponse->HasClientError()) - { + { bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false; error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable); - } - else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1) - { - auto responseCode = httpResponse->GetResponseCode(); - auto errorCode = GuessBodylessErrorType(responseCode); - - Aws::StringStream ss; - ss << "No response body."; - error = AWSError<CoreErrors>(errorCode, "", ss.str(), - IsRetryableHttpResponseCode(responseCode)); - } - else - { - assert(httpResponse->GetResponseCode() != HttpResponseCode::OK); - error = GetErrorMarshaller()->Marshall(*httpResponse); - } - - error.SetResponseHeaders(httpResponse->GetHeaders()); - error.SetResponseCode(httpResponse->GetResponseCode()); + } + else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1) + { + auto responseCode = httpResponse->GetResponseCode(); + auto errorCode = GuessBodylessErrorType(responseCode); + + Aws::StringStream ss; + ss << "No response body."; + error = AWSError<CoreErrors>(errorCode, "", ss.str(), + IsRetryableHttpResponseCode(responseCode)); + } + else + { + assert(httpResponse->GetResponseCode() != HttpResponseCode::OK); + error = GetErrorMarshaller()->Marshall(*httpResponse); + } + + error.SetResponseHeaders(httpResponse->GetHeaders()); + error.SetResponseCode(httpResponse->GetResponseCode()); error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost()); - AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error); - return error; -} - -///////////////////////////////////////////////////////////////////////////////////////// -AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : - BASECLASS(configuration, signer, errorMarshaller) -{ -} - -AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, - const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, - const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : - BASECLASS(configuration, signerProvider, errorMarshaller) -{ -} - -XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri, - const Aws::AmazonWebServiceRequest& request, - Http::HttpMethod method, + AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error); + return error; +} + +///////////////////////////////////////////////////////////////////////////////////////// +AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Client::AWSAuthSigner>& signer, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : + BASECLASS(configuration, signer, errorMarshaller) +{ +} + +AWSXMLClient::AWSXMLClient(const Aws::Client::ClientConfiguration& configuration, + const std::shared_ptr<Aws::Auth::AWSAuthSignerProvider>& signerProvider, + const std::shared_ptr<AWSErrorMarshaller>& errorMarshaller) : + BASECLASS(configuration, signerProvider, errorMarshaller) +{ +} + +XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri, + const Aws::AmazonWebServiceRequest& request, + Http::HttpMethod method, const char* signerName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride)); - if (!httpOutcome.IsSuccess()) - { + if (!httpOutcome.IsSuccess()) + { return XmlOutcome(std::move(httpOutcome)); - } - - if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) - { - XmlDocument xmlDoc = XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()); - - if (!xmlDoc.WasParseSuccessful()) - { - AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Xml parsing for error failed with message " << xmlDoc.GetErrorMessage().c_str()); - return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Xml Parse Error", xmlDoc.GetErrorMessage(), false); - } - - return XmlOutcome(AmazonWebServiceResult<XmlDocument>(std::move(xmlDoc), - httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode())); - } - - return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders())); -} - -XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri, - Http::HttpMethod method, - const char* signerName, + } + + if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) + { + XmlDocument xmlDoc = XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()); + + if (!xmlDoc.WasParseSuccessful()) + { + AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, "Xml parsing for error failed with message " << xmlDoc.GetErrorMessage().c_str()); + return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "Xml Parse Error", xmlDoc.GetErrorMessage(), false); + } + + return XmlOutcome(AmazonWebServiceResult<XmlDocument>(std::move(xmlDoc), + httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode())); + } + + return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders())); +} + +XmlOutcome AWSXMLClient::MakeRequest(const Aws::Http::URI& uri, + Http::HttpMethod method, + const char* signerName, const char* requestName, const char* signerRegionOverride, const char* signerServiceNameOverride) const -{ +{ HttpResponseOutcome httpOutcome(BASECLASS::AttemptExhaustively(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride)); - if (!httpOutcome.IsSuccess()) - { + if (!httpOutcome.IsSuccess()) + { return XmlOutcome(std::move(httpOutcome)); - } - - if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) - { - return XmlOutcome(AmazonWebServiceResult<XmlDocument>( - XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()), - httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode())); - } - - return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders())); -} - -AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::HttpResponse>& httpResponse) const -{ - AWSError<CoreErrors> error; + } + + if (httpOutcome.GetResult()->GetResponseBody().tellp() > 0) + { + return XmlOutcome(AmazonWebServiceResult<XmlDocument>( + XmlDocument::CreateFromXmlStream(httpOutcome.GetResult()->GetResponseBody()), + httpOutcome.GetResult()->GetHeaders(), httpOutcome.GetResult()->GetResponseCode())); + } + + return XmlOutcome(AmazonWebServiceResult<XmlDocument>(XmlDocument(), httpOutcome.GetResult()->GetHeaders())); +} + +AWSError<CoreErrors> AWSXMLClient::BuildAWSError(const std::shared_ptr<Http::HttpResponse>& httpResponse) const +{ + AWSError<CoreErrors> error; if (httpResponse->HasClientError()) - { + { bool retryable = httpResponse->GetClientErrorType() == CoreErrors::NETWORK_CONNECTION ? true : false; error = AWSError<CoreErrors>(httpResponse->GetClientErrorType(), "", httpResponse->GetClientErrorMessage(), retryable); - } + } else if (!httpResponse->GetResponseBody() || httpResponse->GetResponseBody().tellp() < 1) - { - auto responseCode = httpResponse->GetResponseCode(); - auto errorCode = GuessBodylessErrorType(responseCode); - - Aws::StringStream ss; - ss << "No response body."; - error = AWSError<CoreErrors>(errorCode, "", ss.str(), IsRetryableHttpResponseCode(responseCode)); - } - else - { - assert(httpResponse->GetResponseCode() != HttpResponseCode::OK); - - // When trying to build an AWS Error from a response which is an FStream, we need to rewind the - // file pointer back to the beginning in order to correctly read the input using the XML string iterator - if ((httpResponse->GetResponseBody().tellp() > 0) - && (httpResponse->GetResponseBody().tellg() > 0)) - { - httpResponse->GetResponseBody().seekg(0); - } - - error = GetErrorMarshaller()->Marshall(*httpResponse); - } - - error.SetResponseHeaders(httpResponse->GetHeaders()); - error.SetResponseCode(httpResponse->GetResponseCode()); + { + auto responseCode = httpResponse->GetResponseCode(); + auto errorCode = GuessBodylessErrorType(responseCode); + + Aws::StringStream ss; + ss << "No response body."; + error = AWSError<CoreErrors>(errorCode, "", ss.str(), IsRetryableHttpResponseCode(responseCode)); + } + else + { + assert(httpResponse->GetResponseCode() != HttpResponseCode::OK); + + // When trying to build an AWS Error from a response which is an FStream, we need to rewind the + // file pointer back to the beginning in order to correctly read the input using the XML string iterator + if ((httpResponse->GetResponseBody().tellp() > 0) + && (httpResponse->GetResponseBody().tellg() > 0)) + { + httpResponse->GetResponseBody().seekg(0); + } + + error = GetErrorMarshaller()->Marshall(*httpResponse); + } + + error.SetResponseHeaders(httpResponse->GetHeaders()); + error.SetResponseCode(httpResponse->GetResponseCode()); error.SetRemoteHostIpAddress(httpResponse->GetOriginatingRequest().GetResolvedRemoteHost()); - AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error); - return error; -} + AWS_LOGSTREAM_ERROR(AWS_CLIENT_LOG_TAG, error); + return error; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp index f5fa676f98..061b3d9deb 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AWSErrorMarshaller.cpp @@ -2,41 +2,41 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/client/AWSErrorMarshaller.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/json/JsonSerializer.h> -#include <aws/core/utils/xml/XmlSerializer.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/client/AWSError.h> -#include <aws/core/client/CoreErrors.h> - -using namespace Aws::Utils::Logging; -using namespace Aws::Utils::Json; -using namespace Aws::Utils::Xml; -using namespace Aws::Http; -using namespace Aws::Utils; -using namespace Aws::Client; - + +#include <aws/core/client/AWSErrorMarshaller.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <aws/core/utils/xml/XmlSerializer.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/client/CoreErrors.h> + +using namespace Aws::Utils::Logging; +using namespace Aws::Utils::Json; +using namespace Aws::Utils::Xml; +using namespace Aws::Http; +using namespace Aws::Utils; +using namespace Aws::Client; + static const char AWS_ERROR_MARSHALLER_LOG_TAG[] = "AWSErrorMarshaller"; AWS_CORE_API extern const char MESSAGE_LOWER_CASE[] = "message"; AWS_CORE_API extern const char MESSAGE_CAMEL_CASE[] = "Message"; AWS_CORE_API extern const char ERROR_TYPE_HEADER[] = "x-amzn-ErrorType"; AWS_CORE_API extern const char REQUEST_ID_HEADER[] = "x-amzn-RequestId"; AWS_CORE_API extern const char TYPE[] = "__type"; - -AWSError<CoreErrors> JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const -{ - JsonValue exceptionPayload(httpResponse.GetResponseBody()); - JsonView payloadView(exceptionPayload); + +AWSError<CoreErrors> JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const +{ + JsonValue exceptionPayload(httpResponse.GetResponseBody()); + JsonView payloadView(exceptionPayload); AWSError<CoreErrors> error; if (exceptionPayload.WasParseSuccessful()) - { + { AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << payloadView.WriteReadable()); - + Aws::String message(payloadView.ValueExists(MESSAGE_CAMEL_CASE) ? payloadView.GetString(MESSAGE_CAMEL_CASE) : payloadView.ValueExists(MESSAGE_LOWER_CASE) ? payloadView.GetString(MESSAGE_LOWER_CASE) : ""); - + if (httpResponse.HasHeader(ERROR_TYPE_HEADER)) { error = Marshall(httpResponse.GetHeader(ERROR_TYPE_HEADER), message); @@ -50,131 +50,131 @@ AWSError<CoreErrors> JsonErrorMarshaller::Marshall(const Aws::Http::HttpResponse error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode()); error.SetMessage(message); } - } - else - { + } + else + { error = AWSError<CoreErrors>(CoreErrors::UNKNOWN, "", "Failed to parse error payload", false); - } + } error.SetRequestId(httpResponse.HasHeader(REQUEST_ID_HEADER) ? httpResponse.GetHeader(REQUEST_ID_HEADER) : ""); error.SetJsonPayload(std::move(exceptionPayload)); return error; -} - +} + const JsonValue& JsonErrorMarshaller::GetJsonPayloadFromError(const AWSError<CoreErrors>& error) const { return error.GetJsonPayload(); } -AWSError<CoreErrors> XmlErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const -{ - XmlDocument doc = XmlDocument::CreateFromXmlStream(httpResponse.GetResponseBody()); - AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << doc.ConvertToString()); - bool errorParsed = false; - AWSError<CoreErrors> error; +AWSError<CoreErrors> XmlErrorMarshaller::Marshall(const Aws::Http::HttpResponse& httpResponse) const +{ + XmlDocument doc = XmlDocument::CreateFromXmlStream(httpResponse.GetResponseBody()); + AWS_LOGSTREAM_TRACE(AWS_ERROR_MARSHALLER_LOG_TAG, "Error response is " << doc.ConvertToString()); + bool errorParsed = false; + AWSError<CoreErrors> error; if (doc.WasParseSuccessful() && !doc.GetRootElement().IsNull()) - { - XmlNode errorNode = doc.GetRootElement(); + { + XmlNode errorNode = doc.GetRootElement(); Aws::String requestId(!errorNode.FirstChild("RequestId").IsNull() ? errorNode.FirstChild("RequestId").GetText() : !errorNode.FirstChild("RequestID").IsNull() ? errorNode.FirstChild("RequestID").GetText() : ""); - if (errorNode.GetName() != "Error") - { - errorNode = doc.GetRootElement().FirstChild("Error"); - } - if (errorNode.IsNull()) - { - errorNode = doc.GetRootElement().FirstChild("Errors"); - if(!errorNode.IsNull()) - { - errorNode = errorNode.FirstChild("Error"); - } - } - - if (!errorNode.IsNull()) - { + if (errorNode.GetName() != "Error") + { + errorNode = doc.GetRootElement().FirstChild("Error"); + } + if (errorNode.IsNull()) + { + errorNode = doc.GetRootElement().FirstChild("Errors"); + if(!errorNode.IsNull()) + { + errorNode = errorNode.FirstChild("Error"); + } + } + + if (!errorNode.IsNull()) + { requestId = !requestId.empty() ? requestId : !errorNode.FirstChild("RequestId").IsNull() ? errorNode.FirstChild("RequestId").GetText() : !errorNode.FirstChild("RequestID").IsNull() ? errorNode.FirstChild("RequestID").GetText() : ""; - XmlNode codeNode = errorNode.FirstChild("Code"); - XmlNode messageNode = errorNode.FirstChild("Message"); - - if (!codeNode.IsNull()) - { - error = Marshall(StringUtils::Trim(codeNode.GetText().c_str()), - StringUtils::Trim(messageNode.GetText().c_str())); - errorParsed = true; - } - } + XmlNode codeNode = errorNode.FirstChild("Code"); + XmlNode messageNode = errorNode.FirstChild("Message"); + + if (!codeNode.IsNull()) + { + error = Marshall(StringUtils::Trim(codeNode.GetText().c_str()), + StringUtils::Trim(messageNode.GetText().c_str())); + errorParsed = true; + } + } error.SetRequestId(requestId); - } - - if(!errorParsed) - { - // An error occurred attempting to parse the httpResponse as an XML stream, so we're just - // going to dump the XML parsing error and the http response code as a string - AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Unable to generate a proper httpResponse from the response " - "stream. Response code: " << static_cast< uint32_t >(httpResponse.GetResponseCode())); - error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode()); - } - + } + + if(!errorParsed) + { + // An error occurred attempting to parse the httpResponse as an XML stream, so we're just + // going to dump the XML parsing error and the http response code as a string + AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Unable to generate a proper httpResponse from the response " + "stream. Response code: " << static_cast< uint32_t >(httpResponse.GetResponseCode())); + error = FindErrorByHttpResponseCode(httpResponse.GetResponseCode()); + } + error.SetXmlPayload(std::move(doc)); - return error; -} - + return error; +} + const XmlDocument& XmlErrorMarshaller::GetXmlPayloadFromError(const AWSError<CoreErrors>& error) const { return error.GetXmlPayload(); } -AWSError<CoreErrors> AWSErrorMarshaller::Marshall(const Aws::String& exceptionName, const Aws::String& message) const -{ - if(exceptionName.empty()) - { - return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "", message, false); - } - - auto locationOfPound = exceptionName.find_first_of('#'); - auto locationOfColon = exceptionName.find_first_of(':'); - Aws::String formalExceptionName; - - if (locationOfPound != Aws::String::npos) - { +AWSError<CoreErrors> AWSErrorMarshaller::Marshall(const Aws::String& exceptionName, const Aws::String& message) const +{ + if(exceptionName.empty()) + { + return AWSError<CoreErrors>(CoreErrors::UNKNOWN, "", message, false); + } + + auto locationOfPound = exceptionName.find_first_of('#'); + auto locationOfColon = exceptionName.find_first_of(':'); + Aws::String formalExceptionName; + + if (locationOfPound != Aws::String::npos) + { formalExceptionName = exceptionName.substr(locationOfPound + 1); - } - else if (locationOfColon != Aws::String::npos) - { + } + else if (locationOfColon != Aws::String::npos) + { formalExceptionName = exceptionName.substr(0, locationOfColon); + } + else + { + formalExceptionName = exceptionName; + } + + AWSError<CoreErrors> error = FindErrorByName(formalExceptionName.c_str()); + if (error.GetErrorType() != CoreErrors::UNKNOWN) + { + AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Encountered AWSError '" << formalExceptionName.c_str() << + "': " << message.c_str()); + error.SetExceptionName(formalExceptionName); + error.SetMessage(message); + return error; } - else - { - formalExceptionName = exceptionName; - } - - AWSError<CoreErrors> error = FindErrorByName(formalExceptionName.c_str()); - if (error.GetErrorType() != CoreErrors::UNKNOWN) - { - AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Encountered AWSError '" << formalExceptionName.c_str() << - "': " << message.c_str()); - error.SetExceptionName(formalExceptionName); - error.SetMessage(message); - return error; - } - - AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Encountered Unknown AWSError '" << exceptionName.c_str() << - "': " << message.c_str()); - - return AWSError<CoreErrors>(CoreErrors::UNKNOWN, exceptionName, "Unable to parse ExceptionName: " + exceptionName + " Message: " + message, false); -} - -AWSError<CoreErrors> AWSErrorMarshaller::FindErrorByName(const char* errorName) const -{ - return CoreErrorsMapper::GetErrorForName(errorName); -} - -AWSError<CoreErrors> AWSErrorMarshaller::FindErrorByHttpResponseCode(Aws::Http::HttpResponseCode code) const -{ - return CoreErrorsMapper::GetErrorForHttpResponseCode(code); -} + + AWS_LOGSTREAM_WARN(AWS_ERROR_MARSHALLER_LOG_TAG, "Encountered Unknown AWSError '" << exceptionName.c_str() << + "': " << message.c_str()); + + return AWSError<CoreErrors>(CoreErrors::UNKNOWN, exceptionName, "Unable to parse ExceptionName: " + exceptionName + " Message: " + message, false); +} + +AWSError<CoreErrors> AWSErrorMarshaller::FindErrorByName(const char* errorName) const +{ + return CoreErrorsMapper::GetErrorForName(errorName); +} + +AWSError<CoreErrors> AWSErrorMarshaller::FindErrorByHttpResponseCode(Aws::Http::HttpResponseCode code) const +{ + return CoreErrorsMapper::GetErrorForHttpResponseCode(code); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp index 4f9abdc9e4..5e0e12c8e0 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/AsyncCallerContext.cpp @@ -2,15 +2,15 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/client/AsyncCallerContext.h> -#include <aws/core/utils/UUID.h> - -namespace Aws -{ - namespace Client - { - AsyncCallerContext::AsyncCallerContext() : m_uuid(Aws::Utils::UUID::RandomUUID()) - {} - } -}
\ No newline at end of file + +#include <aws/core/client/AsyncCallerContext.h> +#include <aws/core/utils/UUID.h> + +namespace Aws +{ + namespace Client + { + AsyncCallerContext::AsyncCallerContext() : m_uuid(Aws::Utils::UUID::RandomUUID()) + {} + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp index e517379a77..69e1742988 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp @@ -2,63 +2,63 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/client/ClientConfiguration.h> + +#include <aws/core/client/ClientConfiguration.h> #include <aws/core/auth/AWSCredentialsProvider.h> -#include <aws/core/client/DefaultRetryStrategy.h> +#include <aws/core/client/DefaultRetryStrategy.h> #include <aws/core/platform/Environment.h> -#include <aws/core/platform/OSVersionInfo.h> -#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/platform/OSVersionInfo.h> +#include <aws/core/utils/memory/AWSMemory.h> #include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/threading/Executor.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/Version.h> +#include <aws/core/utils/threading/Executor.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/Version.h> #include <aws/core/config/AWSProfileConfigLoader.h> #include <aws/core/utils/logging/LogMacros.h> - -namespace Aws -{ + +namespace Aws +{ namespace Auth { AWS_CORE_API Aws::String GetConfigProfileFilename(); } -namespace Client -{ - +namespace Client +{ + static const char* CLIENT_CONFIG_TAG = "ClientConfiguration"; - + AWS_CORE_API Aws::String ComputeUserAgentString() -{ - Aws::StringStream ss; - ss << "aws-sdk-cpp/" << Version::GetVersionString() << " " << Aws::OSVersionInfo::ComputeOSVersionString() - << " " << Version::GetCompilerVersionString(); - return ss.str(); -} - +{ + Aws::StringStream ss; + ss << "aws-sdk-cpp/" << Version::GetVersionString() << " " << Aws::OSVersionInfo::ComputeOSVersionString() + << " " << Version::GetCompilerVersionString(); + return ss.str(); +} + ClientConfiguration::ClientConfiguration() : scheme(Aws::Http::Scheme::HTTPS), - useDualStack(false), + useDualStack(false), maxConnections(25), httpRequestTimeoutMs(0), requestTimeoutMs(3000), - connectTimeoutMs(1000), + connectTimeoutMs(1000), enableTcpKeepAlive(true), tcpKeepAliveIntervalMs(30000), lowSpeedLimit(1), - proxyScheme(Aws::Http::Scheme::HTTP), - proxyPort(0), + proxyScheme(Aws::Http::Scheme::HTTP), + proxyPort(0), executor(Aws::MakeShared<Aws::Utils::Threading::DefaultExecutor>(CLIENT_CONFIG_TAG)), - verifySSL(true), - writeRateLimiter(nullptr), - readRateLimiter(nullptr), - httpLibOverride(Aws::Http::TransferLibType::DEFAULT_CLIENT), + verifySSL(true), + writeRateLimiter(nullptr), + readRateLimiter(nullptr), + httpLibOverride(Aws::Http::TransferLibType::DEFAULT_CLIENT), followRedirects(FollowRedirectsPolicy::DEFAULT), - disableExpectHeader(false), + disableExpectHeader(false), enableClockSkewAdjustment(true), enableHostPrefixInjection(true), enableEndpointDiscovery(false), profileName(Aws::Auth::GetConfigProfileName()) -{ +{ AWS_LOGSTREAM_DEBUG(CLIENT_CONFIG_TAG, "ClientConfiguration will use SDK Auto Resolved profile: [" << profileName << "] if not specified by users."); // Initialize Retry Strategy @@ -138,8 +138,8 @@ ClientConfiguration::ClientConfiguration() : } region = Aws::String(Aws::Region::US_EAST_1); -} - +} + ClientConfiguration::ClientConfiguration(const char* profile) : ClientConfiguration() { if (profile && Aws::Config::HasCachedConfigProfile(profile)) @@ -156,5 +156,5 @@ ClientConfiguration::ClientConfiguration(const char* profile) : ClientConfigurat AWS_LOGSTREAM_WARN(CLIENT_CONFIG_TAG, "User specified profile: [" << profile << "] is not found, will use the SDK resolved one."); } -} // namespace Client -} // namespace Aws +} // namespace Client +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp index 8c2c288dcd..f9e1357c86 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/CoreErrors.cpp @@ -2,22 +2,22 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/client/AWSError.h> -#include <aws/core/client/CoreErrors.h> + +#include <aws/core/client/AWSError.h> +#include <aws/core/client/CoreErrors.h> #include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/HashingUtils.h> - -using namespace Aws::Client; -using namespace Aws::Utils; -using namespace Aws::Http; - +#include <aws/core/utils/HashingUtils.h> + +using namespace Aws::Client; +using namespace Aws::Utils; +using namespace Aws::Http; + #ifdef _MSC_VER #pragma warning(push) // VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation) #pragma warning(disable : 4592) #endif - + static Aws::UniquePtr<Aws::Map<Aws::String, AWSError<CoreErrors> > > s_CoreErrorsMapper(nullptr); #ifdef _MSC_VER @@ -25,7 +25,7 @@ static Aws::UniquePtr<Aws::Map<Aws::String, AWSError<CoreErrors> > > s_CoreError #endif void CoreErrorsMapper::InitCoreErrorsMapper() -{ +{ if (s_CoreErrorsMapper) { return; @@ -89,7 +89,7 @@ void CoreErrorsMapper::InitCoreErrorsMapper() s_CoreErrorsMapper->emplace("RequestTimeoutException", AWSError<CoreErrors>(CoreErrors::REQUEST_TIMEOUT, true)); s_CoreErrorsMapper->emplace("RequestTimeout", AWSError<CoreErrors>(CoreErrors::REQUEST_TIMEOUT, true)); } - + void CoreErrorsMapper::CleanupCoreErrorsMapper() { if (s_CoreErrorsMapper) @@ -97,7 +97,7 @@ void CoreErrorsMapper::CleanupCoreErrorsMapper() s_CoreErrorsMapper = nullptr; } } - + AWSError<CoreErrors> CoreErrorsMapper::GetErrorForName(const char* errorName) { auto iter = s_CoreErrorsMapper->find(errorName); @@ -106,46 +106,46 @@ AWSError<CoreErrors> CoreErrorsMapper::GetErrorForName(const char* errorName) return iter->second; } return AWSError<CoreErrors>(CoreErrors::UNKNOWN, false); -} - -AWS_CORE_API AWSError<CoreErrors> CoreErrorsMapper::GetErrorForHttpResponseCode(HttpResponseCode code) -{ - // best effort attempt to map HTTP response codes to CoreErrors - bool retryable = IsRetryableHttpResponseCode(code); +} + +AWS_CORE_API AWSError<CoreErrors> CoreErrorsMapper::GetErrorForHttpResponseCode(HttpResponseCode code) +{ + // best effort attempt to map HTTP response codes to CoreErrors + bool retryable = IsRetryableHttpResponseCode(code); AWSError<CoreErrors> error; switch (code) - { - case HttpResponseCode::UNAUTHORIZED: - case HttpResponseCode::FORBIDDEN: + { + case HttpResponseCode::UNAUTHORIZED: + case HttpResponseCode::FORBIDDEN: error = AWSError<CoreErrors>(CoreErrors::ACCESS_DENIED, retryable); break; - case HttpResponseCode::NOT_FOUND: + case HttpResponseCode::NOT_FOUND: error = AWSError<CoreErrors>(CoreErrors::RESOURCE_NOT_FOUND, retryable); break; - case HttpResponseCode::TOO_MANY_REQUESTS: + case HttpResponseCode::TOO_MANY_REQUESTS: error = AWSError<CoreErrors>(CoreErrors::SLOW_DOWN, retryable); break; - case HttpResponseCode::INTERNAL_SERVER_ERROR: + case HttpResponseCode::INTERNAL_SERVER_ERROR: error = AWSError<CoreErrors>(CoreErrors::INTERNAL_FAILURE, retryable); break; - case HttpResponseCode::BANDWIDTH_LIMIT_EXCEEDED: + case HttpResponseCode::BANDWIDTH_LIMIT_EXCEEDED: error = AWSError<CoreErrors>(CoreErrors::THROTTLING, retryable); break; - case HttpResponseCode::SERVICE_UNAVAILABLE: + case HttpResponseCode::SERVICE_UNAVAILABLE: error = AWSError<CoreErrors>(CoreErrors::SERVICE_UNAVAILABLE, retryable); break; - case HttpResponseCode::REQUEST_TIMEOUT: - case HttpResponseCode::AUTHENTICATION_TIMEOUT: - case HttpResponseCode::LOGIN_TIMEOUT: - case HttpResponseCode::GATEWAY_TIMEOUT: - case HttpResponseCode::NETWORK_READ_TIMEOUT: - case HttpResponseCode::NETWORK_CONNECT_TIMEOUT: + case HttpResponseCode::REQUEST_TIMEOUT: + case HttpResponseCode::AUTHENTICATION_TIMEOUT: + case HttpResponseCode::LOGIN_TIMEOUT: + case HttpResponseCode::GATEWAY_TIMEOUT: + case HttpResponseCode::NETWORK_READ_TIMEOUT: + case HttpResponseCode::NETWORK_CONNECT_TIMEOUT: error = AWSError<CoreErrors>(CoreErrors::REQUEST_TIMEOUT, retryable); break; - default: - int codeValue = static_cast<int>(code); + default: + int codeValue = static_cast<int>(code); error = AWSError<CoreErrors>(CoreErrors::UNKNOWN, codeValue >= 500 && codeValue < 600); - } + } error.SetResponseCode(code); return error; -} +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp index 7e57c79ffc..ad5c3d613f 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/client/DefaultRetryStrategy.cpp @@ -2,31 +2,31 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/client/DefaultRetryStrategy.h> - -#include <aws/core/client/AWSError.h> -#include <aws/core/utils/UnreferencedParam.h> - -using namespace Aws; -using namespace Aws::Client; - -bool DefaultRetryStrategy::ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const -{ - if (attemptedRetries >= m_maxRetries) - return false; - - return error.ShouldRetry(); -} - -long DefaultRetryStrategy::CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const -{ - AWS_UNREFERENCED_PARAM(error); - - if (attemptedRetries == 0) - { - return 0; - } - - return (1 << attemptedRetries) * m_scaleFactor; -} + +#include <aws/core/client/DefaultRetryStrategy.h> + +#include <aws/core/client/AWSError.h> +#include <aws/core/utils/UnreferencedParam.h> + +using namespace Aws; +using namespace Aws::Client; + +bool DefaultRetryStrategy::ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const +{ + if (attemptedRetries >= m_maxRetries) + return false; + + return error.ShouldRetry(); +} + +long DefaultRetryStrategy::CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const +{ + AWS_UNREFERENCED_PARAM(error); + + if (attemptedRetries == 0) + { + return 0; + } + + return (1 << attemptedRetries) * m_scaleFactor; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp index 9ec2e54f55..7d62866a63 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp @@ -2,25 +2,25 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/config/AWSProfileConfigLoader.h> -#include <aws/core/internal/AWSHttpResourceClient.h> + +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/internal/AWSHttpResourceClient.h> #include <aws/core/auth/AWSCredentialsProvider.h> -#include <aws/core/utils/memory/stl/AWSList.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/json/JsonSerializer.h> -#include <fstream> - -namespace Aws -{ - namespace Config - { - using namespace Aws::Utils; - using namespace Aws::Auth; - - static const char* const CONFIG_LOADER_TAG = "Aws::Config::AWSProfileConfigLoader"; +#include <aws/core/utils/memory/stl/AWSList.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <fstream> + +namespace Aws +{ + namespace Config + { + using namespace Aws::Utils; + using namespace Aws::Auth; + + static const char* const CONFIG_LOADER_TAG = "Aws::Config::AWSProfileConfigLoader"; #ifdef _MSC_VER // VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation) AWS_SUPPRESS_WARNING(4592, @@ -29,40 +29,40 @@ namespace Aws #else static Aws::UniquePtr<ConfigAndCredentialsCacheManager> s_configManager(nullptr); #endif - + static const char CONFIG_CREDENTIALS_CACHE_MANAGER_TAG[] = "ConfigAndCredentialsCacheManager"; - bool AWSProfileConfigLoader::Load() - { - if(LoadInternal()) - { - AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully reloaded configuration."); - m_lastLoadTime = DateTime::Now(); + bool AWSProfileConfigLoader::Load() + { + if(LoadInternal()) + { + AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully reloaded configuration."); + m_lastLoadTime = DateTime::Now(); AWS_LOGSTREAM_TRACE(CONFIG_LOADER_TAG, "reloaded config at " - << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); - return true; - } - - AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Failed to reload configuration."); - return false; - } - - bool AWSProfileConfigLoader::PersistProfiles(const Aws::Map<Aws::String, Profile>& profiles) - { - if(PersistInternal(profiles)) - { - AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully persisted configuration."); - m_profiles = profiles; - m_lastLoadTime = DateTime::Now(); + << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); + return true; + } + + AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Failed to reload configuration."); + return false; + } + + bool AWSProfileConfigLoader::PersistProfiles(const Aws::Map<Aws::String, Profile>& profiles) + { + if(PersistInternal(profiles)) + { + AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully persisted configuration."); + m_profiles = profiles; + m_lastLoadTime = DateTime::Now(); AWS_LOGSTREAM_TRACE(CONFIG_LOADER_TAG, "persisted config at " - << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); - return true; - } - - AWS_LOGSTREAM_WARN(CONFIG_LOADER_TAG, "Failed to persist configuration."); - return false; - } - + << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601)); + return true; + } + + AWS_LOGSTREAM_WARN(CONFIG_LOADER_TAG, "Failed to persist configuration."); + return false; + } + static const char REGION_KEY[] = "region"; static const char ACCESS_KEY_ID_KEY[] = "aws_access_key_id"; static const char SECRET_KEY_KEY[] = "aws_secret_access_key"; @@ -76,134 +76,134 @@ namespace Aws static const char LEFT_BRACKET = '['; static const char RIGHT_BRACKET = ']'; static const char PARSER_TAG[] = "Aws::Config::ConfigFileProfileFSM"; - - class ConfigFileProfileFSM - { - public: - ConfigFileProfileFSM() : m_parserState(START) {} - - const Aws::Map<String, Profile>& GetProfiles() const { return m_foundProfiles; } - - void ParseStream(Aws::IStream& stream) - { - static const size_t ASSUME_EMPTY_LEN = 3; - - Aws::String line; - while(std::getline(stream, line) && m_parserState != FAILURE) - { - if (line.empty() || line.length() < ASSUME_EMPTY_LEN) - { - continue; - } - - auto openPos = line.find(LEFT_BRACKET); - auto closePos = line.find(RIGHT_BRACKET); - - switch(m_parserState) - { - - case START: - if(openPos != std::string::npos && closePos != std::string::npos) - { - FlushProfileAndReset(line, openPos, closePos); - m_parserState = PROFILE_FOUND; - } - break; - - //fallthrough here is intentional to reduce duplicate logic - case PROFILE_KEY_VALUE_FOUND: - if(openPos != std::string::npos && closePos != std::string::npos) - { - m_parserState = PROFILE_FOUND; - FlushProfileAndReset(line, openPos, closePos); - break; - } - // fall through - case PROFILE_FOUND: - { - auto equalsPos = line.find(EQ); - if (equalsPos != std::string::npos) - { - auto key = line.substr(0, equalsPos); - auto value = line.substr(equalsPos + 1); - m_profileKeyValuePairs[StringUtils::Trim(key.c_str())] = - StringUtils::Trim(value.c_str()); - m_parserState = PROFILE_KEY_VALUE_FOUND; - } - - break; - } - default: - m_parserState = FAILURE; - break; - } - } - + + class ConfigFileProfileFSM + { + public: + ConfigFileProfileFSM() : m_parserState(START) {} + + const Aws::Map<String, Profile>& GetProfiles() const { return m_foundProfiles; } + + void ParseStream(Aws::IStream& stream) + { + static const size_t ASSUME_EMPTY_LEN = 3; + + Aws::String line; + while(std::getline(stream, line) && m_parserState != FAILURE) + { + if (line.empty() || line.length() < ASSUME_EMPTY_LEN) + { + continue; + } + + auto openPos = line.find(LEFT_BRACKET); + auto closePos = line.find(RIGHT_BRACKET); + + switch(m_parserState) + { + + case START: + if(openPos != std::string::npos && closePos != std::string::npos) + { + FlushProfileAndReset(line, openPos, closePos); + m_parserState = PROFILE_FOUND; + } + break; + + //fallthrough here is intentional to reduce duplicate logic + case PROFILE_KEY_VALUE_FOUND: + if(openPos != std::string::npos && closePos != std::string::npos) + { + m_parserState = PROFILE_FOUND; + FlushProfileAndReset(line, openPos, closePos); + break; + } + // fall through + case PROFILE_FOUND: + { + auto equalsPos = line.find(EQ); + if (equalsPos != std::string::npos) + { + auto key = line.substr(0, equalsPos); + auto value = line.substr(equalsPos + 1); + m_profileKeyValuePairs[StringUtils::Trim(key.c_str())] = + StringUtils::Trim(value.c_str()); + m_parserState = PROFILE_KEY_VALUE_FOUND; + } + + break; + } + default: + m_parserState = FAILURE; + break; + } + } + FlushProfileAndReset(line, std::string::npos, std::string::npos); - } - - private: - - void FlushProfileAndReset(Aws::String& line, size_t openPos, size_t closePos) - { - if(!m_currentWorkingProfile.empty() && !m_profileKeyValuePairs.empty()) - { - Profile profile; - profile.SetName(m_currentWorkingProfile); - - auto regionIter = m_profileKeyValuePairs.find(REGION_KEY); - if (regionIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found region " << regionIter->second); - profile.SetRegion(regionIter->second); - } - - auto accessKeyIdIter = m_profileKeyValuePairs.find(ACCESS_KEY_ID_KEY); - Aws::String accessKey, secretKey, sessionToken; - if (accessKeyIdIter != m_profileKeyValuePairs.end()) - { - accessKey = accessKeyIdIter->second; - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found access key " << accessKey); - - auto secretAccessKeyIter = m_profileKeyValuePairs.find(SECRET_KEY_KEY); - auto sessionTokenIter = m_profileKeyValuePairs.find(SESSION_TOKEN_KEY); - if (secretAccessKeyIter != m_profileKeyValuePairs.end()) - { - secretKey = secretAccessKeyIter->second; - } - else - { - AWS_LOGSTREAM_ERROR(PARSER_TAG, "No secret access key found even though an access key was specified. This will cause all signed AWS calls to fail."); - } - - if (sessionTokenIter != m_profileKeyValuePairs.end()) - { - sessionToken = sessionTokenIter->second; + } + + private: + + void FlushProfileAndReset(Aws::String& line, size_t openPos, size_t closePos) + { + if(!m_currentWorkingProfile.empty() && !m_profileKeyValuePairs.empty()) + { + Profile profile; + profile.SetName(m_currentWorkingProfile); + + auto regionIter = m_profileKeyValuePairs.find(REGION_KEY); + if (regionIter != m_profileKeyValuePairs.end()) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found region " << regionIter->second); + profile.SetRegion(regionIter->second); + } + + auto accessKeyIdIter = m_profileKeyValuePairs.find(ACCESS_KEY_ID_KEY); + Aws::String accessKey, secretKey, sessionToken; + if (accessKeyIdIter != m_profileKeyValuePairs.end()) + { + accessKey = accessKeyIdIter->second; + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found access key " << accessKey); + + auto secretAccessKeyIter = m_profileKeyValuePairs.find(SECRET_KEY_KEY); + auto sessionTokenIter = m_profileKeyValuePairs.find(SESSION_TOKEN_KEY); + if (secretAccessKeyIter != m_profileKeyValuePairs.end()) + { + secretKey = secretAccessKeyIter->second; + } + else + { + AWS_LOGSTREAM_ERROR(PARSER_TAG, "No secret access key found even though an access key was specified. This will cause all signed AWS calls to fail."); + } + + if (sessionTokenIter != m_profileKeyValuePairs.end()) + { + sessionToken = sessionTokenIter->second; } - - profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken)); - } - - auto assumeRoleArnIter = m_profileKeyValuePairs.find(ROLE_ARN_KEY); - if (assumeRoleArnIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found role arn " << assumeRoleArnIter->second); - profile.SetRoleArn(assumeRoleArnIter->second); - } - - auto externalIdIter = m_profileKeyValuePairs.find(EXTERNAL_ID_KEY); - if (externalIdIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found external id " << externalIdIter->second); - profile.SetExternalId(externalIdIter->second); - } - - auto sourceProfileIter = m_profileKeyValuePairs.find(SOURCE_PROFILE_KEY); - if (sourceProfileIter != m_profileKeyValuePairs.end()) - { - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found source profile " << sourceProfileIter->second); - profile.SetSourceProfile(sourceProfileIter->second); - } + + profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken)); + } + + auto assumeRoleArnIter = m_profileKeyValuePairs.find(ROLE_ARN_KEY); + if (assumeRoleArnIter != m_profileKeyValuePairs.end()) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found role arn " << assumeRoleArnIter->second); + profile.SetRoleArn(assumeRoleArnIter->second); + } + + auto externalIdIter = m_profileKeyValuePairs.find(EXTERNAL_ID_KEY); + if (externalIdIter != m_profileKeyValuePairs.end()) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found external id " << externalIdIter->second); + profile.SetExternalId(externalIdIter->second); + } + + auto sourceProfileIter = m_profileKeyValuePairs.find(SOURCE_PROFILE_KEY); + if (sourceProfileIter != m_profileKeyValuePairs.end()) + { + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found source profile " << sourceProfileIter->second); + profile.SetSourceProfile(sourceProfileIter->second); + } auto credentialProcessIter = m_profileKeyValuePairs.find(CREDENTIAL_PROCESS_COMMAND); if (credentialProcessIter != m_profileKeyValuePairs.end()) @@ -211,154 +211,154 @@ namespace Aws AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found credential process " << credentialProcessIter->second); profile.SetCredentialProcess(credentialProcessIter->second); } - profile.SetAllKeyValPairs(m_profileKeyValuePairs); - - m_foundProfiles[profile.GetName()] = std::move(profile); - m_currentWorkingProfile.clear(); - m_profileKeyValuePairs.clear(); - } - - if(!line.empty() && openPos != std::string::npos && closePos != std::string::npos) - { - m_currentWorkingProfile = StringUtils::Trim(line.substr(openPos + 1, closePos - openPos - 1).c_str()); - StringUtils::Replace(m_currentWorkingProfile, PROFILE_PREFIX, ""); - AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found profile " << m_currentWorkingProfile); - } - } - - enum State - { - START = 0, - PROFILE_FOUND, - PROFILE_KEY_VALUE_FOUND, - FAILURE - }; - - Aws::String m_currentWorkingProfile; - Aws::Map<String, String> m_profileKeyValuePairs; - State m_parserState; - Aws::Map<String, Profile> m_foundProfiles; - }; - - static const char* const CONFIG_FILE_LOADER = "Aws::Config::AWSConfigFileProfileConfigLoader"; - - AWSConfigFileProfileConfigLoader::AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix) : - m_fileName(fileName), m_useProfilePrefix(useProfilePrefix) - { + profile.SetAllKeyValPairs(m_profileKeyValuePairs); + + m_foundProfiles[profile.GetName()] = std::move(profile); + m_currentWorkingProfile.clear(); + m_profileKeyValuePairs.clear(); + } + + if(!line.empty() && openPos != std::string::npos && closePos != std::string::npos) + { + m_currentWorkingProfile = StringUtils::Trim(line.substr(openPos + 1, closePos - openPos - 1).c_str()); + StringUtils::Replace(m_currentWorkingProfile, PROFILE_PREFIX, ""); + AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found profile " << m_currentWorkingProfile); + } + } + + enum State + { + START = 0, + PROFILE_FOUND, + PROFILE_KEY_VALUE_FOUND, + FAILURE + }; + + Aws::String m_currentWorkingProfile; + Aws::Map<String, String> m_profileKeyValuePairs; + State m_parserState; + Aws::Map<String, Profile> m_foundProfiles; + }; + + static const char* const CONFIG_FILE_LOADER = "Aws::Config::AWSConfigFileProfileConfigLoader"; + + AWSConfigFileProfileConfigLoader::AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix) : + m_fileName(fileName), m_useProfilePrefix(useProfilePrefix) + { AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Initializing config loader against fileName " - << fileName << " and using profilePrefix = " << useProfilePrefix); - } - - bool AWSConfigFileProfileConfigLoader::LoadInternal() - { - m_profiles.clear(); - - Aws::IFStream inputFile(m_fileName.c_str()); - if(inputFile) - { - ConfigFileProfileFSM parser; - parser.ParseStream(inputFile); - m_profiles = parser.GetProfiles(); - return m_profiles.size() > 0; - } - - AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for reading."); - - return false; - } - - bool AWSConfigFileProfileConfigLoader::PersistInternal(const Aws::Map<Aws::String, Profile>& profiles) - { - Aws::OFStream outputFile(m_fileName.c_str(), std::ios_base::out | std::ios_base::trunc); - if(outputFile) - { - for(auto& profile : profiles) - { - Aws::String prefix = m_useProfilePrefix ? PROFILE_PREFIX : ""; - - AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing profile " << profile.first << " to disk."); - - outputFile << LEFT_BRACKET << prefix << profile.second.GetName() << RIGHT_BRACKET << std::endl; - const Aws::Auth::AWSCredentials& credentials = profile.second.GetCredentials(); - outputFile << ACCESS_KEY_ID_KEY << EQ << credentials.GetAWSAccessKeyId() << std::endl; - outputFile << SECRET_KEY_KEY << EQ << credentials.GetAWSSecretKey() << std::endl; - - if(!credentials.GetSessionToken().empty()) - { - outputFile << SESSION_TOKEN_KEY << EQ << credentials.GetSessionToken() << std::endl; - } - - if(!profile.second.GetRegion().empty()) - { - outputFile << REGION_KEY << EQ << profile.second.GetRegion() << std::endl; - } - - if(!profile.second.GetRoleArn().empty()) - { - outputFile << ROLE_ARN_KEY << EQ << profile.second.GetRoleArn() << std::endl; - } - - if(!profile.second.GetSourceProfile().empty()) - { - outputFile << SOURCE_PROFILE_KEY << EQ << profile.second.GetSourceProfile() << std::endl; - } - - outputFile << std::endl; - } - - AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Profiles written to config file " << m_fileName); - - return true; - } - - AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for writing."); - - return false; - } - - static const char* const EC2_INSTANCE_PROFILE_LOG_TAG = "Aws::Config::EC2InstanceProfileConfigLoader"; - - EC2InstanceProfileConfigLoader::EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& client) - : m_ec2metadataClient(client == nullptr ? Aws::MakeShared<Aws::Internal::EC2MetadataClient>(EC2_INSTANCE_PROFILE_LOG_TAG) : client) - { - } - - bool EC2InstanceProfileConfigLoader::LoadInternal() - { + << fileName << " and using profilePrefix = " << useProfilePrefix); + } + + bool AWSConfigFileProfileConfigLoader::LoadInternal() + { + m_profiles.clear(); + + Aws::IFStream inputFile(m_fileName.c_str()); + if(inputFile) + { + ConfigFileProfileFSM parser; + parser.ParseStream(inputFile); + m_profiles = parser.GetProfiles(); + return m_profiles.size() > 0; + } + + AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for reading."); + + return false; + } + + bool AWSConfigFileProfileConfigLoader::PersistInternal(const Aws::Map<Aws::String, Profile>& profiles) + { + Aws::OFStream outputFile(m_fileName.c_str(), std::ios_base::out | std::ios_base::trunc); + if(outputFile) + { + for(auto& profile : profiles) + { + Aws::String prefix = m_useProfilePrefix ? PROFILE_PREFIX : ""; + + AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing profile " << profile.first << " to disk."); + + outputFile << LEFT_BRACKET << prefix << profile.second.GetName() << RIGHT_BRACKET << std::endl; + const Aws::Auth::AWSCredentials& credentials = profile.second.GetCredentials(); + outputFile << ACCESS_KEY_ID_KEY << EQ << credentials.GetAWSAccessKeyId() << std::endl; + outputFile << SECRET_KEY_KEY << EQ << credentials.GetAWSSecretKey() << std::endl; + + if(!credentials.GetSessionToken().empty()) + { + outputFile << SESSION_TOKEN_KEY << EQ << credentials.GetSessionToken() << std::endl; + } + + if(!profile.second.GetRegion().empty()) + { + outputFile << REGION_KEY << EQ << profile.second.GetRegion() << std::endl; + } + + if(!profile.second.GetRoleArn().empty()) + { + outputFile << ROLE_ARN_KEY << EQ << profile.second.GetRoleArn() << std::endl; + } + + if(!profile.second.GetSourceProfile().empty()) + { + outputFile << SOURCE_PROFILE_KEY << EQ << profile.second.GetSourceProfile() << std::endl; + } + + outputFile << std::endl; + } + + AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Profiles written to config file " << m_fileName); + + return true; + } + + AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for writing."); + + return false; + } + + static const char* const EC2_INSTANCE_PROFILE_LOG_TAG = "Aws::Config::EC2InstanceProfileConfigLoader"; + + EC2InstanceProfileConfigLoader::EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& client) + : m_ec2metadataClient(client == nullptr ? Aws::MakeShared<Aws::Internal::EC2MetadataClient>(EC2_INSTANCE_PROFILE_LOG_TAG) : client) + { + } + + bool EC2InstanceProfileConfigLoader::LoadInternal() + { auto credentialsStr = m_ec2metadataClient->GetDefaultCredentialsSecurely(); - if(credentialsStr.empty()) return false; - - Json::JsonValue credentialsDoc(credentialsStr); + if(credentialsStr.empty()) return false; + + Json::JsonValue credentialsDoc(credentialsStr); if (!credentialsDoc.WasParseSuccessful()) - { + { AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG, "Failed to parse output from EC2MetadataService."); - return false; - } - const char* accessKeyId = "AccessKeyId"; - const char* secretAccessKey = "SecretAccessKey"; - Aws::String accessKey, secretKey, token; - - auto credentialsView = credentialsDoc.View(); - accessKey = credentialsView.GetString(accessKeyId); + return false; + } + const char* accessKeyId = "AccessKeyId"; + const char* secretAccessKey = "SecretAccessKey"; + Aws::String accessKey, secretKey, token; + + auto credentialsView = credentialsDoc.View(); + accessKey = credentialsView.GetString(accessKeyId); AWS_LOGSTREAM_INFO(EC2_INSTANCE_PROFILE_LOG_TAG, - "Successfully pulled credentials from metadata service with access key " << accessKey); - - secretKey = credentialsView.GetString(secretAccessKey); - token = credentialsView.GetString("Token"); - - auto region = m_ec2metadataClient->GetCurrentRegion(); - - Profile profile; - profile.SetCredentials(AWSCredentials(accessKey, secretKey, token)); - profile.SetRegion(region); - profile.SetName(INSTANCE_PROFILE_KEY); - - m_profiles[INSTANCE_PROFILE_KEY] = profile; - - return true; - } - + "Successfully pulled credentials from metadata service with access key " << accessKey); + + secretKey = credentialsView.GetString(secretAccessKey); + token = credentialsView.GetString("Token"); + + auto region = m_ec2metadataClient->GetCurrentRegion(); + + Profile profile; + profile.SetCredentials(AWSCredentials(accessKey, secretKey, token)); + profile.SetRegion(region); + profile.SetName(INSTANCE_PROFILE_KEY); + + m_profiles[INSTANCE_PROFILE_KEY] = profile; + + return true; + } + ConfigAndCredentialsCacheManager::ConfigAndCredentialsCacheManager() : m_credentialsFileLoader(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()), m_configFileLoader(Aws::Auth::GetConfigProfileFilename(), true/*use profile prefix*/) @@ -536,5 +536,5 @@ namespace Aws assert(s_configManager); return s_configManager->GetCredentials(profileName); } - } // Config namespace -} // Aws namespace + } // Config namespace +} // Aws namespace diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp index 2525976334..f7b1357d37 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/cjson/cJSON.cpp @@ -1,2334 +1,2334 @@ -/* - Copyright (c) 2009-2017 Dave Gamble and cJSON contributors - - 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. -*/ - -/* cJSON */ -/* JSON parser in C. */ - -/* disable warnings about old C89 functions in MSVC */ -#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) -#define _CRT_SECURE_NO_DEPRECATE -#endif - -#ifdef __GNUC__ -#pragma GCC visibility push(default) -#endif -#if defined(_MSC_VER) -#pragma warning (push) -/* disable warning about single line comments in system headers */ -#pragma warning (disable : 4001) -#endif - -#include <string.h> -#include <stdio.h> -#include <math.h> -#include <stdlib.h> -#include <limits.h> -#include <ctype.h> - -#ifdef ENABLE_LOCALES -#include <locale.h> -#endif - -#if defined(_MSC_VER) -#pragma warning (pop) -#endif -#ifdef __GNUC__ -#pragma GCC visibility pop -#endif - -#include <aws/core/external/cjson/cJSON.h> - -/* define our own boolean type */ -// #define true ((cJSON_bool)1) -// #define false ((cJSON_bool)0) - -typedef struct { - const unsigned char *json; - size_t position; -} error; -static error global_error = { NULL, 0 }; - -CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) -{ - return (const char*) (global_error.json + global_error.position); -} - -CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) { - if (!cJSON_IsString(item)) { - return NULL; - } - - return item->valuestring; -} - -/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ -#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 7) - #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. -#endif - -CJSON_PUBLIC(const char*) cJSON_Version(void) -{ - static char version[15]; - sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); - - return version; -} - -/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ -static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) -{ - if ((string1 == NULL) || (string2 == NULL)) - { - return 1; - } - - if (string1 == string2) - { - return 0; - } - - for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) - { - if (*string1 == '\0') - { - return 0; - } - } - - return tolower(*string1) - tolower(*string2); -} - -typedef struct internal_hooks -{ - void *(*allocate)(size_t size); - void (*deallocate)(void *pointer); - void *(*reallocate)(void *pointer, size_t size); -} internal_hooks; - -#if defined(_MSC_VER) -/* work around MSVC error C2322: '...' address of dillimport '...' is not static */ -static void *internal_malloc(size_t size) -{ - return malloc(size); -} -static void internal_free(void *pointer) -{ - free(pointer); -} -static void *internal_realloc(void *pointer, size_t size) -{ - return realloc(pointer, size); -} -#else -#define internal_malloc malloc -#define internal_free free -#define internal_realloc realloc -#endif - -static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; - -static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) -{ - size_t length = 0; - unsigned char *copy = NULL; - - if (string == NULL) - { - return NULL; - } - - length = strlen((const char*)string) + sizeof(""); - copy = (unsigned char*)hooks->allocate(length); - if (copy == NULL) - { - return NULL; - } - memcpy(copy, string, length); - - return copy; -} - -CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) -{ - if (hooks == NULL) - { - /* Reset hooks */ - global_hooks.allocate = malloc; - global_hooks.deallocate = free; - global_hooks.reallocate = realloc; - return; - } - - global_hooks.allocate = malloc; - if (hooks->malloc_fn != NULL) - { - global_hooks.allocate = hooks->malloc_fn; - } - - global_hooks.deallocate = free; - if (hooks->free_fn != NULL) - { - global_hooks.deallocate = hooks->free_fn; - } - - /* use realloc only if both free and malloc are used */ - global_hooks.reallocate = NULL; - if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) - { - global_hooks.reallocate = realloc; - } -} - -/* Internal constructor. */ -static cJSON *cJSON_New_Item(const internal_hooks * const hooks) -{ - cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); - if (node) - { - memset(node, '\0', sizeof(cJSON)); - } - - return node; -} - -/* Delete a cJSON structure. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) -{ - cJSON *next = NULL; - while (item != NULL) - { - next = item->next; - if (!(item->type & cJSON_IsReference) && (item->child != NULL)) - { - cJSON_Delete(item->child); - } - if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) - { - global_hooks.deallocate(item->valuestring); - } - if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) - { - global_hooks.deallocate(item->string); - } - global_hooks.deallocate(item); - item = next; - } -} - -/* get the decimal point character of the current locale */ -static unsigned char get_decimal_point(void) -{ -#ifdef ENABLE_LOCALES - struct lconv *lconv = localeconv(); - return (unsigned char) lconv->decimal_point[0]; -#else - return '.'; -#endif -} - -typedef struct -{ - const unsigned char *content; - size_t length; - size_t offset; - size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ - internal_hooks hooks; -} parse_buffer; - -/* check if the given size is left to read in a given parse buffer (starting with 1) */ -#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) -/* check if the buffer can be accessed at the given index (starting with 0) */ -#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) -#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) -/* get a pointer to the buffer at the position */ -#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) - -/* Parse the input text to generate a number, and populate the result into item. */ -static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) -{ - double number = 0; - unsigned char *after_end = NULL; - unsigned char number_c_string[64]; - unsigned char decimal_point = get_decimal_point(); +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + 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. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif + +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <stdlib.h> +#include <limits.h> +#include <ctype.h> + +#ifdef ENABLE_LOCALES +#include <locale.h> +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include <aws/core/external/cjson/cJSON.h> + +/* define our own boolean type */ +// #define true ((cJSON_bool)1) +// #define false ((cJSON_bool)0) + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item) { + if (!cJSON_IsString(item)) { + return NULL; + } + + return item->valuestring; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 7) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(*allocate)(size_t size); + void (*deallocate)(void *pointer); + void *(*reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dillimport '...' is not static */ +static void *internal_malloc(size_t size) +{ + return malloc(size); +} +static void internal_free(void *pointer) +{ + free(pointer); +} +static void *internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); bool isInteger = true; - size_t i = 0; - - if ((input_buffer == NULL) || (input_buffer->content == NULL)) - { - return false; - } - - /* copy the number into a temporary buffer and replace '.' with the decimal point - * of the current locale (for strtod) - * This also takes care of '\0' not necessarily being available for marking the end of the input */ - for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) - { - switch (buffer_at_offset(input_buffer)[i]) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '+': - case '-': + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': number_c_string[i] = buffer_at_offset(input_buffer)[i]; break; - case 'e': - case 'E': - number_c_string[i] = buffer_at_offset(input_buffer)[i]; + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; isInteger = false; - break; - - case '.': - number_c_string[i] = decimal_point; + break; + + case '.': + number_c_string[i] = decimal_point; isInteger = false; - break; - - default: - goto loop_end; - } - } -loop_end: - number_c_string[i] = '\0'; - - number = strtod((const char*)number_c_string, (char**)&after_end); - if (number_c_string == after_end) - { - return false; /* parse_error */ - } - - item->valuedouble = number; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; // For integer which is out of the range of [INT_MIN, INT_MAX], it may lose precision if we cast it to double. // Instead, we keep the integer literal as a string. if (isInteger && (number > INT_MAX || number < INT_MIN)) { item->valuestring = (char*)cJSON_strdup(number_c_string, &global_hooks); } - - /* use saturation in case of overflow */ - if (number >= INT_MAX) - { - item->valueint = INT_MAX; - } - else if (number <= INT_MIN) - { - item->valueint = INT_MIN; - } - else - { - item->valueint = (int)number; - } - - item->type = cJSON_Number; - - input_buffer->offset += (size_t)(after_end - number_c_string); - return true; -} - -/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) -{ - if (number >= INT_MAX) - { - object->valueint = INT_MAX; - } - else if (number <= INT_MIN) - { - object->valueint = INT_MIN; - } - else - { - object->valueint = (int)number; - } - - return object->valuedouble = number; -} - -typedef struct -{ - unsigned char *buffer; - size_t length; - size_t offset; - size_t depth; /* current nesting depth (for formatted printing) */ - cJSON_bool noalloc; - cJSON_bool format; /* is this print a formatted print */ - internal_hooks hooks; -} printbuffer; - -/* realloc printbuffer if necessary to have at least "needed" bytes more */ -static unsigned char* ensure(printbuffer * const p, size_t needed) -{ - unsigned char *newbuffer = NULL; - size_t newsize = 0; - - if ((p == NULL) || (p->buffer == NULL)) - { - return NULL; - } - - if ((p->length > 0) && (p->offset >= p->length)) - { - /* make sure that offset is valid */ - return NULL; - } - - if (needed > INT_MAX) - { - /* sizes bigger than INT_MAX are currently not supported */ - return NULL; - } - - needed += p->offset + 1; - if (needed <= p->length) - { - return p->buffer + p->offset; - } - - if (p->noalloc) { - return NULL; - } - - /* calculate new buffer size */ - if (needed > (INT_MAX / 2)) - { - /* overflow of int, use INT_MAX if possible */ - if (needed <= INT_MAX) - { - newsize = INT_MAX; - } - else - { - return NULL; - } - } - else - { - newsize = needed * 2; - } - - if (p->hooks.reallocate != NULL) - { - /* reallocate with realloc if available */ - newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); - if (newbuffer == NULL) - { - p->hooks.deallocate(p->buffer); - p->length = 0; - p->buffer = NULL; - - return NULL; - } - } - else - { - /* otherwise reallocate manually */ - newbuffer = (unsigned char*)p->hooks.allocate(newsize); - if (!newbuffer) - { - p->hooks.deallocate(p->buffer); - p->length = 0; - p->buffer = NULL; - - return NULL; - } - if (newbuffer) - { - memcpy(newbuffer, p->buffer, p->offset + 1); - } - p->hooks.deallocate(p->buffer); - } - p->length = newsize; - p->buffer = newbuffer; - - return newbuffer + p->offset; -} - -/* calculate the new length of the string in a printbuffer and update the offset */ -static void update_offset(printbuffer * const buffer) -{ - const unsigned char *buffer_pointer = NULL; - if ((buffer == NULL) || (buffer->buffer == NULL)) - { - return; - } - buffer_pointer = buffer->buffer + buffer->offset; - - buffer->offset += strlen((const char*)buffer_pointer); -} - -/* Render the number nicely from the given item into a string. */ -static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) -{ - unsigned char *output_pointer = NULL; - double d = item->valuedouble; - int length = 0; - size_t i = 0; - unsigned char number_buffer[26]; /* temporary buffer to print the number into */ - unsigned char decimal_point = get_decimal_point(); - double test; - - if (output_buffer == NULL) - { - return false; - } - + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + if (newbuffer) + { + memcpy(newbuffer, p->buffer, p->offset + 1); + } + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26]; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test; + + if (output_buffer == NULL) + { + return false; + } + /* For integer which is out of the range of [INT_MIN, INT_MAX], valuestring is an integer literal. */ if (item->valuestring) { length = sprintf((char*)number_buffer, "%s", item->valuestring); } - /* This checks for NaN and Infinity */ + /* This checks for NaN and Infinity */ else if ((d * 0) != 0) - { - length = sprintf((char*)number_buffer, "null"); - } - else - { - /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ - length = sprintf((char*)number_buffer, "%1.15g", d); - - /* Check whether the original double can be recovered */ - if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d)) - { - /* If not, print with 17 decimal places of precision */ - length = sprintf((char*)number_buffer, "%1.17g", d); - } - } - + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || ((double)test != d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + /* sprintf failed or buffer overrun occurred */ - if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) - { - return false; - } - - /* reserve appropriate space in the output */ - output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); - if (output_pointer == NULL) - { - return false; - } - - /* copy the printed number to the output and replace locale - * dependent decimal point with '.' */ - for (i = 0; i < ((size_t)length); i++) - { - if (number_buffer[i] == decimal_point) - { - output_pointer[i] = '.'; - continue; - } - - output_pointer[i] = number_buffer[i]; - } - output_pointer[i] = '\0'; - - output_buffer->offset += (size_t)length; - - return true; -} - -/* parse 4 digit hexadecimal number */ -static unsigned parse_hex4(const unsigned char * const input) -{ - unsigned int h = 0; - size_t i = 0; - - for (i = 0; i < 4; i++) - { - /* parse digit */ - if ((input[i] >= '0') && (input[i] <= '9')) - { - h += (unsigned int) input[i] - '0'; - } - else if ((input[i] >= 'A') && (input[i] <= 'F')) - { - h += (unsigned int) 10 + input[i] - 'A'; - } - else if ((input[i] >= 'a') && (input[i] <= 'f')) - { - h += (unsigned int) 10 + input[i] - 'a'; - } - else /* invalid */ - { - return 0; - } - - if (i < 3) - { - /* shift left to make place for the next nibble */ - h = h << 4; - } - } - - return h; -} - -/* converts a UTF-16 literal to UTF-8 - * A literal can be one or two sequences of the form \uXXXX */ -static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) -{ - long unsigned int codepoint = 0; - unsigned int first_code = 0; - const unsigned char *first_sequence = input_pointer; - unsigned char utf8_length = 0; - unsigned char utf8_position = 0; - unsigned char sequence_length = 0; - unsigned char first_byte_mark = 0; - - if ((input_end - first_sequence) < 6) - { - /* input ends unexpectedly */ - goto fail; - } - - /* get the first utf16 sequence */ - first_code = parse_hex4(first_sequence + 2); - - /* check that the code is valid */ - if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) - { - goto fail; - } - - /* UTF16 surrogate pair */ - if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) - { - const unsigned char *second_sequence = first_sequence + 6; - unsigned int second_code = 0; - sequence_length = 12; /* \uXXXX\uXXXX */ - - if ((input_end - second_sequence) < 6) - { - /* input ends unexpectedly */ - goto fail; - } - - if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) - { - /* missing second half of the surrogate pair */ - goto fail; - } - - /* get the second utf16 sequence */ - second_code = parse_hex4(second_sequence + 2); - /* check that the code is valid */ - if ((second_code < 0xDC00) || (second_code > 0xDFFF)) - { - /* invalid second half of the surrogate pair */ - goto fail; - } - - - /* calculate the unicode codepoint from the surrogate pair */ - codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); - } - else - { - sequence_length = 6; /* \uXXXX */ - codepoint = first_code; - } - - /* encode as UTF-8 - * takes at maximum 4 bytes to encode: - * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - if (codepoint < 0x80) - { - /* normal ascii, encoding 0xxxxxxx */ - utf8_length = 1; - } - else if (codepoint < 0x800) - { - /* two bytes, encoding 110xxxxx 10xxxxxx */ - utf8_length = 2; - first_byte_mark = 0xC0; /* 11000000 */ - } - else if (codepoint < 0x10000) - { - /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ - utf8_length = 3; - first_byte_mark = 0xE0; /* 11100000 */ - } - else if (codepoint <= 0x10FFFF) - { - /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ - utf8_length = 4; - first_byte_mark = 0xF0; /* 11110000 */ - } - else - { - /* invalid unicode codepoint */ - goto fail; - } - - /* encode as utf8 */ - for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) - { - /* 10xxxxxx */ - (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); - codepoint >>= 6; - } - /* encode first byte */ - if (utf8_length > 1) - { - (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); - } - else - { - (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); - } - - *output_pointer += utf8_length; - - return sequence_length; - -fail: - return 0; -} - -/* Parse the input text into an unescaped cinput, and populate item. */ -static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) -{ - const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; - const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; - unsigned char *output_pointer = NULL; - unsigned char *output = NULL; - - /* not a string */ - if (buffer_at_offset(input_buffer)[0] != '\"') - { - goto fail; - } - - { - /* calculate approximate size of the output (overestimate) */ - size_t allocation_length = 0; - size_t skipped_bytes = 0; - while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) - { - /* is escape sequence */ - if (input_end[0] == '\\') - { - if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) - { - /* prevent buffer overflow when last input character is a backslash */ - goto fail; - } - skipped_bytes++; - input_end++; - } - input_end++; - } - if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) - { - goto fail; /* string ended unexpectedly */ - } - - /* This is at most how much we need for the output */ - allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; - output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); - if (output == NULL) - { - goto fail; /* allocation failure */ - } - } - - output_pointer = output; - /* loop through the string literal */ - while (input_pointer < input_end) - { - if (*input_pointer != '\\') - { - *output_pointer++ = *input_pointer++; - } - /* escape sequence */ - else - { - unsigned char sequence_length = 2; - if ((input_end - input_pointer) < 1) - { - goto fail; - } - - switch (input_pointer[1]) - { - case 'b': - *output_pointer++ = '\b'; - break; - case 'f': - *output_pointer++ = '\f'; - break; - case 'n': - *output_pointer++ = '\n'; - break; - case 'r': - *output_pointer++ = '\r'; - break; - case 't': - *output_pointer++ = '\t'; - break; - case '\"': - case '\\': - case '/': - *output_pointer++ = input_pointer[1]; - break; - - /* UTF-16 literal */ - case 'u': - sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); - if (sequence_length == 0) - { - /* failed to convert UTF16-literal to UTF-8 */ - goto fail; - } - break; - - default: - goto fail; - } - input_pointer += sequence_length; - } - } - - /* zero terminate the output */ - *output_pointer = '\0'; - - item->type = cJSON_String; - item->valuestring = (char*)output; - - input_buffer->offset = (size_t) (input_end - input_buffer->content); - input_buffer->offset++; - - return true; - -fail: - if (output != NULL) - { - input_buffer->hooks.deallocate(output); - } - - if (input_pointer != NULL) - { - input_buffer->offset = (size_t)(input_pointer - input_buffer->content); - } - - return false; -} - -/* Render the cstring provided to an escaped version that can be printed. */ -static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) -{ - const unsigned char *input_pointer = NULL; - unsigned char *output = NULL; - unsigned char *output_pointer = NULL; - size_t output_length = 0; - /* numbers of additional characters needed for escaping */ - size_t escape_characters = 0; - - if (output_buffer == NULL) - { - return false; - } - - /* empty string */ - if (input == NULL) - { - output = ensure(output_buffer, sizeof("\"\"")); - if (output == NULL) - { - return false; - } - strcpy((char*)output, "\"\""); - - return true; - } - - /* set "flag" to 1 if something needs to be escaped */ - for (input_pointer = input; *input_pointer; input_pointer++) - { - switch (*input_pointer) - { - case '\"': - case '\\': - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - /* one character escape sequence */ - escape_characters++; - break; - default: - if (*input_pointer < 32) - { - /* UTF-16 escape sequence uXXXX */ - escape_characters += 5; - } - break; - } - } - output_length = (size_t)(input_pointer - input) + escape_characters; - - output = ensure(output_buffer, output_length + sizeof("\"\"")); - if (output == NULL) - { - return false; - } - - /* no characters have to be escaped */ - if (escape_characters == 0) - { - output[0] = '\"'; - memcpy(output + 1, input, output_length); - output[output_length + 1] = '\"'; - output[output_length + 2] = '\0'; - - return true; - } - - output[0] = '\"'; - output_pointer = output + 1; - /* copy the string */ - for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) - { - if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) - { - /* normal character, copy */ - *output_pointer = *input_pointer; - } - else - { - /* character needs to be escaped */ - *output_pointer++ = '\\'; - switch (*input_pointer) - { - case '\\': - *output_pointer = '\\'; - break; - case '\"': - *output_pointer = '\"'; - break; - case '\b': - *output_pointer = 'b'; - break; - case '\f': - *output_pointer = 'f'; - break; - case '\n': - *output_pointer = 'n'; - break; - case '\r': - *output_pointer = 'r'; - break; - case '\t': - *output_pointer = 't'; - break; - default: - /* escape and print as unicode codepoint */ - sprintf((char*)output_pointer, "u%04x", *input_pointer); - output_pointer += 4; - break; - } - } - } - output[output_length + 1] = '\"'; - output[output_length + 2] = '\0'; - - return true; -} - -/* Invoke print_string_ptr (which is useful) on an item. */ -static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) -{ - return print_string_ptr((unsigned char*)item->valuestring, p); -} - -/* Predeclare these prototypes. */ -static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); -static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); -static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); -static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); -static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); -static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); - -/* Utility to jump whitespace and cr/lf */ -static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) -{ - if ((buffer == NULL) || (buffer->content == NULL)) - { - return NULL; - } - - while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) - { - buffer->offset++; - } - - if (buffer->offset == buffer->length) - { - buffer->offset--; - } - - return buffer; -} - -/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ -static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) -{ - if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) - { - return NULL; - } - - if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) - { - buffer->offset += 3; - } - - return buffer; -} - -/* Parse an object - create a new root, and populate. */ -CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) -{ - parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; - cJSON *item = NULL; - - /* reset error position */ - global_error.json = NULL; - global_error.position = 0; - - if (value == NULL) - { - goto fail; - } - - buffer.content = (const unsigned char*)value; - buffer.length = strlen((const char*)value) + sizeof(""); - buffer.offset = 0; - buffer.hooks = global_hooks; - - item = cJSON_New_Item(&global_hooks); - if (item == NULL) /* memory fail */ - { - goto fail; - } - - if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) - { - /* parse failure. ep is set. */ - goto fail; - } - - /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ - if (require_null_terminated) - { - buffer_skip_whitespace(&buffer); - if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') - { - goto fail; - } - } - if (return_parse_end) - { - *return_parse_end = (const char*)buffer_at_offset(&buffer); - } - - return item; - -fail: - if (item != NULL) - { - cJSON_Delete(item); - } - - if (value != NULL) - { - error local_error; - local_error.json = (const unsigned char*)value; - local_error.position = 0; - - if (buffer.offset < buffer.length) - { - local_error.position = buffer.offset; - } - else if (buffer.length > 0) - { - local_error.position = buffer.length - 1; - } - - if (return_parse_end != NULL) - { - *return_parse_end = (const char*)local_error.json + local_error.position; - } - - global_error = local_error; - } - - return NULL; -} - -/* Default options for cJSON_Parse */ -CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) -{ - return cJSON_ParseWithOpts(value, 0, 0); -} - -#define cjson_min(a, b) ((a < b) ? a : b) - -static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) -{ - static const size_t default_buffer_size = 256; - printbuffer buffer[1]; - unsigned char *printed = NULL; - - memset(buffer, 0, sizeof(buffer)); - - /* create buffer */ - buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); - buffer->length = default_buffer_size; - buffer->format = format; - buffer->hooks = *hooks; - if (buffer->buffer == NULL) - { - goto fail; - } - - /* print the value */ - if (!print_value(item, buffer)) - { - goto fail; - } - update_offset(buffer); - - /* check if reallocate is available */ - if (hooks->reallocate != NULL) - { - printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); - if (printed == NULL) { - goto fail; - } - buffer->buffer = NULL; - } - else /* otherwise copy the JSON over to a new buffer */ - { - printed = (unsigned char*) hooks->allocate(buffer->offset + 1); - if (printed == NULL) - { - goto fail; - } - memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); - printed[buffer->offset] = '\0'; /* just to be sure */ - - /* free the buffer */ - hooks->deallocate(buffer->buffer); - } - - return printed; - -fail: - if (buffer->buffer != NULL) - { - hooks->deallocate(buffer->buffer); - } - - if (printed != NULL) - { - hooks->deallocate(printed); - } - - return NULL; -} - -/* Render a cJSON item/entity/structure to text. */ -CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) -{ - return (char*)print(item, true, &global_hooks); -} - -CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) -{ - return (char*)print(item, false, &global_hooks); -} - -CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) -{ - printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; - - if (prebuffer < 0) - { - return NULL; - } - - p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); - if (!p.buffer) - { - return NULL; - } - - p.length = (size_t)prebuffer; - p.offset = 0; - p.noalloc = false; - p.format = fmt; - p.hooks = global_hooks; - - if (!print_value(item, &p)) - { - global_hooks.deallocate(p.buffer); - return NULL; - } - - return (char*)p.buffer; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt) -{ - printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; - - if ((len < 0) || (buf == NULL)) - { - return false; - } - - p.buffer = (unsigned char*)buf; - p.length = (size_t)len; - p.offset = 0; - p.noalloc = true; - p.format = fmt; - p.hooks = global_hooks; - - return print_value(item, &p); -} - -/* Parser core - when encountering text, process appropriately. */ -static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) -{ - if ((input_buffer == NULL) || (input_buffer->content == NULL)) - { - return false; /* no input */ - } - - /* parse the different types of values */ - /* null */ - if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) - { - item->type = cJSON_NULL; - input_buffer->offset += 4; - return true; - } - /* false */ - if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) - { - item->type = cJSON_False; - input_buffer->offset += 5; - return true; - } - /* true */ - if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) - { - item->type = cJSON_True; - item->valueint = 1; - input_buffer->offset += 4; - return true; - } - /* string */ - if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) - { - return parse_string(item, input_buffer); - } - /* number */ - if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) - { - return parse_number(item, input_buffer); - } - /* array */ - if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) - { - return parse_array(item, input_buffer); - } - /* object */ - if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) - { - return parse_object(item, input_buffer); - } - - return false; -} - -/* Render a value to text. */ -static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) -{ - unsigned char *output = NULL; - - if ((item == NULL) || (output_buffer == NULL)) - { - return false; - } - - switch ((item->type) & 0xFF) - { - case cJSON_NULL: - output = ensure(output_buffer, 5); - if (output == NULL) - { - return false; - } - strcpy((char*)output, "null"); - return true; - - case cJSON_False: - output = ensure(output_buffer, 6); - if (output == NULL) - { - return false; - } - strcpy((char*)output, "false"); - return true; - - case cJSON_True: - output = ensure(output_buffer, 5); - if (output == NULL) - { - return false; - } - strcpy((char*)output, "true"); - return true; - - case cJSON_Number: - return print_number(item, output_buffer); - - case cJSON_Raw: - { - size_t raw_length = 0; - if (item->valuestring == NULL) - { - return false; - } - - raw_length = strlen(item->valuestring) + sizeof(""); - output = ensure(output_buffer, raw_length); - if (output == NULL) - { - return false; - } - memcpy(output, item->valuestring, raw_length); - return true; - } - - case cJSON_String: - return print_string(item, output_buffer); - - case cJSON_Array: - return print_array(item, output_buffer); - - case cJSON_Object: - return print_object(item, output_buffer); - - default: - return false; - } -} - -/* Build an array from input text. */ -static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) -{ - cJSON *head = NULL; /* head of the linked list */ - cJSON *current_item = NULL; - - if (input_buffer->depth >= CJSON_NESTING_LIMIT) - { - return false; /* to deeply nested */ - } - input_buffer->depth++; - - if (buffer_at_offset(input_buffer)[0] != '[') - { - /* not an array */ - goto fail; - } - - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) - { - /* empty array */ - goto success; - } - - /* check if we skipped to the end of the buffer */ - if (cannot_access_at_index(input_buffer, 0)) - { - input_buffer->offset--; - goto fail; - } - - /* step back to character in front of the first element */ - input_buffer->offset--; - /* loop through the comma separated array elements */ - do - { - /* allocate next item */ - cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); - if (new_item == NULL) - { - goto fail; /* allocation failure */ - } - - /* attach next item to list */ - if (head == NULL) - { - /* start the linked list */ - current_item = head = new_item; - } - else - { - /* add to the end and advance */ - current_item->next = new_item; - new_item->prev = current_item; - current_item = new_item; - } - - /* parse next value */ - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if (!parse_value(current_item, input_buffer)) - { - goto fail; /* failed to parse value */ - } - buffer_skip_whitespace(input_buffer); - } - while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); - - if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') - { - goto fail; /* expected end of array */ - } - -success: - input_buffer->depth--; - - item->type = cJSON_Array; - item->child = head; - - input_buffer->offset++; - - return true; - -fail: - if (head != NULL) - { - cJSON_Delete(head); - } - - return false; -} - -/* Render an array to text */ -static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) -{ - unsigned char *output_pointer = NULL; - size_t length = 0; - cJSON *current_element = item->child; - - if (output_buffer == NULL) - { - return false; - } - - /* Compose the output array. */ - /* opening square bracket */ - output_pointer = ensure(output_buffer, 1); - if (output_pointer == NULL) - { - return false; - } - - *output_pointer = '['; - output_buffer->offset++; - output_buffer->depth++; - - while (current_element != NULL) - { - if (!print_value(current_element, output_buffer)) - { - return false; - } - update_offset(output_buffer); - if (current_element->next) - { - length = (size_t) (output_buffer->format ? 2 : 1); - output_pointer = ensure(output_buffer, length + 1); - if (output_pointer == NULL) - { - return false; - } - *output_pointer++ = ','; - if(output_buffer->format) - { - *output_pointer++ = ' '; - } - *output_pointer = '\0'; - output_buffer->offset += length; - } - current_element = current_element->next; - } - - output_pointer = ensure(output_buffer, 2); - if (output_pointer == NULL) - { - return false; - } - *output_pointer++ = ']'; - *output_pointer = '\0'; - output_buffer->depth--; - - return true; -} - -/* Build an object from the text. */ -static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) -{ - cJSON *head = NULL; /* linked list head */ - cJSON *current_item = NULL; - - if (input_buffer->depth >= CJSON_NESTING_LIMIT) - { - return false; /* to deeply nested */ - } - input_buffer->depth++; - - if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) - { - goto fail; /* not an object */ - } - - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) - { - goto success; /* empty object */ - } - - /* check if we skipped to the end of the buffer */ - if (cannot_access_at_index(input_buffer, 0)) - { - input_buffer->offset--; - goto fail; - } - - /* step back to character in front of the first element */ - input_buffer->offset--; - /* loop through the comma separated array elements */ - do - { - /* allocate next item */ - cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); - if (new_item == NULL) - { - goto fail; /* allocation failure */ - } - - /* attach next item to list */ - if (head == NULL) - { - /* start the linked list */ - current_item = head = new_item; - } - else - { - /* add to the end and advance */ - current_item->next = new_item; - new_item->prev = current_item; - current_item = new_item; - } - - /* parse the name of the child */ - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if (!parse_string(current_item, input_buffer)) - { + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = strlen((const char*)value) + sizeof(""); + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +#define cjson_min(a, b) ((a < b) ? a : b) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buf, const int len, const cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((len < 0) || (buf == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buf; + p.length = (size_t)len; + p.offset = 0; + p.noalloc = true; + p.format = fmt; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { goto fail; /* failed to parse name */ - } - buffer_skip_whitespace(input_buffer); - - /* swap valuestring and string, because we parsed the name */ - current_item->string = current_item->valuestring; - current_item->valuestring = NULL; - - if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) - { - goto fail; /* invalid object */ - } - - /* parse the value */ - input_buffer->offset++; - buffer_skip_whitespace(input_buffer); - if (!parse_value(current_item, input_buffer)) - { - goto fail; /* failed to parse value */ - } - buffer_skip_whitespace(input_buffer); - } - while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); - - if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) - { - goto fail; /* expected end of object */ - } - -success: - input_buffer->depth--; - - item->type = cJSON_Object; - item->child = head; - - input_buffer->offset++; - return true; - -fail: - if (head != NULL) - { - cJSON_Delete(head); - } - - return false; -} - -/* Render an object to text. */ -static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) -{ - unsigned char *output_pointer = NULL; - size_t length = 0; - cJSON *current_item = item->child; - - if (output_buffer == NULL) - { - return false; - } - - /* Compose the output: */ - length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ - output_pointer = ensure(output_buffer, length + 1); - if (output_pointer == NULL) - { - return false; - } - - *output_pointer++ = '{'; - output_buffer->depth++; - if (output_buffer->format) - { - *output_pointer++ = '\n'; - } - output_buffer->offset += length; - - while (current_item) - { - if (output_buffer->format) - { - size_t i; - output_pointer = ensure(output_buffer, output_buffer->depth); - if (output_pointer == NULL) - { - return false; - } - for (i = 0; i < output_buffer->depth; i++) - { - *output_pointer++ = '\t'; - } - output_buffer->offset += output_buffer->depth; - } - - /* print key */ - if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) - { - return false; - } - update_offset(output_buffer); - - length = (size_t) (output_buffer->format ? 2 : 1); - output_pointer = ensure(output_buffer, length); - if (output_pointer == NULL) - { - return false; - } - *output_pointer++ = ':'; - if (output_buffer->format) - { - *output_pointer++ = '\t'; - } - output_buffer->offset += length; - - /* print value */ - if (!print_value(current_item, output_buffer)) - { - return false; - } - update_offset(output_buffer); - - /* print comma if not last */ - length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0)); - output_pointer = ensure(output_buffer, length + 1); - if (output_pointer == NULL) - { - return false; - } - if (current_item->next) - { - *output_pointer++ = ','; - } - - if (output_buffer->format) - { - *output_pointer++ = '\n'; - } - *output_pointer = '\0'; - output_buffer->offset += length; - - current_item = current_item->next; - } - - output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); - if (output_pointer == NULL) - { - return false; - } - if (output_buffer->format) - { - size_t i; - for (i = 0; i < (output_buffer->depth - 1); i++) - { - *output_pointer++ = '\t'; - } - } - *output_pointer++ = '}'; - *output_pointer = '\0'; - output_buffer->depth--; - - return true; -} - -/* Get Array size/item / object item. */ -CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) -{ - cJSON *child = NULL; - size_t size = 0; - - if (array == NULL) - { - return 0; - } - - child = array->child; - - while(child != NULL) - { - size++; - child = child->next; - } - - /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ - - return (int)size; -} - -static cJSON* get_array_item(const cJSON *array, size_t index) -{ - cJSON *current_child = NULL; - - if (array == NULL) - { - return NULL; - } - - current_child = array->child; - while ((current_child != NULL) && (index > 0)) - { - index--; - current_child = current_child->next; - } - - return current_child; -} - -CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) -{ - if (index < 0) - { - return NULL; - } - - return get_array_item(array, (size_t)index); -} - -static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) -{ - cJSON *current_element = NULL; - - if ((object == NULL) || (name == NULL)) - { - return NULL; - } - - current_element = object->child; - if (case_sensitive) - { - while ((current_element != NULL) && (strcmp(name, current_element->string) != 0)) - { - current_element = current_element->next; - } - } - else - { - while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) - { - current_element = current_element->next; - } - } - - return current_element; -} - -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) -{ - return get_object_item(object, string, false); -} - -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) -{ - return get_object_item(object, string, true); -} - -CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) -{ - return cJSON_GetObjectItem(object, string) ? 1 : 0; -} - -/* Utility for array list handling. */ -static void suffix_object(cJSON *prev, cJSON *item) -{ - prev->next = item; - item->prev = prev; -} - -/* Utility for handling references. */ -static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) -{ - cJSON *reference = NULL; - if (item == NULL) - { - return NULL; - } - - reference = cJSON_New_Item(hooks); - if (reference == NULL) - { - return NULL; - } - - memcpy(reference, item, sizeof(cJSON)); - reference->string = NULL; - reference->type |= cJSON_IsReference; - reference->next = reference->prev = NULL; - return reference; -} - -static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) -{ - cJSON *child = NULL; - - if ((item == NULL) || (array == NULL)) - { - return false; - } - - child = array->child; - - if (child == NULL) - { - /* list is empty, start new one */ - array->child = item; - } - else - { - /* append to the end */ - while (child->next) - { - child = child->next; - } - suffix_object(child, item); - } - - return true; -} - -/* Add item to array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) -{ - add_item_to_array(array, item); -} - -#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) - #pragma GCC diagnostic push -#endif -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wcast-qual" -#endif -/* helper function to cast away const */ -static void* cast_away_const(const void* string) -{ - return (void*)string; -} -#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) - #pragma GCC diagnostic pop -#endif - - -static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) -{ - char *new_key = NULL; - int new_type = cJSON_Invalid; - - if ((object == NULL) || (string == NULL) || (item == NULL)) - { - return false; - } - - if (constant_key) - { - new_key = (char*)cast_away_const(string); - new_type = item->type | cJSON_StringIsConst; - } - else - { - new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); - if (new_key == NULL) - { - return false; - } - - new_type = item->type & ~cJSON_StringIsConst; - } - - if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) - { - hooks->deallocate(item->string); - } - - item->string = new_key; - item->type = new_type; - - return add_item_to_array(object, item); -} - -CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) -{ - add_item_to_object(object, string, item, &global_hooks, false); -} - -/* Add an item to an object with constant string as key */ -CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) -{ - add_item_to_object(object, string, item, &global_hooks, true); -} - -CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) -{ - if (array == NULL) - { - return; - } - - add_item_to_array(array, create_reference(item, &global_hooks)); -} - -CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) -{ - if ((object == NULL) || (string == NULL)) - { - return; - } - - add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); -} - -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) -{ - cJSON *null = cJSON_CreateNull(); - if (add_item_to_object(object, name, null, &global_hooks, false)) - { - return null; - } - - cJSON_Delete(null); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) -{ - cJSON *true_item = cJSON_CreateTrue(); - if (add_item_to_object(object, name, true_item, &global_hooks, false)) - { - return true_item; - } - - cJSON_Delete(true_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) -{ - cJSON *false_item = cJSON_CreateFalse(); - if (add_item_to_object(object, name, false_item, &global_hooks, false)) - { - return false_item; - } - - cJSON_Delete(false_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) -{ - cJSON *bool_item = cJSON_CreateBool(boolean); - if (add_item_to_object(object, name, bool_item, &global_hooks, false)) - { - return bool_item; - } - - cJSON_Delete(bool_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) -{ - cJSON *number_item = cJSON_CreateNumber(number); - if (add_item_to_object(object, name, number_item, &global_hooks, false)) - { - return number_item; - } - - cJSON_Delete(number_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) -{ - cJSON *string_item = cJSON_CreateString(string); - if (add_item_to_object(object, name, string_item, &global_hooks, false)) - { - return string_item; - } - - cJSON_Delete(string_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) -{ - cJSON *raw_item = cJSON_CreateRaw(raw); - if (add_item_to_object(object, name, raw_item, &global_hooks, false)) - { - return raw_item; - } - - cJSON_Delete(raw_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) -{ - cJSON *object_item = cJSON_CreateObject(); - if (add_item_to_object(object, name, object_item, &global_hooks, false)) - { - return object_item; - } - - cJSON_Delete(object_item); - return NULL; -} - -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) -{ - cJSON *array = cJSON_CreateArray(); - if (add_item_to_object(object, name, array, &global_hooks, false)) - { - return array; - } - - cJSON_Delete(array); - return NULL; -} - -CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) -{ - if ((parent == NULL) || (item == NULL)) - { - return NULL; - } - - if (item->prev != NULL) - { - /* not the first element */ - item->prev->next = item->next; - } - if (item->next != NULL) - { - /* not the last element */ - item->next->prev = item->prev; - } - - if (item == parent->child) - { - /* first element */ - parent->child = item->next; - } - /* make sure the detached item doesn't point anywhere anymore */ - item->prev = NULL; - item->next = NULL; - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) -{ - if (which < 0) - { - return NULL; - } - - return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); -} - -CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) -{ - cJSON_Delete(cJSON_DetachItemFromArray(array, which)); -} - -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) -{ - cJSON *to_detach = cJSON_GetObjectItem(object, string); - - return cJSON_DetachItemViaPointer(object, to_detach); -} - -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) -{ - cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); - - return cJSON_DetachItemViaPointer(object, to_detach); -} - -CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) -{ - cJSON_Delete(cJSON_DetachItemFromObject(object, string)); -} - -CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) -{ - cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); -} - -/* Replace array/object items with new ones. */ -CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) -{ - cJSON *after_inserted = NULL; - - if (which < 0) - { - return; - } - - after_inserted = get_array_item(array, (size_t)which); - if (after_inserted == NULL) - { - add_item_to_array(array, newitem); - return; - } - - newitem->next = after_inserted; - newitem->prev = after_inserted->prev; - after_inserted->prev = newitem; - if (after_inserted == array->child) - { - array->child = newitem; - } - else - { - newitem->prev->next = newitem; - } -} - -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) -{ - if ((parent == NULL) || (replacement == NULL) || (item == NULL)) - { - return false; - } - - if (replacement == item) - { - return true; - } - - replacement->next = item->next; - replacement->prev = item->prev; - - if (replacement->next != NULL) - { - replacement->next->prev = replacement; - } - if (replacement->prev != NULL) - { - replacement->prev->next = replacement; - } - if (parent->child == item) - { - parent->child = replacement; - } - - item->next = NULL; - item->prev = NULL; - cJSON_Delete(item); - - return true; -} - -CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) -{ - if (which < 0) - { - return; - } - - cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); -} - -static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) -{ - if ((replacement == NULL) || (string == NULL)) - { - return false; - } - - /* replace the name in the replacement */ - if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) - { - cJSON_free(replacement->string); - } - replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); - replacement->type &= ~cJSON_StringIsConst; - - cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); - - return true; -} - -CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) -{ - replace_item_in_object(object, string, newitem, false); -} - -CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) -{ - replace_item_in_object(object, string, newitem, true); -} - -/* Create basic types: */ -CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = cJSON_NULL; - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = cJSON_True; - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = cJSON_False; - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = b ? cJSON_True : cJSON_False; - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = cJSON_Number; - item->valuedouble = num; - - /* use saturation in case of overflow */ - if (num >= INT_MAX) - { - item->valueint = INT_MAX; - } - else if (num <= INT_MIN) - { - item->valueint = INT_MIN; - } - else - { - item->valueint = (int)num; - } - } - - return item; -} - + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = (size_t) ((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL)) + { + return false; + } + + child = array->child; + + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + } + else + { + /* append to the end */ + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return; + } + + add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return; + } + + add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item->prev != NULL) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + add_item_to_array(array, newitem); + return; + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (parent->child == item) + { + parent->child = replacement; + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return; + } + + cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); + + return true; +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool b) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = b ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + CJSON_PUBLIC(cJSON *) cJSON_CreateInt64(long long num) { cJSON *item = cJSON_New_Item(&global_hooks); @@ -2364,620 +2364,620 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateInt64(long long num) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = cJSON_String; - item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); - if(!item->valuestring) - { - cJSON_Delete(item); - return NULL; - } - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if (item != NULL) - { - item->type = cJSON_String | cJSON_IsReference; - item->valuestring = (char*)cast_away_const(string); - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if (item != NULL) { - item->type = cJSON_Object | cJSON_IsReference; - item->child = (cJSON*)cast_away_const(child); - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { - cJSON *item = cJSON_New_Item(&global_hooks); - if (item != NULL) { - item->type = cJSON_Array | cJSON_IsReference; - item->child = (cJSON*)cast_away_const(child); - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type = cJSON_Raw; - item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); - if(!item->valuestring) - { - cJSON_Delete(item); - return NULL; - } - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) - { - item->type=cJSON_Array; - } - - return item; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) -{ - cJSON *item = cJSON_New_Item(&global_hooks); - if (item) - { - item->type = cJSON_Object; - } - - return item; -} - -/* Create Arrays: */ -CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) -{ - size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; - - if ((count < 0) || (numbers == NULL)) - { - return NULL; - } - - a = cJSON_CreateArray(); - for(i = 0; a && (i < (size_t)count); i++) - { - n = cJSON_CreateNumber(numbers[i]); - if (!n) - { - cJSON_Delete(a); - return NULL; - } - if(!i) - { - a->child = n; - } - else - { - suffix_object(p, n); - } - p = n; - } - - return a; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) -{ - size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; - - if ((count < 0) || (numbers == NULL)) - { - return NULL; - } - - a = cJSON_CreateArray(); - - for(i = 0; a && (i < (size_t)count); i++) - { - n = cJSON_CreateNumber((double)numbers[i]); - if(!n) - { - cJSON_Delete(a); - return NULL; - } - if(!i) - { - a->child = n; - } - else - { - suffix_object(p, n); - } - p = n; - } - - return a; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) -{ - size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; - - if ((count < 0) || (numbers == NULL)) - { - return NULL; - } - - a = cJSON_CreateArray(); - - for(i = 0;a && (i < (size_t)count); i++) - { - n = cJSON_CreateNumber(numbers[i]); - if(!n) - { - cJSON_Delete(a); - return NULL; - } - if(!i) - { - a->child = n; - } - else - { - suffix_object(p, n); - } - p = n; - } - - return a; -} - -CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count) -{ - size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; - - if ((count < 0) || (strings == NULL)) - { - return NULL; - } - - a = cJSON_CreateArray(); - - for (i = 0; a && (i < (size_t)count); i++) - { - n = cJSON_CreateString(strings[i]); - if(!n) - { - cJSON_Delete(a); - return NULL; - } - if(!i) - { - a->child = n; - } - else - { - suffix_object(p,n); - } - p = n; - } - - return a; -} - -/* Duplication */ -CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) -{ - cJSON *newitem = NULL; - cJSON *child = NULL; - cJSON *next = NULL; - cJSON *newchild = NULL; - - /* Bail on bad ptr */ - if (!item) - { - goto fail; - } - /* Create new item */ - newitem = cJSON_New_Item(&global_hooks); - if (!newitem) - { - goto fail; - } - /* Copy over all vars */ - newitem->type = item->type & (~cJSON_IsReference); - newitem->valueint = item->valueint; - newitem->valuedouble = item->valuedouble; - if (item->valuestring) - { - newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); - if (!newitem->valuestring) - { - goto fail; - } - } - if (item->string) - { - newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); - if (!newitem->string) - { - goto fail; - } - } - /* If non-recursive, then we're done! */ - if (!recurse) - { - return newitem; - } - /* Walk the ->next chain for the child. */ - child = item->child; - while (child != NULL) - { - newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ - if (!newchild) - { - goto fail; - } - if (next != NULL) - { - /* If newitem->child already set, then crosswire ->prev and ->next and move on */ - next->next = newchild; - newchild->prev = next; - next = newchild; - } - else - { - /* Set newitem->child and move to it */ - newitem->child = newchild; - next = newchild; - } - child = child->next; - } - - return newitem; - -fail: - if (newitem != NULL) - { - cJSON_Delete(newitem); - } - - return NULL; -} - -CJSON_PUBLIC(void) cJSON_Minify(char *json) -{ - unsigned char *into = (unsigned char*)json; - - if (json == NULL) - { - return; - } - - while (*json) - { - if (*json == ' ') - { - json++; - } - else if (*json == '\t') - { - /* Whitespace characters. */ - json++; - } - else if (*json == '\r') - { - json++; - } - else if (*json=='\n') - { - json++; - } - else if ((*json == '/') && (json[1] == '/')) - { - /* double-slash comments, to end of line. */ - while (*json && (*json != '\n')) - { - json++; - } - } - else if ((*json == '/') && (json[1] == '*')) - { - /* multiline comments. */ - while (*json && !((*json == '*') && (json[1] == '/'))) - { - json++; - } - json += 2; - } - else if (*json == '\"') - { - /* string literals, which are \" sensitive. */ - *into++ = (unsigned char)*json++; - while (*json && (*json != '\"')) - { - if (*json == '\\') - { - *into++ = (unsigned char)*json++; - } - *into++ = (unsigned char)*json++; - } - *into++ = (unsigned char)*json++; - } - else - { - /* All other characters. */ - *into++ = (unsigned char)*json++; - } - } - - /* and null-terminate. */ - *into = '\0'; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_Invalid; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_False; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xff) == cJSON_True; -} - - -CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & (cJSON_True | cJSON_False)) != 0; -} -CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_NULL; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_Number; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_String; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_Array; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_Object; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) -{ - if (item == NULL) - { - return false; - } - - return (item->type & 0xFF) == cJSON_Raw; -} - -CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) -{ - if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) - { - return false; - } - - /* check if type is valid */ - switch (a->type & 0xFF) - { - case cJSON_False: - case cJSON_True: - case cJSON_NULL: - case cJSON_Number: - case cJSON_String: - case cJSON_Raw: - case cJSON_Array: - case cJSON_Object: - break; - - default: - return false; - } - - /* identical objects are equal */ - if (a == b) - { - return true; - } - - switch (a->type & 0xFF) - { - /* in these cases and equal type is enough */ - case cJSON_False: - case cJSON_True: - case cJSON_NULL: - return true; - - case cJSON_Number: - if (a->valuedouble == b->valuedouble) - { - return true; - } - return false; - - case cJSON_String: - case cJSON_Raw: - if ((a->valuestring == NULL) || (b->valuestring == NULL)) - { - return false; - } - if (strcmp(a->valuestring, b->valuestring) == 0) - { - return true; - } - - return false; - - case cJSON_Array: - { - cJSON *a_element = a->child; - cJSON *b_element = b->child; - - for (; (a_element != NULL) && (b_element != NULL);) - { - if (!cJSON_Compare(a_element, b_element, case_sensitive)) - { - return false; - } - - a_element = a_element->next; - b_element = b_element->next; - } - - /* one of the arrays is longer than the other */ - if (a_element != b_element) { - return false; - } - - return true; - } - - case cJSON_Object: - { - cJSON *a_element = NULL; - cJSON *b_element = NULL; - cJSON_ArrayForEach(a_element, a) - { - /* TODO This has O(n^2) runtime, which is horrible! */ - b_element = get_object_item(b, a_element->string, case_sensitive); - if (b_element == NULL) - { - return false; - } - - if (!cJSON_Compare(a_element, b_element, case_sensitive)) - { - return false; - } - } - - /* doing this twice, once on a and b to prevent true comparison if a subset of b - * TODO: Do this the proper way, this is just a fix for now */ - cJSON_ArrayForEach(b_element, b) - { - a_element = get_object_item(a, b_element->string, case_sensitive); - if (a_element == NULL) - { - return false; - } - - if (!cJSON_Compare(b_element, a_element, case_sensitive)) - { - return false; - } - } - - return true; - } - - default: - return false; - } -} - -CJSON_PUBLIC(void *) cJSON_malloc(size_t size) -{ - return global_hooks.allocate(size); -} - -CJSON_PUBLIC(void) cJSON_free(void *object) -{ - global_hooks.deallocate(object); -} +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + unsigned char *into = (unsigned char*)json; + + if (json == NULL) + { + return; + } + + while (*json) + { + if (*json == ' ') + { + json++; + } + else if (*json == '\t') + { + /* Whitespace characters. */ + json++; + } + else if (*json == '\r') + { + json++; + } + else if (*json=='\n') + { + json++; + } + else if ((*json == '/') && (json[1] == '/')) + { + /* double-slash comments, to end of line. */ + while (*json && (*json != '\n')) + { + json++; + } + } + else if ((*json == '/') && (json[1] == '*')) + { + /* multiline comments. */ + while (*json && !((*json == '*') && (json[1] == '/'))) + { + json++; + } + json += 2; + } + else if (*json == '\"') + { + /* string literals, which are \" sensitive. */ + *into++ = (unsigned char)*json++; + while (*json && (*json != '\"')) + { + if (*json == '\\') + { + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + *into++ = (unsigned char)*json++; + } + else + { + /* All other characters. */ + *into++ = (unsigned char)*json++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (a->valuedouble == b->valuedouble) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp index ebe0fd9eec..b880ff007d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/external/tinyxml2/tinyxml2.cpp @@ -1,2802 +1,2802 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -/* -This file has been modified from its original version by Amazon: - (1) Memory management operations use aws memory management api - (2) #includes all use <> -*/ - -#include <aws/core/external/tinyxml2/tinyxml2.h> - -#include <new> // yes, this one new style header, is in the Android SDK. -#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) -# include <stddef.h> -# include <stdarg.h> -#else -# include <cstddef> -# include <cstdarg> -#endif - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) - // Microsoft Visual Studio, version 2005 and higher. Not WinCE. - /*int _snprintf_s( - char *buffer, - size_t sizeOfBuffer, - size_t count, - const char *format [, - argument] ... - );*/ - static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) - { - va_list va; - va_start( va, format ); - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - va_end( va ); - return result; - } - - static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va ) - { - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - return result; - } - - #define TIXML_VSCPRINTF _vscprintf - #define TIXML_SSCANF sscanf_s -#elif defined _MSC_VER - // Microsoft Visual Studio 2003 and earlier or WinCE - #define TIXML_SNPRINTF _snprintf - #define TIXML_VSNPRINTF _vsnprintf - #define TIXML_SSCANF sscanf - #if (_MSC_VER < 1400 ) && (!defined WINCE) - // Microsoft Visual Studio 2003 and not WinCE. - #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. - #else - // Microsoft Visual Studio 2003 and earlier or WinCE. - static inline int TIXML_VSCPRINTF( const char* format, va_list va ) - { - int len = 512; - for (;;) { - len = len*2; - char* str = Aws::NewArray<char>(len, ALLOCATION_TAG); - const int required = _vsnprintf(str, len, format, va); - Aws::DeleteArray(str); - if ( required != -1 ) { - TIXMLASSERT( required >= 0 ); - len = required; - break; - } - } - TIXMLASSERT( len >= 0 ); - return len; - } - #endif -#else - // GCC version 3 and higher - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_VSNPRINTF vsnprintf - static inline int TIXML_VSCPRINTF( const char* format, va_list va ) - { - int len = vsnprintf( 0, 0, format, va ); - TIXMLASSERT( len >= 0 ); - return len; - } - #define TIXML_SSCANF sscanf -#endif - - -static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF -static const char LF = LINE_FEED; -static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out -static const char CR = CARRIAGE_RETURN; -static const char SINGLE_QUOTE = '\''; -static const char DOUBLE_QUOTE = '\"'; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// ef bb bf (Microsoft "lead bytes") - designates UTF-8 - -static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - -namespace Aws -{ -namespace External -{ -namespace tinyxml2 -{ - -struct Entity { - const char* pattern; - int length; - char value; -}; - -static const int NUM_ENTITIES = 5; -static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } -}; - - -StrPair::~StrPair() -{ - Reset(); -} - - -void StrPair::TransferTo( StrPair* other ) -{ - if ( this == other ) { - return; - } - // This in effect implements the assignment operator by "moving" - // ownership (as in auto_ptr). - - TIXMLASSERT( other != 0 ); - TIXMLASSERT( other->_flags == 0 ); - TIXMLASSERT( other->_start == 0 ); - TIXMLASSERT( other->_end == 0 ); - - other->Reset(); - - other->_flags = _flags; - other->_start = _start; - other->_end = _end; - - _flags = 0; - _start = 0; - _end = 0; -} - - -void StrPair::Reset() -{ - if ( _flags & NEEDS_DELETE ) { - Aws::DeleteArray(_start); - } - _flags = 0; - _start = 0; - _end = 0; -} - - -void StrPair::SetStr( const char* str, int flags ) -{ - TIXMLASSERT( str ); - Reset(); - size_t len = strlen( str ); - TIXMLASSERT( _start == 0 ); - _start = Aws::NewArray<char>(len+1, ALLOCATION_TAG); - memcpy( _start, str, len+1 ); - _end = _start + len; - _flags = flags | NEEDS_DELETE; -} - - -char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr ) -{ - TIXMLASSERT( p ); - TIXMLASSERT( endTag && *endTag ); - TIXMLASSERT(curLineNumPtr); - - char* start = p; - char endChar = *endTag; - size_t length = strlen( endTag ); - - // Inner loop of text parsing. - while ( *p ) { - if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { - Set( start, p, strFlags ); - return p + length; - } else if (*p == '\n') { - ++(*curLineNumPtr); - } - ++p; - TIXMLASSERT( p ); - } - return 0; -} - - -char* StrPair::ParseName( char* p ) -{ - if ( !p || !(*p) ) { - return 0; - } - if ( !XMLUtil::IsNameStartChar( *p ) ) { - return 0; - } - - char* const start = p; - ++p; - while ( *p && XMLUtil::IsNameChar( *p ) ) { - ++p; - } - - Set( start, p, 0 ); - return p; -} - - -void StrPair::CollapseWhitespace() -{ - // Adjusting _start would cause undefined behavior on delete[] - TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 ); - // Trim leading space. - _start = XMLUtil::SkipWhiteSpace( _start, 0 ); - - if ( *_start ) { - const char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( *p ) { - if ( XMLUtil::IsWhiteSpace( *p )) { - p = XMLUtil::SkipWhiteSpace( p, 0 ); - if ( *p == 0 ) { - break; // don't write to q; this trims the trailing space. - } - *q = ' '; - ++q; - } - *q = *p; - ++q; - ++p; - } - *q = 0; - } -} - - -const char* StrPair::GetStr() -{ - TIXMLASSERT( _start ); - TIXMLASSERT( _end ); - if ( _flags & NEEDS_FLUSH ) { - *_end = 0; - _flags ^= NEEDS_FLUSH; - - if ( _flags ) { - const char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( p < _end ) { - if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { - // CR-LF pair becomes LF - // CR alone becomes LF - // LF-CR becomes LF - if ( *(p+1) == LF ) { - p += 2; - } - else { - ++p; - } - *q = LF; - ++q; - } - else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { - if ( *(p+1) == CR ) { - p += 2; - } - else { - ++p; - } - *q = LF; - ++q; - } - else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { - // Entities handled by tinyXML2: - // - special entities in the entity table [in/out] - // - numeric character reference [in] - // 中 or 中 - - if ( *(p+1) == '#' ) { - const int buflen = 10; - char buf[buflen] = { 0 }; - int len = 0; - char* adjusted = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) ); - if ( adjusted == 0 ) { - *q = *p; - ++p; - ++q; - } - else { - TIXMLASSERT( 0 <= len && len <= buflen ); - TIXMLASSERT( q + len <= adjusted ); - p = adjusted; - memcpy( q, buf, len ); - q += len; - } - } - else { - bool entityFound = false; - for( int i = 0; i < NUM_ENTITIES; ++i ) { - const Entity& entity = entities[i]; - if ( strncmp( p + 1, entity.pattern, entity.length ) == 0 - && *( p + entity.length + 1 ) == ';' ) { - // Found an entity - convert. - *q = entity.value; - ++q; - p += entity.length + 2; - entityFound = true; - break; - } - } - if ( !entityFound ) { - // fixme: treat as error? - ++p; - ++q; - } - } - } - else { - *q = *p; - ++p; - ++q; - } - } - *q = 0; - } - // The loop below has plenty going on, and this - // is a less useful mode. Break it out. - if ( _flags & NEEDS_WHITESPACE_COLLAPSING ) { - CollapseWhitespace(); - } - _flags = (_flags & NEEDS_DELETE); - } - TIXMLASSERT( _start ); - return _start; -} - - - - -// --------- XMLUtil ----------- // - -const char* XMLUtil::writeBoolTrue = "true"; -const char* XMLUtil::writeBoolFalse = "false"; - -void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse) -{ - static const char* defTrue = "true"; - static const char* defFalse = "false"; - - writeBoolTrue = (writeTrue) ? writeTrue : defTrue; - writeBoolFalse = (writeFalse) ? writeFalse : defFalse; -} - - -const char* XMLUtil::ReadBOM( const char* p, bool* bom ) -{ - TIXMLASSERT( p ); - TIXMLASSERT( bom ); - *bom = false; - const unsigned char* pu = reinterpret_cast<const unsigned char*>(p); - // Check for BOM: - if ( *(pu+0) == TIXML_UTF_LEAD_0 - && *(pu+1) == TIXML_UTF_LEAD_1 - && *(pu+2) == TIXML_UTF_LEAD_2 ) { - *bom = true; - p += 3; - } - TIXMLASSERT( p ); - return p; -} - - -void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) { - *length = 1; - } - else if ( input < 0x800 ) { - *length = 2; - } - else if ( input < 0x10000 ) { - *length = 3; - } - else if ( input < 0x200000 ) { - *length = 4; - } - else { - *length = 0; // This code won't convert this correctly anyway. - return; - } - - output += *length; - - // Scary scary fall throughs are annotated with carefully designed comments - // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc - switch (*length) { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - break; - default: - TIXMLASSERT( false ); - } -} - - -const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) -{ - // Presume an entity, and pull it out. - *length = 0; - - if ( *(p+1) == '#' && *(p+2) ) { - unsigned long ucs = 0; - TIXMLASSERT( sizeof( ucs ) >= 4 ); - ptrdiff_t delta = 0; - unsigned mult = 1; - static const char SEMICOLON = ';'; - - if ( *(p+2) == 'x' ) { - // Hexadecimal. - const char* q = p+3; - if ( !(*q) ) { - return 0; - } - - q = strchr( q, SEMICOLON ); - - if ( !q ) { - return 0; - } - TIXMLASSERT( *q == SEMICOLON ); - - delta = q-p; - --q; - - while ( *q != 'x' ) { - unsigned int digit = 0; - - if ( *q >= '0' && *q <= '9' ) { - digit = *q - '0'; - } - else if ( *q >= 'a' && *q <= 'f' ) { - digit = *q - 'a' + 10; - } - else if ( *q >= 'A' && *q <= 'F' ) { - digit = *q - 'A' + 10; - } - else { - return 0; - } - TIXMLASSERT( digit < 16 ); - TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); - const unsigned int digitScaled = mult * digit; - TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); - ucs += digitScaled; - TIXMLASSERT( mult <= UINT_MAX / 16 ); - mult *= 16; - --q; - } - } - else { - // Decimal. - const char* q = p+2; - if ( !(*q) ) { - return 0; - } - - q = strchr( q, SEMICOLON ); - - if ( !q ) { - return 0; - } - TIXMLASSERT( *q == SEMICOLON ); - - delta = q-p; - --q; - - while ( *q != '#' ) { - if ( *q >= '0' && *q <= '9' ) { - const unsigned int digit = *q - '0'; - TIXMLASSERT( digit < 10 ); - TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); - const unsigned int digitScaled = mult * digit; - TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); - ucs += digitScaled; - } - else { - return 0; - } - TIXMLASSERT( mult <= UINT_MAX / 10 ); - mult *= 10; - --q; - } - } - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - return p + delta + 1; - } - return p+1; -} - - -void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); -} - - -void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); -} - - -void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); -} - -/* - ToStr() of a number is a very tricky topic. - https://github.com/leethomason/tinyxml2/issues/106 -*/ -void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v ); -} - - -void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v ); -} - - -void XMLUtil::ToStr(int64_t v, char* buffer, int bufferSize) -{ - // horrible syntax trick to make the compiler happy about %lld - TIXML_SNPRINTF(buffer, bufferSize, "%lld", (long long)v); -} - - -bool XMLUtil::ToInt( const char* str, int* value ) -{ - if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) -{ - if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToBool( const char* str, bool* value ) -{ - int ival = 0; - if ( ToInt( str, &ival )) { - *value = (ival==0) ? false : true; - return true; - } - if ( StringEqual( str, "true" ) ) { - *value = true; - return true; - } - else if ( StringEqual( str, "false" ) ) { - *value = false; - return true; - } - return false; -} - - -bool XMLUtil::ToFloat( const char* str, float* value ) -{ - if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { - return true; - } - return false; -} - - -bool XMLUtil::ToDouble( const char* str, double* value ) -{ - if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { - return true; - } - return false; -} - - -bool XMLUtil::ToInt64(const char* str, int64_t* value) -{ - long long v = 0; // horrible syntax trick to make the compiler happy about %lld - if (TIXML_SSCANF(str, "%lld", &v) == 1) { - *value = (int64_t)v; - return true; - } - return false; -} - - -char* XMLDocument::Identify( char* p, XMLNode** node ) -{ - TIXMLASSERT( node ); - TIXMLASSERT( p ); - char* const start = p; - int const startLine = _parseCurLineNum; - p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); - if( !*p ) { - *node = 0; - TIXMLASSERT( p ); - return p; - } - - // These strings define the matching patterns: - static const char* xmlHeader = { "<?" }; - static const char* commentHeader = { "<!--" }; - static const char* cdataHeader = { "<![CDATA[" }; - static const char* dtdHeader = { "<!" }; - static const char* elementHeader = { "<" }; // and a header for everything else; check last. - - static const int xmlHeaderLen = 2; - static const int commentHeaderLen = 4; - static const int cdataHeaderLen = 9; - static const int dtdHeaderLen = 2; - static const int elementHeaderLen = 1; - - TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool - TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool - XMLNode* returnNode = 0; - if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) { - returnNode = CreateUnlinkedNode<XMLDeclaration>( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += xmlHeaderLen; - } - else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { - returnNode = CreateUnlinkedNode<XMLComment>( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += commentHeaderLen; - } - else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { - XMLText* text = CreateUnlinkedNode<XMLText>( _textPool ); - returnNode = text; - returnNode->_parseLineNum = _parseCurLineNum; - p += cdataHeaderLen; - text->SetCData( true ); - } - else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { - returnNode = CreateUnlinkedNode<XMLUnknown>( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += dtdHeaderLen; - } - else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { - returnNode = CreateUnlinkedNode<XMLElement>( _elementPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += elementHeaderLen; - } - else { - returnNode = CreateUnlinkedNode<XMLText>( _textPool ); - returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character - p = start; // Back it up, all the text counts. - _parseCurLineNum = startLine; - } - - TIXMLASSERT( returnNode ); - TIXMLASSERT( p ); - *node = returnNode; - return p; -} - - -bool XMLDocument::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - if ( visitor->VisitEnter( *this ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLNode ----------- // - -XMLNode::XMLNode( XMLDocument* doc ) : - _document( doc ), - _parent( 0 ), - _value(), - _parseLineNum( 0 ), - _firstChild( 0 ), _lastChild( 0 ), - _prev( 0 ), _next( 0 ), - _userData( 0 ), - _memPool( 0 ) -{ -} - - -XMLNode::~XMLNode() -{ - DeleteChildren(); - if ( _parent ) { - _parent->Unlink( this ); - } -} - +/* +Original code by Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* +This file has been modified from its original version by Amazon: + (1) Memory management operations use aws memory management api + (2) #includes all use <> +*/ + +#include <aws/core/external/tinyxml2/tinyxml2.h> + +#include <new> // yes, this one new style header, is in the Android SDK. +#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) +# include <stddef.h> +# include <stdarg.h> +#else +# include <cstddef> +# include <cstdarg> +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) + // Microsoft Visual Studio, version 2005 and higher. Not WinCE. + /*int _snprintf_s( + char *buffer, + size_t sizeOfBuffer, + size_t count, + const char *format [, + argument] ... + );*/ + static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) + { + va_list va; + va_start( va, format ); + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + va_end( va ); + return result; + } + + static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va ) + { + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + return result; + } + + #define TIXML_VSCPRINTF _vscprintf + #define TIXML_SSCANF sscanf_s +#elif defined _MSC_VER + // Microsoft Visual Studio 2003 and earlier or WinCE + #define TIXML_SNPRINTF _snprintf + #define TIXML_VSNPRINTF _vsnprintf + #define TIXML_SSCANF sscanf + #if (_MSC_VER < 1400 ) && (!defined WINCE) + // Microsoft Visual Studio 2003 and not WinCE. + #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. + #else + // Microsoft Visual Studio 2003 and earlier or WinCE. + static inline int TIXML_VSCPRINTF( const char* format, va_list va ) + { + int len = 512; + for (;;) { + len = len*2; + char* str = Aws::NewArray<char>(len, ALLOCATION_TAG); + const int required = _vsnprintf(str, len, format, va); + Aws::DeleteArray(str); + if ( required != -1 ) { + TIXMLASSERT( required >= 0 ); + len = required; + break; + } + } + TIXMLASSERT( len >= 0 ); + return len; + } + #endif +#else + // GCC version 3 and higher + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_VSNPRINTF vsnprintf + static inline int TIXML_VSCPRINTF( const char* format, va_list va ) + { + int len = vsnprintf( 0, 0, format, va ); + TIXMLASSERT( len >= 0 ); + return len; + } + #define TIXML_SSCANF sscanf +#endif + + +static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF +static const char LF = LINE_FEED; +static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out +static const char CR = CARRIAGE_RETURN; +static const char SINGLE_QUOTE = '\''; +static const char DOUBLE_QUOTE = '\"'; + +// Bunch of unicode info at: +// http://www.unicode.org/faq/utf_bom.html +// ef bb bf (Microsoft "lead bytes") - designates UTF-8 + +static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; +static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; +static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + +namespace Aws +{ +namespace External +{ +namespace tinyxml2 +{ + +struct Entity { + const char* pattern; + int length; + char value; +}; + +static const int NUM_ENTITIES = 5; +static const Entity entities[NUM_ENTITIES] = { + { "quot", 4, DOUBLE_QUOTE }, + { "amp", 3, '&' }, + { "apos", 4, SINGLE_QUOTE }, + { "lt", 2, '<' }, + { "gt", 2, '>' } +}; + + +StrPair::~StrPair() +{ + Reset(); +} + + +void StrPair::TransferTo( StrPair* other ) +{ + if ( this == other ) { + return; + } + // This in effect implements the assignment operator by "moving" + // ownership (as in auto_ptr). + + TIXMLASSERT( other != 0 ); + TIXMLASSERT( other->_flags == 0 ); + TIXMLASSERT( other->_start == 0 ); + TIXMLASSERT( other->_end == 0 ); + + other->Reset(); + + other->_flags = _flags; + other->_start = _start; + other->_end = _end; + + _flags = 0; + _start = 0; + _end = 0; +} + + +void StrPair::Reset() +{ + if ( _flags & NEEDS_DELETE ) { + Aws::DeleteArray(_start); + } + _flags = 0; + _start = 0; + _end = 0; +} + + +void StrPair::SetStr( const char* str, int flags ) +{ + TIXMLASSERT( str ); + Reset(); + size_t len = strlen( str ); + TIXMLASSERT( _start == 0 ); + _start = Aws::NewArray<char>(len+1, ALLOCATION_TAG); + memcpy( _start, str, len+1 ); + _end = _start + len; + _flags = flags | NEEDS_DELETE; +} + + +char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr ) +{ + TIXMLASSERT( p ); + TIXMLASSERT( endTag && *endTag ); + TIXMLASSERT(curLineNumPtr); + + char* start = p; + char endChar = *endTag; + size_t length = strlen( endTag ); + + // Inner loop of text parsing. + while ( *p ) { + if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { + Set( start, p, strFlags ); + return p + length; + } else if (*p == '\n') { + ++(*curLineNumPtr); + } + ++p; + TIXMLASSERT( p ); + } + return 0; +} + + +char* StrPair::ParseName( char* p ) +{ + if ( !p || !(*p) ) { + return 0; + } + if ( !XMLUtil::IsNameStartChar( *p ) ) { + return 0; + } + + char* const start = p; + ++p; + while ( *p && XMLUtil::IsNameChar( *p ) ) { + ++p; + } + + Set( start, p, 0 ); + return p; +} + + +void StrPair::CollapseWhitespace() +{ + // Adjusting _start would cause undefined behavior on delete[] + TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 ); + // Trim leading space. + _start = XMLUtil::SkipWhiteSpace( _start, 0 ); + + if ( *_start ) { + const char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( *p ) { + if ( XMLUtil::IsWhiteSpace( *p )) { + p = XMLUtil::SkipWhiteSpace( p, 0 ); + if ( *p == 0 ) { + break; // don't write to q; this trims the trailing space. + } + *q = ' '; + ++q; + } + *q = *p; + ++q; + ++p; + } + *q = 0; + } +} + + +const char* StrPair::GetStr() +{ + TIXMLASSERT( _start ); + TIXMLASSERT( _end ); + if ( _flags & NEEDS_FLUSH ) { + *_end = 0; + _flags ^= NEEDS_FLUSH; + + if ( _flags ) { + const char* p = _start; // the read pointer + char* q = _start; // the write pointer + + while( p < _end ) { + if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { + // CR-LF pair becomes LF + // CR alone becomes LF + // LF-CR becomes LF + if ( *(p+1) == LF ) { + p += 2; + } + else { + ++p; + } + *q = LF; + ++q; + } + else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { + if ( *(p+1) == CR ) { + p += 2; + } + else { + ++p; + } + *q = LF; + ++q; + } + else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { + // Entities handled by tinyXML2: + // - special entities in the entity table [in/out] + // - numeric character reference [in] + // 中 or 中 + + if ( *(p+1) == '#' ) { + const int buflen = 10; + char buf[buflen] = { 0 }; + int len = 0; + char* adjusted = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) ); + if ( adjusted == 0 ) { + *q = *p; + ++p; + ++q; + } + else { + TIXMLASSERT( 0 <= len && len <= buflen ); + TIXMLASSERT( q + len <= adjusted ); + p = adjusted; + memcpy( q, buf, len ); + q += len; + } + } + else { + bool entityFound = false; + for( int i = 0; i < NUM_ENTITIES; ++i ) { + const Entity& entity = entities[i]; + if ( strncmp( p + 1, entity.pattern, entity.length ) == 0 + && *( p + entity.length + 1 ) == ';' ) { + // Found an entity - convert. + *q = entity.value; + ++q; + p += entity.length + 2; + entityFound = true; + break; + } + } + if ( !entityFound ) { + // fixme: treat as error? + ++p; + ++q; + } + } + } + else { + *q = *p; + ++p; + ++q; + } + } + *q = 0; + } + // The loop below has plenty going on, and this + // is a less useful mode. Break it out. + if ( _flags & NEEDS_WHITESPACE_COLLAPSING ) { + CollapseWhitespace(); + } + _flags = (_flags & NEEDS_DELETE); + } + TIXMLASSERT( _start ); + return _start; +} + + + + +// --------- XMLUtil ----------- // + +const char* XMLUtil::writeBoolTrue = "true"; +const char* XMLUtil::writeBoolFalse = "false"; + +void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse) +{ + static const char* defTrue = "true"; + static const char* defFalse = "false"; + + writeBoolTrue = (writeTrue) ? writeTrue : defTrue; + writeBoolFalse = (writeFalse) ? writeFalse : defFalse; +} + + +const char* XMLUtil::ReadBOM( const char* p, bool* bom ) +{ + TIXMLASSERT( p ); + TIXMLASSERT( bom ); + *bom = false; + const unsigned char* pu = reinterpret_cast<const unsigned char*>(p); + // Check for BOM: + if ( *(pu+0) == TIXML_UTF_LEAD_0 + && *(pu+1) == TIXML_UTF_LEAD_1 + && *(pu+2) == TIXML_UTF_LEAD_2 ) { + *bom = true; + p += 3; + } + TIXMLASSERT( p ); + return p; +} + + +void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +{ + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) { + *length = 1; + } + else if ( input < 0x800 ) { + *length = 2; + } + else if ( input < 0x10000 ) { + *length = 3; + } + else if ( input < 0x200000 ) { + *length = 4; + } + else { + *length = 0; // This code won't convert this correctly anyway. + return; + } + + output += *length; + + // Scary scary fall throughs are annotated with carefully designed comments + // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc + switch (*length) { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + break; + default: + TIXMLASSERT( false ); + } +} + + +const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) +{ + // Presume an entity, and pull it out. + *length = 0; + + if ( *(p+1) == '#' && *(p+2) ) { + unsigned long ucs = 0; + TIXMLASSERT( sizeof( ucs ) >= 4 ); + ptrdiff_t delta = 0; + unsigned mult = 1; + static const char SEMICOLON = ';'; + + if ( *(p+2) == 'x' ) { + // Hexadecimal. + const char* q = p+3; + if ( !(*q) ) { + return 0; + } + + q = strchr( q, SEMICOLON ); + + if ( !q ) { + return 0; + } + TIXMLASSERT( *q == SEMICOLON ); + + delta = q-p; + --q; + + while ( *q != 'x' ) { + unsigned int digit = 0; + + if ( *q >= '0' && *q <= '9' ) { + digit = *q - '0'; + } + else if ( *q >= 'a' && *q <= 'f' ) { + digit = *q - 'a' + 10; + } + else if ( *q >= 'A' && *q <= 'F' ) { + digit = *q - 'A' + 10; + } + else { + return 0; + } + TIXMLASSERT( digit < 16 ); + TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); + const unsigned int digitScaled = mult * digit; + TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); + ucs += digitScaled; + TIXMLASSERT( mult <= UINT_MAX / 16 ); + mult *= 16; + --q; + } + } + else { + // Decimal. + const char* q = p+2; + if ( !(*q) ) { + return 0; + } + + q = strchr( q, SEMICOLON ); + + if ( !q ) { + return 0; + } + TIXMLASSERT( *q == SEMICOLON ); + + delta = q-p; + --q; + + while ( *q != '#' ) { + if ( *q >= '0' && *q <= '9' ) { + const unsigned int digit = *q - '0'; + TIXMLASSERT( digit < 10 ); + TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); + const unsigned int digitScaled = mult * digit; + TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); + ucs += digitScaled; + } + else { + return 0; + } + TIXMLASSERT( mult <= UINT_MAX / 10 ); + mult *= 10; + --q; + } + } + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + return p + delta + 1; + } + return p+1; +} + + +void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); +} + + +void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); +} + + +void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); +} + +/* + ToStr() of a number is a very tricky topic. + https://github.com/leethomason/tinyxml2/issues/106 +*/ +void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v ); +} + + +void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) +{ + TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v ); +} + + +void XMLUtil::ToStr(int64_t v, char* buffer, int bufferSize) +{ + // horrible syntax trick to make the compiler happy about %lld + TIXML_SNPRINTF(buffer, bufferSize, "%lld", (long long)v); +} + + +bool XMLUtil::ToInt( const char* str, int* value ) +{ + if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) +{ + if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { + return true; + } + return false; +} + +bool XMLUtil::ToBool( const char* str, bool* value ) +{ + int ival = 0; + if ( ToInt( str, &ival )) { + *value = (ival==0) ? false : true; + return true; + } + if ( StringEqual( str, "true" ) ) { + *value = true; + return true; + } + else if ( StringEqual( str, "false" ) ) { + *value = false; + return true; + } + return false; +} + + +bool XMLUtil::ToFloat( const char* str, float* value ) +{ + if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { + return true; + } + return false; +} + + +bool XMLUtil::ToDouble( const char* str, double* value ) +{ + if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { + return true; + } + return false; +} + + +bool XMLUtil::ToInt64(const char* str, int64_t* value) +{ + long long v = 0; // horrible syntax trick to make the compiler happy about %lld + if (TIXML_SSCANF(str, "%lld", &v) == 1) { + *value = (int64_t)v; + return true; + } + return false; +} + + +char* XMLDocument::Identify( char* p, XMLNode** node ) +{ + TIXMLASSERT( node ); + TIXMLASSERT( p ); + char* const start = p; + int const startLine = _parseCurLineNum; + p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); + if( !*p ) { + *node = 0; + TIXMLASSERT( p ); + return p; + } + + // These strings define the matching patterns: + static const char* xmlHeader = { "<?" }; + static const char* commentHeader = { "<!--" }; + static const char* cdataHeader = { "<![CDATA[" }; + static const char* dtdHeader = { "<!" }; + static const char* elementHeader = { "<" }; // and a header for everything else; check last. + + static const int xmlHeaderLen = 2; + static const int commentHeaderLen = 4; + static const int cdataHeaderLen = 9; + static const int dtdHeaderLen = 2; + static const int elementHeaderLen = 1; + + TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool + TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool + XMLNode* returnNode = 0; + if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) { + returnNode = CreateUnlinkedNode<XMLDeclaration>( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += xmlHeaderLen; + } + else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { + returnNode = CreateUnlinkedNode<XMLComment>( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += commentHeaderLen; + } + else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { + XMLText* text = CreateUnlinkedNode<XMLText>( _textPool ); + returnNode = text; + returnNode->_parseLineNum = _parseCurLineNum; + p += cdataHeaderLen; + text->SetCData( true ); + } + else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { + returnNode = CreateUnlinkedNode<XMLUnknown>( _commentPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += dtdHeaderLen; + } + else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { + returnNode = CreateUnlinkedNode<XMLElement>( _elementPool ); + returnNode->_parseLineNum = _parseCurLineNum; + p += elementHeaderLen; + } + else { + returnNode = CreateUnlinkedNode<XMLText>( _textPool ); + returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character + p = start; // Back it up, all the text counts. + _parseCurLineNum = startLine; + } + + TIXMLASSERT( returnNode ); + TIXMLASSERT( p ); + *node = returnNode; + return p; +} + + +bool XMLDocument::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + if ( visitor->VisitEnter( *this ) ) { + for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { + if ( !node->Accept( visitor ) ) { + break; + } + } + } + return visitor->VisitExit( *this ); +} + + +// --------- XMLNode ----------- // + +XMLNode::XMLNode( XMLDocument* doc ) : + _document( doc ), + _parent( 0 ), + _value(), + _parseLineNum( 0 ), + _firstChild( 0 ), _lastChild( 0 ), + _prev( 0 ), _next( 0 ), + _userData( 0 ), + _memPool( 0 ) +{ +} + + +XMLNode::~XMLNode() +{ + DeleteChildren(); + if ( _parent ) { + _parent->Unlink( this ); + } +} + const char* XMLNode::Value() const -{ - // Edge case: XMLDocuments don't have a Value. Return null. - if ( this->ToDocument() ) - return 0; - return _value.GetStr(); -} - -void XMLNode::SetValue( const char* str, bool staticMem ) -{ - if ( staticMem ) { - _value.SetInternedStr( str ); - } - else { - _value.SetStr( str ); - } -} - -XMLNode* XMLNode::DeepClone(XMLDocument* target) const -{ - XMLNode* clone = this->ShallowClone(target); - if (!clone) return 0; - - for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) { - XMLNode* childClone = child->DeepClone(target); - TIXMLASSERT(childClone); - clone->InsertEndChild(childClone); - } - return clone; -} - -void XMLNode::DeleteChildren() -{ - while( _firstChild ) { - TIXMLASSERT( _lastChild ); - DeleteChild( _firstChild ); - } - _firstChild = _lastChild = 0; -} - - -void XMLNode::Unlink( XMLNode* child ) -{ - TIXMLASSERT( child ); - TIXMLASSERT( child->_document == _document ); - TIXMLASSERT( child->_parent == this ); - if ( child == _firstChild ) { - _firstChild = _firstChild->_next; - } - if ( child == _lastChild ) { - _lastChild = _lastChild->_prev; - } - - if ( child->_prev ) { - child->_prev->_next = child->_next; - } - if ( child->_next ) { - child->_next->_prev = child->_prev; - } - child->_next = 0; - child->_prev = 0; - child->_parent = 0; -} - - -void XMLNode::DeleteChild( XMLNode* node ) -{ - TIXMLASSERT( node ); - TIXMLASSERT( node->_document == _document ); - TIXMLASSERT( node->_parent == this ); - Unlink( node ); - TIXMLASSERT(node->_prev == 0); - TIXMLASSERT(node->_next == 0); - TIXMLASSERT(node->_parent == 0); - DeleteNode( node ); -} - - -XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) -{ - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - InsertChildPreamble( addThis ); - - if ( _lastChild ) { - TIXMLASSERT( _firstChild ); - TIXMLASSERT( _lastChild->_next == 0 ); - _lastChild->_next = addThis; - addThis->_prev = _lastChild; - _lastChild = addThis; - - addThis->_next = 0; - } - else { - TIXMLASSERT( _firstChild == 0 ); - _firstChild = _lastChild = addThis; - - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; -} - - -XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) -{ - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - InsertChildPreamble( addThis ); - - if ( _firstChild ) { - TIXMLASSERT( _lastChild ); - TIXMLASSERT( _firstChild->_prev == 0 ); - - _firstChild->_prev = addThis; - addThis->_next = _firstChild; - _firstChild = addThis; - - addThis->_prev = 0; - } - else { - TIXMLASSERT( _lastChild == 0 ); - _firstChild = _lastChild = addThis; - - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; -} - - -XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) -{ - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - - TIXMLASSERT( afterThis ); - - if ( afterThis->_parent != this ) { - TIXMLASSERT( false ); - return 0; - } - if ( afterThis == addThis ) { - // Current state: BeforeThis -> AddThis -> OneAfterAddThis - // Now AddThis must disappear from it's location and then - // reappear between BeforeThis and OneAfterAddThis. - // So just leave it where it is. - return addThis; - } - - if ( afterThis->_next == 0 ) { - // The last node or the only node. - return InsertEndChild( addThis ); - } - InsertChildPreamble( addThis ); - addThis->_prev = afterThis; - addThis->_next = afterThis->_next; - afterThis->_next->_prev = addThis; - afterThis->_next = addThis; - addThis->_parent = this; - return addThis; -} - - - - -const XMLElement* XMLNode::FirstChildElement( const char* name ) const -{ - for( const XMLNode* node = _firstChild; node; node = node->_next ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -const XMLElement* XMLNode::LastChildElement( const char* name ) const -{ - for( const XMLNode* node = _lastChild; node; node = node->_prev ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -const XMLElement* XMLNode::NextSiblingElement( const char* name ) const -{ - for( const XMLNode* node = _next; node; node = node->_next ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const -{ - for( const XMLNode* node = _prev; node; node = node->_prev ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; -} - - -char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) -{ - // This is a recursive method, but thinking about it "at the current level" - // it is a pretty simple flat list: - // <foo/> - // <!-- comment --> - // - // With a special case: - // <foo> - // </foo> - // <!-- comment --> - // - // Where the closing element (/foo) *must* be the next thing after the opening - // element, and the names must match. BUT the tricky bit is that the closing - // element will be read by the child. - // - // 'endTag' is the end tag for this node, it is returned by a call to a child. - // 'parentEnd' is the end tag for the parent, which is filled in and returned. - - while( p && *p ) { - XMLNode* node = 0; - - p = _document->Identify( p, &node ); - TIXMLASSERT( p ); - if ( node == 0 ) { - break; - } - - int initialLineNum = node->_parseLineNum; - - StrPair endTag; - p = node->ParseDeep( p, &endTag, curLineNumPtr ); - if ( !p ) { - DeleteNode( node ); - if ( !_document->Error() ) { - _document->SetError( XML_ERROR_PARSING, initialLineNum, 0); - } - break; - } - - XMLDeclaration* decl = node->ToDeclaration(); - if ( decl ) { - // Declarations are only allowed at document level - bool wellLocated = ( ToDocument() != 0 ); - if ( wellLocated ) { - // Multiple declarations are allowed but all declarations - // must occur before anything else - for ( const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling() ) { - if ( !existingNode->ToDeclaration() ) { - wellLocated = false; - break; - } - } - } - if ( !wellLocated ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); - DeleteNode( node ); - break; - } - } - - XMLElement* ele = node->ToElement(); - if ( ele ) { - // We read the end tag. Return it to the parent. - if ( ele->ClosingType() == XMLElement::CLOSING ) { - if ( parentEndTag ) { - ele->_value.TransferTo( parentEndTag ); - } - node->_memPool->SetTracked(); // created and then immediately deleted. - DeleteNode( node ); - return p; - } - - // Handle an end tag returned to this level. - // And handle a bunch of annoying errors. - bool mismatch = false; - if ( endTag.Empty() ) { - if ( ele->ClosingType() == XMLElement::OPEN ) { - mismatch = true; - } - } - else { - if ( ele->ClosingType() != XMLElement::OPEN ) { - mismatch = true; - } - else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) { - mismatch = true; - } - } - if ( mismatch ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); - DeleteNode( node ); - break; - } - } - InsertEndChild( node ); - } - return 0; -} - -/*static*/ void XMLNode::DeleteNode( XMLNode* node ) -{ - if ( node == 0 ) { - return; - } - TIXMLASSERT(node->_document); - if (!node->ToDocument()) { - node->_document->MarkInUse(node); - } - - MemPool* pool = node->_memPool; - node->~XMLNode(); - pool->Free( node ); -} - -void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const -{ - TIXMLASSERT( insertThis ); - TIXMLASSERT( insertThis->_document == _document ); - - if (insertThis->_parent) { - insertThis->_parent->Unlink( insertThis ); - } - else { - insertThis->_document->MarkInUse(insertThis); - insertThis->_memPool->SetTracked(); - } -} - -const XMLElement* XMLNode::ToElementWithName( const char* name ) const -{ - const XMLElement* element = this->ToElement(); - if ( element == 0 ) { - return 0; - } - if ( name == 0 ) { - return element; - } - if ( XMLUtil::StringEqual( element->Name(), name ) ) { - return element; - } - return 0; -} - -// --------- XMLText ---------- // -char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - if ( this->CData() ) { - p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_CDATA, _parseLineNum, 0 ); - } - return p; - } - else { - int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; - if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { - flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; - } - - p = _value.ParseText( p, "<", flags, curLineNumPtr ); - if ( p && *p ) { - return p-1; - } - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_TEXT, _parseLineNum, 0 ); - } - } - return 0; -} - - -XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? - text->SetCData( this->CData() ); - return text; -} - - -bool XMLText::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLText* text = compare->ToText(); - return ( text && XMLUtil::StringEqual( text->Value(), Value() ) ); -} - - -bool XMLText::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - - -// --------- XMLComment ---------- // - -XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLComment::~XMLComment() -{ -} - - -char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - // Comment parses as text. - p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 ); - } - return p; -} - - -XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? - return comment; -} - - -bool XMLComment::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLComment* comment = compare->ToComment(); - return ( comment && XMLUtil::StringEqual( comment->Value(), Value() )); -} - - -bool XMLComment::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - - -// --------- XMLDeclaration ---------- // - -XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLDeclaration::~XMLDeclaration() -{ - //printf( "~XMLDeclaration\n" ); -} - - -char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - // Declaration parses as text. - p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 ); - } - return p; -} - - -XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? - return dec; -} - - -bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLDeclaration* declaration = compare->ToDeclaration(); - return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() )); -} - - - -bool XMLDeclaration::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - -// --------- XMLUnknown ---------- // - -XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLUnknown::~XMLUnknown() -{ -} - - -char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) -{ - // Unknown parses as text. - p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 ); - } - return p; -} - - -XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? - return text; -} - - -bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLUnknown* unknown = compare->ToUnknown(); - return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() )); -} - - -bool XMLUnknown::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); -} - -// --------- XMLAttribute ---------- // - +{ + // Edge case: XMLDocuments don't have a Value. Return null. + if ( this->ToDocument() ) + return 0; + return _value.GetStr(); +} + +void XMLNode::SetValue( const char* str, bool staticMem ) +{ + if ( staticMem ) { + _value.SetInternedStr( str ); + } + else { + _value.SetStr( str ); + } +} + +XMLNode* XMLNode::DeepClone(XMLDocument* target) const +{ + XMLNode* clone = this->ShallowClone(target); + if (!clone) return 0; + + for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) { + XMLNode* childClone = child->DeepClone(target); + TIXMLASSERT(childClone); + clone->InsertEndChild(childClone); + } + return clone; +} + +void XMLNode::DeleteChildren() +{ + while( _firstChild ) { + TIXMLASSERT( _lastChild ); + DeleteChild( _firstChild ); + } + _firstChild = _lastChild = 0; +} + + +void XMLNode::Unlink( XMLNode* child ) +{ + TIXMLASSERT( child ); + TIXMLASSERT( child->_document == _document ); + TIXMLASSERT( child->_parent == this ); + if ( child == _firstChild ) { + _firstChild = _firstChild->_next; + } + if ( child == _lastChild ) { + _lastChild = _lastChild->_prev; + } + + if ( child->_prev ) { + child->_prev->_next = child->_next; + } + if ( child->_next ) { + child->_next->_prev = child->_prev; + } + child->_next = 0; + child->_prev = 0; + child->_parent = 0; +} + + +void XMLNode::DeleteChild( XMLNode* node ) +{ + TIXMLASSERT( node ); + TIXMLASSERT( node->_document == _document ); + TIXMLASSERT( node->_parent == this ); + Unlink( node ); + TIXMLASSERT(node->_prev == 0); + TIXMLASSERT(node->_next == 0); + TIXMLASSERT(node->_parent == 0); + DeleteNode( node ); +} + + +XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) +{ + TIXMLASSERT( addThis ); + if ( addThis->_document != _document ) { + TIXMLASSERT( false ); + return 0; + } + InsertChildPreamble( addThis ); + + if ( _lastChild ) { + TIXMLASSERT( _firstChild ); + TIXMLASSERT( _lastChild->_next == 0 ); + _lastChild->_next = addThis; + addThis->_prev = _lastChild; + _lastChild = addThis; + + addThis->_next = 0; + } + else { + TIXMLASSERT( _firstChild == 0 ); + _firstChild = _lastChild = addThis; + + addThis->_prev = 0; + addThis->_next = 0; + } + addThis->_parent = this; + return addThis; +} + + +XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) +{ + TIXMLASSERT( addThis ); + if ( addThis->_document != _document ) { + TIXMLASSERT( false ); + return 0; + } + InsertChildPreamble( addThis ); + + if ( _firstChild ) { + TIXMLASSERT( _lastChild ); + TIXMLASSERT( _firstChild->_prev == 0 ); + + _firstChild->_prev = addThis; + addThis->_next = _firstChild; + _firstChild = addThis; + + addThis->_prev = 0; + } + else { + TIXMLASSERT( _lastChild == 0 ); + _firstChild = _lastChild = addThis; + + addThis->_prev = 0; + addThis->_next = 0; + } + addThis->_parent = this; + return addThis; +} + + +XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) +{ + TIXMLASSERT( addThis ); + if ( addThis->_document != _document ) { + TIXMLASSERT( false ); + return 0; + } + + TIXMLASSERT( afterThis ); + + if ( afterThis->_parent != this ) { + TIXMLASSERT( false ); + return 0; + } + if ( afterThis == addThis ) { + // Current state: BeforeThis -> AddThis -> OneAfterAddThis + // Now AddThis must disappear from it's location and then + // reappear between BeforeThis and OneAfterAddThis. + // So just leave it where it is. + return addThis; + } + + if ( afterThis->_next == 0 ) { + // The last node or the only node. + return InsertEndChild( addThis ); + } + InsertChildPreamble( addThis ); + addThis->_prev = afterThis; + addThis->_next = afterThis->_next; + afterThis->_next->_prev = addThis; + afterThis->_next = addThis; + addThis->_parent = this; + return addThis; +} + + + + +const XMLElement* XMLNode::FirstChildElement( const char* name ) const +{ + for( const XMLNode* node = _firstChild; node; node = node->_next ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +const XMLElement* XMLNode::LastChildElement( const char* name ) const +{ + for( const XMLNode* node = _lastChild; node; node = node->_prev ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +const XMLElement* XMLNode::NextSiblingElement( const char* name ) const +{ + for( const XMLNode* node = _next; node; node = node->_next ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const +{ + for( const XMLNode* node = _prev; node; node = node->_prev ) { + const XMLElement* element = node->ToElementWithName( name ); + if ( element ) { + return element; + } + } + return 0; +} + + +char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) +{ + // This is a recursive method, but thinking about it "at the current level" + // it is a pretty simple flat list: + // <foo/> + // <!-- comment --> + // + // With a special case: + // <foo> + // </foo> + // <!-- comment --> + // + // Where the closing element (/foo) *must* be the next thing after the opening + // element, and the names must match. BUT the tricky bit is that the closing + // element will be read by the child. + // + // 'endTag' is the end tag for this node, it is returned by a call to a child. + // 'parentEnd' is the end tag for the parent, which is filled in and returned. + + while( p && *p ) { + XMLNode* node = 0; + + p = _document->Identify( p, &node ); + TIXMLASSERT( p ); + if ( node == 0 ) { + break; + } + + int initialLineNum = node->_parseLineNum; + + StrPair endTag; + p = node->ParseDeep( p, &endTag, curLineNumPtr ); + if ( !p ) { + DeleteNode( node ); + if ( !_document->Error() ) { + _document->SetError( XML_ERROR_PARSING, initialLineNum, 0); + } + break; + } + + XMLDeclaration* decl = node->ToDeclaration(); + if ( decl ) { + // Declarations are only allowed at document level + bool wellLocated = ( ToDocument() != 0 ); + if ( wellLocated ) { + // Multiple declarations are allowed but all declarations + // must occur before anything else + for ( const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling() ) { + if ( !existingNode->ToDeclaration() ) { + wellLocated = false; + break; + } + } + } + if ( !wellLocated ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); + DeleteNode( node ); + break; + } + } + + XMLElement* ele = node->ToElement(); + if ( ele ) { + // We read the end tag. Return it to the parent. + if ( ele->ClosingType() == XMLElement::CLOSING ) { + if ( parentEndTag ) { + ele->_value.TransferTo( parentEndTag ); + } + node->_memPool->SetTracked(); // created and then immediately deleted. + DeleteNode( node ); + return p; + } + + // Handle an end tag returned to this level. + // And handle a bunch of annoying errors. + bool mismatch = false; + if ( endTag.Empty() ) { + if ( ele->ClosingType() == XMLElement::OPEN ) { + mismatch = true; + } + } + else { + if ( ele->ClosingType() != XMLElement::OPEN ) { + mismatch = true; + } + else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) { + mismatch = true; + } + } + if ( mismatch ) { + _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); + DeleteNode( node ); + break; + } + } + InsertEndChild( node ); + } + return 0; +} + +/*static*/ void XMLNode::DeleteNode( XMLNode* node ) +{ + if ( node == 0 ) { + return; + } + TIXMLASSERT(node->_document); + if (!node->ToDocument()) { + node->_document->MarkInUse(node); + } + + MemPool* pool = node->_memPool; + node->~XMLNode(); + pool->Free( node ); +} + +void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const +{ + TIXMLASSERT( insertThis ); + TIXMLASSERT( insertThis->_document == _document ); + + if (insertThis->_parent) { + insertThis->_parent->Unlink( insertThis ); + } + else { + insertThis->_document->MarkInUse(insertThis); + insertThis->_memPool->SetTracked(); + } +} + +const XMLElement* XMLNode::ToElementWithName( const char* name ) const +{ + const XMLElement* element = this->ToElement(); + if ( element == 0 ) { + return 0; + } + if ( name == 0 ) { + return element; + } + if ( XMLUtil::StringEqual( element->Name(), name ) ) { + return element; + } + return 0; +} + +// --------- XMLText ---------- // +char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + if ( this->CData() ) { + p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_CDATA, _parseLineNum, 0 ); + } + return p; + } + else { + int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; + if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { + flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; + } + + p = _value.ParseText( p, "<", flags, curLineNumPtr ); + if ( p && *p ) { + return p-1; + } + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_TEXT, _parseLineNum, 0 ); + } + } + return 0; +} + + +XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? + text->SetCData( this->CData() ); + return text; +} + + +bool XMLText::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLText* text = compare->ToText(); + return ( text && XMLUtil::StringEqual( text->Value(), Value() ) ); +} + + +bool XMLText::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + + +// --------- XMLComment ---------- // + +XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLComment::~XMLComment() +{ +} + + +char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + // Comment parses as text. + p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 ); + } + return p; +} + + +XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? + return comment; +} + + +bool XMLComment::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLComment* comment = compare->ToComment(); + return ( comment && XMLUtil::StringEqual( comment->Value(), Value() )); +} + + +bool XMLComment::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + + +// --------- XMLDeclaration ---------- // + +XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLDeclaration::~XMLDeclaration() +{ + //printf( "~XMLDeclaration\n" ); +} + + +char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + // Declaration parses as text. + p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); + if ( p == 0 ) { + _document->SetError( XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 ); + } + return p; +} + + +XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? + return dec; +} + + +bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLDeclaration* declaration = compare->ToDeclaration(); + return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() )); +} + + + +bool XMLDeclaration::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + +// --------- XMLUnknown ---------- // + +XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) +{ +} + + +XMLUnknown::~XMLUnknown() +{ +} + + +char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +{ + // Unknown parses as text. + p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); + if ( !p ) { + _document->SetError( XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 ); + } + return p; +} + + +XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? + return text; +} + + +bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLUnknown* unknown = compare->ToUnknown(); + return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() )); +} + + +bool XMLUnknown::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + return visitor->Visit( *this ); +} + +// --------- XMLAttribute ---------- // + const char* XMLAttribute::Name() const -{ - return _name.GetStr(); -} - +{ + return _name.GetStr(); +} + const char* XMLAttribute::Value() const -{ - return _value.GetStr(); -} - -char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr ) -{ - // Parse using the name rules: bug fix, was using ParseText before - p = _name.ParseName( p ); - if ( !p || !*p ) { - return 0; - } - - // Skip white space before = - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( *p != '=' ) { - return 0; - } - - ++p; // move up to opening quote - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( *p != '\"' && *p != '\'' ) { - return 0; - } - - char endTag[2] = { *p, 0 }; - ++p; // move past opening quote - - p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr ); - return p; -} - - -void XMLAttribute::SetName( const char* n ) -{ - _name.SetStr( n ); -} - - -XMLError XMLAttribute::QueryIntValue( int* value ) const -{ - if ( XMLUtil::ToInt( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const -{ - if ( XMLUtil::ToUnsigned( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryInt64Value(int64_t* value) const -{ - if (XMLUtil::ToInt64(Value(), value)) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryBoolValue( bool* value ) const -{ - if ( XMLUtil::ToBool( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryFloatValue( float* value ) const -{ - if ( XMLUtil::ToFloat( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryDoubleValue( double* value ) const -{ - if ( XMLUtil::ToDouble( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -void XMLAttribute::SetAttribute( const char* v ) -{ - _value.SetStr( v ); -} - - -void XMLAttribute::SetAttribute( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute(int64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - _value.SetStr(buf); -} - - - -void XMLAttribute::SetAttribute( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -// --------- XMLElement ---------- // -XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), - _closingType( OPEN ), - _rootAttribute( 0 ) -{ -} - - -XMLElement::~XMLElement() -{ - while( _rootAttribute ) { - XMLAttribute* next = _rootAttribute->_next; - DeleteAttribute( _rootAttribute ); - _rootAttribute = next; - } -} - - -const XMLAttribute* XMLElement::FindAttribute( const char* name ) const -{ - for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; -} - - -const char* XMLElement::Attribute( const char* name, const char* value ) const -{ - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return 0; - } - if ( !value || XMLUtil::StringEqual( a->Value(), value )) { - return a->Value(); - } - return 0; -} - +{ + return _value.GetStr(); +} + +char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr ) +{ + // Parse using the name rules: bug fix, was using ParseText before + p = _name.ParseName( p ); + if ( !p || !*p ) { + return 0; + } + + // Skip white space before = + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + if ( *p != '=' ) { + return 0; + } + + ++p; // move up to opening quote + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + if ( *p != '\"' && *p != '\'' ) { + return 0; + } + + char endTag[2] = { *p, 0 }; + ++p; // move past opening quote + + p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr ); + return p; +} + + +void XMLAttribute::SetName( const char* n ) +{ + _name.SetStr( n ); +} + + +XMLError XMLAttribute::QueryIntValue( int* value ) const +{ + if ( XMLUtil::ToInt( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const +{ + if ( XMLUtil::ToUnsigned( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryInt64Value(int64_t* value) const +{ + if (XMLUtil::ToInt64(Value(), value)) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryBoolValue( bool* value ) const +{ + if ( XMLUtil::ToBool( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryFloatValue( float* value ) const +{ + if ( XMLUtil::ToFloat( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +XMLError XMLAttribute::QueryDoubleValue( double* value ) const +{ + if ( XMLUtil::ToDouble( Value(), value )) { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; +} + + +void XMLAttribute::SetAttribute( const char* v ) +{ + _value.SetStr( v ); +} + + +void XMLAttribute::SetAttribute( int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute( unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +void XMLAttribute::SetAttribute(int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); +} + + + +void XMLAttribute::SetAttribute( bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + +void XMLAttribute::SetAttribute( float v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + _value.SetStr( buf ); +} + + +// --------- XMLElement ---------- // +XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), + _closingType( OPEN ), + _rootAttribute( 0 ) +{ +} + + +XMLElement::~XMLElement() +{ + while( _rootAttribute ) { + XMLAttribute* next = _rootAttribute->_next; + DeleteAttribute( _rootAttribute ); + _rootAttribute = next; + } +} + + +const XMLAttribute* XMLElement::FindAttribute( const char* name ) const +{ + for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) { + if ( XMLUtil::StringEqual( a->Name(), name ) ) { + return a; + } + } + return 0; +} + + +const char* XMLElement::Attribute( const char* name, const char* value ) const +{ + const XMLAttribute* a = FindAttribute( name ); + if ( !a ) { + return 0; + } + if ( !value || XMLUtil::StringEqual( a->Value(), value )) { + return a->Value(); + } + return 0; +} + int XMLElement::IntAttribute(const char* name, int defaultValue) const -{ - int i = defaultValue; - QueryIntAttribute(name, &i); - return i; -} - +{ + int i = defaultValue; + QueryIntAttribute(name, &i); + return i; +} + unsigned XMLElement::UnsignedAttribute(const char* name, unsigned defaultValue) const -{ - unsigned i = defaultValue; - QueryUnsignedAttribute(name, &i); - return i; -} - +{ + unsigned i = defaultValue; + QueryUnsignedAttribute(name, &i); + return i; +} + int64_t XMLElement::Int64Attribute(const char* name, int64_t defaultValue) const -{ - int64_t i = defaultValue; - QueryInt64Attribute(name, &i); - return i; -} - +{ + int64_t i = defaultValue; + QueryInt64Attribute(name, &i); + return i; +} + bool XMLElement::BoolAttribute(const char* name, bool defaultValue) const -{ - bool b = defaultValue; - QueryBoolAttribute(name, &b); - return b; -} - +{ + bool b = defaultValue; + QueryBoolAttribute(name, &b); + return b; +} + double XMLElement::DoubleAttribute(const char* name, double defaultValue) const -{ - double d = defaultValue; - QueryDoubleAttribute(name, &d); - return d; -} - +{ + double d = defaultValue; + QueryDoubleAttribute(name, &d); + return d; +} + float XMLElement::FloatAttribute(const char* name, float defaultValue) const -{ - float f = defaultValue; - QueryFloatAttribute(name, &f); - return f; -} - -const char* XMLElement::GetText() const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - return FirstChild()->Value(); - } - return 0; -} - - -void XMLElement::SetText( const char* inText ) -{ - if ( FirstChild() && FirstChild()->ToText() ) - FirstChild()->SetValue( inText ); - else { - XMLText* theText = GetDocument()->NewText( inText ); - InsertFirstChild( theText ); - } -} - - +{ + float f = defaultValue; + QueryFloatAttribute(name, &f); + return f; +} + +const char* XMLElement::GetText() const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + return FirstChild()->Value(); + } + return 0; +} + + +void XMLElement::SetText( const char* inText ) +{ + if ( FirstChild() && FirstChild()->ToText() ) + FirstChild()->SetValue( inText ); + else { + XMLText* theText = GetDocument()->NewText( inText ); + InsertFirstChild( theText ); + } +} + + void XMLElement::SetText( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + void XMLElement::SetText( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText(int64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - SetText(buf); -} - - -void XMLElement::SetText( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +void XMLElement::SetText(int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); +} + + +void XMLElement::SetText( bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + void XMLElement::SetText( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + void XMLElement::SetText( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -XMLError XMLElement::QueryIntText( int* ival ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToInt( t, ival ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToUnsigned( t, uval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryInt64Text(int64_t* ival) const -{ - if (FirstChild() && FirstChild()->ToText()) { - const char* t = FirstChild()->Value(); - if (XMLUtil::ToInt64(t, ival)) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryBoolText( bool* bval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToBool( t, bval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryDoubleText( double* dval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToDouble( t, dval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryFloatText( float* fval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToFloat( t, fval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - -int XMLElement::IntText(int defaultValue) const -{ - int i = defaultValue; - QueryIntText(&i); - return i; -} - -unsigned XMLElement::UnsignedText(unsigned defaultValue) const -{ - unsigned i = defaultValue; - QueryUnsignedText(&i); - return i; -} - -int64_t XMLElement::Int64Text(int64_t defaultValue) const -{ - int64_t i = defaultValue; - QueryInt64Text(&i); - return i; -} - -bool XMLElement::BoolText(bool defaultValue) const -{ - bool b = defaultValue; - QueryBoolText(&b); - return b; -} - -double XMLElement::DoubleText(double defaultValue) const -{ - double d = defaultValue; - QueryDoubleText(&d); - return d; -} - -float XMLElement::FloatText(float defaultValue) const -{ - float f = defaultValue; - QueryFloatText(&f); - return f; -} - - -XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) -{ - XMLAttribute* last = 0; - XMLAttribute* attrib = 0; - for( attrib = _rootAttribute; - attrib; - last = attrib, attrib = attrib->_next ) { - if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { - break; - } - } - if ( !attrib ) { - attrib = CreateAttribute(); - TIXMLASSERT( attrib ); - if ( last ) { - TIXMLASSERT( last->_next == 0 ); - last->_next = attrib; - } - else { - TIXMLASSERT( _rootAttribute == 0 ); - _rootAttribute = attrib; - } - attrib->SetName( name ); - } - return attrib; -} - - -void XMLElement::DeleteAttribute( const char* name ) -{ - XMLAttribute* prev = 0; - for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { - if ( XMLUtil::StringEqual( name, a->Name() ) ) { - if ( prev ) { - prev->_next = a->_next; - } - else { - _rootAttribute = a->_next; - } - DeleteAttribute( a ); - break; - } - prev = a; - } -} - - -char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr ) -{ - XMLAttribute* prevAttribute = 0; - - // Read the attributes. - while( p ) { - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( !(*p) ) { - _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() ); - return 0; - } - - // attribute. - if (XMLUtil::IsNameStartChar( *p ) ) { - XMLAttribute* attrib = CreateAttribute(); - TIXMLASSERT( attrib ); - attrib->_parseLineNum = _document->_parseCurLineNum; - - int attrLineNum = attrib->_parseLineNum; - - p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr ); - if ( !p || Attribute( attrib->Name() ) ) { - DeleteAttribute( attrib ); - _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() ); - return 0; - } - // There is a minor bug here: if the attribute in the source xml - // document is duplicated, it will not be detected and the - // attribute will be doubly added. However, tracking the 'prevAttribute' - // avoids re-scanning the attribute list. Preferring performance for - // now, may reconsider in the future. - if ( prevAttribute ) { - TIXMLASSERT( prevAttribute->_next == 0 ); - prevAttribute->_next = attrib; - } - else { - TIXMLASSERT( _rootAttribute == 0 ); - _rootAttribute = attrib; - } - prevAttribute = attrib; - } - // end of the tag - else if ( *p == '>' ) { - ++p; - break; - } - // end of the tag - else if ( *p == '/' && *(p+1) == '>' ) { - _closingType = CLOSED; - return p+2; // done; sealed element. - } - else { - _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 ); - return 0; - } - } - return p; -} - -void XMLElement::DeleteAttribute( XMLAttribute* attribute ) -{ - if ( attribute == 0 ) { - return; - } - MemPool* pool = attribute->_memPool; - attribute->~XMLAttribute(); - pool->Free( attribute ); -} - -XMLAttribute* XMLElement::CreateAttribute() -{ - TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); - XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - TIXMLASSERT( attrib ); - attrib->_memPool = &_document->_attributePool; - attrib->_memPool->SetTracked(); - return attrib; -} - -// -// <ele></ele> -// <ele>foo<b>bar</b></ele> -// -char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) -{ - // Read the element name. - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - - // The closing element is the </element> form. It is - // parsed just like a regular element then deleted from - // the DOM. - if ( *p == '/' ) { - _closingType = CLOSING; - ++p; - } - - p = _value.ParseName( p ); - if ( _value.Empty() ) { - return 0; - } - - p = ParseAttributes( p, curLineNumPtr ); - if ( !p || !*p || _closingType != OPEN ) { - return p; - } - - p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr ); - return p; -} - - - -XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? - for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { - element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? - } - return element; -} - - -bool XMLElement::ShallowEqual( const XMLNode* compare ) const -{ - TIXMLASSERT( compare ); - const XMLElement* other = compare->ToElement(); - if ( other && XMLUtil::StringEqual( other->Name(), Name() )) { - - const XMLAttribute* a=FirstAttribute(); - const XMLAttribute* b=other->FirstAttribute(); - - while ( a && b ) { - if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { - return false; - } - a = a->Next(); - b = b->Next(); - } - if ( a || b ) { - // different count - return false; - } - return true; - } - return false; -} - - -bool XMLElement::Accept( XMLVisitor* visitor ) const -{ - TIXMLASSERT( visitor ); - if ( visitor->VisitEnter( *this, _rootAttribute ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLDocument ----------- // - -// Warning: List must match 'enum XMLError' -const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { - "XML_SUCCESS", - "XML_NO_ATTRIBUTE", - "XML_WRONG_ATTRIBUTE_TYPE", - "XML_ERROR_FILE_NOT_FOUND", - "XML_ERROR_FILE_COULD_NOT_BE_OPENED", - "XML_ERROR_FILE_READ_ERROR", - "UNUSED_XML_ERROR_ELEMENT_MISMATCH", - "XML_ERROR_PARSING_ELEMENT", - "XML_ERROR_PARSING_ATTRIBUTE", - "UNUSED_XML_ERROR_IDENTIFYING_TAG", - "XML_ERROR_PARSING_TEXT", - "XML_ERROR_PARSING_CDATA", - "XML_ERROR_PARSING_COMMENT", - "XML_ERROR_PARSING_DECLARATION", - "XML_ERROR_PARSING_UNKNOWN", - "XML_ERROR_EMPTY_DOCUMENT", - "XML_ERROR_MISMATCHED_ELEMENT", - "XML_ERROR_PARSING", - "XML_CAN_NOT_CONVERT_TEXT", - "XML_NO_TEXT_NODE" -}; - - -XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) : - XMLNode( 0 ), - _writeBOM( false ), - _processEntities( processEntities ), - _errorID(XML_SUCCESS), - _whitespaceMode( whitespaceMode ), - _errorStr(), - _errorLineNum( 0 ), - _charBuffer( 0 ), - _parseCurLineNum( 0 ), - _unlinked(), - _elementPool(), - _attributePool(), - _textPool(), - _commentPool() -{ - // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) - _document = this; -} - - -XMLDocument::~XMLDocument() -{ - Clear(); -} - - -void XMLDocument::MarkInUse(XMLNode* node) -{ - TIXMLASSERT(node); - TIXMLASSERT(node->_parent == 0); - - for (int i = 0; i < _unlinked.Size(); ++i) { - if (node == _unlinked[i]) { - _unlinked.SwapRemove(i); - break; - } - } -} - -void XMLDocument::Clear() -{ - DeleteChildren(); - while( _unlinked.Size()) { - DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. - } - -#ifdef DEBUG - const bool hadError = Error(); -#endif - ClearError(); - - Aws::DeleteArray(_charBuffer); - _charBuffer = 0; - -#if 0 - _textPool.Trace( "text" ); - _elementPool.Trace( "element" ); - _commentPool.Trace( "comment" ); - _attributePool.Trace( "attribute" ); -#endif - -#ifdef DEBUG - if ( !hadError ) { - TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); - TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); - TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); - TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); - } -#endif -} - - -void XMLDocument::DeepCopy(XMLDocument* target) const -{ - TIXMLASSERT(target); - if (target == this) { - return; // technically success - a no-op. - } - - target->Clear(); - for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) { - target->InsertEndChild(node->DeepClone(target)); - } -} - -XMLElement* XMLDocument::NewElement( const char* name ) -{ - XMLElement* ele = CreateUnlinkedNode<XMLElement>( _elementPool ); - ele->SetName( name ); - return ele; -} - - -XMLComment* XMLDocument::NewComment( const char* str ) -{ - XMLComment* comment = CreateUnlinkedNode<XMLComment>( _commentPool ); - comment->SetValue( str ); - return comment; -} - - -XMLText* XMLDocument::NewText( const char* str ) -{ - XMLText* text = CreateUnlinkedNode<XMLText>( _textPool ); - text->SetValue( str ); - return text; -} - - -XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) -{ - XMLDeclaration* dec = CreateUnlinkedNode<XMLDeclaration>( _commentPool ); - dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); - return dec; -} - - -XMLUnknown* XMLDocument::NewUnknown( const char* str ) -{ - XMLUnknown* unk = CreateUnlinkedNode<XMLUnknown>( _commentPool ); - unk->SetValue( str ); - return unk; -} - -static FILE* callfopen( const char* filepath, const char* mode ) -{ - TIXMLASSERT( filepath ); - TIXMLASSERT( mode ); -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) - FILE* fp = 0; - errno_t err = fopen_s( &fp, filepath, mode ); - if ( err ) { - return 0; - } -#else - FILE* fp = fopen( filepath, mode ); -#endif - return fp; -} - -void XMLDocument::DeleteNode( XMLNode* node ) { - TIXMLASSERT( node ); - TIXMLASSERT(node->_document == this ); - if (node->_parent) { - node->_parent->DeleteChild( node ); - } - else { - // Isn't in the tree. - // Use the parent delete. - // Also, we need to mark it tracked: we 'know' - // it was never used. - node->_memPool->SetTracked(); - // Call the static XMLNode version: - XMLNode::DeleteNode(node); - } -} - - -XMLError XMLDocument::LoadFile( const char* filename ) -{ - Clear(); - FILE* fp = callfopen( filename, "rb" ); - if ( !fp ) { - SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ? filename : "<null>"); - return _errorID; - } - LoadFile( fp ); - fclose( fp ); - return _errorID; -} - -// This is likely overengineered template art to have a check that unsigned long value incremented -// by one still fits into size_t. If size_t type is larger than unsigned long type -// (x86_64-w64-mingw32 target) then the check is redundant and gcc and clang emit -// -Wtype-limits warning. This piece makes the compiler select code with a check when a check -// is useful and code with no check when a check is redundant depending on how size_t and unsigned long -// types sizes relate to each other. -template -<bool = (sizeof(unsigned long) >= sizeof(size_t))> -struct LongFitsIntoSizeTMinusOne { - static bool Fits( unsigned long value ) - { - return value < (size_t)-1; - } -}; - -template <> -struct LongFitsIntoSizeTMinusOne<false> { - static bool Fits( unsigned long ) - { - return true; - } -}; - -XMLError XMLDocument::LoadFile( FILE* fp ) -{ - Clear(); - - fseek( fp, 0, SEEK_SET ); - if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - fseek( fp, 0, SEEK_END ); - const long filelength = ftell( fp ); - fseek( fp, 0, SEEK_SET ); - if ( filelength == -1L ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - TIXMLASSERT( filelength >= 0 ); - - if ( !LongFitsIntoSizeTMinusOne<>::Fits( filelength ) ) { - // Cannot handle files which won't fit in buffer together with null terminator - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - if ( filelength == 0 ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - const size_t size = filelength; - TIXMLASSERT( _charBuffer == 0 ); - _charBuffer = Aws::NewArray <char>(size+1, ALLOCATION_TAG); - size_t read = fread( _charBuffer, 1, size, fp ); - if ( read != size ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - _charBuffer[size] = 0; - - Parse(); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( const char* filename, bool compact ) -{ - FILE* fp = callfopen( filename, "w" ); - if ( !fp ) { - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ? filename : "<null>"); - return _errorID; - } - SaveFile(fp, compact); - fclose( fp ); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) -{ - // Clear any error from the last save, otherwise it will get reported - // for *this* call. - ClearError(); - XMLPrinter stream( fp, compact ); - Print( &stream ); - return _errorID; -} - - -XMLError XMLDocument::Parse( const char* p, size_t len ) -{ - Clear(); - - if ( len == 0 || !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - if ( len == (size_t)(-1) ) { - len = strlen( p ); - } - TIXMLASSERT( _charBuffer == 0 ); - _charBuffer = Aws::NewArray<char>(len+1, ALLOCATION_TAG); - memcpy( _charBuffer, p, len ); - _charBuffer[len] = 0; - - Parse(); - if ( Error() ) { - // clean up now essentially dangling memory. - // and the parse fail can put objects in the - // pools that are dead and inaccessible. - DeleteChildren(); - _elementPool.Clear(); - _attributePool.Clear(); - _textPool.Clear(); - _commentPool.Clear(); - } - return _errorID; -} - - -void XMLDocument::Print( XMLPrinter* streamer ) const -{ - if ( streamer ) { - Accept( streamer ); - } - else { - XMLPrinter stdoutStreamer( stdout ); - Accept( &stdoutStreamer ); - } -} - - -void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... ) -{ - TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT ); - _errorID = error; - _errorLineNum = lineNum; - _errorStr.Reset(); - - if (format) { - size_t BUFFER_SIZE = 1000; - char* buffer = Aws::NewArray<char>(BUFFER_SIZE, ALLOCATION_TAG); - TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d: ", ErrorIDToName(error), int(error), int(error), lineNum); - size_t len = strlen(buffer); - - va_list va; - va_start( va, format ); - TIXML_VSNPRINTF( buffer + len, BUFFER_SIZE - len, format, va ); - va_end( va ); - - _errorStr.SetStr(buffer); - Aws::DeleteArray(buffer); - } -} - - -/*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID) -{ - TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT ); - const char* errorName = _errorNames[errorID]; - TIXMLASSERT( errorName && errorName[0] ); - return errorName; -} - +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + SetText( buf ); +} + + +XMLError XMLElement::QueryIntText( int* ival ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToInt( t, ival ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToUnsigned( t, uval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryInt64Text(int64_t* ival) const +{ + if (FirstChild() && FirstChild()->ToText()) { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToInt64(t, ival)) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryBoolText( bool* bval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToBool( t, bval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryDoubleText( double* dval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToDouble( t, dval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + + +XMLError XMLElement::QueryFloatText( float* fval ) const +{ + if ( FirstChild() && FirstChild()->ToText() ) { + const char* t = FirstChild()->Value(); + if ( XMLUtil::ToFloat( t, fval ) ) { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + +int XMLElement::IntText(int defaultValue) const +{ + int i = defaultValue; + QueryIntText(&i); + return i; +} + +unsigned XMLElement::UnsignedText(unsigned defaultValue) const +{ + unsigned i = defaultValue; + QueryUnsignedText(&i); + return i; +} + +int64_t XMLElement::Int64Text(int64_t defaultValue) const +{ + int64_t i = defaultValue; + QueryInt64Text(&i); + return i; +} + +bool XMLElement::BoolText(bool defaultValue) const +{ + bool b = defaultValue; + QueryBoolText(&b); + return b; +} + +double XMLElement::DoubleText(double defaultValue) const +{ + double d = defaultValue; + QueryDoubleText(&d); + return d; +} + +float XMLElement::FloatText(float defaultValue) const +{ + float f = defaultValue; + QueryFloatText(&f); + return f; +} + + +XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) +{ + XMLAttribute* last = 0; + XMLAttribute* attrib = 0; + for( attrib = _rootAttribute; + attrib; + last = attrib, attrib = attrib->_next ) { + if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { + break; + } + } + if ( !attrib ) { + attrib = CreateAttribute(); + TIXMLASSERT( attrib ); + if ( last ) { + TIXMLASSERT( last->_next == 0 ); + last->_next = attrib; + } + else { + TIXMLASSERT( _rootAttribute == 0 ); + _rootAttribute = attrib; + } + attrib->SetName( name ); + } + return attrib; +} + + +void XMLElement::DeleteAttribute( const char* name ) +{ + XMLAttribute* prev = 0; + for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { + if ( XMLUtil::StringEqual( name, a->Name() ) ) { + if ( prev ) { + prev->_next = a->_next; + } + else { + _rootAttribute = a->_next; + } + DeleteAttribute( a ); + break; + } + prev = a; + } +} + + +char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr ) +{ + XMLAttribute* prevAttribute = 0; + + // Read the attributes. + while( p ) { + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + if ( !(*p) ) { + _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() ); + return 0; + } + + // attribute. + if (XMLUtil::IsNameStartChar( *p ) ) { + XMLAttribute* attrib = CreateAttribute(); + TIXMLASSERT( attrib ); + attrib->_parseLineNum = _document->_parseCurLineNum; + + int attrLineNum = attrib->_parseLineNum; + + p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr ); + if ( !p || Attribute( attrib->Name() ) ) { + DeleteAttribute( attrib ); + _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() ); + return 0; + } + // There is a minor bug here: if the attribute in the source xml + // document is duplicated, it will not be detected and the + // attribute will be doubly added. However, tracking the 'prevAttribute' + // avoids re-scanning the attribute list. Preferring performance for + // now, may reconsider in the future. + if ( prevAttribute ) { + TIXMLASSERT( prevAttribute->_next == 0 ); + prevAttribute->_next = attrib; + } + else { + TIXMLASSERT( _rootAttribute == 0 ); + _rootAttribute = attrib; + } + prevAttribute = attrib; + } + // end of the tag + else if ( *p == '>' ) { + ++p; + break; + } + // end of the tag + else if ( *p == '/' && *(p+1) == '>' ) { + _closingType = CLOSED; + return p+2; // done; sealed element. + } + else { + _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 ); + return 0; + } + } + return p; +} + +void XMLElement::DeleteAttribute( XMLAttribute* attribute ) +{ + if ( attribute == 0 ) { + return; + } + MemPool* pool = attribute->_memPool; + attribute->~XMLAttribute(); + pool->Free( attribute ); +} + +XMLAttribute* XMLElement::CreateAttribute() +{ + TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); + XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); + TIXMLASSERT( attrib ); + attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); + return attrib; +} + +// +// <ele></ele> +// <ele>foo<b>bar</b></ele> +// +char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) +{ + // Read the element name. + p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + + // The closing element is the </element> form. It is + // parsed just like a regular element then deleted from + // the DOM. + if ( *p == '/' ) { + _closingType = CLOSING; + ++p; + } + + p = _value.ParseName( p ); + if ( _value.Empty() ) { + return 0; + } + + p = ParseAttributes( p, curLineNumPtr ); + if ( !p || !*p || _closingType != OPEN ) { + return p; + } + + p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr ); + return p; +} + + + +XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const +{ + if ( !doc ) { + doc = _document; + } + XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? + for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { + element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? + } + return element; +} + + +bool XMLElement::ShallowEqual( const XMLNode* compare ) const +{ + TIXMLASSERT( compare ); + const XMLElement* other = compare->ToElement(); + if ( other && XMLUtil::StringEqual( other->Name(), Name() )) { + + const XMLAttribute* a=FirstAttribute(); + const XMLAttribute* b=other->FirstAttribute(); + + while ( a && b ) { + if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { + return false; + } + a = a->Next(); + b = b->Next(); + } + if ( a || b ) { + // different count + return false; + } + return true; + } + return false; +} + + +bool XMLElement::Accept( XMLVisitor* visitor ) const +{ + TIXMLASSERT( visitor ); + if ( visitor->VisitEnter( *this, _rootAttribute ) ) { + for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { + if ( !node->Accept( visitor ) ) { + break; + } + } + } + return visitor->VisitExit( *this ); +} + + +// --------- XMLDocument ----------- // + +// Warning: List must match 'enum XMLError' +const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { + "XML_SUCCESS", + "XML_NO_ATTRIBUTE", + "XML_WRONG_ATTRIBUTE_TYPE", + "XML_ERROR_FILE_NOT_FOUND", + "XML_ERROR_FILE_COULD_NOT_BE_OPENED", + "XML_ERROR_FILE_READ_ERROR", + "UNUSED_XML_ERROR_ELEMENT_MISMATCH", + "XML_ERROR_PARSING_ELEMENT", + "XML_ERROR_PARSING_ATTRIBUTE", + "UNUSED_XML_ERROR_IDENTIFYING_TAG", + "XML_ERROR_PARSING_TEXT", + "XML_ERROR_PARSING_CDATA", + "XML_ERROR_PARSING_COMMENT", + "XML_ERROR_PARSING_DECLARATION", + "XML_ERROR_PARSING_UNKNOWN", + "XML_ERROR_EMPTY_DOCUMENT", + "XML_ERROR_MISMATCHED_ELEMENT", + "XML_ERROR_PARSING", + "XML_CAN_NOT_CONVERT_TEXT", + "XML_NO_TEXT_NODE" +}; + + +XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) : + XMLNode( 0 ), + _writeBOM( false ), + _processEntities( processEntities ), + _errorID(XML_SUCCESS), + _whitespaceMode( whitespaceMode ), + _errorStr(), + _errorLineNum( 0 ), + _charBuffer( 0 ), + _parseCurLineNum( 0 ), + _unlinked(), + _elementPool(), + _attributePool(), + _textPool(), + _commentPool() +{ + // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) + _document = this; +} + + +XMLDocument::~XMLDocument() +{ + Clear(); +} + + +void XMLDocument::MarkInUse(XMLNode* node) +{ + TIXMLASSERT(node); + TIXMLASSERT(node->_parent == 0); + + for (int i = 0; i < _unlinked.Size(); ++i) { + if (node == _unlinked[i]) { + _unlinked.SwapRemove(i); + break; + } + } +} + +void XMLDocument::Clear() +{ + DeleteChildren(); + while( _unlinked.Size()) { + DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. + } + +#ifdef DEBUG + const bool hadError = Error(); +#endif + ClearError(); + + Aws::DeleteArray(_charBuffer); + _charBuffer = 0; + +#if 0 + _textPool.Trace( "text" ); + _elementPool.Trace( "element" ); + _commentPool.Trace( "comment" ); + _attributePool.Trace( "attribute" ); +#endif + +#ifdef DEBUG + if ( !hadError ) { + TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); + TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); + TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); + TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); + } +#endif +} + + +void XMLDocument::DeepCopy(XMLDocument* target) const +{ + TIXMLASSERT(target); + if (target == this) { + return; // technically success - a no-op. + } + + target->Clear(); + for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) { + target->InsertEndChild(node->DeepClone(target)); + } +} + +XMLElement* XMLDocument::NewElement( const char* name ) +{ + XMLElement* ele = CreateUnlinkedNode<XMLElement>( _elementPool ); + ele->SetName( name ); + return ele; +} + + +XMLComment* XMLDocument::NewComment( const char* str ) +{ + XMLComment* comment = CreateUnlinkedNode<XMLComment>( _commentPool ); + comment->SetValue( str ); + return comment; +} + + +XMLText* XMLDocument::NewText( const char* str ) +{ + XMLText* text = CreateUnlinkedNode<XMLText>( _textPool ); + text->SetValue( str ); + return text; +} + + +XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) +{ + XMLDeclaration* dec = CreateUnlinkedNode<XMLDeclaration>( _commentPool ); + dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); + return dec; +} + + +XMLUnknown* XMLDocument::NewUnknown( const char* str ) +{ + XMLUnknown* unk = CreateUnlinkedNode<XMLUnknown>( _commentPool ); + unk->SetValue( str ); + return unk; +} + +static FILE* callfopen( const char* filepath, const char* mode ) +{ + TIXMLASSERT( filepath ); + TIXMLASSERT( mode ); +#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) + FILE* fp = 0; + errno_t err = fopen_s( &fp, filepath, mode ); + if ( err ) { + return 0; + } +#else + FILE* fp = fopen( filepath, mode ); +#endif + return fp; +} + +void XMLDocument::DeleteNode( XMLNode* node ) { + TIXMLASSERT( node ); + TIXMLASSERT(node->_document == this ); + if (node->_parent) { + node->_parent->DeleteChild( node ); + } + else { + // Isn't in the tree. + // Use the parent delete. + // Also, we need to mark it tracked: we 'know' + // it was never used. + node->_memPool->SetTracked(); + // Call the static XMLNode version: + XMLNode::DeleteNode(node); + } +} + + +XMLError XMLDocument::LoadFile( const char* filename ) +{ + Clear(); + FILE* fp = callfopen( filename, "rb" ); + if ( !fp ) { + SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ? filename : "<null>"); + return _errorID; + } + LoadFile( fp ); + fclose( fp ); + return _errorID; +} + +// This is likely overengineered template art to have a check that unsigned long value incremented +// by one still fits into size_t. If size_t type is larger than unsigned long type +// (x86_64-w64-mingw32 target) then the check is redundant and gcc and clang emit +// -Wtype-limits warning. This piece makes the compiler select code with a check when a check +// is useful and code with no check when a check is redundant depending on how size_t and unsigned long +// types sizes relate to each other. +template +<bool = (sizeof(unsigned long) >= sizeof(size_t))> +struct LongFitsIntoSizeTMinusOne { + static bool Fits( unsigned long value ) + { + return value < (size_t)-1; + } +}; + +template <> +struct LongFitsIntoSizeTMinusOne<false> { + static bool Fits( unsigned long ) + { + return true; + } +}; + +XMLError XMLDocument::LoadFile( FILE* fp ) +{ + Clear(); + + fseek( fp, 0, SEEK_SET ); + if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + fseek( fp, 0, SEEK_END ); + const long filelength = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + if ( filelength == -1L ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + TIXMLASSERT( filelength >= 0 ); + + if ( !LongFitsIntoSizeTMinusOne<>::Fits( filelength ) ) { + // Cannot handle files which won't fit in buffer together with null terminator + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + if ( filelength == 0 ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + + const size_t size = filelength; + TIXMLASSERT( _charBuffer == 0 ); + _charBuffer = Aws::NewArray <char>(size+1, ALLOCATION_TAG); + size_t read = fread( _charBuffer, 1, size, fp ); + if ( read != size ) { + SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); + return _errorID; + } + + _charBuffer[size] = 0; + + Parse(); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( const char* filename, bool compact ) +{ + FILE* fp = callfopen( filename, "w" ); + if ( !fp ) { + SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ? filename : "<null>"); + return _errorID; + } + SaveFile(fp, compact); + fclose( fp ); + return _errorID; +} + + +XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) +{ + // Clear any error from the last save, otherwise it will get reported + // for *this* call. + ClearError(); + XMLPrinter stream( fp, compact ); + Print( &stream ); + return _errorID; +} + + +XMLError XMLDocument::Parse( const char* p, size_t len ) +{ + Clear(); + + if ( len == 0 || !p || !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return _errorID; + } + if ( len == (size_t)(-1) ) { + len = strlen( p ); + } + TIXMLASSERT( _charBuffer == 0 ); + _charBuffer = Aws::NewArray<char>(len+1, ALLOCATION_TAG); + memcpy( _charBuffer, p, len ); + _charBuffer[len] = 0; + + Parse(); + if ( Error() ) { + // clean up now essentially dangling memory. + // and the parse fail can put objects in the + // pools that are dead and inaccessible. + DeleteChildren(); + _elementPool.Clear(); + _attributePool.Clear(); + _textPool.Clear(); + _commentPool.Clear(); + } + return _errorID; +} + + +void XMLDocument::Print( XMLPrinter* streamer ) const +{ + if ( streamer ) { + Accept( streamer ); + } + else { + XMLPrinter stdoutStreamer( stdout ); + Accept( &stdoutStreamer ); + } +} + + +void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... ) +{ + TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT ); + _errorID = error; + _errorLineNum = lineNum; + _errorStr.Reset(); + + if (format) { + size_t BUFFER_SIZE = 1000; + char* buffer = Aws::NewArray<char>(BUFFER_SIZE, ALLOCATION_TAG); + TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d: ", ErrorIDToName(error), int(error), int(error), lineNum); + size_t len = strlen(buffer); + + va_list va; + va_start( va, format ); + TIXML_VSNPRINTF( buffer + len, BUFFER_SIZE - len, format, va ); + va_end( va ); + + _errorStr.SetStr(buffer); + Aws::DeleteArray(buffer); + } +} + + +/*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID) +{ + TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT ); + const char* errorName = _errorNames[errorID]; + TIXMLASSERT( errorName && errorName[0] ); + return errorName; +} + const char* XMLDocument::ErrorStr() const -{ - return _errorStr.Empty() ? "" : _errorStr.GetStr(); -} - - -void XMLDocument::PrintError() const -{ - printf("%s\n", ErrorStr()); -} - -const char* XMLDocument::ErrorName() const -{ - return ErrorIDToName(_errorID); -} - -void XMLDocument::Parse() -{ - TIXMLASSERT( NoChildren() ); // Clear() must have been called previously - TIXMLASSERT( _charBuffer ); - _parseCurLineNum = 1; - _parseLineNum = 1; - char* p = _charBuffer; - p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); - p = const_cast<char*>( XMLUtil::ReadBOM( p, &_writeBOM ) ); - if ( !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return; - } - ParseDeep(p, 0, &_parseCurLineNum ); -} - -XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : - _elementJustOpened( false ), - _stack(), - _firstElement( true ), - _fp( file ), - _depth( depth ), - _textDepth( -1 ), - _processEntities( true ), - _compactMode( compact ), - _buffer() -{ - for( int i=0; i<ENTITY_RANGE; ++i ) { - _entityFlag[i] = false; - _restrictedEntityFlag[i] = false; - } - for( int i=0; i<NUM_ENTITIES; ++i ) { - const char entityValue = entities[i].value; - const unsigned char flagIndex = (unsigned char)entityValue; - TIXMLASSERT( flagIndex < ENTITY_RANGE ); - _entityFlag[flagIndex] = true; - } - _restrictedEntityFlag[(unsigned char)'&'] = true; - _restrictedEntityFlag[(unsigned char)'<'] = true; - _restrictedEntityFlag[(unsigned char)'>'] = true; // not required, but consistency is nice - _buffer.Push( 0 ); -} - - -void XMLPrinter::Print( const char* format, ... ) -{ - va_list va; - va_start( va, format ); - - if ( _fp ) { - vfprintf( _fp, format, va ); - } - else { - const int len = TIXML_VSCPRINTF( format, va ); - // Close out and re-start the va-args - va_end( va ); - TIXMLASSERT( len >= 0 ); - va_start( va, format ); - TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 ); - char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. - TIXML_VSNPRINTF( p, len+1, format, va ); - } - va_end( va ); -} - - -void XMLPrinter::Write( const char* data, size_t size ) -{ - if ( _fp ) { - fwrite ( data , sizeof(char), size, _fp); - } - else { - char* p = _buffer.PushArr( static_cast<int>(size) ) - 1; // back up over the null terminator. - memcpy( p, data, size ); - p[size] = 0; - } -} - - -void XMLPrinter::Putc( char ch ) -{ - if ( _fp ) { - fputc ( ch, _fp); - } - else { - char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator. - p[0] = ch; - p[1] = 0; - } -} - - -void XMLPrinter::PrintSpace( int depth ) -{ - for( int i=0; i<depth; ++i ) { - Write( " " ); - } -} - - -void XMLPrinter::PrintString( const char* p, bool restricted ) -{ - // Look for runs of bytes between entities to print. - const char* q = p; - - if ( _processEntities ) { - const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; - while ( *q ) { - TIXMLASSERT( p <= q ); - // Remember, char is sometimes signed. (How many times has that bitten me?) - if ( *q > 0 && *q < ENTITY_RANGE ) { - // Check for entities. If one is found, flush - // the stream up until the entity, write the - // entity, and keep looking. - if ( flag[(unsigned char)(*q)] ) { - while ( p < q ) { - const size_t delta = q - p; - const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; - Write( p, toPrint ); - p += toPrint; - } - bool entityPatternPrinted = false; - for( int i=0; i<NUM_ENTITIES; ++i ) { - if ( entities[i].value == *q ) { - Putc( '&' ); - Write( entities[i].pattern, entities[i].length ); - Putc( ';' ); - entityPatternPrinted = true; - break; - } - } - if ( !entityPatternPrinted ) { - // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release - TIXMLASSERT( false ); - } - ++p; - } - } - ++q; - TIXMLASSERT( p <= q ); - } - } - // Flush the remaining string. This will be the entire - // string if an entity wasn't found. - TIXMLASSERT( p <= q ); - if ( !_processEntities || ( p < q ) ) { - const size_t delta = q - p; - const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; - Write( p, toPrint ); - } -} - - -void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) -{ - if ( writeBOM ) { - static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; - Write( reinterpret_cast< const char* >( bom ) ); - } - if ( writeDec ) { - PushDeclaration( "xml version=\"1.0\"" ); - } -} - - -void XMLPrinter::OpenElement( const char* name, bool compactMode ) -{ - SealElementIfJustOpened(); - _stack.Push( name ); - - if ( _textDepth < 0 && !_firstElement && !compactMode ) { - Putc( '\n' ); - } - if ( !compactMode ) { - PrintSpace( _depth ); - } - - Write ( "<" ); - Write ( name ); - - _elementJustOpened = true; - _firstElement = false; - ++_depth; -} - - -void XMLPrinter::PushAttribute( const char* name, const char* value ) -{ - TIXMLASSERT( _elementJustOpened ); - Putc ( ' ' ); - Write( name ); - Write( "=\"" ); - PrintString( value, false ); - Putc ( '\"' ); -} - - -void XMLPrinter::PushAttribute( const char* name, int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute(const char* name, int64_t v) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr(v, buf, BUF_SIZE); - PushAttribute(name, buf); -} - - -void XMLPrinter::PushAttribute( const char* name, bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::CloseElement( bool compactMode ) -{ - --_depth; - const char* name = _stack.Pop(); - - if ( _elementJustOpened ) { - Write( "/>" ); - } - else { - if ( _textDepth < 0 && !compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - Write ( "</" ); - Write ( name ); - Write ( ">" ); - } - - if ( _textDepth == _depth ) { - _textDepth = -1; - } - if ( _depth == 0 && !compactMode) { - Putc( '\n' ); - } - _elementJustOpened = false; -} - - -void XMLPrinter::SealElementIfJustOpened() -{ - if ( !_elementJustOpened ) { - return; - } - _elementJustOpened = false; - Putc( '>' ); -} - - -void XMLPrinter::PushText( const char* text, bool cdata ) -{ - _textDepth = _depth-1; - - SealElementIfJustOpened(); - if ( cdata ) { - Write( "<![CDATA[" ); - Write( text ); - Write( "]]>" ); - } - else { - PrintString( text, true ); - } -} - -void XMLPrinter::PushText( int64_t value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - -void XMLPrinter::PushText( int value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( unsigned value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( bool value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( float value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( double value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushComment( const char* comment ) -{ - SealElementIfJustOpened(); - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - _firstElement = false; - - Write( "<!--" ); - Write( comment ); - Write( "-->" ); -} - - -void XMLPrinter::PushDeclaration( const char* value ) -{ - SealElementIfJustOpened(); - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - _firstElement = false; - - Write( "<?" ); - Write( value ); - Write( "?>" ); -} - - -void XMLPrinter::PushUnknown( const char* value ) -{ - SealElementIfJustOpened(); - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - _firstElement = false; - - Write( "<!" ); - Write( value ); - Putc( '>' ); -} - - -bool XMLPrinter::VisitEnter( const XMLDocument& doc ) -{ - _processEntities = doc.ProcessEntities(); - if ( doc.HasBOM() ) { - PushHeader( true, false ); - } - return true; -} - - -bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) -{ - const XMLElement* parentElem = 0; - if ( element.Parent() ) { - parentElem = element.Parent()->ToElement(); - } - const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode; - OpenElement( element.Name(), compactMode ); - while ( attribute ) { - PushAttribute( attribute->Name(), attribute->Value() ); - attribute = attribute->Next(); - } - return true; -} - - -bool XMLPrinter::VisitExit( const XMLElement& element ) -{ - CloseElement( CompactMode(element) ); - return true; -} - - -bool XMLPrinter::Visit( const XMLText& text ) -{ - PushText( text.Value(), text.CData() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLComment& comment ) -{ - PushComment( comment.Value() ); - return true; -} - -bool XMLPrinter::Visit( const XMLDeclaration& declaration ) -{ - PushDeclaration( declaration.Value() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLUnknown& unknown ) -{ - PushUnknown( unknown.Value() ); - return true; -} - -} // namespace tinyxml2 +{ + return _errorStr.Empty() ? "" : _errorStr.GetStr(); +} + + +void XMLDocument::PrintError() const +{ + printf("%s\n", ErrorStr()); +} + +const char* XMLDocument::ErrorName() const +{ + return ErrorIDToName(_errorID); +} + +void XMLDocument::Parse() +{ + TIXMLASSERT( NoChildren() ); // Clear() must have been called previously + TIXMLASSERT( _charBuffer ); + _parseCurLineNum = 1; + _parseLineNum = 1; + char* p = _charBuffer; + p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); + p = const_cast<char*>( XMLUtil::ReadBOM( p, &_writeBOM ) ); + if ( !*p ) { + SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); + return; + } + ParseDeep(p, 0, &_parseCurLineNum ); +} + +XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : + _elementJustOpened( false ), + _stack(), + _firstElement( true ), + _fp( file ), + _depth( depth ), + _textDepth( -1 ), + _processEntities( true ), + _compactMode( compact ), + _buffer() +{ + for( int i=0; i<ENTITY_RANGE; ++i ) { + _entityFlag[i] = false; + _restrictedEntityFlag[i] = false; + } + for( int i=0; i<NUM_ENTITIES; ++i ) { + const char entityValue = entities[i].value; + const unsigned char flagIndex = (unsigned char)entityValue; + TIXMLASSERT( flagIndex < ENTITY_RANGE ); + _entityFlag[flagIndex] = true; + } + _restrictedEntityFlag[(unsigned char)'&'] = true; + _restrictedEntityFlag[(unsigned char)'<'] = true; + _restrictedEntityFlag[(unsigned char)'>'] = true; // not required, but consistency is nice + _buffer.Push( 0 ); +} + + +void XMLPrinter::Print( const char* format, ... ) +{ + va_list va; + va_start( va, format ); + + if ( _fp ) { + vfprintf( _fp, format, va ); + } + else { + const int len = TIXML_VSCPRINTF( format, va ); + // Close out and re-start the va-args + va_end( va ); + TIXMLASSERT( len >= 0 ); + va_start( va, format ); + TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 ); + char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. + TIXML_VSNPRINTF( p, len+1, format, va ); + } + va_end( va ); +} + + +void XMLPrinter::Write( const char* data, size_t size ) +{ + if ( _fp ) { + fwrite ( data , sizeof(char), size, _fp); + } + else { + char* p = _buffer.PushArr( static_cast<int>(size) ) - 1; // back up over the null terminator. + memcpy( p, data, size ); + p[size] = 0; + } +} + + +void XMLPrinter::Putc( char ch ) +{ + if ( _fp ) { + fputc ( ch, _fp); + } + else { + char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator. + p[0] = ch; + p[1] = 0; + } +} + + +void XMLPrinter::PrintSpace( int depth ) +{ + for( int i=0; i<depth; ++i ) { + Write( " " ); + } +} + + +void XMLPrinter::PrintString( const char* p, bool restricted ) +{ + // Look for runs of bytes between entities to print. + const char* q = p; + + if ( _processEntities ) { + const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; + while ( *q ) { + TIXMLASSERT( p <= q ); + // Remember, char is sometimes signed. (How many times has that bitten me?) + if ( *q > 0 && *q < ENTITY_RANGE ) { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if ( flag[(unsigned char)(*q)] ) { + while ( p < q ) { + const size_t delta = q - p; + const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; + Write( p, toPrint ); + p += toPrint; + } + bool entityPatternPrinted = false; + for( int i=0; i<NUM_ENTITIES; ++i ) { + if ( entities[i].value == *q ) { + Putc( '&' ); + Write( entities[i].pattern, entities[i].length ); + Putc( ';' ); + entityPatternPrinted = true; + break; + } + } + if ( !entityPatternPrinted ) { + // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release + TIXMLASSERT( false ); + } + ++p; + } + } + ++q; + TIXMLASSERT( p <= q ); + } + } + // Flush the remaining string. This will be the entire + // string if an entity wasn't found. + TIXMLASSERT( p <= q ); + if ( !_processEntities || ( p < q ) ) { + const size_t delta = q - p; + const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; + Write( p, toPrint ); + } +} + + +void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) +{ + if ( writeBOM ) { + static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; + Write( reinterpret_cast< const char* >( bom ) ); + } + if ( writeDec ) { + PushDeclaration( "xml version=\"1.0\"" ); + } +} + + +void XMLPrinter::OpenElement( const char* name, bool compactMode ) +{ + SealElementIfJustOpened(); + _stack.Push( name ); + + if ( _textDepth < 0 && !_firstElement && !compactMode ) { + Putc( '\n' ); + } + if ( !compactMode ) { + PrintSpace( _depth ); + } + + Write ( "<" ); + Write ( name ); + + _elementJustOpened = true; + _firstElement = false; + ++_depth; +} + + +void XMLPrinter::PushAttribute( const char* name, const char* value ) +{ + TIXMLASSERT( _elementJustOpened ); + Putc ( ' ' ); + Write( name ); + Write( "=\"" ); + PrintString( value, false ); + Putc ( '\"' ); +} + + +void XMLPrinter::PushAttribute( const char* name, int v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, unsigned v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute(const char* name, int64_t v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); +} + + +void XMLPrinter::PushAttribute( const char* name, bool v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::PushAttribute( const char* name, double v ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( v, buf, BUF_SIZE ); + PushAttribute( name, buf ); +} + + +void XMLPrinter::CloseElement( bool compactMode ) +{ + --_depth; + const char* name = _stack.Pop(); + + if ( _elementJustOpened ) { + Write( "/>" ); + } + else { + if ( _textDepth < 0 && !compactMode) { + Putc( '\n' ); + PrintSpace( _depth ); + } + Write ( "</" ); + Write ( name ); + Write ( ">" ); + } + + if ( _textDepth == _depth ) { + _textDepth = -1; + } + if ( _depth == 0 && !compactMode) { + Putc( '\n' ); + } + _elementJustOpened = false; +} + + +void XMLPrinter::SealElementIfJustOpened() +{ + if ( !_elementJustOpened ) { + return; + } + _elementJustOpened = false; + Putc( '>' ); +} + + +void XMLPrinter::PushText( const char* text, bool cdata ) +{ + _textDepth = _depth-1; + + SealElementIfJustOpened(); + if ( cdata ) { + Write( "<![CDATA[" ); + Write( text ); + Write( "]]>" ); + } + else { + PrintString( text, true ); + } +} + +void XMLPrinter::PushText( int64_t value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + +void XMLPrinter::PushText( int value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( unsigned value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( bool value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( float value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushText( double value ) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr( value, buf, BUF_SIZE ); + PushText( buf, false ); +} + + +void XMLPrinter::PushComment( const char* comment ) +{ + SealElementIfJustOpened(); + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Putc( '\n' ); + PrintSpace( _depth ); + } + _firstElement = false; + + Write( "<!--" ); + Write( comment ); + Write( "-->" ); +} + + +void XMLPrinter::PushDeclaration( const char* value ) +{ + SealElementIfJustOpened(); + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Putc( '\n' ); + PrintSpace( _depth ); + } + _firstElement = false; + + Write( "<?" ); + Write( value ); + Write( "?>" ); +} + + +void XMLPrinter::PushUnknown( const char* value ) +{ + SealElementIfJustOpened(); + if ( _textDepth < 0 && !_firstElement && !_compactMode) { + Putc( '\n' ); + PrintSpace( _depth ); + } + _firstElement = false; + + Write( "<!" ); + Write( value ); + Putc( '>' ); +} + + +bool XMLPrinter::VisitEnter( const XMLDocument& doc ) +{ + _processEntities = doc.ProcessEntities(); + if ( doc.HasBOM() ) { + PushHeader( true, false ); + } + return true; +} + + +bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) +{ + const XMLElement* parentElem = 0; + if ( element.Parent() ) { + parentElem = element.Parent()->ToElement(); + } + const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode; + OpenElement( element.Name(), compactMode ); + while ( attribute ) { + PushAttribute( attribute->Name(), attribute->Value() ); + attribute = attribute->Next(); + } + return true; +} + + +bool XMLPrinter::VisitExit( const XMLElement& element ) +{ + CloseElement( CompactMode(element) ); + return true; +} + + +bool XMLPrinter::Visit( const XMLText& text ) +{ + PushText( text.Value(), text.CData() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLComment& comment ) +{ + PushComment( comment.Value() ); + return true; +} + +bool XMLPrinter::Visit( const XMLDeclaration& declaration ) +{ + PushDeclaration( declaration.Value() ); + return true; +} + + +bool XMLPrinter::Visit( const XMLUnknown& unknown ) +{ + PushUnknown( unknown.Value() ); + return true; +} + +} // namespace tinyxml2 } // namespace External -} // namespace Aws
\ No newline at end of file +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp index 8542023393..91a802c170 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClient.cpp @@ -2,48 +2,48 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/HttpClient.h> -#include <aws/core/http/HttpRequest.h> - -using namespace Aws; -using namespace Aws::Http; - -HttpClient::HttpClient() : - m_disableRequestProcessing( false ), - m_requestProcessingSignalLock(), - m_requestProcessingSignal() -{ -} - -void HttpClient::DisableRequestProcessing() + +#include <aws/core/http/HttpClient.h> +#include <aws/core/http/HttpRequest.h> + +using namespace Aws; +using namespace Aws::Http; + +HttpClient::HttpClient() : + m_disableRequestProcessing( false ), + m_requestProcessingSignalLock(), + m_requestProcessingSignal() { - m_disableRequestProcessing = true; - m_requestProcessingSignal.notify_all(); -} - -void HttpClient::EnableRequestProcessing() +} + +void HttpClient::DisableRequestProcessing() +{ + m_disableRequestProcessing = true; + m_requestProcessingSignal.notify_all(); +} + +void HttpClient::EnableRequestProcessing() +{ + m_disableRequestProcessing = false; +} + +bool HttpClient::IsRequestProcessingEnabled() const +{ + return m_disableRequestProcessing.load() == false; +} + +void HttpClient::RetryRequestSleep(std::chrono::milliseconds sleepTime) { - m_disableRequestProcessing = false; -} - -bool HttpClient::IsRequestProcessingEnabled() const + std::unique_lock< std::mutex > signalLocker(m_requestProcessingSignalLock); + m_requestProcessingSignal.wait_for(signalLocker, sleepTime, [this](){ return m_disableRequestProcessing.load() == true; }); +} + +bool HttpClient::ContinueRequest(const Aws::Http::HttpRequest& request) const { - return m_disableRequestProcessing.load() == false; -} - -void HttpClient::RetryRequestSleep(std::chrono::milliseconds sleepTime) -{ - std::unique_lock< std::mutex > signalLocker(m_requestProcessingSignalLock); - m_requestProcessingSignal.wait_for(signalLocker, sleepTime, [this](){ return m_disableRequestProcessing.load() == true; }); -} - -bool HttpClient::ContinueRequest(const Aws::Http::HttpRequest& request) const -{ - if (request.GetContinueRequestHandler()) - { - return request.GetContinueRequestHandler()(&request); - } - - return true; -} + if (request.GetContinueRequestHandler()) + { + return request.GetContinueRequestHandler()(&request); + } + + return true; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp index a556e39a5d..72287b1403 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpClientFactory.cpp @@ -3,201 +3,201 @@ * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/http/HttpClientFactory.h> - -#if ENABLE_CURL_CLIENT -#include <aws/core/http/curl/CurlHttpClient.h> -#include <signal.h> - -#elif ENABLE_WINDOWS_CLIENT -#include <aws/core/client/ClientConfiguration.h> -#if ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT -#error #include <aws/core/http/windows/IXmlHttpRequest2HttpClient.h> -#if BYPASS_DEFAULT_PROXY -#error #include <aws/core/http/windows/WinHttpSyncHttpClient.h> -#endif -#else -#error #include <aws/core/http/windows/WinINetSyncHttpClient.h> -#error #include <aws/core/http/windows/WinHttpSyncHttpClient.h> -#endif -#endif - -#include <aws/core/http/standard/StandardHttpRequest.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <cassert> - -using namespace Aws::Client; -using namespace Aws::Http; -using namespace Aws::Utils::Logging; - -namespace Aws -{ - namespace Http - { +#include <aws/core/http/HttpClientFactory.h> + +#if ENABLE_CURL_CLIENT +#include <aws/core/http/curl/CurlHttpClient.h> +#include <signal.h> + +#elif ENABLE_WINDOWS_CLIENT +#include <aws/core/client/ClientConfiguration.h> +#if ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT +#error #include <aws/core/http/windows/IXmlHttpRequest2HttpClient.h> +#if BYPASS_DEFAULT_PROXY +#error #include <aws/core/http/windows/WinHttpSyncHttpClient.h> +#endif +#else +#error #include <aws/core/http/windows/WinINetSyncHttpClient.h> +#error #include <aws/core/http/windows/WinHttpSyncHttpClient.h> +#endif +#endif + +#include <aws/core/http/standard/StandardHttpRequest.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <cassert> + +using namespace Aws::Client; +using namespace Aws::Http; +using namespace Aws::Utils::Logging; + +namespace Aws +{ + namespace Http + { static std::shared_ptr<HttpClientFactory>& GetHttpClientFactory() { static std::shared_ptr<HttpClientFactory> s_HttpClientFactory(nullptr); return s_HttpClientFactory; } - static bool s_InitCleanupCurlFlag(false); - static bool s_InstallSigPipeHandler(false); - - static const char* HTTP_CLIENT_FACTORY_ALLOCATION_TAG = "HttpClientFactory"; - -#if ENABLE_CURL_CLIENT && !defined(_WIN32) - static void LogAndSwallowHandler(int signal) - { - switch(signal) - { - case SIGPIPE: - AWS_LOGSTREAM_ERROR(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Received a SIGPIPE error"); - break; - default: - AWS_LOGSTREAM_ERROR(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Unhandled system SIGNAL error" << signal); - } - } -#endif - - class DefaultHttpClientFactory : public HttpClientFactory - { - std::shared_ptr<HttpClient> CreateHttpClient(const ClientConfiguration& clientConfiguration) const override - { - // Figure out whether the selected option is available but fail gracefully and return a default of some type if not - // Windows clients: Http and Inet are always options, Curl MIGHT be an option if USE_CURL_CLIENT is on, and http is "default" - // Other clients: Curl is your default -#if ENABLE_WINDOWS_CLIENT -#if ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT -#if BYPASS_DEFAULT_PROXY - switch (clientConfiguration.httpLibOverride) - { - case TransferLibType::WIN_HTTP_CLIENT: - AWS_LOGSTREAM_INFO(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Creating WinHTTP http client."); - return Aws::MakeShared<WinHttpSyncHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); - case TransferLibType::WIN_INET_CLIENT: - AWS_LOGSTREAM_WARN(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "WinINet http client is not supported with the current build configuration."); - // fall-through - default: - AWS_LOGSTREAM_INFO(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Creating IXMLHttpRequest http client."); - return Aws::MakeShared<IXmlHttpRequest2HttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); - } -#else - return Aws::MakeShared<IXmlHttpRequest2HttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); -#endif // BYPASS_DEFAULT_PROXY -#else - switch (clientConfiguration.httpLibOverride) - { - case TransferLibType::WIN_INET_CLIENT: - return Aws::MakeShared<WinINetSyncHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); - - default: - return Aws::MakeShared<WinHttpSyncHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); - } -#endif // ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT -#elif ENABLE_CURL_CLIENT - return Aws::MakeShared<CurlHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); -#else - // When neither of these clients is enabled, gcc gives a warning (converted - // to error by -Werror) about the unused clientConfiguration parameter. We - // prevent that warning with AWS_UNREFERENCED_PARAM. - AWS_UNREFERENCED_PARAM(clientConfiguration); + static bool s_InitCleanupCurlFlag(false); + static bool s_InstallSigPipeHandler(false); + + static const char* HTTP_CLIENT_FACTORY_ALLOCATION_TAG = "HttpClientFactory"; + +#if ENABLE_CURL_CLIENT && !defined(_WIN32) + static void LogAndSwallowHandler(int signal) + { + switch(signal) + { + case SIGPIPE: + AWS_LOGSTREAM_ERROR(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Received a SIGPIPE error"); + break; + default: + AWS_LOGSTREAM_ERROR(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Unhandled system SIGNAL error" << signal); + } + } +#endif + + class DefaultHttpClientFactory : public HttpClientFactory + { + std::shared_ptr<HttpClient> CreateHttpClient(const ClientConfiguration& clientConfiguration) const override + { + // Figure out whether the selected option is available but fail gracefully and return a default of some type if not + // Windows clients: Http and Inet are always options, Curl MIGHT be an option if USE_CURL_CLIENT is on, and http is "default" + // Other clients: Curl is your default +#if ENABLE_WINDOWS_CLIENT +#if ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT +#if BYPASS_DEFAULT_PROXY + switch (clientConfiguration.httpLibOverride) + { + case TransferLibType::WIN_HTTP_CLIENT: + AWS_LOGSTREAM_INFO(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Creating WinHTTP http client."); + return Aws::MakeShared<WinHttpSyncHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); + case TransferLibType::WIN_INET_CLIENT: + AWS_LOGSTREAM_WARN(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "WinINet http client is not supported with the current build configuration."); + // fall-through + default: + AWS_LOGSTREAM_INFO(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "Creating IXMLHttpRequest http client."); + return Aws::MakeShared<IXmlHttpRequest2HttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); + } +#else + return Aws::MakeShared<IXmlHttpRequest2HttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); +#endif // BYPASS_DEFAULT_PROXY +#else + switch (clientConfiguration.httpLibOverride) + { + case TransferLibType::WIN_INET_CLIENT: + return Aws::MakeShared<WinINetSyncHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); + + default: + return Aws::MakeShared<WinHttpSyncHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); + } +#endif // ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT +#elif ENABLE_CURL_CLIENT + return Aws::MakeShared<CurlHttpClient>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, clientConfiguration); +#else + // When neither of these clients is enabled, gcc gives a warning (converted + // to error by -Werror) about the unused clientConfiguration parameter. We + // prevent that warning with AWS_UNREFERENCED_PARAM. + AWS_UNREFERENCED_PARAM(clientConfiguration); AWS_LOGSTREAM_WARN(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, "SDK was built without an Http implementation, default http client factory can't create an Http client instance."); - return nullptr; -#endif - } - - std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String &uri, HttpMethod method, - const Aws::IOStreamFactory &streamFactory) const override - { - return CreateHttpRequest(URI(uri), method, streamFactory); - } - - std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) const override - { - auto request = Aws::MakeShared<Standard::StandardHttpRequest>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, uri, method); - request->SetResponseStreamFactory(streamFactory); - - return request; - } - - void InitStaticState() override - { -#if ENABLE_CURL_CLIENT - if(s_InitCleanupCurlFlag) - { - CurlHttpClient::InitGlobalState(); - } -#if !defined (_WIN32) - if(s_InstallSigPipeHandler) - { - ::signal(SIGPIPE, LogAndSwallowHandler); - } -#endif -#elif ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT - IXmlHttpRequest2HttpClient::InitCOM(); -#endif - } - - virtual void CleanupStaticState() override - { -#if ENABLE_CURL_CLIENT - if(s_InitCleanupCurlFlag) - { - CurlHttpClient::CleanupGlobalState(); - } -#endif - } - }; - - void SetInitCleanupCurlFlag(bool initCleanupFlag) - { - s_InitCleanupCurlFlag = initCleanupFlag; - } - - void SetInstallSigPipeHandlerFlag(bool install) - { - s_InstallSigPipeHandler = install; - } - - void InitHttp() - { + return nullptr; +#endif + } + + std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String &uri, HttpMethod method, + const Aws::IOStreamFactory &streamFactory) const override + { + return CreateHttpRequest(URI(uri), method, streamFactory); + } + + std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) const override + { + auto request = Aws::MakeShared<Standard::StandardHttpRequest>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG, uri, method); + request->SetResponseStreamFactory(streamFactory); + + return request; + } + + void InitStaticState() override + { +#if ENABLE_CURL_CLIENT + if(s_InitCleanupCurlFlag) + { + CurlHttpClient::InitGlobalState(); + } +#if !defined (_WIN32) + if(s_InstallSigPipeHandler) + { + ::signal(SIGPIPE, LogAndSwallowHandler); + } +#endif +#elif ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT + IXmlHttpRequest2HttpClient::InitCOM(); +#endif + } + + virtual void CleanupStaticState() override + { +#if ENABLE_CURL_CLIENT + if(s_InitCleanupCurlFlag) + { + CurlHttpClient::CleanupGlobalState(); + } +#endif + } + }; + + void SetInitCleanupCurlFlag(bool initCleanupFlag) + { + s_InitCleanupCurlFlag = initCleanupFlag; + } + + void SetInstallSigPipeHandlerFlag(bool install) + { + s_InstallSigPipeHandler = install; + } + + void InitHttp() + { if(!GetHttpClientFactory()) - { + { GetHttpClientFactory() = Aws::MakeShared<DefaultHttpClientFactory>(HTTP_CLIENT_FACTORY_ALLOCATION_TAG); - } + } GetHttpClientFactory()->InitStaticState(); - } - - void CleanupHttp() - { + } + + void CleanupHttp() + { if(GetHttpClientFactory()) - { + { GetHttpClientFactory()->CleanupStaticState(); GetHttpClientFactory() = nullptr; - } - } - - void SetHttpClientFactory(const std::shared_ptr<HttpClientFactory>& factory) - { - CleanupHttp(); + } + } + + void SetHttpClientFactory(const std::shared_ptr<HttpClientFactory>& factory) + { + CleanupHttp(); GetHttpClientFactory() = factory; - } - - std::shared_ptr<HttpClient> CreateHttpClient(const Aws::Client::ClientConfiguration& clientConfiguration) - { + } + + std::shared_ptr<HttpClient> CreateHttpClient(const Aws::Client::ClientConfiguration& clientConfiguration) + { assert(GetHttpClientFactory()); return GetHttpClientFactory()->CreateHttpClient(clientConfiguration); - } - - std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) - { + } + + std::shared_ptr<HttpRequest> CreateHttpRequest(const Aws::String& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) + { assert(GetHttpClientFactory()); return GetHttpClientFactory()->CreateHttpRequest(uri, method, streamFactory); - } - - std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) - { + } + + std::shared_ptr<HttpRequest> CreateHttpRequest(const URI& uri, HttpMethod method, const Aws::IOStreamFactory& streamFactory) + { assert(GetHttpClientFactory()); return GetHttpClientFactory()->CreateHttpRequest(uri, method, streamFactory); - } - } -} + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp index 95cb626c22..2e20ba2ff5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpRequest.cpp @@ -2,14 +2,14 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/HttpRequest.h> - -namespace Aws -{ -namespace Http -{ - + +#include <aws/core/http/HttpRequest.h> + +namespace Aws +{ +namespace Http +{ + const char DATE_HEADER[] = "date"; const char AWS_DATE_HEADER[] = "X-Amz-Date"; const char AWS_SECURITY_TOKEN[] = "X-Amz-Security-Token"; @@ -32,9 +32,9 @@ const char API_VERSION_HEADER[] = "x-amz-api-version"; const char SDK_INVOCATION_ID_HEADER[] = "amz-sdk-invocation-id"; const char SDK_REQUEST_HEADER[] = "amz-sdk-request"; const char CHUNKED_VALUE[] = "chunked"; - -} // Http -} // Aws - - - + +} // Http +} // Aws + + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp index 4d313e52f3..02407c16d1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/HttpTypes.cpp @@ -2,41 +2,41 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/HttpTypes.h> -#include <cassert> - -using namespace Aws::Http; - -namespace Aws -{ -namespace Http -{ - -namespace HttpMethodMapper -{ -const char* GetNameForHttpMethod(HttpMethod httpMethod) -{ - switch (httpMethod) - { - case HttpMethod::HTTP_GET: - return "GET"; - case HttpMethod::HTTP_POST: - return "POST"; - case HttpMethod::HTTP_DELETE: - return "DELETE"; - case HttpMethod::HTTP_PUT: - return "PUT"; - case HttpMethod::HTTP_HEAD: - return "HEAD"; - case HttpMethod::HTTP_PATCH: - return "PATCH"; - default: - assert(0); - return "GET"; - } -} - -} // namespace HttpMethodMapper -} // namespace Http -} // namespace Aws + +#include <aws/core/http/HttpTypes.h> +#include <cassert> + +using namespace Aws::Http; + +namespace Aws +{ +namespace Http +{ + +namespace HttpMethodMapper +{ +const char* GetNameForHttpMethod(HttpMethod httpMethod) +{ + switch (httpMethod) + { + case HttpMethod::HTTP_GET: + return "GET"; + case HttpMethod::HTTP_POST: + return "POST"; + case HttpMethod::HTTP_DELETE: + return "DELETE"; + case HttpMethod::HTTP_PUT: + return "PUT"; + case HttpMethod::HTTP_HEAD: + return "HEAD"; + case HttpMethod::HTTP_PATCH: + return "PATCH"; + default: + assert(0); + return "GET"; + } +} + +} // namespace HttpMethodMapper +} // namespace Http +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp index 5dcea06aab..d75bb4a66d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/Scheme.cpp @@ -2,53 +2,53 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/Scheme.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <aws/core/utils/StringUtils.h> - -using namespace Aws::Http; -using namespace Aws::Utils; - -namespace Aws -{ -namespace Http -{ -namespace SchemeMapper -{ - - const char* ToString(Scheme scheme) - { - switch (scheme) - { - case Scheme::HTTP: - return "http"; - case Scheme::HTTPS: - return "https"; - default: - return "http"; - } - } - - Scheme FromString(const char* name) - { - Aws::String trimmedString = StringUtils::Trim(name); - Aws::String loweredTrimmedString = StringUtils::ToLower(trimmedString.c_str()); - - if (loweredTrimmedString == "http") - { - return Scheme::HTTP; - } - //this branch is technically unneeded, but it is here so we don't have a subtle bug - //creep in as we extend this enum. - else if (loweredTrimmedString == "https") - { - return Scheme::HTTPS; - } - - return Scheme::HTTPS; - } - -} // namespace SchemeMapper -} // namespace Http -} // namespace Aws + +#include <aws/core/http/Scheme.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <aws/core/utils/StringUtils.h> + +using namespace Aws::Http; +using namespace Aws::Utils; + +namespace Aws +{ +namespace Http +{ +namespace SchemeMapper +{ + + const char* ToString(Scheme scheme) + { + switch (scheme) + { + case Scheme::HTTP: + return "http"; + case Scheme::HTTPS: + return "https"; + default: + return "http"; + } + } + + Scheme FromString(const char* name) + { + Aws::String trimmedString = StringUtils::Trim(name); + Aws::String loweredTrimmedString = StringUtils::ToLower(trimmedString.c_str()); + + if (loweredTrimmedString == "http") + { + return Scheme::HTTP; + } + //this branch is technically unneeded, but it is here so we don't have a subtle bug + //creep in as we extend this enum. + else if (loweredTrimmedString == "https") + { + return Scheme::HTTPS; + } + + return Scheme::HTTPS; + } + +} // namespace SchemeMapper +} // namespace Http +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp index a2239df54b..e5a8e4cade 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/URI.cpp @@ -2,170 +2,170 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/URI.h> - -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/utils/memory/stl/AWSSet.h> - -#include <cstdlib> -#include <cctype> -#include <cassert> -#include <algorithm> -#include <iomanip> - -using namespace Aws::Http; -using namespace Aws::Utils; - -namespace Aws -{ -namespace Http -{ - -const char* SEPARATOR = "://"; - -} // namespace Http -} // namespace Aws - -URI::URI() : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) -{ -} - -URI::URI(const Aws::String& uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) -{ - ParseURIParts(uri); -} - -URI::URI(const char* uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) -{ - ParseURIParts(uri); -} - -URI& URI::operator =(const Aws::String& uri) -{ - this->ParseURIParts(uri); - return *this; -} - -URI& URI::operator =(const char* uri) -{ - this->ParseURIParts(uri); - return *this; -} - -bool URI::operator ==(const URI& other) const -{ - return CompareURIParts(other); -} - -bool URI::operator ==(const Aws::String& other) const -{ - return CompareURIParts(other); -} - -bool URI::operator ==(const char* other) const -{ - return CompareURIParts(other); -} - -bool URI::operator !=(const URI& other) const -{ - return !(*this == other); -} - -bool URI::operator !=(const Aws::String& other) const -{ - return !(*this == other); -} - -bool URI::operator !=(const char* other) const -{ - return !(*this == other); -} - -void URI::SetScheme(Scheme value) -{ - assert(value == Scheme::HTTP || value == Scheme::HTTPS); - - if (value == Scheme::HTTP) - { - m_port = m_port == HTTPS_DEFAULT_PORT || m_port == 0 ? HTTP_DEFAULT_PORT : m_port; - m_scheme = value; - } - else if (value == Scheme::HTTPS) - { - m_port = m_port == HTTP_DEFAULT_PORT || m_port == 0 ? HTTPS_DEFAULT_PORT : m_port; - m_scheme = value; - } -} - -Aws::String URI::URLEncodePathRFC3986(const Aws::String& path) -{ - if(path.empty()) - { - return path; - } - - const Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/'); - Aws::StringStream ss; - ss << std::hex << std::uppercase; - - // escape characters appearing in a URL path according to RFC 3986 - for (const auto& segment : pathParts) - { - ss << '/'; - for(unsigned char c : segment) // alnum results in UB if the value of c is not unsigned char & is not EOF - { + +#include <aws/core/http/URI.h> + +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/memory/stl/AWSSet.h> + +#include <cstdlib> +#include <cctype> +#include <cassert> +#include <algorithm> +#include <iomanip> + +using namespace Aws::Http; +using namespace Aws::Utils; + +namespace Aws +{ +namespace Http +{ + +const char* SEPARATOR = "://"; + +} // namespace Http +} // namespace Aws + +URI::URI() : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) +{ +} + +URI::URI(const Aws::String& uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) +{ + ParseURIParts(uri); +} + +URI::URI(const char* uri) : m_scheme(Scheme::HTTP), m_port(HTTP_DEFAULT_PORT) +{ + ParseURIParts(uri); +} + +URI& URI::operator =(const Aws::String& uri) +{ + this->ParseURIParts(uri); + return *this; +} + +URI& URI::operator =(const char* uri) +{ + this->ParseURIParts(uri); + return *this; +} + +bool URI::operator ==(const URI& other) const +{ + return CompareURIParts(other); +} + +bool URI::operator ==(const Aws::String& other) const +{ + return CompareURIParts(other); +} + +bool URI::operator ==(const char* other) const +{ + return CompareURIParts(other); +} + +bool URI::operator !=(const URI& other) const +{ + return !(*this == other); +} + +bool URI::operator !=(const Aws::String& other) const +{ + return !(*this == other); +} + +bool URI::operator !=(const char* other) const +{ + return !(*this == other); +} + +void URI::SetScheme(Scheme value) +{ + assert(value == Scheme::HTTP || value == Scheme::HTTPS); + + if (value == Scheme::HTTP) + { + m_port = m_port == HTTPS_DEFAULT_PORT || m_port == 0 ? HTTP_DEFAULT_PORT : m_port; + m_scheme = value; + } + else if (value == Scheme::HTTPS) + { + m_port = m_port == HTTP_DEFAULT_PORT || m_port == 0 ? HTTPS_DEFAULT_PORT : m_port; + m_scheme = value; + } +} + +Aws::String URI::URLEncodePathRFC3986(const Aws::String& path) +{ + if(path.empty()) + { + return path; + } + + const Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/'); + Aws::StringStream ss; + ss << std::hex << std::uppercase; + + // escape characters appearing in a URL path according to RFC 3986 + for (const auto& segment : pathParts) + { + ss << '/'; + for(unsigned char c : segment) // alnum results in UB if the value of c is not unsigned char & is not EOF + { // §2.3 unreserved characters if (StringUtils::IsAlnum(c)) - { - ss << c; - continue; - } - switch(c) - { - // §2.3 unreserved characters - case '-': case '_': case '.': case '~': - // The path section of the URL allow reserved characters to appear unescaped - // RFC 3986 §2.2 Reserved characters - // NOTE: this implementation does not accurately implement the RFC on purpose to accommodate for - // discrepancies in the implementations of URL encoding between AWS services for legacy reasons. + { + ss << c; + continue; + } + switch(c) + { + // §2.3 unreserved characters + case '-': case '_': case '.': case '~': + // The path section of the URL allow reserved characters to appear unescaped + // RFC 3986 §2.2 Reserved characters + // NOTE: this implementation does not accurately implement the RFC on purpose to accommodate for + // discrepancies in the implementations of URL encoding between AWS services for legacy reasons. case '$': case '&': case ',': case ':': case '=': case '@': - ss << c; - break; - default: + ss << c; + break; + default: ss << '%' << std::setfill('0') << std::setw(2) << (int)((unsigned char)c) << std::setw(0); - } - } - } - - //if the last character was also a slash, then add that back here. - if (path.back() == '/') - { - ss << '/'; - } - - return ss.str(); -} - -Aws::String URI::URLEncodePath(const Aws::String& path) -{ - Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/'); - Aws::StringStream ss; - - for (Aws::Vector<Aws::String>::iterator iter = pathParts.begin(); iter != pathParts.end(); ++iter) - { - ss << '/' << StringUtils::URLEncode(iter->c_str()); - } - - //if the last character was also a slash, then add that back here. + } + } + } + + //if the last character was also a slash, then add that back here. + if (path.back() == '/') + { + ss << '/'; + } + + return ss.str(); +} + +Aws::String URI::URLEncodePath(const Aws::String& path) +{ + Aws::Vector<Aws::String> pathParts = StringUtils::Split(path, '/'); + Aws::StringStream ss; + + for (Aws::Vector<Aws::String>::iterator iter = pathParts.begin(); iter != pathParts.end(); ++iter) + { + ss << '/' << StringUtils::URLEncode(iter->c_str()); + } + + //if the last character was also a slash, then add that back here. if (path.length() > 0 && path[path.length() - 1] == '/') - { - ss << '/'; - } - + { + ss << '/'; + } + if (path.length() > 0 && path[0] != '/') { return ss.str().substr(1); @@ -174,9 +174,9 @@ Aws::String URI::URLEncodePath(const Aws::String& path) { return ss.str(); } -} - -void URI::SetPath(const Aws::String& value) +} + +void URI::SetPath(const Aws::String& value) { const Aws::Vector<Aws::String> pathParts = StringUtils::Split(value, '/'); Aws::String path; @@ -193,318 +193,318 @@ void URI::SetPath(const Aws::String& value) path.push_back('/'); } m_path = std::move(path); -} - -//ugh, this isn't even part of the canonicalization spec. It is part of how our services have implemented their signers though.... +} + +//ugh, this isn't even part of the canonicalization spec. It is part of how our services have implemented their signers though.... //it doesn't really hurt anything to reorder it though, so go ahead and sort the values for parameters with the same key -void InsertValueOrderedParameter(QueryStringParameterCollection& queryParams, const Aws::String& key, const Aws::String& value) -{ - auto entriesAtKey = queryParams.equal_range(key); - for (auto& entry = entriesAtKey.first; entry != entriesAtKey.second; ++entry) - { - if (entry->second > value) - { +void InsertValueOrderedParameter(QueryStringParameterCollection& queryParams, const Aws::String& key, const Aws::String& value) +{ + auto entriesAtKey = queryParams.equal_range(key); + for (auto& entry = entriesAtKey.first; entry != entriesAtKey.second; ++entry) + { + if (entry->second > value) + { queryParams.emplace_hint(entry, key, value); - return; - } - } - - queryParams.emplace(key, value); -} - -QueryStringParameterCollection URI::GetQueryStringParameters(bool decode) const -{ - Aws::String queryString = GetQueryString(); - - QueryStringParameterCollection parameterCollection; - - //if we actually have a query string - if (queryString.size() > 0) - { - size_t currentPos = 1, locationOfNextDelimiter = 1; - - //while we have params left to parse - while (currentPos < queryString.size()) - { - //find next key/value pair - locationOfNextDelimiter = queryString.find('&', currentPos); - - Aws::String keyValuePair; - - //if this isn't the last parameter - if (locationOfNextDelimiter != Aws::String::npos) - { - keyValuePair = queryString.substr(currentPos, locationOfNextDelimiter - currentPos); - } - //if it is the last parameter - else - { - keyValuePair = queryString.substr(currentPos); - } - - //split on = - size_t locationOfEquals = keyValuePair.find('='); - Aws::String key = keyValuePair.substr(0, locationOfEquals); - Aws::String value = keyValuePair.substr(locationOfEquals + 1); - - if(decode) - { - InsertValueOrderedParameter(parameterCollection, StringUtils::URLDecode(key.c_str()), StringUtils::URLDecode(value.c_str())); - } - else - { - InsertValueOrderedParameter(parameterCollection, key, value); - } - - currentPos += keyValuePair.size() + 1; - } - } - - return parameterCollection; -} - -void URI::CanonicalizeQueryString() -{ - QueryStringParameterCollection sortedParameters = GetQueryStringParameters(false); - Aws::StringStream queryStringStream; - - bool first = true; - - if(sortedParameters.size() > 0) - { - queryStringStream << "?"; - } - + return; + } + } + + queryParams.emplace(key, value); +} + +QueryStringParameterCollection URI::GetQueryStringParameters(bool decode) const +{ + Aws::String queryString = GetQueryString(); + + QueryStringParameterCollection parameterCollection; + + //if we actually have a query string + if (queryString.size() > 0) + { + size_t currentPos = 1, locationOfNextDelimiter = 1; + + //while we have params left to parse + while (currentPos < queryString.size()) + { + //find next key/value pair + locationOfNextDelimiter = queryString.find('&', currentPos); + + Aws::String keyValuePair; + + //if this isn't the last parameter + if (locationOfNextDelimiter != Aws::String::npos) + { + keyValuePair = queryString.substr(currentPos, locationOfNextDelimiter - currentPos); + } + //if it is the last parameter + else + { + keyValuePair = queryString.substr(currentPos); + } + + //split on = + size_t locationOfEquals = keyValuePair.find('='); + Aws::String key = keyValuePair.substr(0, locationOfEquals); + Aws::String value = keyValuePair.substr(locationOfEquals + 1); + + if(decode) + { + InsertValueOrderedParameter(parameterCollection, StringUtils::URLDecode(key.c_str()), StringUtils::URLDecode(value.c_str())); + } + else + { + InsertValueOrderedParameter(parameterCollection, key, value); + } + + currentPos += keyValuePair.size() + 1; + } + } + + return parameterCollection; +} + +void URI::CanonicalizeQueryString() +{ + QueryStringParameterCollection sortedParameters = GetQueryStringParameters(false); + Aws::StringStream queryStringStream; + + bool first = true; + + if(sortedParameters.size() > 0) + { + queryStringStream << "?"; + } + if(m_queryString.find('=') != std::string::npos) - { - for (QueryStringParameterCollection::iterator iter = sortedParameters.begin(); - iter != sortedParameters.end(); ++iter) - { - if (!first) - { - queryStringStream << "&"; - } - - first = false; - queryStringStream << iter->first.c_str() << "=" << iter->second.c_str(); - } - - m_queryString = queryStringStream.str(); - } -} - -void URI::AddQueryStringParameter(const char* key, const Aws::String& value) -{ - if (m_queryString.size() <= 0) - { - m_queryString.append("?"); - } - else - { - m_queryString.append("&"); - } - - m_queryString.append(StringUtils::URLEncode(key) + "=" + StringUtils::URLEncode(value.c_str())); -} - -void URI::AddQueryStringParameter(const Aws::Map<Aws::String, Aws::String>& queryStringPairs) -{ - for(const auto& entry: queryStringPairs) - { - AddQueryStringParameter(entry.first.c_str(), entry.second); - } -} - -void URI::SetQueryString(const Aws::String& str) -{ - m_queryString = ""; - - if (str.empty()) return; - - if (str.front() != '?') - { - m_queryString.append("?").append(str); - } - else - { - m_queryString = str; - } -} - -Aws::String URI::GetURIString(bool includeQueryString) const -{ - assert(m_authority.size() > 0); - - Aws::StringStream ss; - ss << SchemeMapper::ToString(m_scheme) << SEPARATOR << m_authority; - - if (m_scheme == Scheme::HTTP && m_port != HTTP_DEFAULT_PORT) - { - ss << ":" << m_port; - } - else if (m_scheme == Scheme::HTTPS && m_port != HTTPS_DEFAULT_PORT) - { - ss << ":" << m_port; - } - - if(m_path != "/") - { - ss << URLEncodePathRFC3986(m_path); - } - - if(includeQueryString) - { - ss << m_queryString; - } - - return ss.str(); -} - -void URI::ParseURIParts(const Aws::String& uri) -{ - ExtractAndSetScheme(uri); - ExtractAndSetAuthority(uri); - ExtractAndSetPort(uri); - ExtractAndSetPath(uri); - ExtractAndSetQueryString(uri); -} - -void URI::ExtractAndSetScheme(const Aws::String& uri) -{ - size_t posOfSeparator = uri.find(SEPARATOR); - - if (posOfSeparator != Aws::String::npos) - { - Aws::String schemePortion = uri.substr(0, posOfSeparator); - SetScheme(SchemeMapper::FromString(schemePortion.c_str())); - } - else - { - SetScheme(Scheme::HTTP); - } -} - -void URI::ExtractAndSetAuthority(const Aws::String& uri) -{ - size_t authorityStart = uri.find(SEPARATOR); - - if (authorityStart == Aws::String::npos) - { - authorityStart = 0; - } - else - { - authorityStart += 3; - } - - size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart); - size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart); - size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart); - size_t posEndOfAuthority = (std::min)({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery}); - if (posEndOfAuthority == Aws::String::npos) - { - posEndOfAuthority = uri.length(); - } - - SetAuthority(uri.substr(authorityStart, posEndOfAuthority - authorityStart)); -} - -void URI::ExtractAndSetPort(const Aws::String& uri) -{ - size_t authorityStart = uri.find(SEPARATOR); - - if(authorityStart == Aws::String::npos) - { - authorityStart = 0; - } - else - { - authorityStart += 3; - } - - size_t positionOfPortDelimiter = uri.find(':', authorityStart); - - bool hasPort = positionOfPortDelimiter != Aws::String::npos; - - if ((uri.find('/', authorityStart) < positionOfPortDelimiter) || (uri.find('?', authorityStart) < positionOfPortDelimiter)) - { - hasPort = false; - } - - if (hasPort) - { - Aws::String strPort; - - size_t i = positionOfPortDelimiter + 1; - char currentDigit = uri[i]; - - while (std::isdigit(currentDigit)) - { - strPort += currentDigit; - currentDigit = uri[++i]; - } - - SetPort(static_cast<uint16_t>(atoi(strPort.c_str()))); - } -} - -void URI::ExtractAndSetPath(const Aws::String& uri) -{ - size_t authorityStart = uri.find(SEPARATOR); - - if (authorityStart == Aws::String::npos) - { - authorityStart = 0; - } - else - { - authorityStart += 3; - } - - size_t pathEnd = uri.find('?'); - - if (pathEnd == Aws::String::npos) - { - pathEnd = uri.length(); - } - - Aws::String authorityAndPath = uri.substr(authorityStart, pathEnd - authorityStart); - - size_t pathStart = authorityAndPath.find('/'); - - if (pathStart != Aws::String::npos) - { - SetPath(authorityAndPath.substr(pathStart, pathEnd - pathStart)); - } - else - { - SetPath("/"); - } -} - -void URI::ExtractAndSetQueryString(const Aws::String& uri) -{ - size_t queryStart = uri.find('?'); - - if (queryStart != Aws::String::npos) - { - m_queryString = uri.substr(queryStart); - } -} - -Aws::String URI::GetFormParameters() const -{ - if(m_queryString.length() == 0) - { - return ""; - } - else - { - return m_queryString.substr(1); - } -} - -bool URI::CompareURIParts(const URI& other) const -{ - return m_scheme == other.m_scheme && m_authority == other.m_authority && m_path == other.m_path && m_queryString == other.m_queryString; -} + { + for (QueryStringParameterCollection::iterator iter = sortedParameters.begin(); + iter != sortedParameters.end(); ++iter) + { + if (!first) + { + queryStringStream << "&"; + } + + first = false; + queryStringStream << iter->first.c_str() << "=" << iter->second.c_str(); + } + + m_queryString = queryStringStream.str(); + } +} + +void URI::AddQueryStringParameter(const char* key, const Aws::String& value) +{ + if (m_queryString.size() <= 0) + { + m_queryString.append("?"); + } + else + { + m_queryString.append("&"); + } + + m_queryString.append(StringUtils::URLEncode(key) + "=" + StringUtils::URLEncode(value.c_str())); +} + +void URI::AddQueryStringParameter(const Aws::Map<Aws::String, Aws::String>& queryStringPairs) +{ + for(const auto& entry: queryStringPairs) + { + AddQueryStringParameter(entry.first.c_str(), entry.second); + } +} + +void URI::SetQueryString(const Aws::String& str) +{ + m_queryString = ""; + + if (str.empty()) return; + + if (str.front() != '?') + { + m_queryString.append("?").append(str); + } + else + { + m_queryString = str; + } +} + +Aws::String URI::GetURIString(bool includeQueryString) const +{ + assert(m_authority.size() > 0); + + Aws::StringStream ss; + ss << SchemeMapper::ToString(m_scheme) << SEPARATOR << m_authority; + + if (m_scheme == Scheme::HTTP && m_port != HTTP_DEFAULT_PORT) + { + ss << ":" << m_port; + } + else if (m_scheme == Scheme::HTTPS && m_port != HTTPS_DEFAULT_PORT) + { + ss << ":" << m_port; + } + + if(m_path != "/") + { + ss << URLEncodePathRFC3986(m_path); + } + + if(includeQueryString) + { + ss << m_queryString; + } + + return ss.str(); +} + +void URI::ParseURIParts(const Aws::String& uri) +{ + ExtractAndSetScheme(uri); + ExtractAndSetAuthority(uri); + ExtractAndSetPort(uri); + ExtractAndSetPath(uri); + ExtractAndSetQueryString(uri); +} + +void URI::ExtractAndSetScheme(const Aws::String& uri) +{ + size_t posOfSeparator = uri.find(SEPARATOR); + + if (posOfSeparator != Aws::String::npos) + { + Aws::String schemePortion = uri.substr(0, posOfSeparator); + SetScheme(SchemeMapper::FromString(schemePortion.c_str())); + } + else + { + SetScheme(Scheme::HTTP); + } +} + +void URI::ExtractAndSetAuthority(const Aws::String& uri) +{ + size_t authorityStart = uri.find(SEPARATOR); + + if (authorityStart == Aws::String::npos) + { + authorityStart = 0; + } + else + { + authorityStart += 3; + } + + size_t posOfEndOfAuthorityPort = uri.find(':', authorityStart); + size_t posOfEndOfAuthoritySlash = uri.find('/', authorityStart); + size_t posOfEndOfAuthorityQuery = uri.find('?', authorityStart); + size_t posEndOfAuthority = (std::min)({posOfEndOfAuthorityPort, posOfEndOfAuthoritySlash, posOfEndOfAuthorityQuery}); + if (posEndOfAuthority == Aws::String::npos) + { + posEndOfAuthority = uri.length(); + } + + SetAuthority(uri.substr(authorityStart, posEndOfAuthority - authorityStart)); +} + +void URI::ExtractAndSetPort(const Aws::String& uri) +{ + size_t authorityStart = uri.find(SEPARATOR); + + if(authorityStart == Aws::String::npos) + { + authorityStart = 0; + } + else + { + authorityStart += 3; + } + + size_t positionOfPortDelimiter = uri.find(':', authorityStart); + + bool hasPort = positionOfPortDelimiter != Aws::String::npos; + + if ((uri.find('/', authorityStart) < positionOfPortDelimiter) || (uri.find('?', authorityStart) < positionOfPortDelimiter)) + { + hasPort = false; + } + + if (hasPort) + { + Aws::String strPort; + + size_t i = positionOfPortDelimiter + 1; + char currentDigit = uri[i]; + + while (std::isdigit(currentDigit)) + { + strPort += currentDigit; + currentDigit = uri[++i]; + } + + SetPort(static_cast<uint16_t>(atoi(strPort.c_str()))); + } +} + +void URI::ExtractAndSetPath(const Aws::String& uri) +{ + size_t authorityStart = uri.find(SEPARATOR); + + if (authorityStart == Aws::String::npos) + { + authorityStart = 0; + } + else + { + authorityStart += 3; + } + + size_t pathEnd = uri.find('?'); + + if (pathEnd == Aws::String::npos) + { + pathEnd = uri.length(); + } + + Aws::String authorityAndPath = uri.substr(authorityStart, pathEnd - authorityStart); + + size_t pathStart = authorityAndPath.find('/'); + + if (pathStart != Aws::String::npos) + { + SetPath(authorityAndPath.substr(pathStart, pathEnd - pathStart)); + } + else + { + SetPath("/"); + } +} + +void URI::ExtractAndSetQueryString(const Aws::String& uri) +{ + size_t queryStart = uri.find('?'); + + if (queryStart != Aws::String::npos) + { + m_queryString = uri.substr(queryStart); + } +} + +Aws::String URI::GetFormParameters() const +{ + if(m_queryString.length() == 0) + { + return ""; + } + else + { + return m_queryString.substr(1); + } +} + +bool URI::CompareURIParts(const URI& other) const +{ + return m_scheme == other.m_scheme && m_authority == other.m_authority && m_path == other.m_path && m_queryString == other.m_queryString; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp index 1a965cd795..78f54b964d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHandleContainer.cpp @@ -2,64 +2,64 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/curl/CurlHandleContainer.h> -#include <aws/core/utils/logging/LogMacros.h> - -#include <algorithm> - -using namespace Aws::Utils::Logging; -using namespace Aws::Http; - -static const char* CURL_HANDLE_CONTAINER_TAG = "CurlHandleContainer"; - - + +#include <aws/core/http/curl/CurlHandleContainer.h> +#include <aws/core/utils/logging/LogMacros.h> + +#include <algorithm> + +using namespace Aws::Utils::Logging; +using namespace Aws::Http; + +static const char* CURL_HANDLE_CONTAINER_TAG = "CurlHandleContainer"; + + CurlHandleContainer::CurlHandleContainer(unsigned maxSize, long httpRequestTimeout, long connectTimeout, bool enableTcpKeepAlive, unsigned long tcpKeepAliveIntervalMs, long lowSpeedTime, unsigned long lowSpeedLimit) : m_maxPoolSize(maxSize), m_httpRequestTimeout(httpRequestTimeout), m_connectTimeout(connectTimeout), m_enableTcpKeepAlive(enableTcpKeepAlive), m_tcpKeepAliveIntervalMs(tcpKeepAliveIntervalMs), m_lowSpeedTime(lowSpeedTime), m_lowSpeedLimit(lowSpeedLimit), m_poolSize(0) -{ - AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Initializing CurlHandleContainer with size " << maxSize); -} - -CurlHandleContainer::~CurlHandleContainer() -{ - AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Cleaning up CurlHandleContainer."); - for (CURL* handle : m_handleContainer.ShutdownAndWait(m_poolSize)) - { - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Cleaning up " << handle); - curl_easy_cleanup(handle); - } -} - -CURL* CurlHandleContainer::AcquireCurlHandle() -{ - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Attempting to acquire curl connection."); - - if(!m_handleContainer.HasResourcesAvailable()) - { - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "No current connections available in pool. Attempting to create new connections."); - CheckAndGrowPool(); - } - - CURL* handle = m_handleContainer.Acquire(); - AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Connection has been released. Continuing."); - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Returning connection handle " << handle); - return handle; -} - -void CurlHandleContainer::ReleaseCurlHandle(CURL* handle) -{ - if (handle) - { - curl_easy_reset(handle); - SetDefaultOptionsOnHandle(handle); - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Releasing curl handle " << handle); - m_handleContainer.Release(handle); - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Notified waiting threads."); - } -} - +{ + AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Initializing CurlHandleContainer with size " << maxSize); +} + +CurlHandleContainer::~CurlHandleContainer() +{ + AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Cleaning up CurlHandleContainer."); + for (CURL* handle : m_handleContainer.ShutdownAndWait(m_poolSize)) + { + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Cleaning up " << handle); + curl_easy_cleanup(handle); + } +} + +CURL* CurlHandleContainer::AcquireCurlHandle() +{ + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Attempting to acquire curl connection."); + + if(!m_handleContainer.HasResourcesAvailable()) + { + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "No current connections available in pool. Attempting to create new connections."); + CheckAndGrowPool(); + } + + CURL* handle = m_handleContainer.Acquire(); + AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Connection has been released. Continuing."); + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Returning connection handle " << handle); + return handle; +} + +void CurlHandleContainer::ReleaseCurlHandle(CURL* handle) +{ + if (handle) + { + curl_easy_reset(handle); + SetDefaultOptionsOnHandle(handle); + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Releasing curl handle " << handle); + m_handleContainer.Release(handle); + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "Notified waiting threads."); + } +} + void CurlHandleContainer::DestroyCurlHandle(CURL* handle) { if (!handle) @@ -99,49 +99,49 @@ CURL* CurlHandleContainer::CreateCurlHandleInPool() return curlHandle; } -bool CurlHandleContainer::CheckAndGrowPool() -{ - std::lock_guard<std::mutex> locker(m_containerLock); - if (m_poolSize < m_maxPoolSize) - { - unsigned multiplier = m_poolSize > 0 ? m_poolSize : 1; - unsigned amountToAdd = (std::min)(multiplier * 2, m_maxPoolSize - m_poolSize); - AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "attempting to grow pool size by " << amountToAdd); - - unsigned actuallyAdded = 0; - for (unsigned i = 0; i < amountToAdd; ++i) - { +bool CurlHandleContainer::CheckAndGrowPool() +{ + std::lock_guard<std::mutex> locker(m_containerLock); + if (m_poolSize < m_maxPoolSize) + { + unsigned multiplier = m_poolSize > 0 ? m_poolSize : 1; + unsigned amountToAdd = (std::min)(multiplier * 2, m_maxPoolSize - m_poolSize); + AWS_LOGSTREAM_DEBUG(CURL_HANDLE_CONTAINER_TAG, "attempting to grow pool size by " << amountToAdd); + + unsigned actuallyAdded = 0; + for (unsigned i = 0; i < amountToAdd; ++i) + { CURL* curlHandle = CreateCurlHandleInPool(); - - if (curlHandle) - { - ++actuallyAdded; - } - else - { - break; - } - } - - AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool grown by " << actuallyAdded); - m_poolSize += actuallyAdded; - - return actuallyAdded > 0; - } - - AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool cannot be grown any further, already at max size."); - - return false; -} - -void CurlHandleContainer::SetDefaultOptionsOnHandle(CURL* handle) -{ - //for timeouts to work in a multi-threaded context, - //always turn signals off. This also forces dns queries to - //not be included in the timeout calculations. - curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L); + + if (curlHandle) + { + ++actuallyAdded; + } + else + { + break; + } + } + + AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool grown by " << actuallyAdded); + m_poolSize += actuallyAdded; + + return actuallyAdded > 0; + } + + AWS_LOGSTREAM_INFO(CURL_HANDLE_CONTAINER_TAG, "Pool cannot be grown any further, already at max size."); + + return false; +} + +void CurlHandleContainer::SetDefaultOptionsOnHandle(CURL* handle) +{ + //for timeouts to work in a multi-threaded context, + //always turn signals off. This also forces dns queries to + //not be included in the timeout calculations. + curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, m_httpRequestTimeout); - curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT_MS, m_connectTimeout); + curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT_MS, m_connectTimeout); curl_easy_setopt(handle, CURLOPT_LOW_SPEED_LIMIT, m_lowSpeedLimit); curl_easy_setopt(handle, CURLOPT_LOW_SPEED_TIME, m_lowSpeedTime < 1000 ? (m_lowSpeedTime == 0 ? 0 : 1) : m_lowSpeedTime / 1000); curl_easy_setopt(handle, CURLOPT_TCP_KEEPALIVE, m_enableTcpKeepAlive ? 1L : 0L); @@ -150,4 +150,4 @@ void CurlHandleContainer::SetDefaultOptionsOnHandle(CURL* handle) #ifdef CURL_HAS_H2 curl_easy_setopt(handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); #endif -} +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp index 2fb9cc9643..dcebfc0302 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp @@ -2,164 +2,164 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/curl/CurlHttpClient.h> -#include <aws/core/http/HttpRequest.h> -#include <aws/core/http/standard/StandardHttpResponse.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/ratelimiter/RateLimiterInterface.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/monitoring/HttpClientMetrics.h> -#include <cassert> -#include <algorithm> - - -using namespace Aws::Client; -using namespace Aws::Http; -using namespace Aws::Http::Standard; -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; -using namespace Aws::Monitoring; - -#ifdef AWS_CUSTOM_MEMORY_MANAGEMENT - -static const char* MemTag = "libcurl"; -static size_t offset = sizeof(size_t); - -static void* malloc_callback(size_t size) -{ - char* newMem = reinterpret_cast<char*>(Aws::Malloc(MemTag, size + offset)); - std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem); - *pointerToSize = size; - return reinterpret_cast<void*>(newMem + offset); -} - -static void free_callback(void* ptr) -{ - if(ptr) - { - char* shiftedMemory = reinterpret_cast<char*>(ptr); - Aws::Free(shiftedMemory - offset); - } -} - -static void* realloc_callback(void* ptr, size_t size) -{ - if(!ptr) - { - return malloc_callback(size); - } - - - if(!size && ptr) - { - free_callback(ptr); - return nullptr; - } - - char* originalLenCharPtr = reinterpret_cast<char*>(ptr) - offset; - size_t originalLen = *reinterpret_cast<size_t*>(originalLenCharPtr); - - char* rawMemory = reinterpret_cast<char*>(Aws::Malloc(MemTag, size + offset)); - if(rawMemory) - { - std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(rawMemory); - *pointerToSize = size; - - size_t copyLength = (std::min)(originalLen, size); -#ifdef _MSC_VER - memcpy_s(rawMemory + offset, size, ptr, copyLength); -#else - memcpy(rawMemory + offset, ptr, copyLength); -#endif - free_callback(ptr); - return reinterpret_cast<void*>(rawMemory + offset); - } - else - { - return ptr; - } - -} - -static void* calloc_callback(size_t nmemb, size_t size) -{ - size_t dataSize = nmemb * size; - char* newMem = reinterpret_cast<char*>(Aws::Malloc(MemTag, dataSize + offset)); - std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem); - *pointerToSize = dataSize; -#ifdef _MSC_VER - memset_s(newMem + offset, dataSize, 0, dataSize); -#else - memset(newMem + offset, 0, dataSize); -#endif - - return reinterpret_cast<void*>(newMem + offset); -} - -static char* strdup_callback(const char* str) -{ - size_t len = strlen(str) + 1; - size_t newLen = len + offset; - char* newMem = reinterpret_cast<char*>(Aws::Malloc(MemTag, newLen)); - - if(newMem) - { - std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem); - *pointerToSize = len; -#ifdef _MSC_VER - memcpy_s(newMem + offset, len, str, len); -#else - memcpy(newMem + offset, str, len); -#endif - return newMem + offset; - } - return nullptr; -} - -#endif - -struct CurlWriteCallbackContext -{ - CurlWriteCallbackContext(const CurlHttpClient* client, + +#include <aws/core/http/curl/CurlHttpClient.h> +#include <aws/core/http/HttpRequest.h> +#include <aws/core/http/standard/StandardHttpResponse.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/ratelimiter/RateLimiterInterface.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/monitoring/HttpClientMetrics.h> +#include <cassert> +#include <algorithm> + + +using namespace Aws::Client; +using namespace Aws::Http; +using namespace Aws::Http::Standard; +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; +using namespace Aws::Monitoring; + +#ifdef AWS_CUSTOM_MEMORY_MANAGEMENT + +static const char* MemTag = "libcurl"; +static size_t offset = sizeof(size_t); + +static void* malloc_callback(size_t size) +{ + char* newMem = reinterpret_cast<char*>(Aws::Malloc(MemTag, size + offset)); + std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem); + *pointerToSize = size; + return reinterpret_cast<void*>(newMem + offset); +} + +static void free_callback(void* ptr) +{ + if(ptr) + { + char* shiftedMemory = reinterpret_cast<char*>(ptr); + Aws::Free(shiftedMemory - offset); + } +} + +static void* realloc_callback(void* ptr, size_t size) +{ + if(!ptr) + { + return malloc_callback(size); + } + + + if(!size && ptr) + { + free_callback(ptr); + return nullptr; + } + + char* originalLenCharPtr = reinterpret_cast<char*>(ptr) - offset; + size_t originalLen = *reinterpret_cast<size_t*>(originalLenCharPtr); + + char* rawMemory = reinterpret_cast<char*>(Aws::Malloc(MemTag, size + offset)); + if(rawMemory) + { + std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(rawMemory); + *pointerToSize = size; + + size_t copyLength = (std::min)(originalLen, size); +#ifdef _MSC_VER + memcpy_s(rawMemory + offset, size, ptr, copyLength); +#else + memcpy(rawMemory + offset, ptr, copyLength); +#endif + free_callback(ptr); + return reinterpret_cast<void*>(rawMemory + offset); + } + else + { + return ptr; + } + +} + +static void* calloc_callback(size_t nmemb, size_t size) +{ + size_t dataSize = nmemb * size; + char* newMem = reinterpret_cast<char*>(Aws::Malloc(MemTag, dataSize + offset)); + std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem); + *pointerToSize = dataSize; +#ifdef _MSC_VER + memset_s(newMem + offset, dataSize, 0, dataSize); +#else + memset(newMem + offset, 0, dataSize); +#endif + + return reinterpret_cast<void*>(newMem + offset); +} + +static char* strdup_callback(const char* str) +{ + size_t len = strlen(str) + 1; + size_t newLen = len + offset; + char* newMem = reinterpret_cast<char*>(Aws::Malloc(MemTag, newLen)); + + if(newMem) + { + std::size_t* pointerToSize = reinterpret_cast<std::size_t*>(newMem); + *pointerToSize = len; +#ifdef _MSC_VER + memcpy_s(newMem + offset, len, str, len); +#else + memcpy(newMem + offset, str, len); +#endif + return newMem + offset; + } + return nullptr; +} + +#endif + +struct CurlWriteCallbackContext +{ + CurlWriteCallbackContext(const CurlHttpClient* client, HttpRequest* request, HttpResponse* response, - Aws::Utils::RateLimits::RateLimiterInterface* rateLimiter) : - m_client(client), - m_request(request), - m_response(response), - m_rateLimiter(rateLimiter), - m_numBytesResponseReceived(0) - {} - - const CurlHttpClient* m_client; - HttpRequest* m_request; - HttpResponse* m_response; - Aws::Utils::RateLimits::RateLimiterInterface* m_rateLimiter; - int64_t m_numBytesResponseReceived; -}; - -struct CurlReadCallbackContext -{ - CurlReadCallbackContext(const CurlHttpClient* client, HttpRequest* request, Aws::Utils::RateLimits::RateLimiterInterface* limiter) : - m_client(client), - m_rateLimiter(limiter), - m_request(request) - {} - - const CurlHttpClient* m_client; + Aws::Utils::RateLimits::RateLimiterInterface* rateLimiter) : + m_client(client), + m_request(request), + m_response(response), + m_rateLimiter(rateLimiter), + m_numBytesResponseReceived(0) + {} + + const CurlHttpClient* m_client; + HttpRequest* m_request; + HttpResponse* m_response; + Aws::Utils::RateLimits::RateLimiterInterface* m_rateLimiter; + int64_t m_numBytesResponseReceived; +}; + +struct CurlReadCallbackContext +{ + CurlReadCallbackContext(const CurlHttpClient* client, HttpRequest* request, Aws::Utils::RateLimits::RateLimiterInterface* limiter) : + m_client(client), + m_rateLimiter(limiter), + m_request(request) + {} + + const CurlHttpClient* m_client; CURL* m_curlHandle; - Aws::Utils::RateLimits::RateLimiterInterface* m_rateLimiter; - HttpRequest* m_request; -}; - -static const char* CURL_HTTP_CLIENT_TAG = "CurlHttpClient"; - + Aws::Utils::RateLimits::RateLimiterInterface* m_rateLimiter; + HttpRequest* m_request; +}; + +static const char* CURL_HTTP_CLIENT_TAG = "CurlHttpClient"; + static size_t WriteData(char* ptr, size_t size, size_t nmemb, void* userdata) -{ +{ if (ptr) - { + { CurlWriteCallbackContext* context = reinterpret_cast<CurlWriteCallbackContext*>(userdata); const CurlHttpClient* client = context->m_client; @@ -309,144 +309,144 @@ void SetOptCodeForHttpMethod(CURL* requestHandle, const std::shared_ptr<HttpRequ { switch (request->GetMethod()) { - case HttpMethod::HTTP_GET: - curl_easy_setopt(requestHandle, CURLOPT_HTTPGET, 1L); - break; - case HttpMethod::HTTP_POST: + case HttpMethod::HTTP_GET: + curl_easy_setopt(requestHandle, CURLOPT_HTTPGET, 1L); + break; + case HttpMethod::HTTP_POST: if (request->HasHeader(Aws::Http::CONTENT_LENGTH_HEADER) && request->GetHeaderValue(Aws::Http::CONTENT_LENGTH_HEADER) == "0") - { - curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "POST"); - } - else - { - curl_easy_setopt(requestHandle, CURLOPT_POST, 1L); - } - break; - case HttpMethod::HTTP_PUT: + { + curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "POST"); + } + else + { + curl_easy_setopt(requestHandle, CURLOPT_POST, 1L); + } + break; + case HttpMethod::HTTP_PUT: if ((!request->HasHeader(Aws::Http::CONTENT_LENGTH_HEADER) || request->GetHeaderValue(Aws::Http::CONTENT_LENGTH_HEADER) == "0") && !request->HasHeader(Aws::Http::TRANSFER_ENCODING_HEADER)) - { - curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "PUT"); - } - else - { - curl_easy_setopt(requestHandle, CURLOPT_PUT, 1L); - } - break; - case HttpMethod::HTTP_HEAD: - curl_easy_setopt(requestHandle, CURLOPT_HTTPGET, 1L); - curl_easy_setopt(requestHandle, CURLOPT_NOBODY, 1L); - break; - case HttpMethod::HTTP_PATCH: + { + curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "PUT"); + } + else + { + curl_easy_setopt(requestHandle, CURLOPT_PUT, 1L); + } + break; + case HttpMethod::HTTP_HEAD: + curl_easy_setopt(requestHandle, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(requestHandle, CURLOPT_NOBODY, 1L); + break; + case HttpMethod::HTTP_PATCH: if ((!request->HasHeader(Aws::Http::CONTENT_LENGTH_HEADER)|| request->GetHeaderValue(Aws::Http::CONTENT_LENGTH_HEADER) == "0") && !request->HasHeader(Aws::Http::TRANSFER_ENCODING_HEADER)) - { - curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "PATCH"); - } - else - { - curl_easy_setopt(requestHandle, CURLOPT_POST, 1L); - curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "PATCH"); - } - - break; - case HttpMethod::HTTP_DELETE: - curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "DELETE"); - break; - default: - assert(0); - curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "GET"); - break; - } -} - - -std::atomic<bool> CurlHttpClient::isInit(false); - -void CurlHttpClient::InitGlobalState() -{ - if (!isInit) - { + { + curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "PATCH"); + } + else + { + curl_easy_setopt(requestHandle, CURLOPT_POST, 1L); + curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "PATCH"); + } + + break; + case HttpMethod::HTTP_DELETE: + curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "DELETE"); + break; + default: + assert(0); + curl_easy_setopt(requestHandle, CURLOPT_CUSTOMREQUEST, "GET"); + break; + } +} + + +std::atomic<bool> CurlHttpClient::isInit(false); + +void CurlHttpClient::InitGlobalState() +{ + if (!isInit) + { auto curlVersionData = curl_version_info(CURLVERSION_NOW); AWS_LOGSTREAM_INFO(CURL_HTTP_CLIENT_TAG, "Initializing Curl library with version: " << curlVersionData->version << ", ssl version: " << curlVersionData->ssl_version); - isInit = true; -#ifdef AWS_CUSTOM_MEMORY_MANAGEMENT - curl_global_init_mem(CURL_GLOBAL_ALL, &malloc_callback, &free_callback, &realloc_callback, &strdup_callback, &calloc_callback); -#else - curl_global_init(CURL_GLOBAL_ALL); -#endif - } -} - - -void CurlHttpClient::CleanupGlobalState() -{ - curl_global_cleanup(); -} - -Aws::String CurlInfoTypeToString(curl_infotype type) -{ - switch(type) - { - case CURLINFO_TEXT: - return "Text"; - - case CURLINFO_HEADER_IN: - return "HeaderIn"; - - case CURLINFO_HEADER_OUT: - return "HeaderOut"; - - case CURLINFO_DATA_IN: - return "DataIn"; - - case CURLINFO_DATA_OUT: - return "DataOut"; - - case CURLINFO_SSL_DATA_IN: - return "SSLDataIn"; - - case CURLINFO_SSL_DATA_OUT: - return "SSLDataOut"; - - default: - return "Unknown"; - } -} - -int CurlDebugCallback(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr) -{ - AWS_UNREFERENCED_PARAM(handle); - AWS_UNREFERENCED_PARAM(userptr); - - if(type == CURLINFO_SSL_DATA_IN || type == CURLINFO_SSL_DATA_OUT) - { - AWS_LOGSTREAM_DEBUG("CURL", "(" << CurlInfoTypeToString(type) << ") " << size << "bytes"); - } - else - { - Aws::String debugString(data, size); - AWS_LOGSTREAM_DEBUG("CURL", "(" << CurlInfoTypeToString(type) << ") " << debugString); - } - - return 0; -} - - -CurlHttpClient::CurlHttpClient(const ClientConfiguration& clientConfig) : + isInit = true; +#ifdef AWS_CUSTOM_MEMORY_MANAGEMENT + curl_global_init_mem(CURL_GLOBAL_ALL, &malloc_callback, &free_callback, &realloc_callback, &strdup_callback, &calloc_callback); +#else + curl_global_init(CURL_GLOBAL_ALL); +#endif + } +} + + +void CurlHttpClient::CleanupGlobalState() +{ + curl_global_cleanup(); +} + +Aws::String CurlInfoTypeToString(curl_infotype type) +{ + switch(type) + { + case CURLINFO_TEXT: + return "Text"; + + case CURLINFO_HEADER_IN: + return "HeaderIn"; + + case CURLINFO_HEADER_OUT: + return "HeaderOut"; + + case CURLINFO_DATA_IN: + return "DataIn"; + + case CURLINFO_DATA_OUT: + return "DataOut"; + + case CURLINFO_SSL_DATA_IN: + return "SSLDataIn"; + + case CURLINFO_SSL_DATA_OUT: + return "SSLDataOut"; + + default: + return "Unknown"; + } +} + +int CurlDebugCallback(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr) +{ + AWS_UNREFERENCED_PARAM(handle); + AWS_UNREFERENCED_PARAM(userptr); + + if(type == CURLINFO_SSL_DATA_IN || type == CURLINFO_SSL_DATA_OUT) + { + AWS_LOGSTREAM_DEBUG("CURL", "(" << CurlInfoTypeToString(type) << ") " << size << "bytes"); + } + else + { + Aws::String debugString(data, size); + AWS_LOGSTREAM_DEBUG("CURL", "(" << CurlInfoTypeToString(type) << ") " << debugString); + } + + return 0; +} + + +CurlHttpClient::CurlHttpClient(const ClientConfiguration& clientConfig) : Base(), m_curlHandleContainer(clientConfig.maxConnections, clientConfig.httpRequestTimeoutMs, clientConfig.connectTimeoutMs, clientConfig.enableTcpKeepAlive, clientConfig.tcpKeepAliveIntervalMs, clientConfig.requestTimeoutMs, clientConfig.lowSpeedLimit), - m_isUsingProxy(!clientConfig.proxyHost.empty()), m_proxyUserName(clientConfig.proxyUserName), - m_proxyPassword(clientConfig.proxyPassword), m_proxyScheme(SchemeMapper::ToString(clientConfig.proxyScheme)), m_proxyHost(clientConfig.proxyHost), + m_isUsingProxy(!clientConfig.proxyHost.empty()), m_proxyUserName(clientConfig.proxyUserName), + m_proxyPassword(clientConfig.proxyPassword), m_proxyScheme(SchemeMapper::ToString(clientConfig.proxyScheme)), m_proxyHost(clientConfig.proxyHost), m_proxySSLCertPath(clientConfig.proxySSLCertPath), m_proxySSLCertType(clientConfig.proxySSLCertType), m_proxySSLKeyPath(clientConfig.proxySSLKeyPath), m_proxySSLKeyType(clientConfig.proxySSLKeyType), m_proxyKeyPasswd(clientConfig.proxySSLKeyPassword), - m_proxyPort(clientConfig.proxyPort), m_verifySSL(clientConfig.verifySSL), m_caPath(clientConfig.caPath), + m_proxyPort(clientConfig.proxyPort), m_verifySSL(clientConfig.verifySSL), m_caPath(clientConfig.caPath), m_caFile(clientConfig.caFile), m_proxyCaPath(clientConfig.proxyCaPath), m_proxyCaFile(clientConfig.proxyCaFile), m_disableExpectHeader(clientConfig.disableExpectHeader) -{ +{ if (clientConfig.followRedirects == FollowRedirectsPolicy::NEVER || (clientConfig.followRedirects == FollowRedirectsPolicy::DEFAULT && clientConfig.region == Aws::Region::AWS_GLOBAL)) { @@ -456,132 +456,132 @@ CurlHttpClient::CurlHttpClient(const ClientConfiguration& clientConfig) : { m_allowRedirects = true; } -} - - +} + + std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr<HttpRequest>& request, Aws::Utils::RateLimits::RateLimiterInterface* readLimiter, Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter) const -{ +{ URI uri = request->GetUri(); - Aws::String url = uri.GetURIString(); + Aws::String url = uri.GetURIString(); std::shared_ptr<HttpResponse> response = Aws::MakeShared<StandardHttpResponse>(CURL_HTTP_CLIENT_TAG, request); - - AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Making request to " << url); - struct curl_slist* headers = NULL; - - if (writeLimiter != nullptr) - { + + AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Making request to " << url); + struct curl_slist* headers = NULL; + + if (writeLimiter != nullptr) + { writeLimiter->ApplyAndPayForCost(request->GetSize()); - } - - Aws::StringStream headerStream; + } + + Aws::StringStream headerStream; HeaderValueCollection requestHeaders = request->GetHeaders(); - - AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Including headers:"); - for (auto& requestHeader : requestHeaders) - { - headerStream.str(""); - headerStream << requestHeader.first << ": " << requestHeader.second; - Aws::String headerString = headerStream.str(); - AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, headerString); - headers = curl_slist_append(headers, headerString.c_str()); - } - + + AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Including headers:"); + for (auto& requestHeader : requestHeaders) + { + headerStream.str(""); + headerStream << requestHeader.first << ": " << requestHeader.second; + Aws::String headerString = headerStream.str(); + AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, headerString); + headers = curl_slist_append(headers, headerString.c_str()); + } + if (!request->HasHeader(Http::TRANSFER_ENCODING_HEADER)) - { + { headers = curl_slist_append(headers, "transfer-encoding:"); } if (!request->HasHeader(Http::CONTENT_LENGTH_HEADER)) { - headers = curl_slist_append(headers, "content-length:"); - } - + headers = curl_slist_append(headers, "content-length:"); + } + if (!request->HasHeader(Http::CONTENT_TYPE_HEADER)) - { - headers = curl_slist_append(headers, "content-type:"); - } - - // Discard Expect header so as to avoid using multiple payloads to send a http request (header + body) - if (m_disableExpectHeader) - { - headers = curl_slist_append(headers, "Expect:"); - } - - CURL* connectionHandle = m_curlHandleContainer.AcquireCurlHandle(); - - if (connectionHandle) - { - AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Obtained connection handle " << connectionHandle); - - if (headers) - { - curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, headers); - } - + { + headers = curl_slist_append(headers, "content-type:"); + } + + // Discard Expect header so as to avoid using multiple payloads to send a http request (header + body) + if (m_disableExpectHeader) + { + headers = curl_slist_append(headers, "Expect:"); + } + + CURL* connectionHandle = m_curlHandleContainer.AcquireCurlHandle(); + + if (connectionHandle) + { + AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Obtained connection handle " << connectionHandle); + + if (headers) + { + curl_easy_setopt(connectionHandle, CURLOPT_HTTPHEADER, headers); + } + CurlWriteCallbackContext writeContext(this, request.get(), response.get(), readLimiter); CurlReadCallbackContext readContext(this, request.get(), writeLimiter); - - SetOptCodeForHttpMethod(connectionHandle, request); - - curl_easy_setopt(connectionHandle, CURLOPT_URL, url.c_str()); + + SetOptCodeForHttpMethod(connectionHandle, request); + + curl_easy_setopt(connectionHandle, CURLOPT_URL, url.c_str()); curl_easy_setopt(connectionHandle, CURLOPT_WRITEFUNCTION, WriteData); - curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &writeContext); + curl_easy_setopt(connectionHandle, CURLOPT_WRITEDATA, &writeContext); curl_easy_setopt(connectionHandle, CURLOPT_HEADERFUNCTION, WriteHeader); curl_easy_setopt(connectionHandle, CURLOPT_HEADERDATA, &writeContext); - - //we only want to override the default path if someone has explicitly told us to. - if(!m_caPath.empty()) - { - curl_easy_setopt(connectionHandle, CURLOPT_CAPATH, m_caPath.c_str()); - } - if(!m_caFile.empty()) - { - curl_easy_setopt(connectionHandle, CURLOPT_CAINFO, m_caFile.c_str()); - } - - // only set by android test builds because the emulator is missing a cert needed for aws services -#ifdef TEST_CERT_PATH - curl_easy_setopt(connectionHandle, CURLOPT_CAPATH, TEST_CERT_PATH); -#endif // TEST_CERT_PATH - - if (m_verifySSL) - { - curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYPEER, 1L); - curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYHOST, 2L); - -#if LIBCURL_VERSION_MAJOR >= 7 -#if LIBCURL_VERSION_MINOR >= 34 - curl_easy_setopt(connectionHandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); -#endif //LIBCURL_VERSION_MINOR -#endif //LIBCURL_VERSION_MAJOR - } - else - { - curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYHOST, 0L); - } - - if (m_allowRedirects) - { - curl_easy_setopt(connectionHandle, CURLOPT_FOLLOWLOCATION, 1L); - } - else - { - curl_easy_setopt(connectionHandle, CURLOPT_FOLLOWLOCATION, 0L); - } - + + //we only want to override the default path if someone has explicitly told us to. + if(!m_caPath.empty()) + { + curl_easy_setopt(connectionHandle, CURLOPT_CAPATH, m_caPath.c_str()); + } + if(!m_caFile.empty()) + { + curl_easy_setopt(connectionHandle, CURLOPT_CAINFO, m_caFile.c_str()); + } + + // only set by android test builds because the emulator is missing a cert needed for aws services +#ifdef TEST_CERT_PATH + curl_easy_setopt(connectionHandle, CURLOPT_CAPATH, TEST_CERT_PATH); +#endif // TEST_CERT_PATH + + if (m_verifySSL) + { + curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYPEER, 1L); + curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYHOST, 2L); + +#if LIBCURL_VERSION_MAJOR >= 7 +#if LIBCURL_VERSION_MINOR >= 34 + curl_easy_setopt(connectionHandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); +#endif //LIBCURL_VERSION_MINOR +#endif //LIBCURL_VERSION_MAJOR + } + else + { + curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(connectionHandle, CURLOPT_SSL_VERIFYHOST, 0L); + } + + if (m_allowRedirects) + { + curl_easy_setopt(connectionHandle, CURLOPT_FOLLOWLOCATION, 1L); + } + else + { + curl_easy_setopt(connectionHandle, CURLOPT_FOLLOWLOCATION, 0L); + } + #ifdef ENABLE_CURL_LOGGING curl_easy_setopt(connectionHandle, CURLOPT_VERBOSE, 1); curl_easy_setopt(connectionHandle, CURLOPT_DEBUGFUNCTION, CurlDebugCallback); #endif - if (m_isUsingProxy) - { - Aws::StringStream ss; - ss << m_proxyScheme << "://" << m_proxyHost; - curl_easy_setopt(connectionHandle, CURLOPT_PROXY, ss.str().c_str()); - curl_easy_setopt(connectionHandle, CURLOPT_PROXYPORT, (long) m_proxyPort); + if (m_isUsingProxy) + { + Aws::StringStream ss; + ss << m_proxyScheme << "://" << m_proxyHost; + curl_easy_setopt(connectionHandle, CURLOPT_PROXY, ss.str().c_str()); + curl_easy_setopt(connectionHandle, CURLOPT_PROXYPORT, (long) m_proxyPort); if(!m_proxyCaPath.empty()) { curl_easy_setopt(connectionHandle, CURLOPT_PROXY_CAPATH, m_proxyCaPath.c_str()); @@ -617,91 +617,91 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< } } #endif //CURL_HAS_TLS_PROXY - } - else - { - curl_easy_setopt(connectionHandle, CURLOPT_PROXY, ""); - } - + } + else + { + curl_easy_setopt(connectionHandle, CURLOPT_PROXY, ""); + } + if (request->GetContentBody()) - { + { curl_easy_setopt(connectionHandle, CURLOPT_READFUNCTION, ReadBody); - curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &readContext); + curl_easy_setopt(connectionHandle, CURLOPT_READDATA, &readContext); curl_easy_setopt(connectionHandle, CURLOPT_SEEKFUNCTION, SeekBody); - curl_easy_setopt(connectionHandle, CURLOPT_SEEKDATA, &readContext); - } + curl_easy_setopt(connectionHandle, CURLOPT_SEEKDATA, &readContext); + } OverrideOptionsOnConnectionHandle(connectionHandle); - Aws::Utils::DateTime startTransmissionTime = Aws::Utils::DateTime::Now(); - CURLcode curlResponseCode = curl_easy_perform(connectionHandle); + Aws::Utils::DateTime startTransmissionTime = Aws::Utils::DateTime::Now(); + CURLcode curlResponseCode = curl_easy_perform(connectionHandle); bool shouldContinueRequest = ContinueRequest(*request); - if (curlResponseCode != CURLE_OK && shouldContinueRequest) - { + if (curlResponseCode != CURLE_OK && shouldContinueRequest) + { response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION); Aws::StringStream ss; ss << "curlCode: " << curlResponseCode << ", " << curl_easy_strerror(curlResponseCode); response->SetClientErrorMessage(ss.str()); AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Curl returned error code " << curlResponseCode << " - " << curl_easy_strerror(curlResponseCode)); - } - else if(!shouldContinueRequest) - { + } + else if(!shouldContinueRequest) + { response->SetClientErrorType(CoreErrors::USER_CANCELLED); response->SetClientErrorMessage("Request cancelled by user's continuation handler"); - } - else - { - long responseCode; - curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &responseCode); - response->SetResponseCode(static_cast<HttpResponseCode>(responseCode)); - AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Returned http response code " << responseCode); - - char* contentType = nullptr; - curl_easy_getinfo(connectionHandle, CURLINFO_CONTENT_TYPE, &contentType); - if (contentType) - { - response->SetContentType(contentType); - AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Returned content type " << contentType); - } - + } + else + { + long responseCode; + curl_easy_getinfo(connectionHandle, CURLINFO_RESPONSE_CODE, &responseCode); + response->SetResponseCode(static_cast<HttpResponseCode>(responseCode)); + AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Returned http response code " << responseCode); + + char* contentType = nullptr; + curl_easy_getinfo(connectionHandle, CURLINFO_CONTENT_TYPE, &contentType); + if (contentType) + { + response->SetContentType(contentType); + AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Returned content type " << contentType); + } + if (request->GetMethod() != HttpMethod::HTTP_HEAD && - writeContext.m_client->IsRequestProcessingEnabled() && - response->HasHeader(Aws::Http::CONTENT_LENGTH_HEADER)) - { - const Aws::String& contentLength = response->GetHeader(Aws::Http::CONTENT_LENGTH_HEADER); - int64_t numBytesResponseReceived = writeContext.m_numBytesResponseReceived; - AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Response content-length header: " << contentLength); - AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Response body length: " << numBytesResponseReceived); - if (StringUtils::ConvertToInt64(contentLength.c_str()) != numBytesResponseReceived) - { + writeContext.m_client->IsRequestProcessingEnabled() && + response->HasHeader(Aws::Http::CONTENT_LENGTH_HEADER)) + { + const Aws::String& contentLength = response->GetHeader(Aws::Http::CONTENT_LENGTH_HEADER); + int64_t numBytesResponseReceived = writeContext.m_numBytesResponseReceived; + AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Response content-length header: " << contentLength); + AWS_LOGSTREAM_TRACE(CURL_HTTP_CLIENT_TAG, "Response body length: " << numBytesResponseReceived); + if (StringUtils::ConvertToInt64(contentLength.c_str()) != numBytesResponseReceived) + { response->SetClientErrorType(CoreErrors::NETWORK_CONNECTION); response->SetClientErrorMessage("Response body length doesn't match the content-length header."); - AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Response body length doesn't match the content-length header."); - } - } - - AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Releasing curl handle " << connectionHandle); - } - - double timep; - CURLcode ret = curl_easy_getinfo(connectionHandle, CURLINFO_NAMELOOKUP_TIME, &timep); // DNS Resolve Latency, seconds. - if (ret == CURLE_OK) - { + AWS_LOGSTREAM_ERROR(CURL_HTTP_CLIENT_TAG, "Response body length doesn't match the content-length header."); + } + } + + AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Releasing curl handle " << connectionHandle); + } + + double timep; + CURLcode ret = curl_easy_getinfo(connectionHandle, CURLINFO_NAMELOOKUP_TIME, &timep); // DNS Resolve Latency, seconds. + if (ret == CURLE_OK) + { request->AddRequestMetric(GetHttpClientMetricNameByType(HttpClientMetricsType::DnsLatency), static_cast<int64_t>(timep * 1000));// to milliseconds - } - + } + ret = curl_easy_getinfo(connectionHandle, CURLINFO_STARTTRANSFER_TIME, &timep); // Connect Latency - if (ret == CURLE_OK) - { + if (ret == CURLE_OK) + { request->AddRequestMetric(GetHttpClientMetricNameByType(HttpClientMetricsType::ConnectLatency), static_cast<int64_t>(timep * 1000)); - } - - ret = curl_easy_getinfo(connectionHandle, CURLINFO_APPCONNECT_TIME, &timep); // Ssl Latency - if (ret == CURLE_OK) - { + } + + ret = curl_easy_getinfo(connectionHandle, CURLINFO_APPCONNECT_TIME, &timep); // Ssl Latency + if (ret == CURLE_OK) + { request->AddRequestMetric(GetHttpClientMetricNameByType(HttpClientMetricsType::SslLatency), static_cast<int64_t>(timep * 1000)); - } - + } + const char* ip = nullptr; auto curlGetInfoResult = curl_easy_getinfo(connectionHandle, CURLINFO_PRIMARY_IP, &ip); // Get the IP address of the remote endpoint if (curlGetInfoResult == CURLE_OK && ip) @@ -709,9 +709,9 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< request->SetResolvedRemoteHost(ip); } if (curlResponseCode != CURLE_OK) - { + { m_curlHandleContainer.DestroyCurlHandle(connectionHandle); - } + } else { m_curlHandleContainer.ReleaseCurlHandle(connectionHandle); @@ -719,12 +719,12 @@ std::shared_ptr<HttpResponse> CurlHttpClient::MakeRequest(const std::shared_ptr< //go ahead and flush the response body stream response->GetResponseBody().flush(); request->AddRequestMetric(GetHttpClientMetricNameByType(HttpClientMetricsType::RequestLatency), (DateTime::Now() - startTransmissionTime).count()); - } - - if (headers) - { - curl_slist_free_all(headers); - } - - return response; -} + } + + if (headers) + { + curl_slist_free_all(headers); + } + + return response; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp index 47a0ee4fac..1125eb57ce 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpRequest.cpp @@ -2,103 +2,103 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/standard/StandardHttpRequest.h> - -#include <aws/core/utils/StringUtils.h> - -#include <iostream> -#include <algorithm> -#include <cassert> - -using namespace Aws::Http; -using namespace Aws::Http::Standard; -using namespace Aws::Utils; - -static bool IsDefaultPort(const URI& uri) -{ - switch(uri.GetPort()) - { - case 80: - return uri.GetScheme() == Scheme::HTTP; - case 443: - return uri.GetScheme() == Scheme::HTTPS; - default: - return false; - } -} - -StandardHttpRequest::StandardHttpRequest(const URI& uri, HttpMethod method) : - HttpRequest(uri, method), - bodyStream(nullptr), - m_responseStreamFactory() -{ - if(IsDefaultPort(uri)) - { + +#include <aws/core/http/standard/StandardHttpRequest.h> + +#include <aws/core/utils/StringUtils.h> + +#include <iostream> +#include <algorithm> +#include <cassert> + +using namespace Aws::Http; +using namespace Aws::Http::Standard; +using namespace Aws::Utils; + +static bool IsDefaultPort(const URI& uri) +{ + switch(uri.GetPort()) + { + case 80: + return uri.GetScheme() == Scheme::HTTP; + case 443: + return uri.GetScheme() == Scheme::HTTPS; + default: + return false; + } +} + +StandardHttpRequest::StandardHttpRequest(const URI& uri, HttpMethod method) : + HttpRequest(uri, method), + bodyStream(nullptr), + m_responseStreamFactory() +{ + if(IsDefaultPort(uri)) + { StandardHttpRequest::SetHeaderValue(HOST_HEADER, uri.GetAuthority()); - } - else - { - Aws::StringStream host; - host << uri.GetAuthority() << ":" << uri.GetPort(); + } + else + { + Aws::StringStream host; + host << uri.GetAuthority() << ":" << uri.GetPort(); StandardHttpRequest::SetHeaderValue(HOST_HEADER, host.str()); - } -} - -HeaderValueCollection StandardHttpRequest::GetHeaders() const -{ - HeaderValueCollection headers; - - for (HeaderValueCollection::const_iterator iter = headerMap.begin(); iter != headerMap.end(); ++iter) - { - headers.emplace(HeaderValuePair(iter->first, iter->second)); - } - - return headers; -} - -const Aws::String& StandardHttpRequest::GetHeaderValue(const char* headerName) const -{ - auto iter = headerMap.find(headerName); - assert (iter != headerMap.end()); - return iter->second; -} - -void StandardHttpRequest::SetHeaderValue(const char* headerName, const Aws::String& headerValue) -{ - headerMap[StringUtils::ToLower(headerName)] = StringUtils::Trim(headerValue.c_str()); -} - -void StandardHttpRequest::SetHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) -{ - headerMap[StringUtils::ToLower(headerName.c_str())] = StringUtils::Trim(headerValue.c_str()); -} - -void StandardHttpRequest::DeleteHeader(const char* headerName) -{ - headerMap.erase(StringUtils::ToLower(headerName)); -} - -bool StandardHttpRequest::HasHeader(const char* headerName) const -{ - return headerMap.find(StringUtils::ToLower(headerName)) != headerMap.end(); -} - -int64_t StandardHttpRequest::GetSize() const -{ - int64_t size = 0; - - std::for_each(headerMap.cbegin(), headerMap.cend(), [&](const HeaderValueCollection::value_type& kvPair){ size += kvPair.first.length(); size += kvPair.second.length(); }); - - return size; -} - -const Aws::IOStreamFactory& StandardHttpRequest::GetResponseStreamFactory() const + } +} + +HeaderValueCollection StandardHttpRequest::GetHeaders() const +{ + HeaderValueCollection headers; + + for (HeaderValueCollection::const_iterator iter = headerMap.begin(); iter != headerMap.end(); ++iter) + { + headers.emplace(HeaderValuePair(iter->first, iter->second)); + } + + return headers; +} + +const Aws::String& StandardHttpRequest::GetHeaderValue(const char* headerName) const +{ + auto iter = headerMap.find(headerName); + assert (iter != headerMap.end()); + return iter->second; +} + +void StandardHttpRequest::SetHeaderValue(const char* headerName, const Aws::String& headerValue) +{ + headerMap[StringUtils::ToLower(headerName)] = StringUtils::Trim(headerValue.c_str()); +} + +void StandardHttpRequest::SetHeaderValue(const Aws::String& headerName, const Aws::String& headerValue) +{ + headerMap[StringUtils::ToLower(headerName.c_str())] = StringUtils::Trim(headerValue.c_str()); +} + +void StandardHttpRequest::DeleteHeader(const char* headerName) +{ + headerMap.erase(StringUtils::ToLower(headerName)); +} + +bool StandardHttpRequest::HasHeader(const char* headerName) const { - return m_responseStreamFactory; -} - -void StandardHttpRequest::SetResponseStreamFactory(const Aws::IOStreamFactory& factory) + return headerMap.find(StringUtils::ToLower(headerName)) != headerMap.end(); +} + +int64_t StandardHttpRequest::GetSize() const { - m_responseStreamFactory = factory; -} + int64_t size = 0; + + std::for_each(headerMap.cbegin(), headerMap.cend(), [&](const HeaderValueCollection::value_type& kvPair){ size += kvPair.first.length(); size += kvPair.second.length(); }); + + return size; +} + +const Aws::IOStreamFactory& StandardHttpRequest::GetResponseStreamFactory() const +{ + return m_responseStreamFactory; +} + +void StandardHttpRequest::SetResponseStreamFactory(const Aws::IOStreamFactory& factory) +{ + m_responseStreamFactory = factory; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp index 92d7a062b6..2097a5efa4 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/http/standard/StandardHttpResponse.cpp @@ -2,45 +2,45 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/http/standard/StandardHttpResponse.h> - -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/memory/AWSMemory.h> - -#include <istream> - -using namespace Aws::Http; -using namespace Aws::Http::Standard; -using namespace Aws::Utils; - - -HeaderValueCollection StandardHttpResponse::GetHeaders() const -{ - HeaderValueCollection headerValueCollection; - - for (Aws::Map<Aws::String, Aws::String>::const_iterator iter = headerMap.begin(); iter != headerMap.end(); ++iter) - { - headerValueCollection.emplace(HeaderValuePair(iter->first, iter->second)); - } - - return headerValueCollection; -} - -bool StandardHttpResponse::HasHeader(const char* headerName) const -{ - return headerMap.find(StringUtils::ToLower(headerName)) != headerMap.end(); -} - -const Aws::String& StandardHttpResponse::GetHeader(const Aws::String& headerName) const -{ - Aws::Map<Aws::String, Aws::String>::const_iterator foundValue = headerMap.find(StringUtils::ToLower(headerName.c_str())); - return foundValue->second; -} - -void StandardHttpResponse::AddHeader(const Aws::String& headerName, const Aws::String& headerValue) -{ - headerMap[StringUtils::ToLower(headerName.c_str())] = headerValue; -} - - + +#include <aws/core/http/standard/StandardHttpResponse.h> + +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/memory/AWSMemory.h> + +#include <istream> + +using namespace Aws::Http; +using namespace Aws::Http::Standard; +using namespace Aws::Utils; + + +HeaderValueCollection StandardHttpResponse::GetHeaders() const +{ + HeaderValueCollection headerValueCollection; + + for (Aws::Map<Aws::String, Aws::String>::const_iterator iter = headerMap.begin(); iter != headerMap.end(); ++iter) + { + headerValueCollection.emplace(HeaderValuePair(iter->first, iter->second)); + } + + return headerValueCollection; +} + +bool StandardHttpResponse::HasHeader(const char* headerName) const +{ + return headerMap.find(StringUtils::ToLower(headerName)) != headerMap.end(); +} + +const Aws::String& StandardHttpResponse::GetHeader(const Aws::String& headerName) const +{ + Aws::Map<Aws::String, Aws::String>::const_iterator foundValue = headerMap.find(StringUtils::ToLower(headerName.c_str())); + return foundValue->second; +} + +void StandardHttpResponse::AddHeader(const Aws::String& headerName, const Aws::String& headerValue) +{ + headerMap[StringUtils::ToLower(headerName.c_str())] = headerValue; +} + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp index 24145e4d92..b69c7f5b5d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/internal/AWSHttpResourceClient.cpp @@ -2,30 +2,30 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/internal/AWSHttpResourceClient.h> -#include <aws/core/client/DefaultRetryStrategy.h> -#include <aws/core/http/HttpClient.h> -#include <aws/core/http/HttpClientFactory.h> -#include <aws/core/http/HttpResponse.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/StringUtils.h> + +#include <aws/core/internal/AWSHttpResourceClient.h> +#include <aws/core/client/DefaultRetryStrategy.h> +#include <aws/core/http/HttpClient.h> +#include <aws/core/http/HttpClientFactory.h> +#include <aws/core/http/HttpResponse.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/StringUtils.h> #include <aws/core/utils/HashingUtils.h> -#include <aws/core/platform/Environment.h> -#include <aws/core/client/AWSError.h> -#include <aws/core/client/CoreErrors.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/client/AWSError.h> +#include <aws/core/client/CoreErrors.h> #include <aws/core/utils/xml/XmlSerializer.h> #include <mutex> -#include <sstream> - +#include <sstream> + using namespace Aws; -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; using namespace Aws::Utils::Xml; -using namespace Aws::Http; -using namespace Aws::Client; -using namespace Aws::Internal; - +using namespace Aws::Http; +using namespace Aws::Client; +using namespace Aws::Internal; + static const char EC2_SECURITY_CREDENTIALS_RESOURCE[] = "/latest/meta-data/iam/security-credentials"; static const char EC2_REGION_RESOURCE[] = "/latest/meta-data/placement/availability-zone"; static const char EC2_IMDS_TOKEN_RESOURCE[] = "/latest/api/token"; @@ -35,7 +35,7 @@ static const char EC2_IMDS_TOKEN_HEADER[] = "x-aws-ec2-metadata-token"; static const char RESOURCE_CLIENT_CONFIGURATION_ALLOCATION_TAG[] = "AWSHttpResourceClient"; static const char EC2_METADATA_CLIENT_LOG_TAG[] = "EC2MetadataClient"; static const char ECS_CREDENTIALS_CLIENT_LOG_TAG[] = "ECSCredentialsClient"; - + namespace Aws { namespace Client @@ -48,10 +48,10 @@ namespace Aws static ClientConfiguration MakeDefaultHttpResourceClientConfiguration(const char *logtag) { ClientConfiguration res; - + res.maxConnections = 2; res.scheme = Scheme::HTTP; - + #if defined(WIN32) && defined(BYPASS_DEFAULT_PROXY) // For security reasons, we must bypass any proxy settings when fetching sensitive information, for example // user credentials. On Windows, IXMLHttpRequest2 does not support bypassing proxy settings, therefore, @@ -67,16 +67,16 @@ namespace Aws res.proxyUserName = ""; res.proxyPassword = ""; res.proxyPort = 0; - + // EC2MetadataService throttles by delaying the response so the service client should set a large read timeout. // EC2MetadataService delay is in order of seconds so it only make sense to retry after a couple of seconds. res.connectTimeoutMs = 1000; res.requestTimeoutMs = 1000; res.retryStrategy = Aws::MakeShared<DefaultRetryStrategy>(RESOURCE_CLIENT_CONFIGURATION_ALLOCATION_TAG, 1, 1000); - + return res; } - + AWSHttpResourceClient::AWSHttpResourceClient(const Aws::Client::ClientConfiguration& clientConfiguration, const char* logtag) : m_logtag(logtag), m_retryStrategy(clientConfiguration.retryStrategy), m_httpClient(nullptr) { @@ -85,24 +85,24 @@ namespace Aws << clientConfiguration.maxConnections << " and scheme " << SchemeMapper::ToString(clientConfiguration.scheme)); - + m_httpClient = CreateHttpClient(clientConfiguration); } - + AWSHttpResourceClient::AWSHttpResourceClient(const char* logtag) : AWSHttpResourceClient(MakeDefaultHttpResourceClientConfiguration(logtag), logtag) { } - + AWSHttpResourceClient::~AWSHttpResourceClient() { } - + Aws::String AWSHttpResourceClient::GetResource(const char* endpoint, const char* resource, const char* authToken) const { return GetResourceWithAWSWebServiceResult(endpoint, resource, authToken).GetPayload(); } - + AmazonWebServiceResult<Aws::String> AWSHttpResourceClient::GetResourceWithAWSWebServiceResult(const char *endpoint, const char *resource, const char *authToken) const { Aws::StringStream ss; @@ -113,7 +113,7 @@ namespace Aws } std::shared_ptr<HttpRequest> request(CreateHttpRequest(ss.str(), HttpMethod::HTTP_GET, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod)); - + request->SetUserAgent(ComputeUserAgentString()); if (authToken) @@ -125,7 +125,7 @@ namespace Aws } AmazonWebServiceResult<Aws::String> AWSHttpResourceClient::GetResourceWithAWSWebServiceResult(const std::shared_ptr<HttpRequest> &httpRequest) const - { + { AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Retrieving credentials from " << httpRequest->GetURIString()); for (long retries = 0;; retries++) @@ -167,18 +167,18 @@ namespace Aws AWS_LOGSTREAM_WARN(m_logtag.c_str(), "Request failed, now waiting " << sleepMillis << " ms before attempting again."); m_httpClient->RetryRequestSleep(std::chrono::milliseconds(sleepMillis)); } - } - + } + EC2MetadataClient::EC2MetadataClient(const char* endpoint) : AWSHttpResourceClient(EC2_METADATA_CLIENT_LOG_TAG), m_endpoint(endpoint), m_tokenRequired(true) { } - + EC2MetadataClient::EC2MetadataClient(const Aws::Client::ClientConfiguration &clientConfiguration, const char *endpoint) : AWSHttpResourceClient(clientConfiguration, EC2_METADATA_CLIENT_LOG_TAG), m_endpoint(endpoint), m_tokenRequired(true) - { - } - + { + } + EC2MetadataClient::~EC2MetadataClient() { @@ -193,9 +193,9 @@ namespace Aws { std::unique_lock<std::recursive_mutex> locker(m_tokenMutex); if (m_tokenRequired) - { + { return GetDefaultCredentialsSecurely(); - } + } AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Getting default credentials for ec2 instance"); auto result = GetResourceWithAWSWebServiceResult(m_endpoint.c_str(), EC2_SECURITY_CREDENTIALS_RESOURCE, nullptr); @@ -206,12 +206,12 @@ namespace Aws // then when we fall back to insecure call, it might return 401 ask for secure call, // Then, SDK might get into a recursive loop call situation between secure and insecure call. if (httpResponseCode == Http::HttpResponseCode::UNAUTHORIZED) - { + { m_tokenRequired = true; return {}; } locker.unlock(); - + Aws::String trimmedCredentialsString = StringUtils::Trim(credentialsString.c_str()); if (trimmedCredentialsString.empty()) return {}; @@ -224,8 +224,8 @@ namespace Aws { AWS_LOGSTREAM_WARN(m_logtag.c_str(), "Initial call to ec2Metadataservice to get credentials failed"); return {}; - } - + } + Aws::StringStream ss; ss << EC2_SECURITY_CREDENTIALS_RESOURCE << "/" << securityCredentials[0]; AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource " << ss.str()); @@ -233,7 +233,7 @@ namespace Aws } Aws::String EC2MetadataClient::GetDefaultCredentialsSecurely() const - { + { std::unique_lock<std::recursive_mutex> locker(m_tokenMutex); if (!m_tokenRequired) { @@ -291,17 +291,17 @@ namespace Aws credentialsRequest->SetUserAgent(userAgentString); AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource " << ss.str() << " with token."); return GetResourceWithAWSWebServiceResult(credentialsRequest).GetPayload(); - } - + } + Aws::String EC2MetadataClient::GetCurrentRegion() const { if (!m_region.empty()) { return m_region; } - + AWS_LOGSTREAM_TRACE(m_logtag.c_str(), "Getting current region for ec2 instance"); - + Aws::StringStream ss; ss << m_endpoint << EC2_REGION_RESOURCE; std::shared_ptr<HttpRequest> regionRequest(CreateHttpRequest(ss.str(), HttpMethod::HTTP_GET, @@ -315,21 +315,21 @@ namespace Aws } regionRequest->SetUserAgent(ComputeUserAgentString()); Aws::String azString = GetResourceWithAWSWebServiceResult(regionRequest).GetPayload(); - + if (azString.empty()) { AWS_LOGSTREAM_INFO(m_logtag.c_str() , "Unable to pull region from instance metadata service "); return {}; } - + Aws::String trimmedAZString = StringUtils::Trim(azString.c_str()); AWS_LOGSTREAM_DEBUG(m_logtag.c_str(), "Calling EC2MetadataService resource " << EC2_REGION_RESOURCE << " , returned credential string " << trimmedAZString); - + Aws::String region; region.reserve(trimmedAZString.length()); - + bool digitFound = false; for (auto character : trimmedAZString) { @@ -341,15 +341,15 @@ namespace Aws { digitFound = true; } - + region.append(1, character); } - + AWS_LOGSTREAM_INFO(m_logtag.c_str(), "Detected current region as " << region); m_region = region; return region; } - + #ifdef _MSC_VER // VS2015 compiler's bug, warning s_ec2metadataClient: symbol will be dynamically initialized (implementation limitation) AWS_SUPPRESS_WARNING(4592, @@ -358,7 +358,7 @@ namespace Aws #else static std::shared_ptr<EC2MetadataClient> s_ec2metadataClient(nullptr); #endif - + void InitEC2MetadataClient() { if (s_ec2metadataClient) @@ -367,7 +367,7 @@ namespace Aws } s_ec2metadataClient = Aws::MakeShared<EC2MetadataClient>(EC2_METADATA_CLIENT_LOG_TAG); } - + void CleanupEC2MetadataClient() { if (!s_ec2metadataClient) @@ -376,31 +376,31 @@ namespace Aws } s_ec2metadataClient = nullptr; } - + std::shared_ptr<EC2MetadataClient> GetEC2MetadataClient() { return s_ec2metadataClient; } - - + + ECSCredentialsClient::ECSCredentialsClient(const char* resourcePath, const char* endpoint, const char* token) : AWSHttpResourceClient(ECS_CREDENTIALS_CLIENT_LOG_TAG), m_resourcePath(resourcePath), m_endpoint(endpoint), m_token(token) - { - } + { + } ECSCredentialsClient::ECSCredentialsClient(const Aws::Client::ClientConfiguration& clientConfiguration, const char* resourcePath, const char* endpoint, const char* token) : AWSHttpResourceClient(clientConfiguration, ECS_CREDENTIALS_CLIENT_LOG_TAG), m_resourcePath(resourcePath), m_endpoint(endpoint), m_token(token) - { - } - + { + } + static const char STS_RESOURCE_CLIENT_LOG_TAG[] = "STSResourceClient"; STSCredentialsClient::STSCredentialsClient(const Aws::Client::ClientConfiguration& clientConfiguration) : AWSHttpResourceClient(clientConfiguration, STS_RESOURCE_CLIENT_LOG_TAG) { SetErrorMarshaller(Aws::MakeUnique<Aws::Client::XmlErrorMarshaller>(STS_RESOURCE_CLIENT_LOG_TAG)); - + Aws::StringStream ss; if (clientConfiguration.scheme == Aws::Http::Scheme::HTTP) { @@ -410,11 +410,11 @@ namespace Aws { ss << "https://"; } - + static const int CN_NORTH_1_HASH = Aws::Utils::HashingUtils::HashString(Aws::Region::CN_NORTH_1); static const int CN_NORTHWEST_1_HASH = Aws::Utils::HashingUtils::HashString(Aws::Region::CN_NORTHWEST_1); auto hash = Aws::Utils::HashingUtils::HashString(clientConfiguration.region.c_str()); - + ss << "sts." << clientConfiguration.region << ".amazonaws.com"; if (hash == CN_NORTH_1_HASH || hash == CN_NORTHWEST_1_HASH) { @@ -503,4 +503,4 @@ namespace Aws return result; } } -} +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp index 9953004bc3..28b0cd97b9 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/DefaultMonitoring.cpp @@ -2,109 +2,109 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/monitoring/DefaultMonitoring.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/json/JsonSerializer.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/client/AWSClient.h> -#include <aws/core/auth/AWSCredentialsProvider.h> -#include <aws/core/platform/Environment.h> -#include <aws/core/config/AWSProfileConfigLoader.h> -#include <aws/core/utils/logging/LogMacros.h> -using namespace Aws::Utils; - -namespace Aws -{ - namespace Monitoring - { - static const char DEFAULT_MONITORING_ALLOC_TAG[] = "DefaultMonitoringAllocTag"; - static const int CLIENT_ID_LENGTH_LIMIT = 256; + +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/monitoring/DefaultMonitoring.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/json/JsonSerializer.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/client/AWSClient.h> +#include <aws/core/auth/AWSCredentialsProvider.h> +#include <aws/core/platform/Environment.h> +#include <aws/core/config/AWSProfileConfigLoader.h> +#include <aws/core/utils/logging/LogMacros.h> +using namespace Aws::Utils; + +namespace Aws +{ + namespace Monitoring + { + static const char DEFAULT_MONITORING_ALLOC_TAG[] = "DefaultMonitoringAllocTag"; + static const int CLIENT_ID_LENGTH_LIMIT = 256; static const int USER_AGENT_LENGTH_LIMIT = 256; - static const int ERROR_MESSAGE_LENGTH_LIMIT = 512; - - const char DEFAULT_MONITORING_CLIENT_ID[] = ""; // default to empty; + static const int ERROR_MESSAGE_LENGTH_LIMIT = 512; + + const char DEFAULT_MONITORING_CLIENT_ID[] = ""; // default to empty; const char DEFAULT_MONITORING_HOST[] = "127.0.0.1"; // default to loopback ip address instead of "localhost" based on design specification. - unsigned short DEFAULT_MONITORING_PORT = 31000; //default to 31000; - bool DEFAULT_MONITORING_ENABLE = false; //default to false; - - const int DefaultMonitoring::DEFAULT_MONITORING_VERSION = 1; - const char DefaultMonitoring::DEFAULT_CSM_CONFIG_ENABLED[] = "csm_enabled"; - const char DefaultMonitoring::DEFAULT_CSM_CONFIG_CLIENT_ID[] = "csm_client_id"; + unsigned short DEFAULT_MONITORING_PORT = 31000; //default to 31000; + bool DEFAULT_MONITORING_ENABLE = false; //default to false; + + const int DefaultMonitoring::DEFAULT_MONITORING_VERSION = 1; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_ENABLED[] = "csm_enabled"; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_CLIENT_ID[] = "csm_client_id"; const char DefaultMonitoring::DEFAULT_CSM_CONFIG_HOST[] = "csm_host"; - const char DefaultMonitoring::DEFAULT_CSM_CONFIG_PORT[] = "csm_port"; - const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED[] = "AWS_CSM_ENABLED"; - const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID[] = "AWS_CSM_CLIENT_ID"; + const char DefaultMonitoring::DEFAULT_CSM_CONFIG_PORT[] = "csm_port"; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED[] = "AWS_CSM_ENABLED"; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID[] = "AWS_CSM_CLIENT_ID"; const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_HOST[] = "AWS_CSM_HOST"; - const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_PORT[] = "AWS_CSM_PORT"; - - - struct DefaultContext - { - Aws::Utils::DateTime apiCallStartTime; - Aws::Utils::DateTime attemptStartTime; - int retryCount = 0; + const char DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_PORT[] = "AWS_CSM_PORT"; + + + struct DefaultContext + { + Aws::Utils::DateTime apiCallStartTime; + Aws::Utils::DateTime attemptStartTime; + int retryCount = 0; bool lastAttemptSucceeded = false; bool lastErrorRetryable = false; //doesn't apply if last attempt succeeded. const Aws::Client::HttpResponseOutcome* outcome = nullptr; - }; - + }; + static inline void FillRequiredFieldsToJson(Json::JsonValue& json, const Aws::String& type, - const Aws::String& service, - const Aws::String& api, - const Aws::String& clientId, - const DateTime& timestamp, + const Aws::String& service, + const Aws::String& api, + const Aws::String& clientId, + const DateTime& timestamp, int version, const Aws::String& userAgent) - { - json.WithString("Type", type) - .WithString("Service", service) - .WithString("Api", api) - .WithString("ClientId", clientId.substr(0, CLIENT_ID_LENGTH_LIMIT)) - .WithInt64("Timestamp", timestamp.Millis()) + { + json.WithString("Type", type) + .WithString("Service", service) + .WithString("Api", api) + .WithString("ClientId", clientId.substr(0, CLIENT_ID_LENGTH_LIMIT)) + .WithInt64("Timestamp", timestamp.Millis()) .WithInteger("Version", version) .WithString("UserAgent", userAgent.substr(0, USER_AGENT_LENGTH_LIMIT)); - } - - static inline void FillRequiredApiCallFieldsToJson(Json::JsonValue& json, - int attemptCount, + } + + static inline void FillRequiredApiCallFieldsToJson(Json::JsonValue& json, + int attemptCount, int64_t apiCallLatency, bool maxRetriesExceeded) - { - json.WithInteger("AttemptCount", attemptCount) + { + json.WithInteger("AttemptCount", attemptCount) .WithInt64("Latency", apiCallLatency) .WithInteger("MaxRetriesExceeded", maxRetriesExceeded ? 1 : 0); - } - - static inline void FillRequiredApiAttemptFieldsToJson(Json::JsonValue& json, - const Aws::String& domainName, - int64_t attemptLatency) - { - json.WithString("Fqdn", domainName) - .WithInt64("AttemptLatency", attemptLatency); - } - + } + + static inline void FillRequiredApiAttemptFieldsToJson(Json::JsonValue& json, + const Aws::String& domainName, + int64_t attemptLatency) + { + json.WithString("Fqdn", domainName) + .WithInt64("AttemptLatency", attemptLatency); + } + static inline void ExportResponseHeaderToJson(Json::JsonValue& json, const Aws::Http::HeaderValueCollection& headers, - const Aws::String& headerName, const Aws::String& targetName) - { - auto iter = headers.find(headerName); - if (iter != headers.end()) - { - json.WithString(targetName, iter->second); - } - } - - static inline void ExportHttpMetricsToJson(Json::JsonValue& json, const Aws::Monitoring::HttpClientMetricsCollection& httpMetrics, Aws::Monitoring::HttpClientMetricsType type) - { - auto iter = httpMetrics.find(GetHttpClientMetricNameByType(type)); - if (iter != httpMetrics.end()) - { - json.WithInt64(GetHttpClientMetricNameByType(type), iter->second); - } - } - + const Aws::String& headerName, const Aws::String& targetName) + { + auto iter = headers.find(headerName); + if (iter != headers.end()) + { + json.WithString(targetName, iter->second); + } + } + + static inline void ExportHttpMetricsToJson(Json::JsonValue& json, const Aws::Monitoring::HttpClientMetricsCollection& httpMetrics, Aws::Monitoring::HttpClientMetricsType type) + { + auto iter = httpMetrics.find(GetHttpClientMetricNameByType(type)); + if (iter != httpMetrics.end()) + { + json.WithInt64(GetHttpClientMetricNameByType(type), iter->second); + } + } + static inline void FillOptionalApiCallFieldsToJson(Json::JsonValue& json, const Aws::Http::HttpRequest* request, const Aws::Client::HttpResponseOutcome& outcome) @@ -132,155 +132,155 @@ namespace Aws } } - static inline void FillOptionalApiAttemptFieldsToJson(Json::JsonValue& json, + static inline void FillOptionalApiAttemptFieldsToJson(Json::JsonValue& json, const Aws::Http::HttpRequest* request, - const Aws::Client::HttpResponseOutcome& outcome, - const CoreMetricsCollection& metricsFromCore) - { - /** - *No matter request succeeded or not, these fields should be included as long as their requirements + const Aws::Client::HttpResponseOutcome& outcome, + const CoreMetricsCollection& metricsFromCore) + { + /** + *No matter request succeeded or not, these fields should be included as long as their requirements *are met. We should be able to access response (so as to access original request) if the response has error. - */ - if (request->HasAwsSessionToken() && !request->GetAwsSessionToken().empty()) - { - json.WithString("SessionToken", request->GetAwsSessionToken()); - } - if (!request->GetSigningRegion().empty()) - { - json.WithString("Region", request->GetSigningRegion()); - } - if (!request->GetSigningAccessKey().empty()) - { - json.WithString("AccessKey", request->GetSigningAccessKey()); - } - - const auto& headers = outcome.IsSuccess() ? outcome.GetResult()->GetHeaders() : outcome.GetError().GetResponseHeaders(); - - ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amzn-RequestId"), "XAmznRequestId"); - ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amz-request-id"), "XAmzRequestId"); - ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amz-id-2"), "XAmzId2"); - - if (!outcome.IsSuccess()) - { + */ + if (request->HasAwsSessionToken() && !request->GetAwsSessionToken().empty()) + { + json.WithString("SessionToken", request->GetAwsSessionToken()); + } + if (!request->GetSigningRegion().empty()) + { + json.WithString("Region", request->GetSigningRegion()); + } + if (!request->GetSigningAccessKey().empty()) + { + json.WithString("AccessKey", request->GetSigningAccessKey()); + } + + const auto& headers = outcome.IsSuccess() ? outcome.GetResult()->GetHeaders() : outcome.GetError().GetResponseHeaders(); + + ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amzn-RequestId"), "XAmznRequestId"); + ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amz-request-id"), "XAmzRequestId"); + ExportResponseHeaderToJson(json, headers, StringUtils::ToLower("x-amz-id-2"), "XAmzId2"); + + if (!outcome.IsSuccess()) + { if (outcome.GetError().GetExceptionName().empty()) // Not Aws Exception - { + { json.WithString("SdkExceptionMessage", outcome.GetError().GetMessage().substr(0, ERROR_MESSAGE_LENGTH_LIMIT)); - } - else // Aws Exception - { + } + else // Aws Exception + { json.WithString("AwsException", outcome.GetError().GetExceptionName()) .WithString("AwsExceptionMessage", outcome.GetError().GetMessage().substr(0, ERROR_MESSAGE_LENGTH_LIMIT)); - } + } json.WithInteger("HttpStatusCode", static_cast<int>(outcome.GetError().GetResponseCode())); - } + } else { json.WithInteger("HttpStatusCode", static_cast<int>(outcome.GetResult()->GetResponseCode())); } - - // Optional MetricsCollectedFromCore - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::AcquireConnectionLatency); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::ConnectionReused); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::ConnectLatency); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::DestinationIp); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::DnsLatency); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::RequestLatency); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::SslLatency); - ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::TcpLatency); - } - + + // Optional MetricsCollectedFromCore + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::AcquireConnectionLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::ConnectionReused); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::ConnectLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::DestinationIp); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::DnsLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::RequestLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::SslLatency); + ExportHttpMetricsToJson(json, metricsFromCore.httpClientMetrics, HttpClientMetricsType::TcpLatency); + } + DefaultMonitoring::DefaultMonitoring(const Aws::String& clientId, const Aws::String& host, unsigned short port): m_udp(host.c_str(), port), m_clientId(clientId) - { - } - - void* DefaultMonitoring::OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) const - { - AWS_UNREFERENCED_PARAM(request); - - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestStart Service: " << serviceName << "Request: " << requestName); - auto context = Aws::New<DefaultContext>(DEFAULT_MONITORING_ALLOC_TAG); - context->apiCallStartTime = Aws::Utils::DateTime::Now(); - context->attemptStartTime = context->apiCallStartTime; - context->retryCount = 0; - return context; - } - - - void DefaultMonitoring::OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const - { - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestSucceeded Service: " << serviceName << "Request: " << requestName); - CollectAndSendAttemptData(serviceName, requestName, request, outcome, metricsFromCore, context); - } - - void DefaultMonitoring::OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const - { - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestFailed Service: " << serviceName << "Request: " << requestName); - CollectAndSendAttemptData(serviceName, requestName, request, outcome, metricsFromCore, context); - } - + { + } + + void* DefaultMonitoring::OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) const + { + AWS_UNREFERENCED_PARAM(request); + + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestStart Service: " << serviceName << "Request: " << requestName); + auto context = Aws::New<DefaultContext>(DEFAULT_MONITORING_ALLOC_TAG); + context->apiCallStartTime = Aws::Utils::DateTime::Now(); + context->attemptStartTime = context->apiCallStartTime; + context->retryCount = 0; + return context; + } + + + void DefaultMonitoring::OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const + { + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestSucceeded Service: " << serviceName << "Request: " << requestName); + CollectAndSendAttemptData(serviceName, requestName, request, outcome, metricsFromCore, context); + } + + void DefaultMonitoring::OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, void* context) const + { + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestFailed Service: " << serviceName << "Request: " << requestName); + CollectAndSendAttemptData(serviceName, requestName, request, outcome, metricsFromCore, context); + } + void DefaultMonitoring::OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const - { - AWS_UNREFERENCED_PARAM(request); - - DefaultContext* defaultContext = static_cast<DefaultContext*>(context); - defaultContext->retryCount++; - defaultContext->attemptStartTime = Aws::Utils::DateTime::Now(); - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestRetry Service: " << serviceName << "Request: " << requestName << " RetryCnt:" << defaultContext->retryCount); - } - + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const + { + AWS_UNREFERENCED_PARAM(request); + + DefaultContext* defaultContext = static_cast<DefaultContext*>(context); + defaultContext->retryCount++; + defaultContext->attemptStartTime = Aws::Utils::DateTime::Now(); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestRetry Service: " << serviceName << "Request: " << requestName << " RetryCnt:" << defaultContext->retryCount); + } + void DefaultMonitoring::OnFinish(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const - { - AWS_UNREFERENCED_PARAM(request); - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestFinish Service: " << serviceName << "Request: " << requestName); - + const std::shared_ptr<const Aws::Http::HttpRequest>& request, void* context) const + { + AWS_UNREFERENCED_PARAM(request); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "OnRequestFinish Service: " << serviceName << "Request: " << requestName); + DefaultContext* defaultContext = static_cast<DefaultContext*>(context); - Aws::Utils::Json::JsonValue json; + Aws::Utils::Json::JsonValue json; FillRequiredFieldsToJson(json, "ApiCall", serviceName, requestName, m_clientId, defaultContext->apiCallStartTime, DEFAULT_MONITORING_VERSION, request->GetUserAgent()); FillRequiredApiCallFieldsToJson(json, defaultContext->retryCount + 1, (DateTime::Now() - defaultContext->apiCallStartTime).count(), (!defaultContext->lastAttemptSucceeded && defaultContext->lastErrorRetryable)); FillOptionalApiCallFieldsToJson(json, request.get(), *(defaultContext->outcome)); - Aws::String compactData = json.View().WriteCompact(); + Aws::String compactData = json.View().WriteCompact(); m_udp.SendData(reinterpret_cast<const uint8_t*>(compactData.c_str()), static_cast<int>(compactData.size())); - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Send API Metrics: \n" << json.View().WriteReadable()); - Aws::Delete(defaultContext); - } - - void DefaultMonitoring::CollectAndSendAttemptData(const Aws::String& serviceName, const Aws::String& requestName, + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Send API Metrics: \n" << json.View().WriteReadable()); + Aws::Delete(defaultContext); + } + + void DefaultMonitoring::CollectAndSendAttemptData(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Client::HttpResponseOutcome& outcome, - const CoreMetricsCollection& metricsFromCore, void* context) const - { + const CoreMetricsCollection& metricsFromCore, void* context) const + { DefaultContext* defaultContext = static_cast<DefaultContext*>(context); defaultContext->outcome = &outcome; defaultContext->lastAttemptSucceeded = outcome.IsSuccess() ? true : false; defaultContext->lastErrorRetryable = (!outcome.IsSuccess() && outcome.GetError().ShouldRetry()) ? true : false; - Aws::Utils::Json::JsonValue json; + Aws::Utils::Json::JsonValue json; FillRequiredFieldsToJson(json, "ApiCallAttempt", serviceName, requestName, m_clientId, defaultContext->attemptStartTime, DEFAULT_MONITORING_VERSION, request->GetUserAgent()); FillRequiredApiAttemptFieldsToJson(json, request->GetUri().GetAuthority(), (DateTime::Now() - defaultContext->attemptStartTime).count()); FillOptionalApiAttemptFieldsToJson(json, request.get(), outcome, metricsFromCore); - Aws::String compactData = json.View().WriteCompact(); - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Send Attempt Metrics: \n" << json.View().WriteReadable()); + Aws::String compactData = json.View().WriteCompact(); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Send Attempt Metrics: \n" << json.View().WriteReadable()); m_udp.SendData(reinterpret_cast<const uint8_t*>(compactData.c_str()), static_cast<int>(compactData.size())); - } - - Aws::UniquePtr<MonitoringInterface> DefaultMonitoringFactory::CreateMonitoringInstance() const + } + + Aws::UniquePtr<MonitoringInterface> DefaultMonitoringFactory::CreateMonitoringInstance() const { - Aws::String clientId(DEFAULT_MONITORING_CLIENT_ID); // default to empty + Aws::String clientId(DEFAULT_MONITORING_CLIENT_ID); // default to empty Aws::String host(DEFAULT_MONITORING_HOST); // default to 127.0.0.1 - unsigned short port = DEFAULT_MONITORING_PORT; // default to 31000 - bool enable = DEFAULT_MONITORING_ENABLE; //default to false; - - //check profile_config + unsigned short port = DEFAULT_MONITORING_PORT; // default to 31000 + bool enable = DEFAULT_MONITORING_ENABLE; //default to false; + + //check profile_config Aws::String tmpEnable = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_ENABLED); Aws::String tmpClientId = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_CLIENT_ID); Aws::String tmpHost = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_HOST); Aws::String tmpPort = Aws::Config::GetCachedConfigValue(DefaultMonitoring::DEFAULT_CSM_CONFIG_PORT); - + if (!tmpEnable.empty()) - { + { enable = StringUtils::CaselessCompare(tmpEnable.c_str(), "true") ? true : false; AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_enabled from profile_config to be " << enable); } @@ -289,52 +289,52 @@ namespace Aws clientId = tmpClientId; AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_client_id from profile_config to be " << clientId); } - + if (!tmpHost.empty()) { host = tmpHost; AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_host from profile_config to be " << host); - } - + } + if (!tmpPort.empty()) { port = static_cast<short>(StringUtils::ConvertToInt32(tmpPort.c_str())); AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved csm_port from profile_config to be " << port); } - // check environment variables + // check environment variables tmpEnable = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_ENABLED); tmpClientId = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_CLIENT_ID); tmpHost = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_HOST); tmpPort = Aws::Environment::GetEnv(DefaultMonitoring::DEFAULT_CSM_ENVIRONMENT_VAR_PORT); - if (!tmpEnable.empty()) - { - enable = StringUtils::CaselessCompare(tmpEnable.c_str(), "true") ? true : false; - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_ENABLED from Environment variable to be " << enable); - } - if (!tmpClientId.empty()) - { - clientId = tmpClientId; - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_CLIENT_ID from Environment variable to be " << clientId); - - } + if (!tmpEnable.empty()) + { + enable = StringUtils::CaselessCompare(tmpEnable.c_str(), "true") ? true : false; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_ENABLED from Environment variable to be " << enable); + } + if (!tmpClientId.empty()) + { + clientId = tmpClientId; + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_CLIENT_ID from Environment variable to be " << clientId); + + } if (!tmpHost.empty()) { host = tmpHost; AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_HOST from Environment variable to be " << host); } - if (!tmpPort.empty()) - { - port = static_cast<unsigned short>(StringUtils::ConvertToInt32(tmpPort.c_str())); - AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_PORT from Environment variable to be " << port); - } - - if (!enable) - { - return nullptr; - } + if (!tmpPort.empty()) + { + port = static_cast<unsigned short>(StringUtils::ConvertToInt32(tmpPort.c_str())); + AWS_LOGSTREAM_DEBUG(DEFAULT_MONITORING_ALLOC_TAG, "Resolved AWS_CSM_PORT from Environment variable to be " << port); + } + + if (!enable) + { + return nullptr; + } return Aws::MakeUnique<DefaultMonitoring>(DEFAULT_MONITORING_ALLOC_TAG, clientId, host, port); - } - - } -} + } + + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp index f3ef582867..ce269c66fb 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/HttpClientMetrics.cpp @@ -1,71 +1,71 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/monitoring/HttpClientMetrics.h> - -namespace Aws -{ - namespace Monitoring - { + */ + +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/monitoring/HttpClientMetrics.h> + +namespace Aws +{ + namespace Monitoring + { static const char HTTP_CLIENT_METRICS_DESTINATION_IP[] = "DestinationIp"; - static const char HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY[] = "AcquireConnectionLatency"; - static const char HTTP_CLIENT_METRICS_CONNECTION_REUSED[] = "ConnectionReused"; - static const char HTTP_CLIENT_METRICS_CONNECTION_LATENCY[] = "ConnectLatency"; - static const char HTTP_CLIENT_METRICS_REQUEST_LATENCY[] = "RequestLatency"; - static const char HTTP_CLIENT_METRICS_DNS_LATENCY[] = "DnsLatency"; + static const char HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY[] = "AcquireConnectionLatency"; + static const char HTTP_CLIENT_METRICS_CONNECTION_REUSED[] = "ConnectionReused"; + static const char HTTP_CLIENT_METRICS_CONNECTION_LATENCY[] = "ConnectLatency"; + static const char HTTP_CLIENT_METRICS_REQUEST_LATENCY[] = "RequestLatency"; + static const char HTTP_CLIENT_METRICS_DNS_LATENCY[] = "DnsLatency"; static const char HTTP_CLIENT_METRICS_TCP_LATENCY[] = "TcpLatency"; - static const char HTTP_CLIENT_METRICS_SSL_LATENCY[] = "SslLatency"; - static const char HTTP_CLIENT_METRICS_UNKNOWN[] = "Unknown"; - - using namespace Aws::Utils; - HttpClientMetricsType GetHttpClientMetricTypeByName(const Aws::String& name) - { + static const char HTTP_CLIENT_METRICS_SSL_LATENCY[] = "SslLatency"; + static const char HTTP_CLIENT_METRICS_UNKNOWN[] = "Unknown"; + + using namespace Aws::Utils; + HttpClientMetricsType GetHttpClientMetricTypeByName(const Aws::String& name) + { static std::map<int, HttpClientMetricsType> metricsNameHashToType = - { + { std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_DESTINATION_IP), HttpClientMetricsType::DestinationIp), - std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY), HttpClientMetricsType::AcquireConnectionLatency), - std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_CONNECTION_REUSED), HttpClientMetricsType::ConnectionReused), - std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_CONNECTION_LATENCY), HttpClientMetricsType::ConnectLatency), - std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_REQUEST_LATENCY), HttpClientMetricsType::RequestLatency), - std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_DNS_LATENCY), HttpClientMetricsType::DnsLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY), HttpClientMetricsType::AcquireConnectionLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_CONNECTION_REUSED), HttpClientMetricsType::ConnectionReused), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_CONNECTION_LATENCY), HttpClientMetricsType::ConnectLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_REQUEST_LATENCY), HttpClientMetricsType::RequestLatency), + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_DNS_LATENCY), HttpClientMetricsType::DnsLatency), std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_TCP_LATENCY), HttpClientMetricsType::TcpLatency), - std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_SSL_LATENCY), HttpClientMetricsType::SslLatency) - }; - - int nameHash = HashingUtils::HashString(name.c_str()); - auto it = metricsNameHashToType.find(nameHash); - if (it == metricsNameHashToType.end()) - { - return HttpClientMetricsType::Unknown; - } - return it->second; - } - - Aws::String GetHttpClientMetricNameByType(HttpClientMetricsType type) - { + std::pair<int, HttpClientMetricsType>(HashingUtils::HashString(HTTP_CLIENT_METRICS_SSL_LATENCY), HttpClientMetricsType::SslLatency) + }; + + int nameHash = HashingUtils::HashString(name.c_str()); + auto it = metricsNameHashToType.find(nameHash); + if (it == metricsNameHashToType.end()) + { + return HttpClientMetricsType::Unknown; + } + return it->second; + } + + Aws::String GetHttpClientMetricNameByType(HttpClientMetricsType type) + { static std::map<int, std::string> metricsTypeToName = - { + { std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::DestinationIp), HTTP_CLIENT_METRICS_DESTINATION_IP), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::AcquireConnectionLatency), HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::ConnectionReused), HTTP_CLIENT_METRICS_CONNECTION_REUSED), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::ConnectLatency), HTTP_CLIENT_METRICS_CONNECTION_LATENCY), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::RequestLatency), HTTP_CLIENT_METRICS_REQUEST_LATENCY), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::DnsLatency), HTTP_CLIENT_METRICS_DNS_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::AcquireConnectionLatency), HTTP_CLIENT_METRICS_ACQUIRE_CONNECTION_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::ConnectionReused), HTTP_CLIENT_METRICS_CONNECTION_REUSED), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::ConnectLatency), HTTP_CLIENT_METRICS_CONNECTION_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::RequestLatency), HTTP_CLIENT_METRICS_REQUEST_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::DnsLatency), HTTP_CLIENT_METRICS_DNS_LATENCY), std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::TcpLatency), HTTP_CLIENT_METRICS_TCP_LATENCY), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::SslLatency), HTTP_CLIENT_METRICS_SSL_LATENCY), - std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::Unknown), HTTP_CLIENT_METRICS_UNKNOWN) - }; - - auto it = metricsTypeToName.find(static_cast<int>(type)); - if (it == metricsTypeToName.end()) - { - return HTTP_CLIENT_METRICS_UNKNOWN; - } - return Aws::String(it->second.c_str()); - } - - } -} + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::SslLatency), HTTP_CLIENT_METRICS_SSL_LATENCY), + std::pair<int, std::string>(static_cast<int>(HttpClientMetricsType::Unknown), HTTP_CLIENT_METRICS_UNKNOWN) + }; + + auto it = metricsTypeToName.find(static_cast<int>(type)); + if (it == metricsTypeToName.end()) + { + return HTTP_CLIENT_METRICS_UNKNOWN; + } + return Aws::String(it->second.c_str()); + } + + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp index 7a8d3adb41..38dccdec44 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/monitoring/MonitoringManager.cpp @@ -1,129 +1,129 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/monitoring/MonitoringInterface.h> -#include <aws/core/monitoring/MonitoringFactory.h> -#include <aws/core/monitoring/MonitoringManager.h> -#include <aws/core/monitoring/DefaultMonitoring.h> -#include <aws/core/Core_EXPORTS.h> - -#ifdef _MSC_VER -#pragma warning(disable : 4592) -#endif - -namespace Aws -{ - namespace Monitoring - { - typedef Aws::Vector<Aws::UniquePtr<MonitoringInterface>> Monitors; - - const char MonitoringTag[] = "MonitoringAllocTag"; - - /** + */ + +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/monitoring/MonitoringInterface.h> +#include <aws/core/monitoring/MonitoringFactory.h> +#include <aws/core/monitoring/MonitoringManager.h> +#include <aws/core/monitoring/DefaultMonitoring.h> +#include <aws/core/Core_EXPORTS.h> + +#ifdef _MSC_VER +#pragma warning(disable : 4592) +#endif + +namespace Aws +{ + namespace Monitoring + { + typedef Aws::Vector<Aws::UniquePtr<MonitoringInterface>> Monitors; + + const char MonitoringTag[] = "MonitoringAllocTag"; + + /** * Global factory to create global metrics instance. - */ - static Aws::UniquePtr<Monitors> s_monitors; - - Aws::Vector<void*> OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) - { - assert(s_monitors); - Aws::Vector<void*> contexts; - contexts.reserve(s_monitors->size()); + */ + static Aws::UniquePtr<Monitors> s_monitors; + + Aws::Vector<void*> OnRequestStarted(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request) + { + assert(s_monitors); + Aws::Vector<void*> contexts; + contexts.reserve(s_monitors->size()); for (const auto& interface: *s_monitors) - { - contexts.emplace_back(interface->OnRequestStarted(serviceName, requestName, request)); - } - return contexts; - } - - void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) - { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) - { - interface->OnRequestSucceeded(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); - } - } - - void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, - const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) - { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) - { - interface->OnRequestFailed(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); - } - } - + { + contexts.emplace_back(interface->OnRequestStarted(serviceName, requestName, request)); + } + return contexts; + } + + void OnRequestSucceeded(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestSucceeded(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + } + } + + void OnRequestFailed(const Aws::String& serviceName, const Aws::String& requestName, const std::shared_ptr<const Aws::Http::HttpRequest>& request, + const Aws::Client::HttpResponseOutcome& outcome, const CoreMetricsCollection& metricsFromCore, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestFailed(serviceName, requestName, request, outcome, metricsFromCore, contexts[index++]); + } + } + void OnRequestRetry(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) - { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) - { - interface->OnRequestRetry(serviceName, requestName, request, contexts[index++]); - } - } - + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnRequestRetry(serviceName, requestName, request, contexts[index++]); + } + } + void OnFinish(const Aws::String& serviceName, const Aws::String& requestName, - const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) - { - assert(s_monitors); - assert(contexts.size() == s_monitors->size()); - size_t index = 0; - for (const auto& interface: *s_monitors) - { - interface->OnFinish(serviceName, requestName, request, contexts[index++]); - } - } - - void InitMonitoring(const std::vector<MonitoringFactoryCreateFunction>& monitoringFactoryCreateFunctions) - { - if (s_monitors) - { - return; - } - s_monitors = Aws::MakeUnique<Monitors>(MonitoringTag); - for (const auto& function: monitoringFactoryCreateFunctions) - { - auto factory = function(); - if (factory) - { - auto instance = factory->CreateMonitoringInstance(); - if (instance) - { - s_monitors->emplace_back(std::move(instance)); - } - } - } - - auto defaultMonitoringFactory = Aws::MakeShared<DefaultMonitoringFactory>(MonitoringTag); - auto instance = defaultMonitoringFactory->CreateMonitoringInstance(); - if (instance) - { - s_monitors->emplace_back(std::move(instance)); - } - } - - void CleanupMonitoring() - { - if (!s_monitors) - { - return; - } - - s_monitors = nullptr; - } + const std::shared_ptr<const Aws::Http::HttpRequest>& request, const Aws::Vector<void*>& contexts) + { + assert(s_monitors); + assert(contexts.size() == s_monitors->size()); + size_t index = 0; + for (const auto& interface: *s_monitors) + { + interface->OnFinish(serviceName, requestName, request, contexts[index++]); + } + } + + void InitMonitoring(const std::vector<MonitoringFactoryCreateFunction>& monitoringFactoryCreateFunctions) + { + if (s_monitors) + { + return; + } + s_monitors = Aws::MakeUnique<Monitors>(MonitoringTag); + for (const auto& function: monitoringFactoryCreateFunctions) + { + auto factory = function(); + if (factory) + { + auto instance = factory->CreateMonitoringInstance(); + if (instance) + { + s_monitors->emplace_back(std::move(instance)); + } + } + } + + auto defaultMonitoringFactory = Aws::MakeShared<DefaultMonitoringFactory>(MonitoringTag); + auto instance = defaultMonitoringFactory->CreateMonitoringInstance(); + if (instance) + { + s_monitors->emplace_back(std::move(instance)); + } + } + + void CleanupMonitoring() + { + if (!s_monitors) + { + return; + } + + s_monitors = nullptr; + } } // namespace Monitoring - -} // namespace Aws + +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/Net.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/Net.cpp index 244df21945..e39cb3dcf5 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/Net.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/Net.cpp @@ -2,27 +2,27 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/net/Net.h> - -namespace Aws -{ - namespace Net - { - // For Posix system, currently we don't need to do anything for network stack initialization. - // But we need to do initialization for WinSock on Windows and call them in Aws.cpp. So these functions - // also exist for Posix systems. - bool IsNetworkInitiated() - { - return true; - } - - void InitNetwork() - { - } - - void CleanupNetwork() - { - } - } -} + +#include <aws/core/net/Net.h> + +namespace Aws +{ + namespace Net + { + // For Posix system, currently we don't need to do anything for network stack initialization. + // But we need to do initialization for WinSock on Windows and call them in Aws.cpp. So these functions + // also exist for Posix systems. + bool IsNetworkInitiated() + { + return true; + } + + void InitNetwork() + { + } + + void CleanupNetwork() + { + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/SimpleUDP.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/SimpleUDP.cpp index d9e0c385fd..446de6689a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/SimpleUDP.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/net/linux-shared/SimpleUDP.cpp @@ -2,35 +2,35 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <sys/types.h> -#include <sys/socket.h> + +#include <sys/types.h> +#include <sys/socket.h> #include <netdb.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <unistd.h> -#include <fcntl.h> -#include <cassert> -#include <string.h> -#include <aws/core/net/SimpleUDP.h> -#include <aws/core/utils/logging/LogMacros.h> - -namespace Aws -{ - namespace Net - { - static const char ALLOC_TAG[] = "SimpleUDP"; +#include <arpa/inet.h> +#include <netinet/in.h> +#include <unistd.h> +#include <fcntl.h> +#include <cassert> +#include <string.h> +#include <aws/core/net/SimpleUDP.h> +#include <aws/core/utils/logging/LogMacros.h> + +namespace Aws +{ + namespace Net + { + static const char ALLOC_TAG[] = "SimpleUDP"; static const char IPV4_LOOP_BACK_ADDRESS[] = "127.0.0.1"; static const char IPV6_LOOP_BACK_ADDRESS[] = "::1"; static inline bool IsValidIPAddress(const char* ip, int addressFamily/*AF_INET or AF_INET6*/) - { + { char buffer[128]; return inet_pton(addressFamily, ip, (void*)buffer) == 1 ?true :false; - } - + } + static bool GetASockAddrFromHostName(const char* hostName, void* sockAddrBuffer, size_t& addrLength, int& addressFamily) - { + { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); @@ -47,8 +47,8 @@ namespace Aws addressFamily = res->ai_family; freeaddrinfo(res); return true; - } - + } + static sockaddr_in BuildAddrInfoIPV4(const char* hostIP, short port) { #if (__GNUC__ == 4) && !defined(__clang__) @@ -79,18 +79,18 @@ namespace Aws return addrinfo; } - SimpleUDP::SimpleUDP(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking): + SimpleUDP::SimpleUDP(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking): m_addressFamily(addressFamily), m_connected(false), m_socket(-1), m_port(0) - { - CreateSocket(addressFamily, sendBufSize, receiveBufSize, nonBlocking); - } - - SimpleUDP::SimpleUDP(bool IPV4, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) : + { + CreateSocket(addressFamily, sendBufSize, receiveBufSize, nonBlocking); + } + + SimpleUDP::SimpleUDP(bool IPV4, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) : m_addressFamily(IPV4 ? AF_INET : AF_INET6), m_connected(false), m_socket(-1), m_port(0) - { - CreateSocket(m_addressFamily, sendBufSize, receiveBufSize, nonBlocking); - } - + { + CreateSocket(m_addressFamily, sendBufSize, receiveBufSize, nonBlocking); + } + SimpleUDP::SimpleUDP(const char* host, unsigned short port, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) : m_addressFamily(AF_INET), m_connected(false), m_socket(-1), m_port(port) { @@ -131,76 +131,76 @@ namespace Aws CreateSocket(m_addressFamily, sendBufSize, receiveBufSize, nonBlocking); } - SimpleUDP::~SimpleUDP() - { - close(GetUnderlyingSocket()); - } - - void SimpleUDP::CreateSocket(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) - { - int sock = socket(addressFamily, SOCK_DGRAM, IPPROTO_UDP); - assert(sock != -1); - - // Try to set sock to nonblocking mode. - if (nonBlocking) - { - int flags = fcntl(sock, F_GETFL, 0); - if (flags != -1) - { - flags |= O_NONBLOCK; - fcntl(sock, F_SETFL, flags); - } - } - - // if sendBufSize is not zero, try to set send buffer size - if (sendBufSize) - { - int ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendBufSize, sizeof(sendBufSize)); - if (ret) - { - AWS_LOGSTREAM_WARN(ALLOC_TAG, "Failed to set UDP send buffer size to " << sendBufSize << " for socket " << sock << " error message: " << strerror(errno)); - } - assert(ret == 0); - } - - // if receiveBufSize is not zero, try to set receive buffer size - if (receiveBufSize) - { - int ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &receiveBufSize, sizeof(receiveBufSize)); - if (ret) - { - AWS_LOGSTREAM_WARN(ALLOC_TAG, "Failed to set UDP receive buffer size to " << receiveBufSize << " for socket " << sock << " error message: " << strerror(errno)); - } - assert(ret == 0); - } - - SetUnderlyingSocket(sock); - } - - int SimpleUDP::Connect(const sockaddr* address, size_t addressLength) - { - int ret = connect(GetUnderlyingSocket(), address, static_cast<socklen_t>(addressLength)); - m_connected = ret ? false : true; - return ret; - } - + SimpleUDP::~SimpleUDP() + { + close(GetUnderlyingSocket()); + } + + void SimpleUDP::CreateSocket(int addressFamily, size_t sendBufSize, size_t receiveBufSize, bool nonBlocking) + { + int sock = socket(addressFamily, SOCK_DGRAM, IPPROTO_UDP); + assert(sock != -1); + + // Try to set sock to nonblocking mode. + if (nonBlocking) + { + int flags = fcntl(sock, F_GETFL, 0); + if (flags != -1) + { + flags |= O_NONBLOCK; + fcntl(sock, F_SETFL, flags); + } + } + + // if sendBufSize is not zero, try to set send buffer size + if (sendBufSize) + { + int ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendBufSize, sizeof(sendBufSize)); + if (ret) + { + AWS_LOGSTREAM_WARN(ALLOC_TAG, "Failed to set UDP send buffer size to " << sendBufSize << " for socket " << sock << " error message: " << strerror(errno)); + } + assert(ret == 0); + } + + // if receiveBufSize is not zero, try to set receive buffer size + if (receiveBufSize) + { + int ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &receiveBufSize, sizeof(receiveBufSize)); + if (ret) + { + AWS_LOGSTREAM_WARN(ALLOC_TAG, "Failed to set UDP receive buffer size to " << receiveBufSize << " for socket " << sock << " error message: " << strerror(errno)); + } + assert(ret == 0); + } + + SetUnderlyingSocket(sock); + } + + int SimpleUDP::Connect(const sockaddr* address, size_t addressLength) + { + int ret = connect(GetUnderlyingSocket(), address, static_cast<socklen_t>(addressLength)); + m_connected = ret ? false : true; + return ret; + } + int SimpleUDP::ConnectToHost(const char* hostIP, unsigned short port) const - { - int ret; - if (m_addressFamily == AF_INET6) - { + { + int ret; + if (m_addressFamily == AF_INET6) + { sockaddr_in6 addrinfo = BuildAddrInfoIPV6(hostIP, port); - ret = connect(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); - } - else - { + ret = connect(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); + } + else + { sockaddr_in addrinfo = BuildAddrInfoIPV4(hostIP, port); - ret = connect(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); - } - m_connected = ret ? false : true; - return ret; - } - + ret = connect(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); + } + m_connected = ret ? false : true; + return ret; + } + int SimpleUDP::ConnectToLocalHost(unsigned short port) const { if (m_addressFamily == AF_INET6) @@ -213,73 +213,73 @@ namespace Aws } } - int SimpleUDP::Bind(const sockaddr* address, size_t addressLength) const - { - return bind(GetUnderlyingSocket(), address, static_cast<socklen_t>(addressLength)); - } - - int SimpleUDP::BindToLocalHost(unsigned short port) const - { - if (m_addressFamily == AF_INET6) - { + int SimpleUDP::Bind(const sockaddr* address, size_t addressLength) const + { + return bind(GetUnderlyingSocket(), address, static_cast<socklen_t>(addressLength)); + } + + int SimpleUDP::BindToLocalHost(unsigned short port) const + { + if (m_addressFamily == AF_INET6) + { sockaddr_in6 addrinfo = BuildAddrInfoIPV6(IPV6_LOOP_BACK_ADDRESS, port); - return bind(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); - } - else - { + return bind(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); + } + else + { sockaddr_in addrinfo = BuildAddrInfoIPV4(IPV4_LOOP_BACK_ADDRESS, port); - return bind(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); - } - } - - int SimpleUDP::SendData(const uint8_t* data, size_t dataLen) const - { + return bind(GetUnderlyingSocket(), reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); + } + } + + int SimpleUDP::SendData(const uint8_t* data, size_t dataLen) const + { if (!m_connected) { ConnectToHost(m_hostIP.c_str(), m_port); } - return send(GetUnderlyingSocket(), data, dataLen, 0); - } - - int SimpleUDP::SendDataTo(const sockaddr* address, size_t addressLength, const uint8_t* data, size_t dataLen) const - { - if (m_connected) - { + return send(GetUnderlyingSocket(), data, dataLen, 0); + } + + int SimpleUDP::SendDataTo(const sockaddr* address, size_t addressLength, const uint8_t* data, size_t dataLen) const + { + if (m_connected) + { return send(GetUnderlyingSocket(), data, dataLen, 0); - } - else - { - return sendto(GetUnderlyingSocket(), data, dataLen, 0, address, static_cast<socklen_t>(addressLength)); - } - } - - int SimpleUDP::SendDataToLocalHost(const uint8_t* data, size_t dataLen, unsigned short port) const - { - if (m_connected) - { + } + else + { + return sendto(GetUnderlyingSocket(), data, dataLen, 0, address, static_cast<socklen_t>(addressLength)); + } + } + + int SimpleUDP::SendDataToLocalHost(const uint8_t* data, size_t dataLen, unsigned short port) const + { + if (m_connected) + { return send(GetUnderlyingSocket(), data, dataLen, 0); - } - else if (m_addressFamily == AF_INET6) - { + } + else if (m_addressFamily == AF_INET6) + { sockaddr_in6 addrinfo = BuildAddrInfoIPV6(IPV6_LOOP_BACK_ADDRESS, port); - return sendto(GetUnderlyingSocket(), data, dataLen, 0, reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); - } - else - { + return sendto(GetUnderlyingSocket(), data, dataLen, 0, reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in6)); + } + else + { sockaddr_in addrinfo = BuildAddrInfoIPV4(IPV4_LOOP_BACK_ADDRESS, port); - return sendto(GetUnderlyingSocket(), data, dataLen, 0, reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); - } - } - - int SimpleUDP::ReceiveData(uint8_t* buffer, size_t bufferLen) const - { - return recv(GetUnderlyingSocket(), buffer, static_cast<int>(bufferLen), 0); - } - - - int SimpleUDP::ReceiveDataFrom(sockaddr* address, size_t* addressLength, uint8_t* buffer, size_t bufferLen) const - { - return recvfrom(GetUnderlyingSocket(), buffer, static_cast<int>(bufferLen), 0, address, reinterpret_cast<socklen_t*>(addressLength)); - } - } -} + return sendto(GetUnderlyingSocket(), data, dataLen, 0, reinterpret_cast<sockaddr*>(&addrinfo), sizeof(sockaddr_in)); + } + } + + int SimpleUDP::ReceiveData(uint8_t* buffer, size_t bufferLen) const + { + return recv(GetUnderlyingSocket(), buffer, static_cast<int>(bufferLen), 0); + } + + + int SimpleUDP::ReceiveDataFrom(sockaddr* address, size_t* addressLength, uint8_t* buffer, size_t bufferLen) const + { + return recvfrom(GetUnderlyingSocket(), buffer, static_cast<int>(bufferLen), 0, address, reinterpret_cast<socklen_t*>(addressLength)); + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Environment.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Environment.cpp index ee627340bb..a582b80110 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Environment.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Environment.cpp @@ -2,22 +2,22 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/platform/Environment.h> - -//#include <aws/core/utils/memory/stl/AWSStringStream.h> -//#include <sys/utsname.h> - -namespace Aws -{ -namespace Environment -{ - -Aws::String GetEnv(const char* variableName) -{ - auto variableValue = std::getenv(variableName); - return Aws::String( variableValue ? variableValue : "" ); -} - -} // namespace Environment -} // namespace Aws + +#include <aws/core/platform/Environment.h> + +//#include <aws/core/utils/memory/stl/AWSStringStream.h> +//#include <sys/utsname.h> + +namespace Aws +{ +namespace Environment +{ + +Aws::String GetEnv(const char* variableName) +{ + auto variableValue = std::getenv(variableName); + return Aws::String( variableValue ? variableValue : "" ); +} + +} // namespace Environment +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/FileSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/FileSystem.cpp index c1ad818911..8c8dd49aad 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/FileSystem.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/FileSystem.cpp @@ -2,268 +2,268 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/platform/FileSystem.h> - -#include <aws/core/platform/Environment.h> -#include <aws/core/platform/Platform.h> -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/StringUtils.h> +#include <aws/core/platform/FileSystem.h> + +#include <aws/core/platform/Environment.h> +#include <aws/core/platform/Platform.h> +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/StringUtils.h> #include <aws/core/utils/UUID.h> - -#include <unistd.h> -#include <pwd.h> -#include <sys/stat.h> -#include <dirent.h> -#include <errno.h> -#include <climits> - -#include <cassert> + +#include <unistd.h> +#include <pwd.h> +#include <sys/stat.h> +#include <dirent.h> +#include <errno.h> +#include <climits> + +#include <cassert> #ifdef __APPLE__ #include <mach-o/dyld.h> #endif -namespace Aws -{ -namespace FileSystem -{ - -static const char* FILE_SYSTEM_UTILS_LOG_TAG = "FileSystemUtils"; - - class PosixDirectory : public Directory - { - public: - PosixDirectory(const Aws::String& path, const Aws::String& relativePath) : Directory(path, relativePath), m_dir(nullptr) - { - m_dir = opendir(m_directoryEntry.path.c_str()); - AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Entering directory " << m_directoryEntry.path); - - if(m_dir) - { - AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Successfully opened directory " << m_directoryEntry.path); - m_directoryEntry.fileType = FileType::Directory; - } - else - { - AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Could not load directory " << m_directoryEntry.path << " with error code " << errno); - } - } - - ~PosixDirectory() - { - if (m_dir) - { - closedir(m_dir); - } - } - - operator bool() const override { return m_directoryEntry.operator bool() && m_dir != nullptr; } - - DirectoryEntry Next() override - { - assert(m_dir); - DirectoryEntry entry; - - dirent* dirEntry; - bool invalidEntry(true); - - while(invalidEntry) - { - if ((dirEntry = readdir(m_dir))) - { - Aws::String entryName = dirEntry->d_name; - if(entryName != ".." && entryName != ".") - { - entry = ParseFileInfo(dirEntry, true); - invalidEntry = false; - } - else +namespace Aws +{ +namespace FileSystem +{ + +static const char* FILE_SYSTEM_UTILS_LOG_TAG = "FileSystemUtils"; + + class PosixDirectory : public Directory + { + public: + PosixDirectory(const Aws::String& path, const Aws::String& relativePath) : Directory(path, relativePath), m_dir(nullptr) + { + m_dir = opendir(m_directoryEntry.path.c_str()); + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Entering directory " << m_directoryEntry.path); + + if(m_dir) + { + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Successfully opened directory " << m_directoryEntry.path); + m_directoryEntry.fileType = FileType::Directory; + } + else + { + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Could not load directory " << m_directoryEntry.path << " with error code " << errno); + } + } + + ~PosixDirectory() + { + if (m_dir) + { + closedir(m_dir); + } + } + + operator bool() const override { return m_directoryEntry.operator bool() && m_dir != nullptr; } + + DirectoryEntry Next() override + { + assert(m_dir); + DirectoryEntry entry; + + dirent* dirEntry; + bool invalidEntry(true); + + while(invalidEntry) + { + if ((dirEntry = readdir(m_dir))) + { + Aws::String entryName = dirEntry->d_name; + if(entryName != ".." && entryName != ".") { - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "skipping . or .."); - } - } - else - { - break; - } - } - - return entry; - } - - private: - DirectoryEntry ParseFileInfo(dirent* dirEnt, bool computePath) - { - DirectoryEntry entry; - - if(computePath) - { - Aws::StringStream ss; - ss << m_directoryEntry.path << PATH_DELIM << dirEnt->d_name; - entry.path = ss.str(); - - ss.str(""); - if(m_directoryEntry.relativePath.empty()) - { - ss << dirEnt->d_name; - } - else - { - ss << m_directoryEntry.relativePath << PATH_DELIM << dirEnt->d_name; - } - entry.relativePath = ss.str(); - } - else - { - entry.path = m_directoryEntry.path; - entry.relativePath = m_directoryEntry.relativePath; - } - - AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Calling stat on path " << entry.path); - - struct stat dirInfo; - if(!lstat(entry.path.c_str(), &dirInfo)) - { - if(S_ISDIR(dirInfo.st_mode)) - { - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "type directory detected"); - entry.fileType = FileType::Directory; - } - else if(S_ISLNK(dirInfo.st_mode)) - { - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "type symlink detected"); - entry.fileType = FileType::Symlink; - } - else if(S_ISREG(dirInfo.st_mode)) - { - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "type file detected"); - entry.fileType = FileType::File; - } - - entry.fileSize = static_cast<int64_t>(dirInfo.st_size); - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "file size detected as " << entry.fileSize); - } - else - { - AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Failed to stat file path " << entry.path << " with error code " << errno); - } - + entry = ParseFileInfo(dirEntry, true); + invalidEntry = false; + } + else + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "skipping . or .."); + } + } + else + { + break; + } + } + + return entry; + } + + private: + DirectoryEntry ParseFileInfo(dirent* dirEnt, bool computePath) + { + DirectoryEntry entry; + + if(computePath) + { + Aws::StringStream ss; + ss << m_directoryEntry.path << PATH_DELIM << dirEnt->d_name; + entry.path = ss.str(); + + ss.str(""); + if(m_directoryEntry.relativePath.empty()) + { + ss << dirEnt->d_name; + } + else + { + ss << m_directoryEntry.relativePath << PATH_DELIM << dirEnt->d_name; + } + entry.relativePath = ss.str(); + } + else + { + entry.path = m_directoryEntry.path; + entry.relativePath = m_directoryEntry.relativePath; + } + + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Calling stat on path " << entry.path); + + struct stat dirInfo; + if(!lstat(entry.path.c_str(), &dirInfo)) + { + if(S_ISDIR(dirInfo.st_mode)) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "type directory detected"); + entry.fileType = FileType::Directory; + } + else if(S_ISLNK(dirInfo.st_mode)) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "type symlink detected"); + entry.fileType = FileType::Symlink; + } + else if(S_ISREG(dirInfo.st_mode)) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "type file detected"); + entry.fileType = FileType::File; + } + + entry.fileSize = static_cast<int64_t>(dirInfo.st_size); + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "file size detected as " << entry.fileSize); + } + else + { + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Failed to stat file path " << entry.path << " with error code " << errno); + } + return entry; - } - - DIR* m_dir; - }; - -Aws::String GetHomeDirectory() -{ - static const char* HOME_DIR_ENV_VAR = "HOME"; - - AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Checking " << HOME_DIR_ENV_VAR << " for the home directory."); - - Aws::String homeDir = Aws::Environment::GetEnv(HOME_DIR_ENV_VAR); - - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Environment value for variable " << HOME_DIR_ENV_VAR << " is " << homeDir); - - if(homeDir.empty()) - { - AWS_LOGSTREAM_WARN(FILE_SYSTEM_UTILS_LOG_TAG, "Home dir not stored in environment, trying to fetch manually from the OS."); - - passwd pw; - passwd *p_pw = nullptr; - char pw_buffer[4096]; - getpwuid_r(getuid(), &pw, pw_buffer, sizeof(pw_buffer), &p_pw); - if(p_pw && p_pw->pw_dir) - { - homeDir = p_pw->pw_dir; - } - - AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Pulled " << homeDir << " as home directory from the OS."); - } - - Aws::String retVal = homeDir.size() > 0 ? Aws::Utils::StringUtils::Trim(homeDir.c_str()) : ""; - if(!retVal.empty()) - { - if(retVal.at(retVal.length() - 1) != PATH_DELIM) - { - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Home directory is missing the final " << PATH_DELIM << " appending one to normalize"); - retVal += PATH_DELIM; - } - } - - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Final Home Directory is " << retVal); - - return retVal; -} - -bool CreateDirectoryIfNotExists(const char* path, bool createParentDirs) -{ - Aws::String directoryName = path; - AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Creating directory " << directoryName); - - for (size_t i = (createParentDirs ? 0 : directoryName.size() - 1); i < directoryName.size(); i++) - { - // Create the parent directory if we find a delimiter and the delimiter is not the first char, or if this is the target directory. - if (i != 0 && (directoryName[i] == FileSystem::PATH_DELIM || i == directoryName.size() - 1)) - { - if (directoryName[i] == FileSystem::PATH_DELIM) - { - directoryName[i] = '\0'; - } - int errorCode = mkdir(directoryName.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); - if (errorCode != 0 && errno != EEXIST) - { - AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Creation of directory " << directoryName.c_str() << " returned code: " << errno); - return false; - } - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Creation of directory " << directoryName.c_str() << " returned code: " << errno); - directoryName[i] = FileSystem::PATH_DELIM; - } - } - return true; -} - -bool RemoveFileIfExists(const char* path) -{ - AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Deleting file: " << path); - - int errorCode = unlink(path); - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Deletion of file: " << path << " Returned error code: " << errno); - return errorCode == 0 || errno == ENOENT; -} - -bool RemoveDirectoryIfExists(const char* path) -{ - AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Deleting directory: " << path); - int errorCode = rmdir(path); - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Deletion of directory: " << path << " Returned error code: " << errno); - return errorCode == 0 || errno == ENOTDIR || errno == ENOENT; -} - -bool RelocateFileOrDirectory(const char* from, const char* to) -{ - AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Moving file at " << from << " to " << to); - - int errorCode = std::rename(from, to); - - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The moving operation of file at " << from << " to " << to << " Returned error code of " << errno); - return errorCode == 0; -} - -Aws::String CreateTempFilePath() -{ - Aws::StringStream ss; - auto dt = Aws::Utils::DateTime::Now(); + } + + DIR* m_dir; + }; + +Aws::String GetHomeDirectory() +{ + static const char* HOME_DIR_ENV_VAR = "HOME"; + + AWS_LOGSTREAM_TRACE(FILE_SYSTEM_UTILS_LOG_TAG, "Checking " << HOME_DIR_ENV_VAR << " for the home directory."); + + Aws::String homeDir = Aws::Environment::GetEnv(HOME_DIR_ENV_VAR); + + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Environment value for variable " << HOME_DIR_ENV_VAR << " is " << homeDir); + + if(homeDir.empty()) + { + AWS_LOGSTREAM_WARN(FILE_SYSTEM_UTILS_LOG_TAG, "Home dir not stored in environment, trying to fetch manually from the OS."); + + passwd pw; + passwd *p_pw = nullptr; + char pw_buffer[4096]; + getpwuid_r(getuid(), &pw, pw_buffer, sizeof(pw_buffer), &p_pw); + if(p_pw && p_pw->pw_dir) + { + homeDir = p_pw->pw_dir; + } + + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Pulled " << homeDir << " as home directory from the OS."); + } + + Aws::String retVal = homeDir.size() > 0 ? Aws::Utils::StringUtils::Trim(homeDir.c_str()) : ""; + if(!retVal.empty()) + { + if(retVal.at(retVal.length() - 1) != PATH_DELIM) + { + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Home directory is missing the final " << PATH_DELIM << " appending one to normalize"); + retVal += PATH_DELIM; + } + } + + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Final Home Directory is " << retVal); + + return retVal; +} + +bool CreateDirectoryIfNotExists(const char* path, bool createParentDirs) +{ + Aws::String directoryName = path; + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Creating directory " << directoryName); + + for (size_t i = (createParentDirs ? 0 : directoryName.size() - 1); i < directoryName.size(); i++) + { + // Create the parent directory if we find a delimiter and the delimiter is not the first char, or if this is the target directory. + if (i != 0 && (directoryName[i] == FileSystem::PATH_DELIM || i == directoryName.size() - 1)) + { + if (directoryName[i] == FileSystem::PATH_DELIM) + { + directoryName[i] = '\0'; + } + int errorCode = mkdir(directoryName.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + if (errorCode != 0 && errno != EEXIST) + { + AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "Creation of directory " << directoryName.c_str() << " returned code: " << errno); + return false; + } + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Creation of directory " << directoryName.c_str() << " returned code: " << errno); + directoryName[i] = FileSystem::PATH_DELIM; + } + } + return true; +} + +bool RemoveFileIfExists(const char* path) +{ + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Deleting file: " << path); + + int errorCode = unlink(path); + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Deletion of file: " << path << " Returned error code: " << errno); + return errorCode == 0 || errno == ENOENT; +} + +bool RemoveDirectoryIfExists(const char* path) +{ + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Deleting directory: " << path); + int errorCode = rmdir(path); + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "Deletion of directory: " << path << " Returned error code: " << errno); + return errorCode == 0 || errno == ENOTDIR || errno == ENOENT; +} + +bool RelocateFileOrDirectory(const char* from, const char* to) +{ + AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Moving file at " << from << " to " << to); + + int errorCode = std::rename(from, to); + + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The moving operation of file at " << from << " to " << to << " Returned error code of " << errno); + return errorCode == 0; +} + +Aws::String CreateTempFilePath() +{ + Aws::StringStream ss; + auto dt = Aws::Utils::DateTime::Now(); ss << dt.ToGmtString("%Y%m%dT%H%M%S") << dt.Millis() << Aws::String(Aws::Utils::UUID::RandomUUID()); - Aws::String tempFile(ss.str()); - - AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "CreateTempFilePath generated: " << tempFile); - - return tempFile; -} - -Aws::String GetExecutableDirectory() -{ - char dest[PATH_MAX]; + Aws::String tempFile(ss.str()); + + AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "CreateTempFilePath generated: " << tempFile); + + return tempFile; +} + +Aws::String GetExecutableDirectory() +{ + char dest[PATH_MAX]; memset(dest, 0, PATH_MAX); #ifdef __APPLE__ uint32_t destSize = PATH_MAX; @@ -272,21 +272,21 @@ Aws::String GetExecutableDirectory() size_t destSize = PATH_MAX; if (readlink("/proc/self/exe", dest, destSize)) #endif - { - Aws::String executablePath(dest); - auto lastSlash = executablePath.find_last_of('/'); - if(lastSlash != std::string::npos) - { - return executablePath.substr(0, lastSlash); + { + Aws::String executablePath(dest); + auto lastSlash = executablePath.find_last_of('/'); + if(lastSlash != std::string::npos) + { + return executablePath.substr(0, lastSlash); } } - return "./"; -} - -Aws::UniquePtr<Directory> OpenDirectory(const Aws::String& path, const Aws::String& relativePath) -{ - return Aws::MakeUnique<PosixDirectory>(FILE_SYSTEM_UTILS_LOG_TAG, path, relativePath); -} - -} // namespace FileSystem -} // namespace Aws + return "./"; +} + +Aws::UniquePtr<Directory> OpenDirectory(const Aws::String& path, const Aws::String& relativePath) +{ + return Aws::MakeUnique<PosixDirectory>(FILE_SYSTEM_UTILS_LOG_TAG, path, relativePath); +} + +} // namespace FileSystem +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/OSVersionInfo.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/OSVersionInfo.cpp index 040173a2e5..507b374f36 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/OSVersionInfo.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/OSVersionInfo.cpp @@ -2,58 +2,58 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/platform/OSVersionInfo.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/utils/StringUtils.h> -#include <sys/utsname.h> - -namespace Aws -{ -namespace OSVersionInfo -{ - -Aws::String GetSysCommandOutput(const char* command) -{ - Aws::String outputStr; - FILE* outputStream; - const int maxBufferSize = 256; - char outputBuffer[maxBufferSize]; - - outputStream = popen(command, "r"); - - if (outputStream) - { - while (!feof(outputStream)) - { - if (fgets(outputBuffer, maxBufferSize, outputStream) != nullptr) - { - outputStr.append(outputBuffer); - } - } - - pclose(outputStream); - - return Aws::Utils::StringUtils::Trim(outputStr.c_str()); - } - + +#include <aws/core/platform/OSVersionInfo.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/StringUtils.h> +#include <sys/utsname.h> + +namespace Aws +{ +namespace OSVersionInfo +{ + +Aws::String GetSysCommandOutput(const char* command) +{ + Aws::String outputStr; + FILE* outputStream; + const int maxBufferSize = 256; + char outputBuffer[maxBufferSize]; + + outputStream = popen(command, "r"); + + if (outputStream) + { + while (!feof(outputStream)) + { + if (fgets(outputBuffer, maxBufferSize, outputStream) != nullptr) + { + outputStr.append(outputBuffer); + } + } + + pclose(outputStream); + + return Aws::Utils::StringUtils::Trim(outputStr.c_str()); + } + return {}; -} - - -Aws::String ComputeOSVersionString() -{ - utsname name; - int32_t success = uname(&name); - if(success >= 0) - { - Aws::StringStream ss; - ss << name.sysname << "/" << name.release << " " << name.machine; - return ss.str(); - } - - return "non-windows/unknown"; -} - -} // namespace OSVersionInfo -} // namespace Aws +} + + +Aws::String ComputeOSVersionString() +{ + utsname name; + int32_t success = uname(&name); + if(success >= 0) + { + Aws::StringStream ss; + ss << name.sysname << "/" << name.release << " " << name.machine; + return ss.str(); + } + + return "non-windows/unknown"; +} + +} // namespace OSVersionInfo +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Security.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Security.cpp index 286de1a948..b8012da068 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Security.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Security.cpp @@ -2,25 +2,25 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/platform/Security.h> - -#include <string.h> - -namespace Aws -{ -namespace Security -{ - -void SecureMemClear(unsigned char *data, size_t length) -{ -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) - memset_s(data, length, 0, length); -#else - memset(data, 0, length); - asm volatile("" : "+m" (data)); -#endif -} - -} // namespace Security -} // namespace Aws + +#include <aws/core/platform/Security.h> + +#include <string.h> + +namespace Aws +{ +namespace Security +{ + +void SecureMemClear(unsigned char *data, size_t length) +{ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) + memset_s(data, length, 0, length); +#else + memset(data, 0, length); + asm volatile("" : "+m" (data)); +#endif +} + +} // namespace Security +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Time.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Time.cpp index 7a0d3d1c0a..6f2c3acf2e 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Time.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/platform/linux-shared/Time.cpp @@ -2,30 +2,30 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/platform/Time.h> - -#include <time.h> - -namespace Aws -{ -namespace Time -{ - -time_t TimeGM(struct tm* const t) -{ - return timegm(t); -} - -void LocalTime(tm* t, std::time_t time) -{ - localtime_r(&time, t); -} - -void GMTime(tm* t, std::time_t time) -{ - gmtime_r(&time, t); -} - -} // namespace Time -} // namespace Aws + +#include <aws/core/platform/Time.h> + +#include <time.h> + +namespace Aws +{ +namespace Time +{ + +time_t TimeGM(struct tm* const t) +{ + return timegm(t); +} + +void LocalTime(tm* t, std::time_t time) +{ + localtime_r(&time, t); +} + +void GMTime(tm* t, std::time_t time) +{ + gmtime_r(&time, t); +} + +} // namespace Time +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp index 43e7863421..39247ce3b1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp @@ -2,64 +2,64 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/Array.h> - -#include <aws/core/platform/Security.h> - -namespace Aws -{ - namespace Utils - { - Array<CryptoBuffer> CryptoBuffer::Slice(size_t sizeOfSlice) const - { - assert(sizeOfSlice <= GetLength()); - - size_t numberOfSlices = (GetLength() + sizeOfSlice - 1) / sizeOfSlice; - size_t currentSliceIndex = 0; - Array<CryptoBuffer> slices(numberOfSlices); - - for (size_t i = 0; i < numberOfSlices - 1; ++i) - { - CryptoBuffer newArray(sizeOfSlice); - for (size_t cpyIdx = 0; cpyIdx < newArray.GetLength(); ++cpyIdx) - { - newArray[cpyIdx] = GetItem(cpyIdx + currentSliceIndex); - } - currentSliceIndex += sizeOfSlice; - slices[i] = std::move(newArray); - } - - CryptoBuffer lastArray(GetLength() % sizeOfSlice == 0 ? sizeOfSlice : GetLength() % sizeOfSlice ); - for (size_t cpyIdx = 0; cpyIdx < lastArray.GetLength(); ++cpyIdx) - { - lastArray[cpyIdx] = GetItem(cpyIdx + currentSliceIndex); - } - slices[slices.GetLength() - 1] = std::move(lastArray); - - return slices; - } - - CryptoBuffer& CryptoBuffer::operator^(const CryptoBuffer& operand) - { - size_t smallestSize = std::min<size_t>(GetLength(), operand.GetLength()); - for (size_t i = 0; i < smallestSize; ++i) - { - (*this)[i] ^= operand[i]; - } - - return *this; - } - - /** - * Zero out the array securely - */ - void CryptoBuffer::Zero() - { - if (GetUnderlyingData()) - { - Aws::Security::SecureMemClear(GetUnderlyingData(), GetLength()); - } - } - } -}
\ No newline at end of file + +#include <aws/core/utils/Array.h> + +#include <aws/core/platform/Security.h> + +namespace Aws +{ + namespace Utils + { + Array<CryptoBuffer> CryptoBuffer::Slice(size_t sizeOfSlice) const + { + assert(sizeOfSlice <= GetLength()); + + size_t numberOfSlices = (GetLength() + sizeOfSlice - 1) / sizeOfSlice; + size_t currentSliceIndex = 0; + Array<CryptoBuffer> slices(numberOfSlices); + + for (size_t i = 0; i < numberOfSlices - 1; ++i) + { + CryptoBuffer newArray(sizeOfSlice); + for (size_t cpyIdx = 0; cpyIdx < newArray.GetLength(); ++cpyIdx) + { + newArray[cpyIdx] = GetItem(cpyIdx + currentSliceIndex); + } + currentSliceIndex += sizeOfSlice; + slices[i] = std::move(newArray); + } + + CryptoBuffer lastArray(GetLength() % sizeOfSlice == 0 ? sizeOfSlice : GetLength() % sizeOfSlice ); + for (size_t cpyIdx = 0; cpyIdx < lastArray.GetLength(); ++cpyIdx) + { + lastArray[cpyIdx] = GetItem(cpyIdx + currentSliceIndex); + } + slices[slices.GetLength() - 1] = std::move(lastArray); + + return slices; + } + + CryptoBuffer& CryptoBuffer::operator^(const CryptoBuffer& operand) + { + size_t smallestSize = std::min<size_t>(GetLength(), operand.GetLength()); + for (size_t i = 0; i < smallestSize; ++i) + { + (*this)[i] ^= operand[i]; + } + + return *this; + } + + /** + * Zero out the array securely + */ + void CryptoBuffer::Zero() + { + if (GetUnderlyingData()) + { + Aws::Security::SecureMemClear(GetUnderlyingData(), GetLength()); + } + } + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp index ce588150e2..66cc081b77 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp @@ -2,43 +2,43 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/DNS.h> + +#include <aws/core/utils/DNS.h> #include <aws/core/utils/StringUtils.h> - -namespace Aws -{ - namespace Utils - { - bool IsValidDnsLabel(const Aws::String& label) - { - // Valid DNS hostnames are composed of valid DNS labels separated by a period. - // Valid DNS labels are characterized by the following: - // 1- Only contains alphanumeric characters and/or dashes - // 2- Cannot start or end with a dash - // 3- Have a maximum length of 63 characters (the entirety of the domain name should be less than 255 bytes) - - if (label.empty()) - return false; - - if (label.size() > 63) - return false; - + +namespace Aws +{ + namespace Utils + { + bool IsValidDnsLabel(const Aws::String& label) + { + // Valid DNS hostnames are composed of valid DNS labels separated by a period. + // Valid DNS labels are characterized by the following: + // 1- Only contains alphanumeric characters and/or dashes + // 2- Cannot start or end with a dash + // 3- Have a maximum length of 63 characters (the entirety of the domain name should be less than 255 bytes) + + if (label.empty()) + return false; + + if (label.size() > 63) + return false; + if (!StringUtils::IsAlnum(label.front())) - return false; // '-' is not acceptable as the first character - + return false; // '-' is not acceptable as the first character + if (!StringUtils::IsAlnum(label.back())) - return false; // '-' is not acceptable as the last character - - for (size_t i = 1, e = label.size() - 1; i < e; ++i) - { - auto c = label[i]; + return false; // '-' is not acceptable as the last character + + for (size_t i = 1, e = label.size() - 1; i < e; ++i) + { + auto c = label[i]; if (c != '-' && !StringUtils::IsAlnum(c)) - return false; - } - - return true; - } + return false; + } + + return true; + } bool IsValidHost(const Aws::String& host) { @@ -51,5 +51,5 @@ namespace Aws return !std::any_of(labels.begin(), labels.end(), [](const Aws::String& label){ return !IsValidDnsLabel(label); }); } - } -} + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp index b690c90c2d..f2ca5cb82b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp @@ -2,611 +2,611 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/DateTime.h> - -#include <aws/core/platform/Time.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <time.h> -#include <cassert> -#include <iostream> -#include <cstring> - -static const char* CLASS_TAG = "DateTime"; -static const char* RFC822_DATE_FORMAT_STR_MINUS_Z = "%a, %d %b %Y %H:%M:%S"; -static const char* RFC822_DATE_FORMAT_STR_WITH_Z = "%a, %d %b %Y %H:%M:%S %Z"; -static const char* ISO_8601_LONG_DATE_FORMAT_STR = "%Y-%m-%dT%H:%M:%SZ"; + +#include <aws/core/utils/DateTime.h> + +#include <aws/core/platform/Time.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <time.h> +#include <cassert> +#include <iostream> +#include <cstring> + +static const char* CLASS_TAG = "DateTime"; +static const char* RFC822_DATE_FORMAT_STR_MINUS_Z = "%a, %d %b %Y %H:%M:%S"; +static const char* RFC822_DATE_FORMAT_STR_WITH_Z = "%a, %d %b %Y %H:%M:%S %Z"; +static const char* ISO_8601_LONG_DATE_FORMAT_STR = "%Y-%m-%dT%H:%M:%SZ"; static const char* ISO_8601_LONG_BASIC_DATE_FORMAT_STR = "%Y%m%dT%H%M%SZ"; - -using namespace Aws::Utils; - - -std::tm CreateZeroedTm() -{ - std::tm timeStruct; - timeStruct.tm_hour = 0; - timeStruct.tm_isdst = -1; - timeStruct.tm_mday = 0; - timeStruct.tm_min = 0; - timeStruct.tm_mon = 0; - timeStruct.tm_sec = 0; - timeStruct.tm_wday = 0; - timeStruct.tm_yday = 0; - timeStruct.tm_year = 0; - - return timeStruct; -} - -//Get the 0-6 week day number from a string representing WeekDay. Case insensitive and will stop on abbreviation -static int GetWeekDayNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex) -{ - if(stopIndex - startIndex < 3) - { - return -1; - } - - size_t index = startIndex; - - char c = timeString[index]; - char next = 0; - - //it's ugly but this should compile down to EXACTLY 3 comparisons and no memory allocations - switch(c) - { - case 'S': - case 's': - next = timeString[++index]; - switch(next) - { - case 'A': - case 'a': - next = timeString[++index]; - switch (next) - { - case 'T': - case 't': - return 6; - default: - return -1; - } - case 'U': - case 'u': - next = timeString[++index]; - switch (next) - { - case 'N': - case 'n': - return 0; - default: - return -1; - } - default: - return -1; - } - case 'T': - case 't': - next = timeString[++index]; - switch (next) - { - case 'H': - case 'h': - next = timeString[++index]; - switch(next) - { - case 'U': - case 'u': - return 4; - default: - return -1; - } - case 'U': - case 'u': - next = timeString[++index]; - switch(next) - { - case 'E': - case 'e': - return 2; - default: - return -1; - } - default: - return -1; - } - case 'M': - case 'm': - next = timeString[++index]; - switch(next) - { - case 'O': - case 'o': - next = timeString[++index]; - switch (next) - { - case 'N': - case 'n': - return 1; - default: - return -1; - } - default: - return -1; - } - case 'W': - case 'w': - next = timeString[++index]; - switch (next) - { - case 'E': - case 'e': - next = timeString[++index]; - switch (next) - { - case 'D': - case 'd': - return 3; - default: + +using namespace Aws::Utils; + + +std::tm CreateZeroedTm() +{ + std::tm timeStruct; + timeStruct.tm_hour = 0; + timeStruct.tm_isdst = -1; + timeStruct.tm_mday = 0; + timeStruct.tm_min = 0; + timeStruct.tm_mon = 0; + timeStruct.tm_sec = 0; + timeStruct.tm_wday = 0; + timeStruct.tm_yday = 0; + timeStruct.tm_year = 0; + + return timeStruct; +} + +//Get the 0-6 week day number from a string representing WeekDay. Case insensitive and will stop on abbreviation +static int GetWeekDayNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex) +{ + if(stopIndex - startIndex < 3) + { + return -1; + } + + size_t index = startIndex; + + char c = timeString[index]; + char next = 0; + + //it's ugly but this should compile down to EXACTLY 3 comparisons and no memory allocations + switch(c) + { + case 'S': + case 's': + next = timeString[++index]; + switch(next) + { + case 'A': + case 'a': + next = timeString[++index]; + switch (next) + { + case 'T': + case 't': + return 6; + default: + return -1; + } + case 'U': + case 'u': + next = timeString[++index]; + switch (next) + { + case 'N': + case 'n': + return 0; + default: return -1; + } + default: + return -1; + } + case 'T': + case 't': + next = timeString[++index]; + switch (next) + { + case 'H': + case 'h': + next = timeString[++index]; + switch(next) + { + case 'U': + case 'u': + return 4; + default: + return -1; + } + case 'U': + case 'u': + next = timeString[++index]; + switch(next) + { + case 'E': + case 'e': + return 2; + default: + return -1; + } + default: + return -1; + } + case 'M': + case 'm': + next = timeString[++index]; + switch(next) + { + case 'O': + case 'o': + next = timeString[++index]; + switch (next) + { + case 'N': + case 'n': + return 1; + default: + return -1; + } + default: + return -1; + } + case 'W': + case 'w': + next = timeString[++index]; + switch (next) + { + case 'E': + case 'e': + next = timeString[++index]; + switch (next) + { + case 'D': + case 'd': + return 3; + default: + return -1; + } + default: + return -1; + } + case 'F': + case 'f': + next = timeString[++index]; + switch (next) + { + case 'R': + case 'r': + next = timeString[++index]; + switch (next) + { + case 'I': + case 'i': + return 5; + default: + return -1; + } + default: + return -1; + } + default: + return -1; + } +} + +//Get the 0-11 monthy number from a string representing Month. Case insensitive and will stop on abbreviation +static int GetMonthNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex) +{ + if (stopIndex - startIndex < 3) + { + return -1; + } + + size_t index = startIndex; + + char c = timeString[index]; + char next = 0; + + //it's ugly but this should compile down to EXACTLY 3 comparisons and no memory allocations + switch (c) + { + case 'M': + case 'm': + next = timeString[++index]; + switch (next) + { + case 'A': + case 'a': + next = timeString[++index]; + switch (next) + { + case 'Y': + case 'y': + return 4; + case 'R': + case 'r': + return 2; + default: + return -1; } - default: - return -1; - } - case 'F': - case 'f': - next = timeString[++index]; - switch (next) - { - case 'R': - case 'r': - next = timeString[++index]; - switch (next) - { - case 'I': - case 'i': - return 5; - default: - return -1; - } - default: - return -1; - } - default: - return -1; - } -} - -//Get the 0-11 monthy number from a string representing Month. Case insensitive and will stop on abbreviation -static int GetMonthNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex) -{ - if (stopIndex - startIndex < 3) - { - return -1; - } - - size_t index = startIndex; - - char c = timeString[index]; - char next = 0; - - //it's ugly but this should compile down to EXACTLY 3 comparisons and no memory allocations - switch (c) - { - case 'M': - case 'm': - next = timeString[++index]; - switch (next) - { - case 'A': - case 'a': - next = timeString[++index]; - switch (next) - { - case 'Y': - case 'y': - return 4; - case 'R': - case 'r': - return 2; - default: - return -1; - } - default: - return -1; - } - case 'A': - case 'a': - next = timeString[++index]; - switch (next) - { - case 'P': - case 'p': - next = timeString[++index]; - switch (next) - { - case 'R': - case 'r': - return 3; - default: - return -1; - } - case 'U': - case 'u': - next = timeString[++index]; - switch (next) - { - case 'G': - case 'g': - return 7; - default: - return -1; - } - default: - return -1; - } - case 'J': - case 'j': - next = timeString[++index]; - switch (next) - { - case 'A': - case 'a': - next = timeString[++index]; - switch (next) - { - case 'N': - case 'n': - return 0; - default: - return -1; - } - case 'U': - case 'u': - next = timeString[++index]; - switch (next) - { - case 'N': - case 'n': - return 5; - case 'L': - case 'l': - return 6; - default: - return -1; - } - default: - return -1; - } - case 'F': - case 'f': - next = timeString[++index]; - switch (next) - { - case 'E': - case 'e': - next = timeString[++index]; - switch (next) - { - case 'B': - case 'b': - return 1; - default: - return -1; - } - default: - return -1; - } - case 'S': - case 's': - next = timeString[++index]; - switch (next) - { - case 'E': - case 'e': - next = timeString[++index]; - switch (next) - { - case 'P': - case 'p': - return 8; - default: - return -1; - } - default: - return -1; - } - case 'O': - case 'o': - next = timeString[++index]; - switch (next) - { - case 'C': - case 'c': - next = timeString[++index]; - switch (next) - { - case 'T': - case 't': - return 9; - default: - return -1; - } - default: - return -1; - } - case 'N': - case 'n': - next = timeString[++index]; - switch (next) - { - case 'O': - case 'o': - next = timeString[++index]; - switch (next) - { - case 'V': - case 'v': - return 10; - default: - return -1; - } - default: - return -1; - } - case 'D': - case 'd': - next = timeString[++index]; - switch (next) - { - case 'E': - case 'e': - next = timeString[++index]; - switch (next) - { - case 'C': - case 'c': - return 11; - default: - return -1; - } - default: - return -1; - } - default: - return -1; - } -} + default: + return -1; + } + case 'A': + case 'a': + next = timeString[++index]; + switch (next) + { + case 'P': + case 'p': + next = timeString[++index]; + switch (next) + { + case 'R': + case 'r': + return 3; + default: + return -1; + } + case 'U': + case 'u': + next = timeString[++index]; + switch (next) + { + case 'G': + case 'g': + return 7; + default: + return -1; + } + default: + return -1; + } + case 'J': + case 'j': + next = timeString[++index]; + switch (next) + { + case 'A': + case 'a': + next = timeString[++index]; + switch (next) + { + case 'N': + case 'n': + return 0; + default: + return -1; + } + case 'U': + case 'u': + next = timeString[++index]; + switch (next) + { + case 'N': + case 'n': + return 5; + case 'L': + case 'l': + return 6; + default: + return -1; + } + default: + return -1; + } + case 'F': + case 'f': + next = timeString[++index]; + switch (next) + { + case 'E': + case 'e': + next = timeString[++index]; + switch (next) + { + case 'B': + case 'b': + return 1; + default: + return -1; + } + default: + return -1; + } + case 'S': + case 's': + next = timeString[++index]; + switch (next) + { + case 'E': + case 'e': + next = timeString[++index]; + switch (next) + { + case 'P': + case 'p': + return 8; + default: + return -1; + } + default: + return -1; + } + case 'O': + case 'o': + next = timeString[++index]; + switch (next) + { + case 'C': + case 'c': + next = timeString[++index]; + switch (next) + { + case 'T': + case 't': + return 9; + default: + return -1; + } + default: + return -1; + } + case 'N': + case 'n': + next = timeString[++index]; + switch (next) + { + case 'O': + case 'o': + next = timeString[++index]; + switch (next) + { + case 'V': + case 'v': + return 10; + default: + return -1; + } + default: + return -1; + } + case 'D': + case 'd': + next = timeString[++index]; + switch (next) + { + case 'E': + case 'e': + next = timeString[++index]; + switch (next) + { + case 'C': + case 'c': + return 11; + default: + return -1; + } + default: + return -1; + } + default: + return -1; + } +} // Ensure local classes with generic names have internal linkage namespace { - -class DateParser -{ -public: - DateParser(const char* toParse) : m_error(false), m_toParse(toParse), m_utcAssumed(true) - { - m_parsedTimestamp = CreateZeroedTm(); + +class DateParser +{ +public: + DateParser(const char* toParse) : m_error(false), m_toParse(toParse), m_utcAssumed(true) + { + m_parsedTimestamp = CreateZeroedTm(); memset(m_tz, 0, 7); - } - - virtual ~DateParser() = default; - - virtual void Parse() = 0; - bool WasParseSuccessful() const { return !m_error; } - std::tm& GetParsedTimestamp() { return m_parsedTimestamp; } - bool ShouldIAssumeThisIsUTC() const { return m_utcAssumed; } - const char* GetParsedTimezone() const { return m_tz; } - -protected: - bool m_error; - const char* m_toParse; - std::tm m_parsedTimestamp; - bool m_utcAssumed; + } + + virtual ~DateParser() = default; + + virtual void Parse() = 0; + bool WasParseSuccessful() const { return !m_error; } + std::tm& GetParsedTimestamp() { return m_parsedTimestamp; } + bool ShouldIAssumeThisIsUTC() const { return m_utcAssumed; } + const char* GetParsedTimezone() const { return m_tz; } + +protected: + bool m_error; + const char* m_toParse; + std::tm m_parsedTimestamp; + bool m_utcAssumed; // The size should be at least one byte greater than the maximum possible size so that we could use the last char to indicate the end of the string. char m_tz[7]; -}; - -static const int MAX_LEN = 100; - -//Before you send me hate mail because I'm doing this manually, I encourage you to try using std::get_time on all platforms and getting -//uniform results. Timezone information doesn't parse on Windows and it hardly even works on GCC 4.9.x. This is the only way to make sure -//the standard is parsed correctly. strptime isn't available one Windows. This code gets hit pretty hard during http serialization/deserialization -//as a result I'm going for no dynamic allocations and linear complexity -class RFC822DateParser : public DateParser -{ -public: +}; + +static const int MAX_LEN = 100; + +//Before you send me hate mail because I'm doing this manually, I encourage you to try using std::get_time on all platforms and getting +//uniform results. Timezone information doesn't parse on Windows and it hardly even works on GCC 4.9.x. This is the only way to make sure +//the standard is parsed correctly. strptime isn't available one Windows. This code gets hit pretty hard during http serialization/deserialization +//as a result I'm going for no dynamic allocations and linear complexity +class RFC822DateParser : public DateParser +{ +public: RFC822DateParser(const char* toParse) : DateParser(toParse), m_state(0) { - } - - /** - * Really simple state machine for the format %a, %d %b %Y %H:%M:%S %Z - */ - void Parse() override - { + } + + /** + * Really simple state machine for the format %a, %d %b %Y %H:%M:%S %Z + */ + void Parse() override + { size_t len = strlen(m_toParse); - - //DOS check - if (len > MAX_LEN) - { + + //DOS check + if (len > MAX_LEN) + { AWS_LOGSTREAM_WARN(CLASS_TAG, "Incoming String to parse too long with length: " << len) m_error = true; - return; - } - - size_t index = 0; - size_t stateStartIndex = 0; - int finalState = 8; - - while(m_state <= finalState && !m_error && index < len) - { - char c = m_toParse[index]; - - switch (m_state) - { - case 0: - if(c == ',') - { - int weekNumber = GetWeekDayNumberFromStr(m_toParse, stateStartIndex, index + 1); - - if (weekNumber > -1) - { - m_state = 1; - stateStartIndex = index + 1; - m_parsedTimestamp.tm_wday = weekNumber; - } - else - { - m_error = true; - } - } - else if(!isalpha(c)) - { - m_error = true; - } - break; + return; + } + + size_t index = 0; + size_t stateStartIndex = 0; + int finalState = 8; + + while(m_state <= finalState && !m_error && index < len) + { + char c = m_toParse[index]; + + switch (m_state) + { + case 0: + if(c == ',') + { + int weekNumber = GetWeekDayNumberFromStr(m_toParse, stateStartIndex, index + 1); + + if (weekNumber > -1) + { + m_state = 1; + stateStartIndex = index + 1; + m_parsedTimestamp.tm_wday = weekNumber; + } + else + { + m_error = true; + } + } + else if(!isalpha(c)) + { + m_error = true; + } + break; case 1: - if (isspace(c)) - { + if (isspace(c)) + { m_state = 2; - stateStartIndex = index + 1; - } - else - { - m_error = true; - } - break; - case 2: - if (isdigit(c)) - { - m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0'); - } - else if(isspace(c)) - { - m_state = 3; - stateStartIndex = index + 1; - } - else - { - m_error = true; - } - break; - case 3: - if (isspace(c)) - { - int monthNumber = GetMonthNumberFromStr(m_toParse, stateStartIndex, index + 1); - - if (monthNumber > -1) - { - m_state = 4; - stateStartIndex = index + 1; - m_parsedTimestamp.tm_mon = monthNumber; - } - else - { - m_error = true; - } - } - else if (!isalpha(c)) - { - m_error = true; - } - break; - case 4: - if (isspace(c) && index - stateStartIndex == 4) - { - m_state = 5; - stateStartIndex = index + 1; - m_parsedTimestamp.tm_year -= 1900; - } - else if (isspace(c) && index - stateStartIndex == 2) - { - m_state = 5; - stateStartIndex = index + 1; - m_parsedTimestamp.tm_year += 2000 - 1900; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0'); - } - else - { - m_error = true; - } - break; - case 5: - if(c == ':' && index - stateStartIndex == 2) - { - m_state = 6; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0'); - } - else - { - m_error = true; - } - break; - case 6: - if (c == ':' && index - stateStartIndex == 2) - { - m_state = 7; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0'); - } - else - { - m_error = true; - } - break; - case 7: - if (isspace(c) && index - stateStartIndex == 2) - { - m_state = 8; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0'); - } - else - { - m_error = true; - } - break; - case 8: + stateStartIndex = index + 1; + } + else + { + m_error = true; + } + break; + case 2: + if (isdigit(c)) + { + m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0'); + } + else if(isspace(c)) + { + m_state = 3; + stateStartIndex = index + 1; + } + else + { + m_error = true; + } + break; + case 3: + if (isspace(c)) + { + int monthNumber = GetMonthNumberFromStr(m_toParse, stateStartIndex, index + 1); + + if (monthNumber > -1) + { + m_state = 4; + stateStartIndex = index + 1; + m_parsedTimestamp.tm_mon = monthNumber; + } + else + { + m_error = true; + } + } + else if (!isalpha(c)) + { + m_error = true; + } + break; + case 4: + if (isspace(c) && index - stateStartIndex == 4) + { + m_state = 5; + stateStartIndex = index + 1; + m_parsedTimestamp.tm_year -= 1900; + } + else if (isspace(c) && index - stateStartIndex == 2) + { + m_state = 5; + stateStartIndex = index + 1; + m_parsedTimestamp.tm_year += 2000 - 1900; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0'); + } + else + { + m_error = true; + } + break; + case 5: + if(c == ':' && index - stateStartIndex == 2) + { + m_state = 6; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0'); + } + else + { + m_error = true; + } + break; + case 6: + if (c == ':' && index - stateStartIndex == 2) + { + m_state = 7; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0'); + } + else + { + m_error = true; + } + break; + case 7: + if (isspace(c) && index - stateStartIndex == 2) + { + m_state = 8; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0'); + } + else + { + m_error = true; + } + break; + case 8: if ((isalnum(c) || c == '+' || c == '-') && (index - stateStartIndex < 5)) - { - m_tz[index - stateStartIndex] = c; + { + m_tz[index - stateStartIndex] = c; } else { m_error = true; } - break; + break; default: m_error = true; break; - } - - index++; - } - - if (m_tz[0] != 0) - { + } + + index++; + } + + if (m_tz[0] != 0) + { m_utcAssumed = IsUTCTimeZoneDesignator(m_tz); - } - - m_error = (m_error || m_state != finalState); - } - - int GetState() const { return m_state; } - -private: + } + + m_error = (m_error || m_state != finalState); + } + + int GetState() const { return m_state; } + +private: //Detects whether or not the passed in timezone string is a UTC zone. static bool IsUTCTimeZoneDesignator(const char* str) { @@ -702,157 +702,157 @@ private: } - int m_state; -}; - -//Before you send me hate mail because I'm doing this manually, I encourage you to try using std::get_time on all platforms and getting -//uniform results. Timezone information doesn't parse on Windows and it hardly even works on GCC 4.9.x. This is the only way to make sure -//the standard is parsed correctly. strptime isn't available one Windows. This code gets hit pretty hard during http serialization/deserialization -//as a result I'm going for no dynamic allocations and linear complexity -class ISO_8601DateParser : public DateParser -{ -public: - ISO_8601DateParser(const char* stringToParse) : DateParser(stringToParse), m_state(0) - { - } - - //parses "%Y-%m-%dT%H:%M:%SZ or "%Y-%m-%dT%H:%M:%S.000Z" - void Parse() override - { - size_t len = strlen(m_toParse); - - //DOS check - if (len > MAX_LEN) - { + int m_state; +}; + +//Before you send me hate mail because I'm doing this manually, I encourage you to try using std::get_time on all platforms and getting +//uniform results. Timezone information doesn't parse on Windows and it hardly even works on GCC 4.9.x. This is the only way to make sure +//the standard is parsed correctly. strptime isn't available one Windows. This code gets hit pretty hard during http serialization/deserialization +//as a result I'm going for no dynamic allocations and linear complexity +class ISO_8601DateParser : public DateParser +{ +public: + ISO_8601DateParser(const char* stringToParse) : DateParser(stringToParse), m_state(0) + { + } + + //parses "%Y-%m-%dT%H:%M:%SZ or "%Y-%m-%dT%H:%M:%S.000Z" + void Parse() override + { + size_t len = strlen(m_toParse); + + //DOS check + if (len > MAX_LEN) + { AWS_LOGSTREAM_WARN(CLASS_TAG, "Incoming String to parse too long with length: " << len) - m_error = true; - return; - } - - size_t index = 0; - size_t stateStartIndex = 0; - const int finalState = 7; - - while (m_state <= finalState && !m_error && index < len) - { - char c = m_toParse[index]; - switch (m_state) - { - case 0: - if (c == '-' && index - stateStartIndex == 4) - { - m_state = 1; - stateStartIndex = index + 1; - m_parsedTimestamp.tm_year -= 1900; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0'); - } - else - { - m_error = true; - } - break; - case 1: - if (c == '-' && index - stateStartIndex == 2) - { - m_state = 2; - stateStartIndex = index + 1; - m_parsedTimestamp.tm_mon -= 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_mon = m_parsedTimestamp.tm_mon * 10 + (c - '0'); - } - else - { - m_error = true; - } - - break; - case 2: - if (c == 'T' && index - stateStartIndex == 2) - { - m_state = 3; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0'); - } - else - { - m_error = true; - } - - break; - case 3: - if (c == ':' && index - stateStartIndex == 2) - { - m_state = 4; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0'); - } - else - { - m_error = true; - } - - break; - case 4: - if (c == ':' && index - stateStartIndex == 2) - { - m_state = 5; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0'); - } - else - { - m_error = true; - } - - break; - case 5: + m_error = true; + return; + } + + size_t index = 0; + size_t stateStartIndex = 0; + const int finalState = 7; + + while (m_state <= finalState && !m_error && index < len) + { + char c = m_toParse[index]; + switch (m_state) + { + case 0: + if (c == '-' && index - stateStartIndex == 4) + { + m_state = 1; + stateStartIndex = index + 1; + m_parsedTimestamp.tm_year -= 1900; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0'); + } + else + { + m_error = true; + } + break; + case 1: + if (c == '-' && index - stateStartIndex == 2) + { + m_state = 2; + stateStartIndex = index + 1; + m_parsedTimestamp.tm_mon -= 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_mon = m_parsedTimestamp.tm_mon * 10 + (c - '0'); + } + else + { + m_error = true; + } + + break; + case 2: + if (c == 'T' && index - stateStartIndex == 2) + { + m_state = 3; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0'); + } + else + { + m_error = true; + } + + break; + case 3: + if (c == ':' && index - stateStartIndex == 2) + { + m_state = 4; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0'); + } + else + { + m_error = true; + } + + break; + case 4: + if (c == ':' && index - stateStartIndex == 2) + { + m_state = 5; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0'); + } + else + { + m_error = true; + } + + break; + case 5: if ((c == 'Z' || c == '+' || c == '-' ) && (index - stateStartIndex == 2)) - { + { m_tz[0] = c; m_state = 7; - stateStartIndex = index + 1; - } - else if (c == '.' && index - stateStartIndex == 2) - { - m_state = 6; - stateStartIndex = index + 1; - } - else if (isdigit(c)) - { - m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0'); - } - else - { - m_error = true; - } - - break; - case 6: + stateStartIndex = index + 1; + } + else if (c == '.' && index - stateStartIndex == 2) + { + m_state = 6; + stateStartIndex = index + 1; + } + else if (isdigit(c)) + { + m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0'); + } + else + { + m_error = true; + } + + break; + case 6: if ((c == 'Z' || c == '+' || c == '-' ) && (index - stateStartIndex == 3)) - { + { m_tz[0] = c; m_state = 7; - stateStartIndex = index + 1; - } - else if(!isdigit(c)) - { - m_error = true; - } - break; + stateStartIndex = index + 1; + } + else if(!isdigit(c)) + { + m_error = true; + } + break; case 7: if ((isdigit(c) || c == ':') && (index - stateStartIndex < 5)) { @@ -866,24 +866,24 @@ public: default: m_error = true; break; - } - index++; - } - + } + index++; + } + if (m_tz[0] != 0) { m_utcAssumed = IsUTCTimeZoneDesignator(m_tz); } - m_error = (m_error || m_state != finalState); - } - + m_error = (m_error || m_state != finalState); + } + private: //Detects whether or not the passed in timezone string is a UTC zone. static bool IsUTCTimeZoneDesignator(const char* str) { size_t len = strlen(str); - + if (len > 0) { if (len == 1 && str[0] == 'Z') @@ -1075,7 +1075,7 @@ public: m_error = (m_error || m_state != finalState); } -private: +private: //Detects whether or not the passed in timezone string is a UTC zone. static bool IsUTCTimeZoneDesignator(const char* str) { @@ -1103,246 +1103,246 @@ private: return false; } - int m_state; -}; + int m_state; +}; } // namespace - -DateTime::DateTime(const std::chrono::system_clock::time_point& timepointToAssign) : m_time(timepointToAssign), m_valid(true) -{ -} - -DateTime::DateTime(int64_t millisSinceEpoch) : m_valid(true) -{ - std::chrono::duration<int64_t, std::chrono::milliseconds::period> timestamp(millisSinceEpoch); - m_time = std::chrono::system_clock::time_point(timestamp); -} - -DateTime::DateTime(double epoch_millis) : m_valid(true) -{ - std::chrono::duration<double, std::chrono::seconds::period> timestamp(epoch_millis); - m_time = std::chrono::system_clock::time_point(std::chrono::duration_cast<std::chrono::milliseconds>(timestamp)); -} - -DateTime::DateTime(const Aws::String& timestamp, DateFormat format) : m_valid(true) -{ - ConvertTimestampStringToTimePoint(timestamp.c_str(), format); -} - -DateTime::DateTime(const char* timestamp, DateFormat format) : m_valid(true) -{ - ConvertTimestampStringToTimePoint(timestamp, format); -} - -DateTime::DateTime() : m_valid(true) -{ - //init time_point to default by doing nothing. -} - -DateTime& DateTime::operator=(const Aws::String& timestamp) -{ - *this = DateTime(timestamp, DateFormat::AutoDetect); - return *this; -} - -DateTime& DateTime::operator=(double secondsMillis) -{ - *this = DateTime(secondsMillis); - return *this; -} - -DateTime& DateTime::operator=(int64_t millisSinceEpoch) + +DateTime::DateTime(const std::chrono::system_clock::time_point& timepointToAssign) : m_time(timepointToAssign), m_valid(true) { - *this = DateTime(millisSinceEpoch); - return *this; -} - -DateTime& DateTime::operator=(const std::chrono::system_clock::time_point& timepointToAssign) -{ - *this = DateTime(timepointToAssign); - return *this; -} - -bool DateTime::operator == (const DateTime& other) const -{ - return m_time == other.m_time; -} - -bool DateTime::operator < (const DateTime& other) const -{ - return m_time < other.m_time; -} - -bool DateTime::operator > (const DateTime& other) const -{ - return m_time > other.m_time; -} - -bool DateTime::operator != (const DateTime& other) const -{ - return m_time != other.m_time; -} - -bool DateTime::operator <= (const DateTime& other) const -{ - return m_time <= other.m_time; -} - -bool DateTime::operator >= (const DateTime& other) const -{ - return m_time >= other.m_time; -} - -DateTime DateTime::operator +(const std::chrono::milliseconds& a) const -{ - auto timepointCpy = m_time; - timepointCpy += a; - return DateTime(timepointCpy); -} - -DateTime DateTime::operator -(const std::chrono::milliseconds& a) const -{ - auto timepointCpy = m_time; - timepointCpy -= a; - return DateTime(timepointCpy); -} - -Aws::String DateTime::ToLocalTimeString(DateFormat format) const -{ - switch (format) - { - case DateFormat::ISO_8601: - return ToLocalTimeString(ISO_8601_LONG_DATE_FORMAT_STR); +} + +DateTime::DateTime(int64_t millisSinceEpoch) : m_valid(true) +{ + std::chrono::duration<int64_t, std::chrono::milliseconds::period> timestamp(millisSinceEpoch); + m_time = std::chrono::system_clock::time_point(timestamp); +} + +DateTime::DateTime(double epoch_millis) : m_valid(true) +{ + std::chrono::duration<double, std::chrono::seconds::period> timestamp(epoch_millis); + m_time = std::chrono::system_clock::time_point(std::chrono::duration_cast<std::chrono::milliseconds>(timestamp)); +} + +DateTime::DateTime(const Aws::String& timestamp, DateFormat format) : m_valid(true) +{ + ConvertTimestampStringToTimePoint(timestamp.c_str(), format); +} + +DateTime::DateTime(const char* timestamp, DateFormat format) : m_valid(true) +{ + ConvertTimestampStringToTimePoint(timestamp, format); +} + +DateTime::DateTime() : m_valid(true) +{ + //init time_point to default by doing nothing. +} + +DateTime& DateTime::operator=(const Aws::String& timestamp) +{ + *this = DateTime(timestamp, DateFormat::AutoDetect); + return *this; +} + +DateTime& DateTime::operator=(double secondsMillis) +{ + *this = DateTime(secondsMillis); + return *this; +} + +DateTime& DateTime::operator=(int64_t millisSinceEpoch) +{ + *this = DateTime(millisSinceEpoch); + return *this; +} + +DateTime& DateTime::operator=(const std::chrono::system_clock::time_point& timepointToAssign) +{ + *this = DateTime(timepointToAssign); + return *this; +} + +bool DateTime::operator == (const DateTime& other) const +{ + return m_time == other.m_time; +} + +bool DateTime::operator < (const DateTime& other) const +{ + return m_time < other.m_time; +} + +bool DateTime::operator > (const DateTime& other) const +{ + return m_time > other.m_time; +} + +bool DateTime::operator != (const DateTime& other) const +{ + return m_time != other.m_time; +} + +bool DateTime::operator <= (const DateTime& other) const +{ + return m_time <= other.m_time; +} + +bool DateTime::operator >= (const DateTime& other) const +{ + return m_time >= other.m_time; +} + +DateTime DateTime::operator +(const std::chrono::milliseconds& a) const +{ + auto timepointCpy = m_time; + timepointCpy += a; + return DateTime(timepointCpy); +} + +DateTime DateTime::operator -(const std::chrono::milliseconds& a) const +{ + auto timepointCpy = m_time; + timepointCpy -= a; + return DateTime(timepointCpy); +} + +Aws::String DateTime::ToLocalTimeString(DateFormat format) const +{ + switch (format) + { + case DateFormat::ISO_8601: + return ToLocalTimeString(ISO_8601_LONG_DATE_FORMAT_STR); case DateFormat::ISO_8601_BASIC: return ToLocalTimeString(ISO_8601_LONG_BASIC_DATE_FORMAT_STR); - case DateFormat::RFC822: + case DateFormat::RFC822: return ToLocalTimeString(RFC822_DATE_FORMAT_STR_WITH_Z); - default: - assert(0); - return ""; - } -} - -Aws::String DateTime::ToLocalTimeString(const char* formatStr) const -{ - struct tm localTimeStamp = ConvertTimestampToLocalTimeStruct(); - - char formattedString[100]; - std::strftime(formattedString, sizeof(formattedString), formatStr, &localTimeStamp); - return formattedString; -} - -Aws::String DateTime::ToGmtString(DateFormat format) const -{ - switch (format) - { - case DateFormat::ISO_8601: - return ToGmtString(ISO_8601_LONG_DATE_FORMAT_STR); + default: + assert(0); + return ""; + } +} + +Aws::String DateTime::ToLocalTimeString(const char* formatStr) const +{ + struct tm localTimeStamp = ConvertTimestampToLocalTimeStruct(); + + char formattedString[100]; + std::strftime(formattedString, sizeof(formattedString), formatStr, &localTimeStamp); + return formattedString; +} + +Aws::String DateTime::ToGmtString(DateFormat format) const +{ + switch (format) + { + case DateFormat::ISO_8601: + return ToGmtString(ISO_8601_LONG_DATE_FORMAT_STR); case DateFormat::ISO_8601_BASIC: return ToGmtString(ISO_8601_LONG_BASIC_DATE_FORMAT_STR); - case DateFormat::RFC822: - { + case DateFormat::RFC822: + { //Windows erroneously drops the local timezone in for %Z - Aws::String rfc822GmtString = ToGmtString(RFC822_DATE_FORMAT_STR_MINUS_Z); - rfc822GmtString += " GMT"; - return rfc822GmtString; - } - default: - assert(0); - return ""; - } -} - -Aws::String DateTime::ToGmtString(const char* formatStr) const -{ - struct tm gmtTimeStamp = ConvertTimestampToGmtStruct(); - - char formattedString[100]; - std::strftime(formattedString, sizeof(formattedString), formatStr, &gmtTimeStamp); - return formattedString; -} - -double DateTime::SecondsWithMSPrecision() const -{ - std::chrono::duration<double, std::chrono::seconds::period> timestamp(m_time.time_since_epoch()); - return timestamp.count(); -} - -int64_t DateTime::Millis() const -{ - auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(m_time.time_since_epoch()); - return timestamp.count(); -} - -std::chrono::system_clock::time_point DateTime::UnderlyingTimestamp() const -{ - return m_time; -} - -int DateTime::GetYear(bool localTime) const -{ - return GetTimeStruct(localTime).tm_year + 1900; -} - -Month DateTime::GetMonth(bool localTime) const -{ - return static_cast<Aws::Utils::Month>(GetTimeStruct(localTime).tm_mon); -} - -int DateTime::GetDay(bool localTime) const -{ - return GetTimeStruct(localTime).tm_mday; -} - -DayOfWeek DateTime::GetDayOfWeek(bool localTime) const -{ - return static_cast<Aws::Utils::DayOfWeek>(GetTimeStruct(localTime).tm_wday); -} - -int DateTime::GetHour(bool localTime) const -{ - return GetTimeStruct(localTime).tm_hour; -} - -int DateTime::GetMinute(bool localTime) const -{ - return GetTimeStruct(localTime).tm_min; -} - -int DateTime::GetSecond(bool localTime) const -{ - return GetTimeStruct(localTime).tm_sec; -} - -bool DateTime::IsDST(bool localTime) const -{ - return GetTimeStruct(localTime).tm_isdst == 0 ? false : true; -} - -DateTime DateTime::Now() -{ - DateTime dateTime; - dateTime.m_time = std::chrono::system_clock::now(); - return dateTime; -} - -int64_t DateTime::CurrentTimeMillis() -{ - return Now().Millis(); -} - -Aws::String DateTime::CalculateLocalTimestampAsString(const char* formatStr) -{ - DateTime now = Now(); - return now.ToLocalTimeString(formatStr); -} - -Aws::String DateTime::CalculateGmtTimestampAsString(const char* formatStr) + Aws::String rfc822GmtString = ToGmtString(RFC822_DATE_FORMAT_STR_MINUS_Z); + rfc822GmtString += " GMT"; + return rfc822GmtString; + } + default: + assert(0); + return ""; + } +} + +Aws::String DateTime::ToGmtString(const char* formatStr) const { - DateTime now = Now(); - return now.ToGmtString(formatStr); -} - + struct tm gmtTimeStamp = ConvertTimestampToGmtStruct(); + + char formattedString[100]; + std::strftime(formattedString, sizeof(formattedString), formatStr, &gmtTimeStamp); + return formattedString; +} + +double DateTime::SecondsWithMSPrecision() const +{ + std::chrono::duration<double, std::chrono::seconds::period> timestamp(m_time.time_since_epoch()); + return timestamp.count(); +} + +int64_t DateTime::Millis() const +{ + auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(m_time.time_since_epoch()); + return timestamp.count(); +} + +std::chrono::system_clock::time_point DateTime::UnderlyingTimestamp() const +{ + return m_time; +} + +int DateTime::GetYear(bool localTime) const +{ + return GetTimeStruct(localTime).tm_year + 1900; +} + +Month DateTime::GetMonth(bool localTime) const +{ + return static_cast<Aws::Utils::Month>(GetTimeStruct(localTime).tm_mon); +} + +int DateTime::GetDay(bool localTime) const +{ + return GetTimeStruct(localTime).tm_mday; +} + +DayOfWeek DateTime::GetDayOfWeek(bool localTime) const +{ + return static_cast<Aws::Utils::DayOfWeek>(GetTimeStruct(localTime).tm_wday); +} + +int DateTime::GetHour(bool localTime) const +{ + return GetTimeStruct(localTime).tm_hour; +} + +int DateTime::GetMinute(bool localTime) const +{ + return GetTimeStruct(localTime).tm_min; +} + +int DateTime::GetSecond(bool localTime) const +{ + return GetTimeStruct(localTime).tm_sec; +} + +bool DateTime::IsDST(bool localTime) const +{ + return GetTimeStruct(localTime).tm_isdst == 0 ? false : true; +} + +DateTime DateTime::Now() +{ + DateTime dateTime; + dateTime.m_time = std::chrono::system_clock::now(); + return dateTime; +} + +int64_t DateTime::CurrentTimeMillis() +{ + return Now().Millis(); +} + +Aws::String DateTime::CalculateLocalTimestampAsString(const char* formatStr) +{ + DateTime now = Now(); + return now.ToLocalTimeString(formatStr); +} + +Aws::String DateTime::CalculateGmtTimestampAsString(const char* formatStr) +{ + DateTime now = Now(); + return now.ToGmtString(formatStr); +} + Aws::String DateTime::CalculateGmtTimeWithMsPrecision() { auto now = DateTime::Now(); @@ -1368,53 +1368,53 @@ Aws::String DateTime::CalculateGmtTimeWithMsPrecision() return formattedString; } -int DateTime::CalculateCurrentHour() -{ - return Now().GetHour(true); -} - -double DateTime::ComputeCurrentTimestampInAmazonFormat() -{ - return Now().SecondsWithMSPrecision(); -} - -std::chrono::milliseconds DateTime::Diff(const DateTime& a, const DateTime& b) -{ - auto diff = a.m_time - b.m_time; - return std::chrono::duration_cast<std::chrono::milliseconds>(diff); -} - +int DateTime::CalculateCurrentHour() +{ + return Now().GetHour(true); +} + +double DateTime::ComputeCurrentTimestampInAmazonFormat() +{ + return Now().SecondsWithMSPrecision(); +} + +std::chrono::milliseconds DateTime::Diff(const DateTime& a, const DateTime& b) +{ + auto diff = a.m_time - b.m_time; + return std::chrono::duration_cast<std::chrono::milliseconds>(diff); +} + std::chrono::milliseconds DateTime::operator-(const DateTime& other) const +{ + auto diff = this->m_time - other.m_time; + return std::chrono::duration_cast<std::chrono::milliseconds>(diff); +} + +void DateTime::ConvertTimestampStringToTimePoint(const char* timestamp, DateFormat format) { - auto diff = this->m_time - other.m_time; - return std::chrono::duration_cast<std::chrono::milliseconds>(diff); -} - -void DateTime::ConvertTimestampStringToTimePoint(const char* timestamp, DateFormat format) -{ - std::tm timeStruct; - bool isUtc = true; - - switch (format) - { - case DateFormat::RFC822: - { - RFC822DateParser parser(timestamp); - parser.Parse(); - m_valid = parser.WasParseSuccessful(); - isUtc = parser.ShouldIAssumeThisIsUTC(); - timeStruct = parser.GetParsedTimestamp(); - break; - } - case DateFormat::ISO_8601: - { - ISO_8601DateParser parser(timestamp); - parser.Parse(); - m_valid = parser.WasParseSuccessful(); - isUtc = parser.ShouldIAssumeThisIsUTC(); - timeStruct = parser.GetParsedTimestamp(); + std::tm timeStruct; + bool isUtc = true; + + switch (format) + { + case DateFormat::RFC822: + { + RFC822DateParser parser(timestamp); + parser.Parse(); + m_valid = parser.WasParseSuccessful(); + isUtc = parser.ShouldIAssumeThisIsUTC(); + timeStruct = parser.GetParsedTimestamp(); + break; + } + case DateFormat::ISO_8601: + { + ISO_8601DateParser parser(timestamp); + parser.Parse(); + m_valid = parser.WasParseSuccessful(); + isUtc = parser.ShouldIAssumeThisIsUTC(); + timeStruct = parser.GetParsedTimestamp(); break; - } + } case DateFormat::ISO_8601_BASIC: { ISO_8601BasicDateParser parser(timestamp); @@ -1424,26 +1424,26 @@ void DateTime::ConvertTimestampStringToTimePoint(const char* timestamp, DateForm timeStruct = parser.GetParsedTimestamp(); break; } - case DateFormat::AutoDetect: - { - RFC822DateParser rfcParser(timestamp); - rfcParser.Parse(); - if(rfcParser.WasParseSuccessful()) - { - m_valid = true; - isUtc = rfcParser.ShouldIAssumeThisIsUTC(); - timeStruct = rfcParser.GetParsedTimestamp(); - break; - } - ISO_8601DateParser isoParser(timestamp); - isoParser.Parse(); - if (isoParser.WasParseSuccessful()) - { - m_valid = true; - isUtc = isoParser.ShouldIAssumeThisIsUTC(); - timeStruct = isoParser.GetParsedTimestamp(); - break; - } + case DateFormat::AutoDetect: + { + RFC822DateParser rfcParser(timestamp); + rfcParser.Parse(); + if(rfcParser.WasParseSuccessful()) + { + m_valid = true; + isUtc = rfcParser.ShouldIAssumeThisIsUTC(); + timeStruct = rfcParser.GetParsedTimestamp(); + break; + } + ISO_8601DateParser isoParser(timestamp); + isoParser.Parse(); + if (isoParser.WasParseSuccessful()) + { + m_valid = true; + isUtc = isoParser.ShouldIAssumeThisIsUTC(); + timeStruct = isoParser.GetParsedTimestamp(); + break; + } ISO_8601BasicDateParser isoBasicParser(timestamp); isoBasicParser.Parse(); if (isoBasicParser.WasParseSuccessful()) @@ -1453,50 +1453,50 @@ void DateTime::ConvertTimestampStringToTimePoint(const char* timestamp, DateForm timeStruct = isoBasicParser.GetParsedTimestamp(); break; } - m_valid = false; - break; - } + m_valid = false; + break; + } default: - assert(0); + assert(0); } - if (m_valid) + if (m_valid) { - std::time_t tt; - if(isUtc) - { - tt = Aws::Time::TimeGM(&timeStruct); - } - else - { - assert(0); - AWS_LOGSTREAM_WARN(CLASS_TAG, "Non-UTC timestamp detected. This is always a bug. Make the world a better place and fix whatever sent you this timestamp: " << timestamp) - tt = std::mktime(&timeStruct); - } - m_time = std::chrono::system_clock::from_time_t(tt); + std::time_t tt; + if(isUtc) + { + tt = Aws::Time::TimeGM(&timeStruct); + } + else + { + assert(0); + AWS_LOGSTREAM_WARN(CLASS_TAG, "Non-UTC timestamp detected. This is always a bug. Make the world a better place and fix whatever sent you this timestamp: " << timestamp) + tt = std::mktime(&timeStruct); + } + m_time = std::chrono::system_clock::from_time_t(tt); } -} - -tm DateTime::GetTimeStruct(bool localTime) const -{ - return localTime ? ConvertTimestampToLocalTimeStruct() : ConvertTimestampToGmtStruct(); -} - -tm DateTime::ConvertTimestampToLocalTimeStruct() const -{ - std::time_t time = std::chrono::system_clock::to_time_t(m_time); - struct tm localTimeStamp; - - Aws::Time::LocalTime(&localTimeStamp, time); - - return localTimeStamp; -} - -tm DateTime::ConvertTimestampToGmtStruct() const -{ - std::time_t time = std::chrono::system_clock::to_time_t(m_time); - struct tm gmtTimeStamp; - Aws::Time::GMTime(&gmtTimeStamp, time); - - return gmtTimeStamp; -} +} + +tm DateTime::GetTimeStruct(bool localTime) const +{ + return localTime ? ConvertTimestampToLocalTimeStruct() : ConvertTimestampToGmtStruct(); +} + +tm DateTime::ConvertTimestampToLocalTimeStruct() const +{ + std::time_t time = std::chrono::system_clock::to_time_t(m_time); + struct tm localTimeStamp; + + Aws::Time::LocalTime(&localTimeStamp, time); + + return localTimeStamp; +} + +tm DateTime::ConvertTimestampToGmtStruct() const +{ + std::time_t time = std::chrono::system_clock::to_time_t(m_time); + struct tm gmtTimeStamp; + Aws::Time::GMTime(&gmtTimeStamp, time); + + return gmtTimeStamp; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp index 49ca56b280..5423d38793 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp @@ -2,322 +2,322 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/platform/FileSystem.h> -#include <aws/core/utils/memory/stl/AWSQueue.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/utils/memory/stl/AWSStreamFwd.h> -#include <aws/core/utils/StringUtils.h> -#include <fstream> -#include <cassert> - -namespace Aws -{ - namespace FileSystem - { - Aws::String Join(const Aws::String& leftSegment, const Aws::String& rightSegment) - { - return Join(PATH_DELIM, leftSegment, rightSegment); - } - - Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment) - { - Aws::StringStream ss; - - if (!leftSegment.empty()) - { - if (leftSegment.back() == delimiter) - { - ss << leftSegment.substr(0, leftSegment.length() - 1); - } - else - { - ss << leftSegment; - } - } - - ss << delimiter; - - if (!rightSegment.empty()) - { - if (rightSegment.front() == delimiter) - { - ss << rightSegment.substr(1); - } - else - { - ss << rightSegment; - } - } - - return ss.str(); - } - - bool DeepCopyDirectory(const char* from, const char* to) - { - if (!from || !to) return false; - - DirectoryTree fromDir(from); - - if (!fromDir) return false; - - CreateDirectoryIfNotExists(to); - DirectoryTree toDir(to); - - if (!toDir) return false; - - bool success(true); - - auto visitor = [to,&success](const DirectoryTree*, const DirectoryEntry& entry) - { - auto newPath = Aws::FileSystem::Join(to, entry.relativePath); - - if (entry.fileType == Aws::FileSystem::FileType::File) - { - Aws::OFStream copyOutStream(newPath.c_str()); - Aws::IFStream originalStream(entry.path.c_str()); - - if(!copyOutStream.good() || !originalStream.good()) - { - success = false; - return false; - } - - std::copy(std::istreambuf_iterator<char>(originalStream), - std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(copyOutStream)); - } - else if (entry.fileType == Aws::FileSystem::FileType::Directory) - { - success = CreateDirectoryIfNotExists(newPath.c_str()); - return success; - } - - return success; - }; - - fromDir.TraverseDepthFirst(visitor); - return success; - } - - bool DeepDeleteDirectory(const char* toDelete) - { - bool success(true); - - //scope this to a new stack frame, because we won't be able to delete the root directory - //unless the directory handle has closed. - { - DirectoryTree delDir(toDelete); - - if (!delDir) return false; - - auto visitor = [&success](const DirectoryTree*, const DirectoryEntry& entry) - { - if (entry.fileType == FileType::File) - { - success = RemoveFileIfExists(entry.path.c_str()); - } - else - { - success = RemoveDirectoryIfExists(entry.path.c_str()); - } - - return success; - }; - - delDir.TraverseDepthFirst(visitor, true); - } - - if (success) - { - success = RemoveDirectoryIfExists(toDelete); - } - - return success; - } - - Directory::Directory(const Aws::String& path, const Aws::String& relativePath) - { - auto trimmedPath = Utils::StringUtils::Trim(path.c_str()); - auto trimmedRelativePath = Utils::StringUtils::Trim(relativePath.c_str()); - - if (!trimmedPath.empty() && trimmedPath[trimmedPath.length() - 1] == PATH_DELIM) - { - m_directoryEntry.path = trimmedPath.substr(0, trimmedPath.length() - 1); - } - else - { - m_directoryEntry.path = trimmedPath; - } - - if (!trimmedRelativePath.empty() && trimmedRelativePath[trimmedRelativePath.length() - 1] == PATH_DELIM) - { - m_directoryEntry.relativePath = trimmedRelativePath.substr(0, trimmedRelativePath.length() - 1); - } - else - { - m_directoryEntry.relativePath = trimmedRelativePath; - } - } - - Aws::UniquePtr<Directory> Directory::Descend(const DirectoryEntry& directoryEntry) - { - assert(directoryEntry.fileType != FileType::File); - return OpenDirectory(directoryEntry.path, directoryEntry.relativePath); - } - - Aws::Vector<Aws::String> Directory::GetAllFilePathsInDirectory(const Aws::String& path) - { - Aws::FileSystem::DirectoryTree tree(path); - Aws::Vector<Aws::String> filesVector; - auto visitor = [&](const Aws::FileSystem::DirectoryTree*, const Aws::FileSystem::DirectoryEntry& entry) + +#include <aws/core/platform/FileSystem.h> +#include <aws/core/utils/memory/stl/AWSQueue.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/memory/stl/AWSStreamFwd.h> +#include <aws/core/utils/StringUtils.h> +#include <fstream> +#include <cassert> + +namespace Aws +{ + namespace FileSystem + { + Aws::String Join(const Aws::String& leftSegment, const Aws::String& rightSegment) + { + return Join(PATH_DELIM, leftSegment, rightSegment); + } + + Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment) + { + Aws::StringStream ss; + + if (!leftSegment.empty()) + { + if (leftSegment.back() == delimiter) + { + ss << leftSegment.substr(0, leftSegment.length() - 1); + } + else + { + ss << leftSegment; + } + } + + ss << delimiter; + + if (!rightSegment.empty()) + { + if (rightSegment.front() == delimiter) + { + ss << rightSegment.substr(1); + } + else + { + ss << rightSegment; + } + } + + return ss.str(); + } + + bool DeepCopyDirectory(const char* from, const char* to) + { + if (!from || !to) return false; + + DirectoryTree fromDir(from); + + if (!fromDir) return false; + + CreateDirectoryIfNotExists(to); + DirectoryTree toDir(to); + + if (!toDir) return false; + + bool success(true); + + auto visitor = [to,&success](const DirectoryTree*, const DirectoryEntry& entry) + { + auto newPath = Aws::FileSystem::Join(to, entry.relativePath); + + if (entry.fileType == Aws::FileSystem::FileType::File) + { + Aws::OFStream copyOutStream(newPath.c_str()); + Aws::IFStream originalStream(entry.path.c_str()); + + if(!copyOutStream.good() || !originalStream.good()) + { + success = false; + return false; + } + + std::copy(std::istreambuf_iterator<char>(originalStream), + std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(copyOutStream)); + } + else if (entry.fileType == Aws::FileSystem::FileType::Directory) + { + success = CreateDirectoryIfNotExists(newPath.c_str()); + return success; + } + + return success; + }; + + fromDir.TraverseDepthFirst(visitor); + return success; + } + + bool DeepDeleteDirectory(const char* toDelete) + { + bool success(true); + + //scope this to a new stack frame, because we won't be able to delete the root directory + //unless the directory handle has closed. + { + DirectoryTree delDir(toDelete); + + if (!delDir) return false; + + auto visitor = [&success](const DirectoryTree*, const DirectoryEntry& entry) + { + if (entry.fileType == FileType::File) + { + success = RemoveFileIfExists(entry.path.c_str()); + } + else + { + success = RemoveDirectoryIfExists(entry.path.c_str()); + } + + return success; + }; + + delDir.TraverseDepthFirst(visitor, true); + } + + if (success) + { + success = RemoveDirectoryIfExists(toDelete); + } + + return success; + } + + Directory::Directory(const Aws::String& path, const Aws::String& relativePath) + { + auto trimmedPath = Utils::StringUtils::Trim(path.c_str()); + auto trimmedRelativePath = Utils::StringUtils::Trim(relativePath.c_str()); + + if (!trimmedPath.empty() && trimmedPath[trimmedPath.length() - 1] == PATH_DELIM) + { + m_directoryEntry.path = trimmedPath.substr(0, trimmedPath.length() - 1); + } + else + { + m_directoryEntry.path = trimmedPath; + } + + if (!trimmedRelativePath.empty() && trimmedRelativePath[trimmedRelativePath.length() - 1] == PATH_DELIM) + { + m_directoryEntry.relativePath = trimmedRelativePath.substr(0, trimmedRelativePath.length() - 1); + } + else { - if (entry.fileType == Aws::FileSystem::FileType::File) - { - filesVector.push_back(entry.path); - } - return true; - }; - tree.TraverseBreadthFirst(visitor); - return filesVector; - } - - DirectoryTree::DirectoryTree(const Aws::String& path) - { - m_dir = OpenDirectory(path); - } - - DirectoryTree::operator bool() const - { - return m_dir->operator bool(); - } - - bool DirectoryTree::operator==(DirectoryTree& other) - { - return Diff(other).size() == 0; - } - - bool DirectoryTree::operator==(const Aws::String& path) - { - return *this == DirectoryTree(path); - } - - Aws::Map<Aws::String, DirectoryEntry> DirectoryTree::Diff(DirectoryTree& other) - { - Aws::Map<Aws::String, DirectoryEntry> thisEntries; - auto thisTraversal = [&thisEntries](const DirectoryTree*, const DirectoryEntry& entry) - { - thisEntries[entry.relativePath] = entry; - return true; - }; - - Aws::Map<Aws::String, DirectoryEntry> otherEntries; - auto otherTraversal = [&thisEntries, &otherEntries](const DirectoryTree*, const DirectoryEntry& entry) - { - auto thisEntry = thisEntries.find(entry.relativePath); - if (thisEntry != thisEntries.end()) - { - thisEntries.erase(entry.relativePath); - } - else - { - otherEntries[entry.relativePath] = entry; - } - - return true; - }; - - TraverseDepthFirst(thisTraversal); - other.TraverseDepthFirst(otherTraversal); - - thisEntries.insert(otherEntries.begin(), otherEntries.end()); - return thisEntries; - } - - void DirectoryTree::TraverseDepthFirst(const DirectoryEntryVisitor& visitor, bool postOrderTraversal) - { - TraverseDepthFirst(*m_dir, visitor, postOrderTraversal); - m_dir = OpenDirectory(m_dir->GetPath()); - } - - void DirectoryTree::TraverseBreadthFirst(const DirectoryEntryVisitor& visitor) - { - TraverseBreadthFirst(*m_dir, visitor); - m_dir = OpenDirectory(m_dir->GetPath()); - } - - void DirectoryTree::TraverseBreadthFirst(Directory& dir, const DirectoryEntryVisitor& visitor) - { - if (!dir) - { - return; - } - - Aws::Queue<DirectoryEntry> queue; - while (DirectoryEntry&& entry = dir.Next()) - { - queue.push(std::move(entry)); - } - - while (queue.size() > 0) - { - auto entry = queue.front(); - queue.pop(); - if(visitor(this, entry)) - { - if(entry.fileType == FileType::Directory) - { - auto currentDir = dir.Descend(entry); - - while (DirectoryEntry&& dirEntry = currentDir->Next()) - { - queue.push(std::move(dirEntry)); - } - } - } - else - { - return; - } - } - } - - bool DirectoryTree::TraverseDepthFirst(Directory& dir, const DirectoryEntryVisitor& visitor, bool postOrder) - { - if (!dir) - { - return true; - } - - bool exitTraversal(false); - DirectoryEntry entry; - - while ((entry = dir.Next()) && !exitTraversal) - { - if(!postOrder) - { - if(!visitor(this, entry)) - { - return false; - } - } - - if (entry.fileType == FileType::Directory) - { - auto subDir = dir.Descend(entry); - exitTraversal = !TraverseDepthFirst(*subDir, visitor, postOrder); + m_directoryEntry.relativePath = trimmedRelativePath; + } + } + + Aws::UniquePtr<Directory> Directory::Descend(const DirectoryEntry& directoryEntry) + { + assert(directoryEntry.fileType != FileType::File); + return OpenDirectory(directoryEntry.path, directoryEntry.relativePath); + } + + Aws::Vector<Aws::String> Directory::GetAllFilePathsInDirectory(const Aws::String& path) + { + Aws::FileSystem::DirectoryTree tree(path); + Aws::Vector<Aws::String> filesVector; + auto visitor = [&](const Aws::FileSystem::DirectoryTree*, const Aws::FileSystem::DirectoryEntry& entry) + { + if (entry.fileType == Aws::FileSystem::FileType::File) + { + filesVector.push_back(entry.path); } - - if (postOrder) - { - if (!visitor(this, entry)) - { - return false; - } - } - } - - return !exitTraversal; - } - - } -} + return true; + }; + tree.TraverseBreadthFirst(visitor); + return filesVector; + } + + DirectoryTree::DirectoryTree(const Aws::String& path) + { + m_dir = OpenDirectory(path); + } + + DirectoryTree::operator bool() const + { + return m_dir->operator bool(); + } + + bool DirectoryTree::operator==(DirectoryTree& other) + { + return Diff(other).size() == 0; + } + + bool DirectoryTree::operator==(const Aws::String& path) + { + return *this == DirectoryTree(path); + } + + Aws::Map<Aws::String, DirectoryEntry> DirectoryTree::Diff(DirectoryTree& other) + { + Aws::Map<Aws::String, DirectoryEntry> thisEntries; + auto thisTraversal = [&thisEntries](const DirectoryTree*, const DirectoryEntry& entry) + { + thisEntries[entry.relativePath] = entry; + return true; + }; + + Aws::Map<Aws::String, DirectoryEntry> otherEntries; + auto otherTraversal = [&thisEntries, &otherEntries](const DirectoryTree*, const DirectoryEntry& entry) + { + auto thisEntry = thisEntries.find(entry.relativePath); + if (thisEntry != thisEntries.end()) + { + thisEntries.erase(entry.relativePath); + } + else + { + otherEntries[entry.relativePath] = entry; + } + + return true; + }; + + TraverseDepthFirst(thisTraversal); + other.TraverseDepthFirst(otherTraversal); + + thisEntries.insert(otherEntries.begin(), otherEntries.end()); + return thisEntries; + } + + void DirectoryTree::TraverseDepthFirst(const DirectoryEntryVisitor& visitor, bool postOrderTraversal) + { + TraverseDepthFirst(*m_dir, visitor, postOrderTraversal); + m_dir = OpenDirectory(m_dir->GetPath()); + } + + void DirectoryTree::TraverseBreadthFirst(const DirectoryEntryVisitor& visitor) + { + TraverseBreadthFirst(*m_dir, visitor); + m_dir = OpenDirectory(m_dir->GetPath()); + } + + void DirectoryTree::TraverseBreadthFirst(Directory& dir, const DirectoryEntryVisitor& visitor) + { + if (!dir) + { + return; + } + + Aws::Queue<DirectoryEntry> queue; + while (DirectoryEntry&& entry = dir.Next()) + { + queue.push(std::move(entry)); + } + + while (queue.size() > 0) + { + auto entry = queue.front(); + queue.pop(); + if(visitor(this, entry)) + { + if(entry.fileType == FileType::Directory) + { + auto currentDir = dir.Descend(entry); + + while (DirectoryEntry&& dirEntry = currentDir->Next()) + { + queue.push(std::move(dirEntry)); + } + } + } + else + { + return; + } + } + } + + bool DirectoryTree::TraverseDepthFirst(Directory& dir, const DirectoryEntryVisitor& visitor, bool postOrder) + { + if (!dir) + { + return true; + } + + bool exitTraversal(false); + DirectoryEntry entry; + + while ((entry = dir.Next()) && !exitTraversal) + { + if(!postOrder) + { + if(!visitor(this, entry)) + { + return false; + } + } + + if (entry.fileType == FileType::Directory) + { + auto subDir = dir.Descend(entry); + exitTraversal = !TraverseDepthFirst(*subDir, visitor, postOrder); + } + + if (postOrder) + { + if (!visitor(this, entry)) + { + return false; + } + } + } + + return !exitTraversal; + } + + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp index eaeba1d910..3d93de1b97 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp @@ -2,32 +2,32 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/EnumParseOverflowContainer.h> -#include <aws/core/utils/logging/LogMacros.h> - -using namespace Aws::Utils; -using namespace Aws::Utils::Threading; - -static const char LOG_TAG[] = "EnumParseOverflowContainer"; - -const Aws::String& EnumParseOverflowContainer::RetrieveOverflow(int hashCode) const -{ - ReaderLockGuard guard(m_overflowLock); - auto foundIter = m_overflowMap.find(hashCode); - if (foundIter != m_overflowMap.end()) - { - AWS_LOGSTREAM_DEBUG(LOG_TAG, "Found value " << foundIter->second << " for hash " << hashCode << " from enum overflow container."); - return foundIter->second; - } - - AWS_LOGSTREAM_ERROR(LOG_TAG, "Could not find a previously stored overflow value for hash " << hashCode << ". This will likely break some requests."); - return m_emptyString; -} - -void EnumParseOverflowContainer::StoreOverflow(int hashCode, const Aws::String& value) -{ - WriterLockGuard guard(m_overflowLock); - AWS_LOGSTREAM_WARN(LOG_TAG, "Encountered enum member " << value << " which is not modeled in your clients. You should update your clients when you get a chance."); - m_overflowMap[hashCode] = value; -} + +#include <aws/core/utils/EnumParseOverflowContainer.h> +#include <aws/core/utils/logging/LogMacros.h> + +using namespace Aws::Utils; +using namespace Aws::Utils::Threading; + +static const char LOG_TAG[] = "EnumParseOverflowContainer"; + +const Aws::String& EnumParseOverflowContainer::RetrieveOverflow(int hashCode) const +{ + ReaderLockGuard guard(m_overflowLock); + auto foundIter = m_overflowMap.find(hashCode); + if (foundIter != m_overflowMap.end()) + { + AWS_LOGSTREAM_DEBUG(LOG_TAG, "Found value " << foundIter->second << " for hash " << hashCode << " from enum overflow container."); + return foundIter->second; + } + + AWS_LOGSTREAM_ERROR(LOG_TAG, "Could not find a previously stored overflow value for hash " << hashCode << ". This will likely break some requests."); + return m_emptyString; +} + +void EnumParseOverflowContainer::StoreOverflow(int hashCode, const Aws::String& value) +{ + WriterLockGuard guard(m_overflowLock); + AWS_LOGSTREAM_WARN(LOG_TAG, "Encountered enum member " << value << " which is not modeled in your clients. You should update your clients when you get a chance."); + m_overflowMap[hashCode] = value; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp index c47f750960..18e9f8dd28 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp @@ -1,51 +1,51 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/utils/FileSystemUtils.h> - -using namespace Aws::Utils; - -Aws::String PathUtils::GetFileNameFromPathWithoutExt(const Aws::String& path) -{ - Aws::String fileName = Aws::Utils::PathUtils::GetFileNameFromPathWithExt(path); - size_t endPos = fileName.find_last_of('.'); - if (endPos == std::string::npos) - { - return fileName; - } - if (endPos == 0) // fileName is "." - { + */ + +#include <aws/core/utils/FileSystemUtils.h> + +using namespace Aws::Utils; + +Aws::String PathUtils::GetFileNameFromPathWithoutExt(const Aws::String& path) +{ + Aws::String fileName = Aws::Utils::PathUtils::GetFileNameFromPathWithExt(path); + size_t endPos = fileName.find_last_of('.'); + if (endPos == std::string::npos) + { + return fileName; + } + if (endPos == 0) // fileName is "." + { return {}; - } - - return fileName.substr(0, endPos); -} - -Aws::String PathUtils::GetFileNameFromPathWithExt(const Aws::String& path) -{ - if (path.size() == 0) - { - return path; - } - - size_t startPos = path.find_last_of(Aws::FileSystem::PATH_DELIM); - if (startPos == path.size() - 1) - { + } + + return fileName.substr(0, endPos); +} + +Aws::String PathUtils::GetFileNameFromPathWithExt(const Aws::String& path) +{ + if (path.size() == 0) + { + return path; + } + + size_t startPos = path.find_last_of(Aws::FileSystem::PATH_DELIM); + if (startPos == path.size() - 1) + { return {}; - } - - if (startPos == std::string::npos) - { - startPos = 0; - } - else - { - startPos += 1; - } - - size_t endPos = path.size() - 1; - - return path.substr(startPos, endPos - startPos + 1); + } + + if (startPos == std::string::npos) + { + startPos = 0; + } + else + { + startPos += 1; + } + + size_t endPos = path.size() - 1; + + return path.substr(startPos, endPos - startPos + 1); } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp index 6e78b546ab..66f69a3b4b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp @@ -2,35 +2,35 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/utils/GetTheLights.h> -#include <cassert> - -namespace Aws -{ - namespace Utils - { - GetTheLights::GetTheLights() : m_value(0) - { - } - - void GetTheLights::EnterRoom(std::function<void()> &&callable) - { - int cpy = ++m_value; - assert(cpy > 0); - if(cpy == 1) - { - callable(); - } - } - - void GetTheLights::LeaveRoom(std::function<void()> &&callable) - { - int cpy = --m_value; - assert(cpy >= 0); - if(cpy == 0) - { - callable(); - } - } - } -}
\ No newline at end of file +#include <aws/core/utils/GetTheLights.h> +#include <cassert> + +namespace Aws +{ + namespace Utils + { + GetTheLights::GetTheLights() : m_value(0) + { + } + + void GetTheLights::EnterRoom(std::function<void()> &&callable) + { + int cpy = ++m_value; + assert(cpy > 0); + if(cpy == 1) + { + callable(); + } + } + + void GetTheLights::LeaveRoom(std::function<void()> &&callable) + { + int cpy = --m_value; + assert(cpy >= 0); + if(cpy == 0) + { + callable(); + } + } + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp index 147bddf33e..b656c72432 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp @@ -2,235 +2,235 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/logging/LogMacros.h> -#include <aws/core/utils/HashingUtils.h> + +#include <aws/core/utils/logging/LogMacros.h> +#include <aws/core/utils/HashingUtils.h> #include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/base64/Base64.h> -#include <aws/core/utils/crypto/Sha256.h> -#include <aws/core/utils/crypto/Sha256HMAC.h> -#include <aws/core/utils/crypto/MD5.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <aws/core/utils/memory/stl/AWSList.h> - -#include <iomanip> - -using namespace Aws::Utils; -using namespace Aws::Utils::Base64; -using namespace Aws::Utils::Crypto; - -// internal buffers are fixed-size arrays, so this is harmless memory-management wise -static Aws::Utils::Base64::Base64 s_base64; - -// Aws Glacier Tree Hash calculates hash value for each 1MB data -const static size_t TREE_HASH_ONE_MB = 1024 * 1024; - -Aws::String HashingUtils::Base64Encode(const ByteBuffer& message) -{ - return s_base64.Encode(message); -} - -ByteBuffer HashingUtils::Base64Decode(const Aws::String& encodedMessage) -{ - return s_base64.Decode(encodedMessage); -} - -ByteBuffer HashingUtils::CalculateSHA256HMAC(const ByteBuffer& toSign, const ByteBuffer& secret) -{ - Sha256HMAC hash; - return hash.Calculate(toSign, secret).GetResult(); -} - -ByteBuffer HashingUtils::CalculateSHA256(const Aws::String& str) -{ - Sha256 hash; - return hash.Calculate(str).GetResult(); -} - -ByteBuffer HashingUtils::CalculateSHA256(Aws::IOStream& stream) -{ - Sha256 hash; - return hash.Calculate(stream).GetResult(); -} - -/** - * This function is only used by HashingUtils::CalculateSHA256TreeHash() in this cpp file - * It's a helper function be used to compute the TreeHash defined at: - * http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html - */ -static ByteBuffer TreeHashFinalCompute(Aws::List<ByteBuffer>& input) -{ - Sha256 hash; - assert(input.size() != 0); - - // O(n) time complexity of merging (n + n/2 + n/4 + n/8 +...+ 1) - while (input.size() > 1) - { - auto iter = input.begin(); - // if only one element left, just left it there - while (std::next(iter) != input.end()) - { - // if >= two elements - Aws::String str(reinterpret_cast<char*>(iter->GetUnderlyingData()), iter->GetLength()); - // list erase returns iterator of next element next to the erased element or end() if erased the last one - // list insert inserts element before pos, here we erase two elements, and insert a new element - iter = input.erase(iter); - str.append(reinterpret_cast<char*>(iter->GetUnderlyingData()), iter->GetLength()); - iter = input.erase(iter); - input.insert(iter, hash.Calculate(str).GetResult()); - - if (iter == input.end()) break; - } // while process to the last element - } // while the list has only one element left - - return *(input.begin()); -} - -ByteBuffer HashingUtils::CalculateSHA256TreeHash(const Aws::String& str) -{ - Sha256 hash; - if (str.size() == 0) - { - return hash.Calculate(str).GetResult(); - } - - Aws::List<ByteBuffer> input; - size_t pos = 0; - while (pos < str.size()) - { - input.push_back(hash.Calculate(Aws::String(str, pos, TREE_HASH_ONE_MB)).GetResult()); - pos += TREE_HASH_ONE_MB; - } - - return TreeHashFinalCompute(input); -} - -ByteBuffer HashingUtils::CalculateSHA256TreeHash(Aws::IOStream& stream) -{ - Sha256 hash; - Aws::List<ByteBuffer> input; - auto currentPos = stream.tellg(); - if (currentPos == std::ios::pos_type(-1)) - { - currentPos = 0; - stream.clear(); - } - stream.seekg(0, stream.beg); - Array<char> streamBuffer(TREE_HASH_ONE_MB); - while (stream.good()) - { - stream.read(streamBuffer.GetUnderlyingData(), TREE_HASH_ONE_MB); - auto bytesRead = stream.gcount(); - if (bytesRead > 0) - { - input.push_back(hash.Calculate(Aws::String(reinterpret_cast<char*>(streamBuffer.GetUnderlyingData()), static_cast<size_t>(bytesRead))).GetResult()); - } - } - stream.clear(); - stream.seekg(currentPos, stream.beg); - - if (input.size() == 0) - { - return hash.Calculate("").GetResult(); - } - return TreeHashFinalCompute(input); -} - -Aws::String HashingUtils::HexEncode(const ByteBuffer& message) -{ +#include <aws/core/utils/base64/Base64.h> +#include <aws/core/utils/crypto/Sha256.h> +#include <aws/core/utils/crypto/Sha256HMAC.h> +#include <aws/core/utils/crypto/MD5.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <aws/core/utils/memory/stl/AWSList.h> + +#include <iomanip> + +using namespace Aws::Utils; +using namespace Aws::Utils::Base64; +using namespace Aws::Utils::Crypto; + +// internal buffers are fixed-size arrays, so this is harmless memory-management wise +static Aws::Utils::Base64::Base64 s_base64; + +// Aws Glacier Tree Hash calculates hash value for each 1MB data +const static size_t TREE_HASH_ONE_MB = 1024 * 1024; + +Aws::String HashingUtils::Base64Encode(const ByteBuffer& message) +{ + return s_base64.Encode(message); +} + +ByteBuffer HashingUtils::Base64Decode(const Aws::String& encodedMessage) +{ + return s_base64.Decode(encodedMessage); +} + +ByteBuffer HashingUtils::CalculateSHA256HMAC(const ByteBuffer& toSign, const ByteBuffer& secret) +{ + Sha256HMAC hash; + return hash.Calculate(toSign, secret).GetResult(); +} + +ByteBuffer HashingUtils::CalculateSHA256(const Aws::String& str) +{ + Sha256 hash; + return hash.Calculate(str).GetResult(); +} + +ByteBuffer HashingUtils::CalculateSHA256(Aws::IOStream& stream) +{ + Sha256 hash; + return hash.Calculate(stream).GetResult(); +} + +/** + * This function is only used by HashingUtils::CalculateSHA256TreeHash() in this cpp file + * It's a helper function be used to compute the TreeHash defined at: + * http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html + */ +static ByteBuffer TreeHashFinalCompute(Aws::List<ByteBuffer>& input) +{ + Sha256 hash; + assert(input.size() != 0); + + // O(n) time complexity of merging (n + n/2 + n/4 + n/8 +...+ 1) + while (input.size() > 1) + { + auto iter = input.begin(); + // if only one element left, just left it there + while (std::next(iter) != input.end()) + { + // if >= two elements + Aws::String str(reinterpret_cast<char*>(iter->GetUnderlyingData()), iter->GetLength()); + // list erase returns iterator of next element next to the erased element or end() if erased the last one + // list insert inserts element before pos, here we erase two elements, and insert a new element + iter = input.erase(iter); + str.append(reinterpret_cast<char*>(iter->GetUnderlyingData()), iter->GetLength()); + iter = input.erase(iter); + input.insert(iter, hash.Calculate(str).GetResult()); + + if (iter == input.end()) break; + } // while process to the last element + } // while the list has only one element left + + return *(input.begin()); +} + +ByteBuffer HashingUtils::CalculateSHA256TreeHash(const Aws::String& str) +{ + Sha256 hash; + if (str.size() == 0) + { + return hash.Calculate(str).GetResult(); + } + + Aws::List<ByteBuffer> input; + size_t pos = 0; + while (pos < str.size()) + { + input.push_back(hash.Calculate(Aws::String(str, pos, TREE_HASH_ONE_MB)).GetResult()); + pos += TREE_HASH_ONE_MB; + } + + return TreeHashFinalCompute(input); +} + +ByteBuffer HashingUtils::CalculateSHA256TreeHash(Aws::IOStream& stream) +{ + Sha256 hash; + Aws::List<ByteBuffer> input; + auto currentPos = stream.tellg(); + if (currentPos == std::ios::pos_type(-1)) + { + currentPos = 0; + stream.clear(); + } + stream.seekg(0, stream.beg); + Array<char> streamBuffer(TREE_HASH_ONE_MB); + while (stream.good()) + { + stream.read(streamBuffer.GetUnderlyingData(), TREE_HASH_ONE_MB); + auto bytesRead = stream.gcount(); + if (bytesRead > 0) + { + input.push_back(hash.Calculate(Aws::String(reinterpret_cast<char*>(streamBuffer.GetUnderlyingData()), static_cast<size_t>(bytesRead))).GetResult()); + } + } + stream.clear(); + stream.seekg(currentPos, stream.beg); + + if (input.size() == 0) + { + return hash.Calculate("").GetResult(); + } + return TreeHashFinalCompute(input); +} + +Aws::String HashingUtils::HexEncode(const ByteBuffer& message) +{ Aws::String encoded; encoded.reserve(2 * message.GetLength()); - - for (unsigned i = 0; i < message.GetLength(); ++i) - { + + for (unsigned i = 0; i < message.GetLength(); ++i) + { encoded.push_back("0123456789abcdef"[message[i] >> 4]); encoded.push_back("0123456789abcdef"[message[i] & 0x0f]); - } - + } + return encoded; -} - -ByteBuffer HashingUtils::HexDecode(const Aws::String& str) -{ - //number of characters should be even - assert(str.length() % 2 == 0); - assert(str.length() >= 2); - - if(str.length() < 2 || str.length() % 2 != 0) - { - return ByteBuffer(); - } - - size_t strLength = str.length(); - size_t readIndex = 0; - - if(str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) - { - strLength -= 2; - readIndex = 2; - } - - ByteBuffer hexBuffer(strLength / 2); - size_t bufferIndex = 0; - - for (size_t i = readIndex; i < str.length(); i += 2) - { +} + +ByteBuffer HashingUtils::HexDecode(const Aws::String& str) +{ + //number of characters should be even + assert(str.length() % 2 == 0); + assert(str.length() >= 2); + + if(str.length() < 2 || str.length() % 2 != 0) + { + return ByteBuffer(); + } + + size_t strLength = str.length(); + size_t readIndex = 0; + + if(str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + { + strLength -= 2; + readIndex = 2; + } + + ByteBuffer hexBuffer(strLength / 2); + size_t bufferIndex = 0; + + for (size_t i = readIndex; i < str.length(); i += 2) + { if(!StringUtils::IsAlnum(str[i]) || !StringUtils::IsAlnum(str[i + 1])) - { - //contains non-hex characters - assert(0); - } - - char firstChar = str[i]; - uint8_t distance = firstChar - '0'; - - if(isalpha(firstChar)) - { - firstChar = static_cast<char>(toupper(firstChar)); - distance = firstChar - 'A' + 10; - } - - unsigned char val = distance * 16; - - char secondChar = str[i + 1]; - distance = secondChar - '0'; - - if(isalpha(secondChar)) - { - secondChar = static_cast<char>(toupper(secondChar)); - distance = secondChar - 'A' + 10; - } - - val += distance; - hexBuffer[bufferIndex++] = val; - } - - return hexBuffer; -} - -ByteBuffer HashingUtils::CalculateMD5(const Aws::String& str) -{ - MD5 hash; - return hash.Calculate(str).GetResult(); -} - -ByteBuffer HashingUtils::CalculateMD5(Aws::IOStream& stream) -{ - MD5 hash; - return hash.Calculate(stream).GetResult(); -} - -int HashingUtils::HashString(const char* strToHash) -{ - if (!strToHash) - return 0; - + { + //contains non-hex characters + assert(0); + } + + char firstChar = str[i]; + uint8_t distance = firstChar - '0'; + + if(isalpha(firstChar)) + { + firstChar = static_cast<char>(toupper(firstChar)); + distance = firstChar - 'A' + 10; + } + + unsigned char val = distance * 16; + + char secondChar = str[i + 1]; + distance = secondChar - '0'; + + if(isalpha(secondChar)) + { + secondChar = static_cast<char>(toupper(secondChar)); + distance = secondChar - 'A' + 10; + } + + val += distance; + hexBuffer[bufferIndex++] = val; + } + + return hexBuffer; +} + +ByteBuffer HashingUtils::CalculateMD5(const Aws::String& str) +{ + MD5 hash; + return hash.Calculate(str).GetResult(); +} + +ByteBuffer HashingUtils::CalculateMD5(Aws::IOStream& stream) +{ + MD5 hash; + return hash.Calculate(stream).GetResult(); +} + +int HashingUtils::HashString(const char* strToHash) +{ + if (!strToHash) + return 0; + unsigned hash = 0; - while (char charValue = *strToHash++) - { - hash = charValue + 31 * hash; - } - - return hash; -} + while (char charValue = *strToHash++) + { + hash = charValue + 31 * hash; + } + + return hash; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp index e1deb3f046..f1b152b470 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp @@ -2,108 +2,108 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> -#include <algorithm> -#include <iomanip> -#include <cstdlib> -#include <cstdio> -#include <cstring> -#include <functional> - -#ifdef _WIN32 -#include <Windows.h> -#endif - -using namespace Aws::Utils; - -void StringUtils::Replace(Aws::String& s, const char* search, const char* replace) -{ - if(!search || !replace) - { - return; - } - - size_t replaceLength = strlen(replace); - size_t searchLength = strlen(search); - - for (std::size_t pos = 0;; pos += replaceLength) - { - pos = s.find(search, pos); - if (pos == Aws::String::npos) - break; - - s.erase(pos, searchLength); - s.insert(pos, replace); - } -} - - -Aws::String StringUtils::ToLower(const char* source) -{ - Aws::String copy; - size_t sourceLength = strlen(source); - copy.resize(sourceLength); - //appease the latest whims of the VC++ 2017 gods - std::transform(source, source + sourceLength, copy.begin(), [](unsigned char c) { return (char)::tolower(c); }); - - return copy; -} - - -Aws::String StringUtils::ToUpper(const char* source) -{ - Aws::String copy; - size_t sourceLength = strlen(source); - copy.resize(sourceLength); - //appease the latest whims of the VC++ 2017 gods - std::transform(source, source + sourceLength, copy.begin(), [](unsigned char c) { return (char)::toupper(c); }); - - return copy; -} - - -bool StringUtils::CaselessCompare(const char* value1, const char* value2) -{ - Aws::String value1Lower = ToLower(value1); - Aws::String value2Lower = ToLower(value2); - - return value1Lower == value2Lower; -} - -Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn) -{ + + +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> +#include <algorithm> +#include <iomanip> +#include <cstdlib> +#include <cstdio> +#include <cstring> +#include <functional> + +#ifdef _WIN32 +#include <Windows.h> +#endif + +using namespace Aws::Utils; + +void StringUtils::Replace(Aws::String& s, const char* search, const char* replace) +{ + if(!search || !replace) + { + return; + } + + size_t replaceLength = strlen(replace); + size_t searchLength = strlen(search); + + for (std::size_t pos = 0;; pos += replaceLength) + { + pos = s.find(search, pos); + if (pos == Aws::String::npos) + break; + + s.erase(pos, searchLength); + s.insert(pos, replace); + } +} + + +Aws::String StringUtils::ToLower(const char* source) +{ + Aws::String copy; + size_t sourceLength = strlen(source); + copy.resize(sourceLength); + //appease the latest whims of the VC++ 2017 gods + std::transform(source, source + sourceLength, copy.begin(), [](unsigned char c) { return (char)::tolower(c); }); + + return copy; +} + + +Aws::String StringUtils::ToUpper(const char* source) +{ + Aws::String copy; + size_t sourceLength = strlen(source); + copy.resize(sourceLength); + //appease the latest whims of the VC++ 2017 gods + std::transform(source, source + sourceLength, copy.begin(), [](unsigned char c) { return (char)::toupper(c); }); + + return copy; +} + + +bool StringUtils::CaselessCompare(const char* value1, const char* value2) +{ + Aws::String value1Lower = ToLower(value1); + Aws::String value2Lower = ToLower(value2); + + return value1Lower == value2Lower; +} + +Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn) +{ return Split(toSplit, splitOn, SIZE_MAX, SplitOptions::NOT_SET); -} - +} + Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, SplitOptions option) { return Split(toSplit, splitOn, SIZE_MAX, option); } -Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts) -{ +Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts) +{ return Split(toSplit, splitOn, numOfTargetParts, SplitOptions::NOT_SET); } Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts, SplitOptions option) { - Aws::Vector<Aws::String> returnValues; - Aws::StringStream input(toSplit); - Aws::String item; - - while(returnValues.size() < numOfTargetParts - 1 && std::getline(input, item, splitOn)) - { + Aws::Vector<Aws::String> returnValues; + Aws::StringStream input(toSplit); + Aws::String item; + + while(returnValues.size() < numOfTargetParts - 1 && std::getline(input, item, splitOn)) + { if (!item.empty() || option == SplitOptions::INCLUDE_EMPTY_ENTRIES) - { - returnValues.emplace_back(std::move(item)); - } - } - + { + returnValues.emplace_back(std::move(item)); + } + } + if (std::getline(input, item, static_cast<char>(EOF))) - { + { if (option != SplitOptions::INCLUDE_EMPTY_ENTRIES) { // Trim all leading delimiters. @@ -118,103 +118,103 @@ Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char spl returnValues.emplace_back(std::move(item)); } - } + } // To handle the case when there are trailing delimiters. else if (!toSplit.empty() && toSplit.back() == splitOn && option == SplitOptions::INCLUDE_EMPTY_ENTRIES) { returnValues.emplace_back(); } - return returnValues; -} - -Aws::Vector<Aws::String> StringUtils::SplitOnLine(const Aws::String& toSplit) -{ - Aws::StringStream input(toSplit); - Aws::Vector<Aws::String> returnValues; - Aws::String item; - - while (std::getline(input, item)) - { - if (item.size() > 0) - { - returnValues.push_back(item); - } - } - - return returnValues; -} - - -Aws::String StringUtils::URLEncode(const char* unsafe) -{ - Aws::StringStream escaped; - escaped.fill('0'); - escaped << std::hex << std::uppercase; - - size_t unsafeLength = strlen(unsafe); - for (auto i = unsafe, n = unsafe + unsafeLength; i != n; ++i) - { + return returnValues; +} + +Aws::Vector<Aws::String> StringUtils::SplitOnLine(const Aws::String& toSplit) +{ + Aws::StringStream input(toSplit); + Aws::Vector<Aws::String> returnValues; + Aws::String item; + + while (std::getline(input, item)) + { + if (item.size() > 0) + { + returnValues.push_back(item); + } + } + + return returnValues; +} + + +Aws::String StringUtils::URLEncode(const char* unsafe) +{ + Aws::StringStream escaped; + escaped.fill('0'); + escaped << std::hex << std::uppercase; + + size_t unsafeLength = strlen(unsafe); + for (auto i = unsafe, n = unsafe + unsafeLength; i != n; ++i) + { char c = *i; if (IsAlnum(c) || c == '-' || c == '_' || c == '.' || c == '~') - { - escaped << (char)c; - } - else - { - //this unsigned char cast allows us to handle unicode characters. - escaped << '%' << std::setw(2) << int((unsigned char)c) << std::setw(0); - } - } - - return escaped.str(); -} - -Aws::String StringUtils::UTF8Escape(const char* unicodeString, const char* delimiter) -{ - Aws::StringStream escaped; - escaped.fill('0'); - escaped << std::hex << std::uppercase; - - size_t unsafeLength = strlen(unicodeString); - for (auto i = unicodeString, n = unicodeString + unsafeLength; i != n; ++i) - { - int c = *i; - if (c >= ' ' && c < 127 ) - { - escaped << (char)c; - } - else - { - //this unsigned char cast allows us to handle unicode characters. - escaped << delimiter << std::setw(2) << int((unsigned char)c) << std::setw(0); - } - } - - return escaped.str(); -} - -Aws::String StringUtils::URLEncode(double unsafe) -{ - char buffer[32]; -#if defined(_MSC_VER) && _MSC_VER < 1900 - _snprintf_s(buffer, sizeof(buffer), _TRUNCATE, "%g", unsafe); -#else - snprintf(buffer, sizeof(buffer), "%g", unsafe); -#endif - - return StringUtils::URLEncode(buffer); -} - - -Aws::String StringUtils::URLDecode(const char* safe) -{ + { + escaped << (char)c; + } + else + { + //this unsigned char cast allows us to handle unicode characters. + escaped << '%' << std::setw(2) << int((unsigned char)c) << std::setw(0); + } + } + + return escaped.str(); +} + +Aws::String StringUtils::UTF8Escape(const char* unicodeString, const char* delimiter) +{ + Aws::StringStream escaped; + escaped.fill('0'); + escaped << std::hex << std::uppercase; + + size_t unsafeLength = strlen(unicodeString); + for (auto i = unicodeString, n = unicodeString + unsafeLength; i != n; ++i) + { + int c = *i; + if (c >= ' ' && c < 127 ) + { + escaped << (char)c; + } + else + { + //this unsigned char cast allows us to handle unicode characters. + escaped << delimiter << std::setw(2) << int((unsigned char)c) << std::setw(0); + } + } + + return escaped.str(); +} + +Aws::String StringUtils::URLEncode(double unsafe) +{ + char buffer[32]; +#if defined(_MSC_VER) && _MSC_VER < 1900 + _snprintf_s(buffer, sizeof(buffer), _TRUNCATE, "%g", unsafe); +#else + snprintf(buffer, sizeof(buffer), "%g", unsafe); +#endif + + return StringUtils::URLEncode(buffer); +} + + +Aws::String StringUtils::URLDecode(const char* safe) +{ Aws::String unescaped; - + for (; *safe; safe++) - { + { switch(*safe) - { + { case '%': { int hex = 0; @@ -276,12 +276,12 @@ Aws::String StringUtils::URLDecode(const char* safe) default: unescaped.push_back(*safe); break; - } - } - + } + } + return unescaped; -} - +} + static bool IsSpace(int ch) { if (ch < -1 || ch > 255) @@ -292,130 +292,130 @@ static bool IsSpace(int ch) return ::isspace(ch) != 0; } -Aws::String StringUtils::LTrim(const char* source) -{ - Aws::String copy(source); +Aws::String StringUtils::LTrim(const char* source) +{ + Aws::String copy(source); copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](int ch) { return !IsSpace(ch); })); - return copy; -} - -// trim from end -Aws::String StringUtils::RTrim(const char* source) -{ - Aws::String copy(source); + return copy; +} + +// trim from end +Aws::String StringUtils::RTrim(const char* source) +{ + Aws::String copy(source); copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](int ch) { return !IsSpace(ch); }).base(), copy.end()); - return copy; -} - -// trim from both ends -Aws::String StringUtils::Trim(const char* source) -{ - return LTrim(RTrim(source).c_str()); -} - -long long StringUtils::ConvertToInt64(const char* source) -{ - if(!source) - { - return 0; - } - -#ifdef __ANDROID__ - return atoll(source); -#else - return std::atoll(source); -#endif // __ANDROID__ -} - - -long StringUtils::ConvertToInt32(const char* source) -{ - if (!source) - { - return 0; - } - - return std::atol(source); -} - - -bool StringUtils::ConvertToBool(const char* source) -{ - if(!source) - { - return false; - } - - Aws::String strValue = ToLower(source); - if(strValue == "true" || strValue == "1") - { - return true; - } - - return false; -} - - -double StringUtils::ConvertToDouble(const char* source) -{ - if(!source) - { - return 0.0; - } - - return std::strtod(source, NULL); -} - -#ifdef _WIN32 - -Aws::WString StringUtils::ToWString(const char* source) -{ - const auto len = static_cast<int>(std::strlen(source)); - Aws::WString outString; - outString.resize(len); // there is no way UTF-16 would require _more_ code-points than UTF-8 for the _same_ string - const auto result = MultiByteToWideChar(CP_UTF8 /*CodePage*/, - 0 /*dwFlags*/, - source /*lpMultiByteStr*/, - len /*cbMultiByte*/, - &outString[0] /*lpWideCharStr*/, - static_cast<int>(outString.length())/*cchWideChar*/); - if (!result) - { - return L""; - } - outString.resize(result); - return outString; -} - -Aws::String StringUtils::FromWString(const wchar_t* source) -{ - const auto len = static_cast<int>(std::wcslen(source)); - Aws::String output; - if (int requiredSizeInBytes = WideCharToMultiByte(CP_UTF8 /*CodePage*/, - 0 /*dwFlags*/, - source /*lpWideCharStr*/, - len /*cchWideChar*/, - nullptr /*lpMultiByteStr*/, - 0 /*cbMultiByte*/, - nullptr /*lpDefaultChar*/, - nullptr /*lpUsedDefaultChar*/)) - { - output.resize(requiredSizeInBytes); - } - const auto result = WideCharToMultiByte(CP_UTF8 /*CodePage*/, - 0 /*dwFlags*/, - source /*lpWideCharStr*/, - len /*cchWideChar*/, - &output[0] /*lpMultiByteStr*/, - static_cast<int>(output.length()) /*cbMultiByte*/, - nullptr /*lpDefaultChar*/, - nullptr /*lpUsedDefaultChar*/); - if (!result) - { - return ""; - } - output.resize(result); - return output; -} - -#endif + return copy; +} + +// trim from both ends +Aws::String StringUtils::Trim(const char* source) +{ + return LTrim(RTrim(source).c_str()); +} + +long long StringUtils::ConvertToInt64(const char* source) +{ + if(!source) + { + return 0; + } + +#ifdef __ANDROID__ + return atoll(source); +#else + return std::atoll(source); +#endif // __ANDROID__ +} + + +long StringUtils::ConvertToInt32(const char* source) +{ + if (!source) + { + return 0; + } + + return std::atol(source); +} + + +bool StringUtils::ConvertToBool(const char* source) +{ + if(!source) + { + return false; + } + + Aws::String strValue = ToLower(source); + if(strValue == "true" || strValue == "1") + { + return true; + } + + return false; +} + + +double StringUtils::ConvertToDouble(const char* source) +{ + if(!source) + { + return 0.0; + } + + return std::strtod(source, NULL); +} + +#ifdef _WIN32 + +Aws::WString StringUtils::ToWString(const char* source) +{ + const auto len = static_cast<int>(std::strlen(source)); + Aws::WString outString; + outString.resize(len); // there is no way UTF-16 would require _more_ code-points than UTF-8 for the _same_ string + const auto result = MultiByteToWideChar(CP_UTF8 /*CodePage*/, + 0 /*dwFlags*/, + source /*lpMultiByteStr*/, + len /*cbMultiByte*/, + &outString[0] /*lpWideCharStr*/, + static_cast<int>(outString.length())/*cchWideChar*/); + if (!result) + { + return L""; + } + outString.resize(result); + return outString; +} + +Aws::String StringUtils::FromWString(const wchar_t* source) +{ + const auto len = static_cast<int>(std::wcslen(source)); + Aws::String output; + if (int requiredSizeInBytes = WideCharToMultiByte(CP_UTF8 /*CodePage*/, + 0 /*dwFlags*/, + source /*lpWideCharStr*/, + len /*cchWideChar*/, + nullptr /*lpMultiByteStr*/, + 0 /*cbMultiByte*/, + nullptr /*lpDefaultChar*/, + nullptr /*lpUsedDefaultChar*/)) + { + output.resize(requiredSizeInBytes); + } + const auto result = WideCharToMultiByte(CP_UTF8 /*CodePage*/, + 0 /*dwFlags*/, + source /*lpWideCharStr*/, + len /*cchWideChar*/, + &output[0] /*lpMultiByteStr*/, + static_cast<int>(output.length()) /*cbMultiByte*/, + nullptr /*lpDefaultChar*/, + nullptr /*lpUsedDefaultChar*/); + if (!result) + { + return ""; + } + output.resize(result); + return output; +} + +#endif diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp index 7bc07266c9..c1c569e29a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp @@ -2,53 +2,53 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/FileSystemUtils.h> - -#include <aws/core/platform/FileSystem.h> - -namespace Aws -{ - namespace Utils - { - static Aws::String ComputeTempFileName(const char* prefix, const char* suffix) - { - Aws::String prefixStr; - - if (prefix) - { - prefixStr = prefix; - } - - Aws::String suffixStr; - - if (suffix) - { - suffixStr = suffix; - } - - return prefixStr + Aws::FileSystem::CreateTempFilePath() + suffixStr; - } - - TempFile::TempFile(const char* prefix, const char* suffix, std::ios_base::openmode openFlags) : - FStreamWithFileName(ComputeTempFileName(prefix, suffix).c_str(), openFlags) - { - } - - TempFile::TempFile(const char* prefix, std::ios_base::openmode openFlags) : - FStreamWithFileName(ComputeTempFileName(prefix, nullptr).c_str(), openFlags) - { - } - - TempFile::TempFile(std::ios_base::openmode openFlags) : - FStreamWithFileName(ComputeTempFileName(nullptr, nullptr).c_str(), openFlags) - { - } - - - TempFile::~TempFile() - { - Aws::FileSystem::RemoveFileIfExists(m_fileName.c_str()); - } - } -}
\ No newline at end of file + +#include <aws/core/utils/FileSystemUtils.h> + +#include <aws/core/platform/FileSystem.h> + +namespace Aws +{ + namespace Utils + { + static Aws::String ComputeTempFileName(const char* prefix, const char* suffix) + { + Aws::String prefixStr; + + if (prefix) + { + prefixStr = prefix; + } + + Aws::String suffixStr; + + if (suffix) + { + suffixStr = suffix; + } + + return prefixStr + Aws::FileSystem::CreateTempFilePath() + suffixStr; + } + + TempFile::TempFile(const char* prefix, const char* suffix, std::ios_base::openmode openFlags) : + FStreamWithFileName(ComputeTempFileName(prefix, suffix).c_str(), openFlags) + { + } + + TempFile::TempFile(const char* prefix, std::ios_base::openmode openFlags) : + FStreamWithFileName(ComputeTempFileName(prefix, nullptr).c_str(), openFlags) + { + } + + TempFile::TempFile(std::ios_base::openmode openFlags) : + FStreamWithFileName(ComputeTempFileName(nullptr, nullptr).c_str(), openFlags) + { + } + + + TempFile::~TempFile() + { + Aws::FileSystem::RemoveFileIfExists(m_fileName.c_str()); + } + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp index 862f3eacdd..d170082178 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp @@ -2,89 +2,89 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/UUID.h> -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/utils/StringUtils.h> -#include <aws/core/utils/crypto/Factories.h> -#include <aws/core/utils/crypto/SecureRandom.h> -#include <iomanip> - -namespace Aws -{ - namespace Utils - { + +#include <aws/core/utils/UUID.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/StringUtils.h> +#include <aws/core/utils/crypto/Factories.h> +#include <aws/core/utils/crypto/SecureRandom.h> +#include <iomanip> + +namespace Aws +{ + namespace Utils + { static const size_t UUID_STR_SIZE = 0x24u; // 36 characters - static const size_t VERSION_LOCATION = 0x06u; - static const size_t VARIANT_LOCATION = 0x08u; - static const unsigned char VERSION = 0x40u; - static const unsigned char VERSION_MASK = 0x0Fu; - static const unsigned char VARIANT = 0x80u; - static const unsigned char VARIANT_MASK = 0x3Fu; - + static const size_t VERSION_LOCATION = 0x06u; + static const size_t VARIANT_LOCATION = 0x08u; + static const unsigned char VERSION = 0x40u; + static const unsigned char VERSION_MASK = 0x0Fu; + static const unsigned char VARIANT = 0x80u; + static const unsigned char VARIANT_MASK = 0x3Fu; + static void hexify(Aws::String& ss, const unsigned char* toWrite, size_t min, size_t max) - { - for (size_t i = min; i < max; ++i) - { + { + for (size_t i = min; i < max; ++i) + { ss.push_back("0123456789ABCDEF"[toWrite[i] >> 4]); ss.push_back("0123456789ABCDEF"[toWrite[i] & 0x0F]); - } - } - - UUID::UUID(const Aws::String& uuidToConvert) - { - //GUID has 2 characters per byte + 4 dashes = 36 bytes - assert(uuidToConvert.length() == UUID_STR_SIZE); - memset(m_uuid, 0, sizeof(m_uuid)); - Aws::String escapedHexStr(uuidToConvert); - StringUtils::Replace(escapedHexStr, "-", ""); - assert(escapedHexStr.length() == UUID_BINARY_SIZE * 2); - ByteBuffer&& rawUuid = HashingUtils::HexDecode(escapedHexStr); - memcpy(m_uuid, rawUuid.GetUnderlyingData(), rawUuid.GetLength()); - } - - UUID::UUID(const unsigned char toCopy[UUID_BINARY_SIZE]) - { - memcpy(m_uuid, toCopy, sizeof(m_uuid)); - } - - UUID::operator Aws::String() const - { + } + } + + UUID::UUID(const Aws::String& uuidToConvert) + { + //GUID has 2 characters per byte + 4 dashes = 36 bytes + assert(uuidToConvert.length() == UUID_STR_SIZE); + memset(m_uuid, 0, sizeof(m_uuid)); + Aws::String escapedHexStr(uuidToConvert); + StringUtils::Replace(escapedHexStr, "-", ""); + assert(escapedHexStr.length() == UUID_BINARY_SIZE * 2); + ByteBuffer&& rawUuid = HashingUtils::HexDecode(escapedHexStr); + memcpy(m_uuid, rawUuid.GetUnderlyingData(), rawUuid.GetLength()); + } + + UUID::UUID(const unsigned char toCopy[UUID_BINARY_SIZE]) + { + memcpy(m_uuid, toCopy, sizeof(m_uuid)); + } + + UUID::operator Aws::String() const + { Aws::String ss; ss.reserve(UUID_STR_SIZE); hexify(ss, m_uuid, 0, 4); ss.push_back('-'); - + hexify(ss, m_uuid, 4, 6); ss.push_back('-'); - + hexify(ss, m_uuid, 6, 8); ss.push_back('-'); - + hexify(ss, m_uuid, 8, 10); ss.push_back('-'); - + hexify(ss, m_uuid, 10, 16); - + return ss; - } - - UUID UUID::RandomUUID() - { - auto secureRandom = Crypto::CreateSecureRandomBytesImplementation(); - assert(secureRandom); - - unsigned char randomBytes[UUID_BINARY_SIZE]; - memset(randomBytes, 0, UUID_BINARY_SIZE); - secureRandom->GetBytes(randomBytes, UUID_BINARY_SIZE); - //Set version bits to 0100 - //https://tools.ietf.org/html/rfc4122#section-4.1.3 - randomBytes[VERSION_LOCATION] = (randomBytes[VERSION_LOCATION] & VERSION_MASK) | VERSION; - //set variant bits to 10 - //https://tools.ietf.org/html/rfc4122#section-4.1.1 - randomBytes[VARIANT_LOCATION] = (randomBytes[VARIANT_LOCATION] & VARIANT_MASK) | VARIANT; - - return UUID(randomBytes); - } - } -} + } + + UUID UUID::RandomUUID() + { + auto secureRandom = Crypto::CreateSecureRandomBytesImplementation(); + assert(secureRandom); + + unsigned char randomBytes[UUID_BINARY_SIZE]; + memset(randomBytes, 0, UUID_BINARY_SIZE); + secureRandom->GetBytes(randomBytes, UUID_BINARY_SIZE); + //Set version bits to 0100 + //https://tools.ietf.org/html/rfc4122#section-4.1.3 + randomBytes[VERSION_LOCATION] = (randomBytes[VERSION_LOCATION] & VERSION_MASK) | VERSION; + //set variant bits to 10 + //https://tools.ietf.org/html/rfc4122#section-4.1.1 + randomBytes[VARIANT_LOCATION] = (randomBytes[VARIANT_LOCATION] & VARIANT_MASK) | VARIANT; + + return UUID(randomBytes); + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp index 2103d6d5a6..a6a777164d 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp @@ -2,147 +2,147 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/base64/Base64.h> -#include <cstring> - -using namespace Aws::Utils::Base64; - -static const uint8_t SENTINEL_VALUE = 255; -static const char BASE64_ENCODING_TABLE_MIME[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -namespace Aws -{ -namespace Utils -{ -namespace Base64 -{ - -Base64::Base64(const char *encodingTable) -{ - if(encodingTable == nullptr) - { - encodingTable = BASE64_ENCODING_TABLE_MIME; - } - - size_t encodingTableLength = strlen(encodingTable); - if(encodingTableLength != 64) - { - encodingTable = BASE64_ENCODING_TABLE_MIME; - encodingTableLength = 64; - } - - memcpy(m_mimeBase64EncodingTable, encodingTable, encodingTableLength); - - memset((void *)m_mimeBase64DecodingTable, 0, 256); - - for(uint32_t i = 0; i < encodingTableLength; ++i) - { - uint32_t index = static_cast<uint32_t>(m_mimeBase64EncodingTable[i]); - m_mimeBase64DecodingTable[index] = static_cast<uint8_t>(i); - } - - m_mimeBase64DecodingTable[(uint32_t)'='] = SENTINEL_VALUE; -} - -Aws::String Base64::Encode(const Aws::Utils::ByteBuffer& buffer) const -{ - size_t bufferLength = buffer.GetLength(); - size_t blockCount = (bufferLength + 2) / 3; - size_t remainderCount = (bufferLength % 3); - - Aws::String outputString; - outputString.reserve(CalculateBase64EncodedLength(buffer)); - - for(size_t i = 0; i < bufferLength; i += 3 ) - { - uint32_t block = buffer[ i ]; - - block <<= 8; - if (i + 1 < bufferLength) - { - block = block | buffer[ i + 1 ]; - } - - block <<= 8; - if (i + 2 < bufferLength) - { - block = block | buffer[ i + 2 ]; - } - - outputString.push_back(m_mimeBase64EncodingTable[(block >> 18) & 0x3F]); - outputString.push_back(m_mimeBase64EncodingTable[(block >> 12) & 0x3F]); - outputString.push_back(m_mimeBase64EncodingTable[(block >> 6) & 0x3F]); - outputString.push_back(m_mimeBase64EncodingTable[block & 0x3F]); - } - - if(remainderCount > 0) - { - outputString[blockCount * 4 - 1] = '='; - if(remainderCount == 1) - { - outputString[blockCount * 4 - 2] = '='; - } - } - - return outputString; -} - -Aws::Utils::ByteBuffer Base64::Decode(const Aws::String& str) const -{ - size_t decodedLength = CalculateBase64DecodedLength(str); - - Aws::Utils::ByteBuffer buffer(decodedLength); - - const char* rawString = str.c_str(); - size_t blockCount = str.length() / 4; - for(size_t i = 0; i < blockCount; ++i) - { - size_t stringIndex = i * 4; - - uint32_t value1 = m_mimeBase64DecodingTable[uint32_t(rawString[stringIndex])]; - uint32_t value2 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; - uint32_t value3 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; - uint32_t value4 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; - - size_t bufferIndex = i * 3; - buffer[bufferIndex] = static_cast<uint8_t>((value1 << 2) | ((value2 >> 4) & 0x03)); - if(value3 != SENTINEL_VALUE) - { - buffer[++bufferIndex] = static_cast<uint8_t>(((value2 << 4) & 0xF0) | ((value3 >> 2) & 0x0F)); - if(value4 != SENTINEL_VALUE) - { - buffer[++bufferIndex] = static_cast<uint8_t>((value3 & 0x03) << 6 | value4); - } - } - } - - return buffer; -} - -size_t Base64::CalculateBase64DecodedLength(const Aws::String& b64input) -{ + +#include <aws/core/utils/base64/Base64.h> +#include <cstring> + +using namespace Aws::Utils::Base64; + +static const uint8_t SENTINEL_VALUE = 255; +static const char BASE64_ENCODING_TABLE_MIME[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +namespace Aws +{ +namespace Utils +{ +namespace Base64 +{ + +Base64::Base64(const char *encodingTable) +{ + if(encodingTable == nullptr) + { + encodingTable = BASE64_ENCODING_TABLE_MIME; + } + + size_t encodingTableLength = strlen(encodingTable); + if(encodingTableLength != 64) + { + encodingTable = BASE64_ENCODING_TABLE_MIME; + encodingTableLength = 64; + } + + memcpy(m_mimeBase64EncodingTable, encodingTable, encodingTableLength); + + memset((void *)m_mimeBase64DecodingTable, 0, 256); + + for(uint32_t i = 0; i < encodingTableLength; ++i) + { + uint32_t index = static_cast<uint32_t>(m_mimeBase64EncodingTable[i]); + m_mimeBase64DecodingTable[index] = static_cast<uint8_t>(i); + } + + m_mimeBase64DecodingTable[(uint32_t)'='] = SENTINEL_VALUE; +} + +Aws::String Base64::Encode(const Aws::Utils::ByteBuffer& buffer) const +{ + size_t bufferLength = buffer.GetLength(); + size_t blockCount = (bufferLength + 2) / 3; + size_t remainderCount = (bufferLength % 3); + + Aws::String outputString; + outputString.reserve(CalculateBase64EncodedLength(buffer)); + + for(size_t i = 0; i < bufferLength; i += 3 ) + { + uint32_t block = buffer[ i ]; + + block <<= 8; + if (i + 1 < bufferLength) + { + block = block | buffer[ i + 1 ]; + } + + block <<= 8; + if (i + 2 < bufferLength) + { + block = block | buffer[ i + 2 ]; + } + + outputString.push_back(m_mimeBase64EncodingTable[(block >> 18) & 0x3F]); + outputString.push_back(m_mimeBase64EncodingTable[(block >> 12) & 0x3F]); + outputString.push_back(m_mimeBase64EncodingTable[(block >> 6) & 0x3F]); + outputString.push_back(m_mimeBase64EncodingTable[block & 0x3F]); + } + + if(remainderCount > 0) + { + outputString[blockCount * 4 - 1] = '='; + if(remainderCount == 1) + { + outputString[blockCount * 4 - 2] = '='; + } + } + + return outputString; +} + +Aws::Utils::ByteBuffer Base64::Decode(const Aws::String& str) const +{ + size_t decodedLength = CalculateBase64DecodedLength(str); + + Aws::Utils::ByteBuffer buffer(decodedLength); + + const char* rawString = str.c_str(); + size_t blockCount = str.length() / 4; + for(size_t i = 0; i < blockCount; ++i) + { + size_t stringIndex = i * 4; + + uint32_t value1 = m_mimeBase64DecodingTable[uint32_t(rawString[stringIndex])]; + uint32_t value2 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; + uint32_t value3 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; + uint32_t value4 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; + + size_t bufferIndex = i * 3; + buffer[bufferIndex] = static_cast<uint8_t>((value1 << 2) | ((value2 >> 4) & 0x03)); + if(value3 != SENTINEL_VALUE) + { + buffer[++bufferIndex] = static_cast<uint8_t>(((value2 << 4) & 0xF0) | ((value3 >> 2) & 0x0F)); + if(value4 != SENTINEL_VALUE) + { + buffer[++bufferIndex] = static_cast<uint8_t>((value3 & 0x03) << 6 | value4); + } + } + } + + return buffer; +} + +size_t Base64::CalculateBase64DecodedLength(const Aws::String& b64input) +{ const size_t len = b64input.length(); if(len < 2) - { - return 0; - } - - size_t padding = 0; - - if (b64input[len - 1] == '=' && b64input[len - 2] == '=') //last two chars are = - padding = 2; - else if (b64input[len - 1] == '=') //last char is = - padding = 1; - - return (len * 3 / 4 - padding); -} - -size_t Base64::CalculateBase64EncodedLength(const Aws::Utils::ByteBuffer& buffer) -{ - return 4 * ((buffer.GetLength() + 2) / 3); -} - -} // namespace Base64 -} // namespace Utils -} // namespace Aws
\ No newline at end of file + { + return 0; + } + + size_t padding = 0; + + if (b64input[len - 1] == '=' && b64input[len - 2] == '=') //last two chars are = + padding = 2; + else if (b64input[len - 1] == '=') //last char is = + padding = 1; + + return (len * 3 / 4 - padding); +} + +size_t Base64::CalculateBase64EncodedLength(const Aws::Utils::ByteBuffer& buffer) +{ + return 4 * ((buffer.GetLength() + 2) / 3); +} + +} // namespace Base64 +} // namespace Utils +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp index 1c844273f4..128a2cb60a 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp @@ -2,122 +2,122 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/crypto/Cipher.h> -#include <aws/core/utils/crypto/Factories.h> -#include <aws/core/utils/crypto/SecureRandom.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <cstdlib> -#include <climits> - -//if you are reading this, you are witnessing pure brilliance. -#define IS_BIG_ENDIAN (*(uint16_t*)"\0\xff" < 0x100) - -using namespace Aws::Utils::Crypto; -using namespace Aws::Utils; - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - static const char* LOG_TAG = "Cipher"; - - //swap byte ordering - template<class T> - typename std::enable_if<std::is_unsigned<T>::value, T>::type + +#include <aws/core/utils/crypto/Cipher.h> +#include <aws/core/utils/crypto/Factories.h> +#include <aws/core/utils/crypto/SecureRandom.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <cstdlib> +#include <climits> + +//if you are reading this, you are witnessing pure brilliance. +#define IS_BIG_ENDIAN (*(uint16_t*)"\0\xff" < 0x100) + +using namespace Aws::Utils::Crypto; +using namespace Aws::Utils; + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + static const char* LOG_TAG = "Cipher"; + + //swap byte ordering + template<class T> + typename std::enable_if<std::is_unsigned<T>::value, T>::type bswap(T i, T j = 0u, std::size_t n = 0u) + { + return n == sizeof(T) ? j : + bswap<T>(i >> CHAR_BIT, (j << CHAR_BIT) | (i & (T)(unsigned char)(-1)), n + 1); + } + + CryptoBuffer IncrementCTRCounter(const CryptoBuffer& counter, uint32_t numberOfBlocks) { - return n == sizeof(T) ? j : - bswap<T>(i >> CHAR_BIT, (j << CHAR_BIT) | (i & (T)(unsigned char)(-1)), n + 1); - } - - CryptoBuffer IncrementCTRCounter(const CryptoBuffer& counter, uint32_t numberOfBlocks) - { - // minium counter size is 12 bytes. This isn't a variable because some compilers - // are stupid and thing that variable is unused. - assert(counter.GetLength() >= 12); - + // minium counter size is 12 bytes. This isn't a variable because some compilers + // are stupid and thing that variable is unused. + assert(counter.GetLength() >= 12); + CryptoBuffer incrementedCounter(counter); - - //get the last 4 bytes and manipulate them as an integer. + + //get the last 4 bytes and manipulate them as an integer. uint32_t* ctrPtr = (uint32_t*)(incrementedCounter.GetUnderlyingData() + incrementedCounter.GetLength() - sizeof(int32_t)); - if(IS_BIG_ENDIAN) - { - //you likely are not Big Endian, but - //if it's big endian, just go ahead and increment it... done + if(IS_BIG_ENDIAN) + { + //you likely are not Big Endian, but + //if it's big endian, just go ahead and increment it... done *ctrPtr += numberOfBlocks; - } - else - { + } + else + { //otherwise, swap the byte ordering of the integer we loaded from the buffer (because it is backwards). However, the number of blocks is already properly - //aligned. Once we compute the new value, swap it back so that the mirroring operation goes back to the actual buffer. - *ctrPtr = bswap<uint32_t>(bswap<uint32_t>(*ctrPtr) + numberOfBlocks); - } - - return incrementedCounter; - } - - CryptoBuffer GenerateXRandomBytes(size_t lengthBytes, bool ctrMode) - { - std::shared_ptr<SecureRandomBytes> rng = CreateSecureRandomBytesImplementation(); - - CryptoBuffer bytes(lengthBytes); - size_t lengthToGenerate = ctrMode ? (3 * bytes.GetLength()) / 4 : bytes.GetLength(); - - rng->GetBytes(bytes.GetUnderlyingData(), lengthToGenerate); - - if(!*rng) - { - AWS_LOGSTREAM_FATAL(LOG_TAG, "Random Number generation failed. Abort all crypto operations."); - assert(false); + //aligned. Once we compute the new value, swap it back so that the mirroring operation goes back to the actual buffer. + *ctrPtr = bswap<uint32_t>(bswap<uint32_t>(*ctrPtr) + numberOfBlocks); + } + + return incrementedCounter; + } + + CryptoBuffer GenerateXRandomBytes(size_t lengthBytes, bool ctrMode) + { + std::shared_ptr<SecureRandomBytes> rng = CreateSecureRandomBytesImplementation(); + + CryptoBuffer bytes(lengthBytes); + size_t lengthToGenerate = ctrMode ? (3 * bytes.GetLength()) / 4 : bytes.GetLength(); + + rng->GetBytes(bytes.GetUnderlyingData(), lengthToGenerate); + + if(!*rng) + { + AWS_LOGSTREAM_FATAL(LOG_TAG, "Random Number generation failed. Abort all crypto operations."); + assert(false); abort(); - } - - return bytes; - } - - /** - * Generate random number per 4 bytes and use each byte for the byte in the iv - */ - CryptoBuffer SymmetricCipher::GenerateIV(size_t ivLengthBytes, bool ctrMode) - { - CryptoBuffer iv(GenerateXRandomBytes(ivLengthBytes, ctrMode)); - - if(iv.GetLength() == 0) - { - AWS_LOGSTREAM_ERROR(LOG_TAG, "Unable to generate iv of length " << ivLengthBytes); - return iv; - } - - if(ctrMode) - { - //init the counter - size_t length = iv.GetLength(); - //[ nonce 1/4] [ iv 1/2 ] [ ctr 1/4 ] - size_t ctrStart = (length / 2) + (length / 4); - for(; ctrStart < iv.GetLength() - 1; ++ ctrStart) - { - iv[ctrStart] = 0; - } - iv[length - 1] = 1; - } - - return iv; - } - - CryptoBuffer SymmetricCipher::GenerateKey(size_t keyLengthBytes) - { - CryptoBuffer const& key = GenerateXRandomBytes(keyLengthBytes, false); - - if(key.GetLength() == 0) - { - AWS_LOGSTREAM_ERROR(LOG_TAG, "Unable to generate key of length " << keyLengthBytes); - } - - return key; - } - } - } -} + } + + return bytes; + } + + /** + * Generate random number per 4 bytes and use each byte for the byte in the iv + */ + CryptoBuffer SymmetricCipher::GenerateIV(size_t ivLengthBytes, bool ctrMode) + { + CryptoBuffer iv(GenerateXRandomBytes(ivLengthBytes, ctrMode)); + + if(iv.GetLength() == 0) + { + AWS_LOGSTREAM_ERROR(LOG_TAG, "Unable to generate iv of length " << ivLengthBytes); + return iv; + } + + if(ctrMode) + { + //init the counter + size_t length = iv.GetLength(); + //[ nonce 1/4] [ iv 1/2 ] [ ctr 1/4 ] + size_t ctrStart = (length / 2) + (length / 4); + for(; ctrStart < iv.GetLength() - 1; ++ ctrStart) + { + iv[ctrStart] = 0; + } + iv[length - 1] = 1; + } + + return iv; + } + + CryptoBuffer SymmetricCipher::GenerateKey(size_t keyLengthBytes) + { + CryptoBuffer const& key = GenerateXRandomBytes(keyLengthBytes, false); + + if(key.GetLength() == 0) + { + AWS_LOGSTREAM_ERROR(LOG_TAG, "Unable to generate key of length " << keyLengthBytes); + } + + return key; + } + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp index 3036bd70eb..3d484f680b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp @@ -2,33 +2,33 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/utils/crypto/ContentCryptoMaterial.h> -#include <aws/core/utils/crypto/Cipher.h> - -using namespace Aws::Utils::Crypto; - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - ContentCryptoMaterial::ContentCryptoMaterial() : - m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(ContentCryptoScheme::NONE) - { - } - - ContentCryptoMaterial::ContentCryptoMaterial(ContentCryptoScheme contentCryptoScheme) : - m_contentEncryptionKey(SymmetricCipher::GenerateKey()), m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(contentCryptoScheme) - { - - } - - ContentCryptoMaterial::ContentCryptoMaterial(const Aws::Utils::CryptoBuffer & cek, ContentCryptoScheme contentCryptoScheme) : - m_contentEncryptionKey(cek), m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(contentCryptoScheme) - { - - } - } - } -} +#include <aws/core/utils/crypto/ContentCryptoMaterial.h> +#include <aws/core/utils/crypto/Cipher.h> + +using namespace Aws::Utils::Crypto; + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + ContentCryptoMaterial::ContentCryptoMaterial() : + m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(ContentCryptoScheme::NONE) + { + } + + ContentCryptoMaterial::ContentCryptoMaterial(ContentCryptoScheme contentCryptoScheme) : + m_contentEncryptionKey(SymmetricCipher::GenerateKey()), m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(contentCryptoScheme) + { + + } + + ContentCryptoMaterial::ContentCryptoMaterial(const Aws::Utils::CryptoBuffer & cek, ContentCryptoScheme contentCryptoScheme) : + m_contentEncryptionKey(cek), m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(contentCryptoScheme) + { + + } + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp index f39a75df2c..c32df35939 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp @@ -2,60 +2,60 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/utils/crypto/ContentCryptoScheme.h> -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/utils/EnumParseOverflowContainer.h> -#include <aws/core/Globals.h> - -using namespace Aws::Utils; - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - namespace ContentCryptoSchemeMapper - { - static const int cryptoScheme_CBC_HASH = HashingUtils::HashString("AES/CBC/PKCS5Padding"); - static const int cryptoScheme_CTR_HASH = HashingUtils::HashString("AES/CTR/NoPadding"); - static const int cryptoScheme_GCM_HASH = HashingUtils::HashString("AES/GCM/NoPadding"); - - ContentCryptoScheme GetContentCryptoSchemeForName(const Aws::String& name) - { - int hashcode = HashingUtils::HashString(name.c_str()); - if (hashcode == cryptoScheme_CBC_HASH) - { - return ContentCryptoScheme::CBC; - } - else if (hashcode == cryptoScheme_CTR_HASH) - { - return ContentCryptoScheme::CTR; - } - else if (hashcode == cryptoScheme_GCM_HASH) - { - return ContentCryptoScheme::GCM; - } - assert(0); - return ContentCryptoScheme::NONE; - } - - Aws::String GetNameForContentCryptoScheme(ContentCryptoScheme enumValue) - { - switch (enumValue) - { - case ContentCryptoScheme::CBC: - return "AES/CBC/PKCS5Padding"; - case ContentCryptoScheme::CTR: - return "AES/CTR/NoPadding"; - case ContentCryptoScheme::GCM: - return "AES/GCM/NoPadding"; - default: - assert(0); - return ""; - } - } - }//namespace ContentCryptoSchemeMapper - } //namespace Crypto - }//namespace Utils -}//namespace Aws
\ No newline at end of file +#include <aws/core/utils/crypto/ContentCryptoScheme.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/EnumParseOverflowContainer.h> +#include <aws/core/Globals.h> + +using namespace Aws::Utils; + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + namespace ContentCryptoSchemeMapper + { + static const int cryptoScheme_CBC_HASH = HashingUtils::HashString("AES/CBC/PKCS5Padding"); + static const int cryptoScheme_CTR_HASH = HashingUtils::HashString("AES/CTR/NoPadding"); + static const int cryptoScheme_GCM_HASH = HashingUtils::HashString("AES/GCM/NoPadding"); + + ContentCryptoScheme GetContentCryptoSchemeForName(const Aws::String& name) + { + int hashcode = HashingUtils::HashString(name.c_str()); + if (hashcode == cryptoScheme_CBC_HASH) + { + return ContentCryptoScheme::CBC; + } + else if (hashcode == cryptoScheme_CTR_HASH) + { + return ContentCryptoScheme::CTR; + } + else if (hashcode == cryptoScheme_GCM_HASH) + { + return ContentCryptoScheme::GCM; + } + assert(0); + return ContentCryptoScheme::NONE; + } + + Aws::String GetNameForContentCryptoScheme(ContentCryptoScheme enumValue) + { + switch (enumValue) + { + case ContentCryptoScheme::CBC: + return "AES/CBC/PKCS5Padding"; + case ContentCryptoScheme::CTR: + return "AES/CTR/NoPadding"; + case ContentCryptoScheme::GCM: + return "AES/GCM/NoPadding"; + default: + assert(0); + return ""; + } + } + }//namespace ContentCryptoSchemeMapper + } //namespace Crypto + }//namespace Utils +}//namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp index 2b47097679..7f433ce368 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp @@ -2,300 +2,300 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/crypto/CryptoBuf.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - SymmetricCryptoBufSrc::SymmetricCryptoBufSrc(Aws::IStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize) - : - m_isBuf(PUT_BACK_SIZE), m_cipher(cipher), m_stream(stream), m_cipherMode(cipherMode), m_isFinalized(false), - m_bufferSize(bufferSize), m_putBack(PUT_BACK_SIZE) - { - char* end = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData() + m_isBuf.GetLength()); - setg(end, end, end); - } - - SymmetricCryptoBufSrc::pos_type SymmetricCryptoBufSrc::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) - { - if(which == std::ios_base::in) - { - auto curPos = m_stream.tellg(); - //error on seek we may have read past the end already. Try resetting and seeking to the end first - if (curPos == pos_type(-1)) - { - m_stream.clear(); - m_stream.seekg(0, std::ios_base::end); - curPos = m_stream.tellg(); - } - - auto absPosition = ComputeAbsSeekPosition(off, dir, curPos); - size_t seekTo = static_cast<size_t>(absPosition); - size_t index = static_cast<size_t>(curPos); - - if(index == seekTo) - { - return curPos; - } - else if (seekTo < index) - { - m_cipher.Reset(); - m_stream.clear(); - m_stream.seekg(0); - m_isFinalized = false; - index = 0; - } - - CryptoBuffer cryptoBuffer; - while (m_cipher && index < seekTo && !m_isFinalized) - { - size_t max_read = std::min<size_t>(static_cast<size_t>(seekTo - index), m_bufferSize); - - Aws::Utils::Array<char> buf(max_read); - size_t readSize(0); - if(m_stream) - { - m_stream.read(buf.GetUnderlyingData(), max_read); - readSize = static_cast<size_t>(m_stream.gcount()); - } - - if (readSize > 0) - { - if (m_cipherMode == CipherMode::Encrypt) - { - cryptoBuffer = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); - } - else - { - cryptoBuffer = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); - } - } - else - { - if (m_cipherMode == CipherMode::Encrypt) - { - cryptoBuffer = m_cipher.FinalizeEncryption(); - } - else - { - cryptoBuffer = m_cipher.FinalizeDecryption(); - } - - m_isFinalized = true; - } - - index += cryptoBuffer.GetLength(); - } - - if (cryptoBuffer.GetLength() && m_cipher) - { - CryptoBuffer putBackArea(m_putBack); - - m_isBuf = CryptoBuffer({&putBackArea, &cryptoBuffer}); - //in the very unlikely case that the cipher had less output than the source stream. - assert(seekTo <= index); - size_t newBufferPos = index > seekTo ? cryptoBuffer.GetLength() - (index - seekTo) : cryptoBuffer.GetLength(); - char* baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData()); - setg(baseBufPtr, baseBufPtr + m_putBack + newBufferPos, baseBufPtr + m_isBuf.GetLength()); - - return pos_type(seekTo); - } - else if (seekTo == 0) - { - m_isBuf = CryptoBuffer(m_putBack); - char* end = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData() + m_isBuf.GetLength()); - setg(end, end, end); - return pos_type(seekTo); - } - } - - return pos_type(off_type(-1)); - } - - SymmetricCryptoBufSrc::pos_type SymmetricCryptoBufSrc::seekpos(pos_type pos, std::ios_base::openmode which) - { - return seekoff(pos, std::ios_base::beg, which); - } - - SymmetricCryptoBufSrc::int_type SymmetricCryptoBufSrc::underflow() - { - if (!m_cipher || (m_isFinalized && gptr() >= egptr())) - { - return traits_type::eof(); - } - - if (gptr() < egptr()) - { - return traits_type::to_int_type(*gptr()); - } - - char* baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData()); - CryptoBuffer putBackArea(m_putBack); - - //eback is properly set after the first fill. So this guarantees we are on the second or later fill. - if (eback() == baseBufPtr) - { - //just fill in the last bit of the previous buffer into the put back area so that it has some data in it - memcpy(putBackArea.GetUnderlyingData(), egptr() - m_putBack, m_putBack); - } - - CryptoBuffer newDataBuf; - - while(!newDataBuf.GetLength() && !m_isFinalized) - { - Aws::Utils::Array<char> buf(m_bufferSize); - m_stream.read(buf.GetUnderlyingData(), m_bufferSize); - size_t readSize = static_cast<size_t>(m_stream.gcount()); - - if (readSize > 0) - { - if (m_cipherMode == CipherMode::Encrypt) - { - newDataBuf = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); - } - else - { - newDataBuf = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); - } - } - else - { - if (m_cipherMode == CipherMode::Encrypt) - { - newDataBuf = m_cipher.FinalizeEncryption(); - } - else - { - newDataBuf = m_cipher.FinalizeDecryption(); - } - - m_isFinalized = true; - } - } - - - if(newDataBuf.GetLength() > 0) - { - m_isBuf = CryptoBuffer({&putBackArea, &newDataBuf}); - - baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData()); - setg(baseBufPtr, baseBufPtr + m_putBack, baseBufPtr + m_isBuf.GetLength()); - - return traits_type::to_int_type(*gptr()); - } - - return traits_type::eof(); - } - - SymmetricCryptoBufSrc::off_type SymmetricCryptoBufSrc::ComputeAbsSeekPosition(off_type pos, std::ios_base::seekdir dir, std::fpos<FPOS_TYPE> curPos) - { - switch(dir) - { - case std::ios_base::beg: - return pos; - case std::ios_base::cur: - return m_stream.tellg() + pos; - case std::ios_base::end: - { - off_type absPos = m_stream.seekg(0, std::ios_base::end).tellg() - pos; - m_stream.seekg(curPos); - return absPos; - } - default: - assert(0); - return off_type(-1); - } - } - - void SymmetricCryptoBufSrc::FinalizeCipher() - { - if(m_cipher && !m_isFinalized) - { - if(m_cipherMode == CipherMode::Encrypt) - { - m_cipher.FinalizeEncryption(); - } - else - { - m_cipher.FinalizeDecryption(); - } - } - } - - SymmetricCryptoBufSink::SymmetricCryptoBufSink(Aws::OStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize, int16_t blockOffset) - : - m_osBuf(bufferSize), m_cipher(cipher), m_stream(stream), m_cipherMode(cipherMode), m_isFinalized(false), m_blockOffset(blockOffset) - { - assert(m_blockOffset < 16 && m_blockOffset >= 0); - char* outputBase = reinterpret_cast<char*>(m_osBuf.GetUnderlyingData()); - setp(outputBase, outputBase + bufferSize - 1); - } - - SymmetricCryptoBufSink::~SymmetricCryptoBufSink() - { - FinalizeCiphersAndFlushSink(); - } - - void SymmetricCryptoBufSink::FinalizeCiphersAndFlushSink() - { - if(m_cipher && !m_isFinalized) - { - writeOutput(true); - } - } - - bool SymmetricCryptoBufSink::writeOutput(bool finalize) - { - if(!m_isFinalized) - { - CryptoBuffer cryptoBuf; - if (pptr() > pbase()) - { - if (m_cipherMode == CipherMode::Encrypt) - { - cryptoBuf = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(pbase()), pptr() - pbase())); - } - else - { - cryptoBuf = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(pbase()), pptr() - pbase())); - } - - pbump(-(static_cast<int>(pptr() - pbase()))); - } - if(finalize) - { - CryptoBuffer finalBuffer; - if (m_cipherMode == CipherMode::Encrypt) - { - finalBuffer = m_cipher.FinalizeEncryption(); - } - else - { - finalBuffer = m_cipher.FinalizeDecryption(); - } - if(cryptoBuf.GetLength()) - { - cryptoBuf = CryptoBuffer({&cryptoBuf, &finalBuffer}); - } - else - { - cryptoBuf = std::move(finalBuffer); - } - - m_isFinalized = true; - } - - if (m_cipher) - { - if(cryptoBuf.GetLength()) - { - //allow mid block decryption. We have to decrypt it, but we don't have to write it to the stream. + +#include <aws/core/utils/crypto/CryptoBuf.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + SymmetricCryptoBufSrc::SymmetricCryptoBufSrc(Aws::IStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize) + : + m_isBuf(PUT_BACK_SIZE), m_cipher(cipher), m_stream(stream), m_cipherMode(cipherMode), m_isFinalized(false), + m_bufferSize(bufferSize), m_putBack(PUT_BACK_SIZE) + { + char* end = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData() + m_isBuf.GetLength()); + setg(end, end, end); + } + + SymmetricCryptoBufSrc::pos_type SymmetricCryptoBufSrc::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) + { + if(which == std::ios_base::in) + { + auto curPos = m_stream.tellg(); + //error on seek we may have read past the end already. Try resetting and seeking to the end first + if (curPos == pos_type(-1)) + { + m_stream.clear(); + m_stream.seekg(0, std::ios_base::end); + curPos = m_stream.tellg(); + } + + auto absPosition = ComputeAbsSeekPosition(off, dir, curPos); + size_t seekTo = static_cast<size_t>(absPosition); + size_t index = static_cast<size_t>(curPos); + + if(index == seekTo) + { + return curPos; + } + else if (seekTo < index) + { + m_cipher.Reset(); + m_stream.clear(); + m_stream.seekg(0); + m_isFinalized = false; + index = 0; + } + + CryptoBuffer cryptoBuffer; + while (m_cipher && index < seekTo && !m_isFinalized) + { + size_t max_read = std::min<size_t>(static_cast<size_t>(seekTo - index), m_bufferSize); + + Aws::Utils::Array<char> buf(max_read); + size_t readSize(0); + if(m_stream) + { + m_stream.read(buf.GetUnderlyingData(), max_read); + readSize = static_cast<size_t>(m_stream.gcount()); + } + + if (readSize > 0) + { + if (m_cipherMode == CipherMode::Encrypt) + { + cryptoBuffer = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); + } + else + { + cryptoBuffer = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); + } + } + else + { + if (m_cipherMode == CipherMode::Encrypt) + { + cryptoBuffer = m_cipher.FinalizeEncryption(); + } + else + { + cryptoBuffer = m_cipher.FinalizeDecryption(); + } + + m_isFinalized = true; + } + + index += cryptoBuffer.GetLength(); + } + + if (cryptoBuffer.GetLength() && m_cipher) + { + CryptoBuffer putBackArea(m_putBack); + + m_isBuf = CryptoBuffer({&putBackArea, &cryptoBuffer}); + //in the very unlikely case that the cipher had less output than the source stream. + assert(seekTo <= index); + size_t newBufferPos = index > seekTo ? cryptoBuffer.GetLength() - (index - seekTo) : cryptoBuffer.GetLength(); + char* baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData()); + setg(baseBufPtr, baseBufPtr + m_putBack + newBufferPos, baseBufPtr + m_isBuf.GetLength()); + + return pos_type(seekTo); + } + else if (seekTo == 0) + { + m_isBuf = CryptoBuffer(m_putBack); + char* end = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData() + m_isBuf.GetLength()); + setg(end, end, end); + return pos_type(seekTo); + } + } + + return pos_type(off_type(-1)); + } + + SymmetricCryptoBufSrc::pos_type SymmetricCryptoBufSrc::seekpos(pos_type pos, std::ios_base::openmode which) + { + return seekoff(pos, std::ios_base::beg, which); + } + + SymmetricCryptoBufSrc::int_type SymmetricCryptoBufSrc::underflow() + { + if (!m_cipher || (m_isFinalized && gptr() >= egptr())) + { + return traits_type::eof(); + } + + if (gptr() < egptr()) + { + return traits_type::to_int_type(*gptr()); + } + + char* baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData()); + CryptoBuffer putBackArea(m_putBack); + + //eback is properly set after the first fill. So this guarantees we are on the second or later fill. + if (eback() == baseBufPtr) + { + //just fill in the last bit of the previous buffer into the put back area so that it has some data in it + memcpy(putBackArea.GetUnderlyingData(), egptr() - m_putBack, m_putBack); + } + + CryptoBuffer newDataBuf; + + while(!newDataBuf.GetLength() && !m_isFinalized) + { + Aws::Utils::Array<char> buf(m_bufferSize); + m_stream.read(buf.GetUnderlyingData(), m_bufferSize); + size_t readSize = static_cast<size_t>(m_stream.gcount()); + + if (readSize > 0) + { + if (m_cipherMode == CipherMode::Encrypt) + { + newDataBuf = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); + } + else + { + newDataBuf = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize)); + } + } + else + { + if (m_cipherMode == CipherMode::Encrypt) + { + newDataBuf = m_cipher.FinalizeEncryption(); + } + else + { + newDataBuf = m_cipher.FinalizeDecryption(); + } + + m_isFinalized = true; + } + } + + + if(newDataBuf.GetLength() > 0) + { + m_isBuf = CryptoBuffer({&putBackArea, &newDataBuf}); + + baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData()); + setg(baseBufPtr, baseBufPtr + m_putBack, baseBufPtr + m_isBuf.GetLength()); + + return traits_type::to_int_type(*gptr()); + } + + return traits_type::eof(); + } + + SymmetricCryptoBufSrc::off_type SymmetricCryptoBufSrc::ComputeAbsSeekPosition(off_type pos, std::ios_base::seekdir dir, std::fpos<FPOS_TYPE> curPos) + { + switch(dir) + { + case std::ios_base::beg: + return pos; + case std::ios_base::cur: + return m_stream.tellg() + pos; + case std::ios_base::end: + { + off_type absPos = m_stream.seekg(0, std::ios_base::end).tellg() - pos; + m_stream.seekg(curPos); + return absPos; + } + default: + assert(0); + return off_type(-1); + } + } + + void SymmetricCryptoBufSrc::FinalizeCipher() + { + if(m_cipher && !m_isFinalized) + { + if(m_cipherMode == CipherMode::Encrypt) + { + m_cipher.FinalizeEncryption(); + } + else + { + m_cipher.FinalizeDecryption(); + } + } + } + + SymmetricCryptoBufSink::SymmetricCryptoBufSink(Aws::OStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize, int16_t blockOffset) + : + m_osBuf(bufferSize), m_cipher(cipher), m_stream(stream), m_cipherMode(cipherMode), m_isFinalized(false), m_blockOffset(blockOffset) + { + assert(m_blockOffset < 16 && m_blockOffset >= 0); + char* outputBase = reinterpret_cast<char*>(m_osBuf.GetUnderlyingData()); + setp(outputBase, outputBase + bufferSize - 1); + } + + SymmetricCryptoBufSink::~SymmetricCryptoBufSink() + { + FinalizeCiphersAndFlushSink(); + } + + void SymmetricCryptoBufSink::FinalizeCiphersAndFlushSink() + { + if(m_cipher && !m_isFinalized) + { + writeOutput(true); + } + } + + bool SymmetricCryptoBufSink::writeOutput(bool finalize) + { + if(!m_isFinalized) + { + CryptoBuffer cryptoBuf; + if (pptr() > pbase()) + { + if (m_cipherMode == CipherMode::Encrypt) + { + cryptoBuf = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(pbase()), pptr() - pbase())); + } + else + { + cryptoBuf = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(pbase()), pptr() - pbase())); + } + + pbump(-(static_cast<int>(pptr() - pbase()))); + } + if(finalize) + { + CryptoBuffer finalBuffer; + if (m_cipherMode == CipherMode::Encrypt) + { + finalBuffer = m_cipher.FinalizeEncryption(); + } + else + { + finalBuffer = m_cipher.FinalizeDecryption(); + } + if(cryptoBuf.GetLength()) + { + cryptoBuf = CryptoBuffer({&cryptoBuf, &finalBuffer}); + } + else + { + cryptoBuf = std::move(finalBuffer); + } + + m_isFinalized = true; + } + + if (m_cipher) + { + if(cryptoBuf.GetLength()) + { + //allow mid block decryption. We have to decrypt it, but we don't have to write it to the stream. //the assumption here is that tellp() will always be 0 or >= 16 bytes. The block offset should only - //be the offset of the first block read. + //be the offset of the first block read. size_t len = cryptoBuf.GetLength(); size_t blockOffset = m_stream.tellp() > m_blockOffset ? 0 : m_blockOffset; if (len > blockOffset) @@ -307,42 +307,42 @@ namespace Aws { m_blockOffset -= static_cast<int16_t>(len); } - } - return true; - } - } - - return false; - } - - SymmetricCryptoBufSink::int_type SymmetricCryptoBufSink::overflow(int_type ch) - { - if(m_cipher && m_stream) - { - if(ch != traits_type::eof()) - { - *pptr() = (char)ch; - pbump(1); - } - - if(writeOutput(ch == traits_type::eof())) - { - return ch; - } - } - - return traits_type::eof(); - } - - int SymmetricCryptoBufSink::sync() - { - if(m_cipher && m_stream) - { - return writeOutput(false) ? 0 : -1; - } - - return -1; - } - } - } -} + } + return true; + } + } + + return false; + } + + SymmetricCryptoBufSink::int_type SymmetricCryptoBufSink::overflow(int_type ch) + { + if(m_cipher && m_stream) + { + if(ch != traits_type::eof()) + { + *pptr() = (char)ch; + pbump(1); + } + + if(writeOutput(ch == traits_type::eof())) + { + return ch; + } + } + + return traits_type::eof(); + } + + int SymmetricCryptoBufSink::sync() + { + if(m_cipher && m_stream) + { + return writeOutput(false) ? 0 : -1; + } + + return -1; + } + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp index 2d645f7427..aa0ebba128 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp @@ -2,51 +2,51 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/utils/crypto/CryptoStream.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - static const char* CLASS_TAG = "Aws::Utils::Crypto::SymmetricCryptoStream"; - - SymmetricCryptoStream::SymmetricCryptoStream(Aws::IStream& src, CipherMode mode, SymmetricCipher& cipher, size_t bufSize) : - Aws::IOStream(m_cryptoBuf = Aws::New<SymmetricCryptoBufSrc>(CLASS_TAG, src, cipher, mode, bufSize)), m_hasOwnership(true) - { - } - - SymmetricCryptoStream::SymmetricCryptoStream(Aws::OStream& sink, CipherMode mode, SymmetricCipher& cipher, size_t bufSize, int16_t blockOffset) : - Aws::IOStream(m_cryptoBuf = Aws::New<SymmetricCryptoBufSink>(CLASS_TAG, sink, cipher, mode, bufSize, blockOffset)), m_hasOwnership(true) - { - } - - SymmetricCryptoStream::SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSrc& bufSrc) : - Aws::IOStream(&bufSrc), m_cryptoBuf(&bufSrc), m_hasOwnership(false) - { - } - - SymmetricCryptoStream::SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSink& bufSink) : - Aws::IOStream(&bufSink), m_cryptoBuf(&bufSink), m_hasOwnership(false) - { - } - - SymmetricCryptoStream::~SymmetricCryptoStream() - { - Finalize(); - - if(m_hasOwnership && m_cryptoBuf) - { - Aws::Delete(m_cryptoBuf); - } - } - - void SymmetricCryptoStream::Finalize() - { +#include <aws/core/utils/crypto/CryptoStream.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + static const char* CLASS_TAG = "Aws::Utils::Crypto::SymmetricCryptoStream"; + + SymmetricCryptoStream::SymmetricCryptoStream(Aws::IStream& src, CipherMode mode, SymmetricCipher& cipher, size_t bufSize) : + Aws::IOStream(m_cryptoBuf = Aws::New<SymmetricCryptoBufSrc>(CLASS_TAG, src, cipher, mode, bufSize)), m_hasOwnership(true) + { + } + + SymmetricCryptoStream::SymmetricCryptoStream(Aws::OStream& sink, CipherMode mode, SymmetricCipher& cipher, size_t bufSize, int16_t blockOffset) : + Aws::IOStream(m_cryptoBuf = Aws::New<SymmetricCryptoBufSink>(CLASS_TAG, sink, cipher, mode, bufSize, blockOffset)), m_hasOwnership(true) + { + } + + SymmetricCryptoStream::SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSrc& bufSrc) : + Aws::IOStream(&bufSrc), m_cryptoBuf(&bufSrc), m_hasOwnership(false) + { + } + + SymmetricCryptoStream::SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSink& bufSink) : + Aws::IOStream(&bufSink), m_cryptoBuf(&bufSink), m_hasOwnership(false) + { + } + + SymmetricCryptoStream::~SymmetricCryptoStream() + { + Finalize(); + + if(m_hasOwnership && m_cryptoBuf) + { + Aws::Delete(m_cryptoBuf); + } + } + + void SymmetricCryptoStream::Finalize() + { assert(m_cryptoBuf); - m_cryptoBuf->Finalize(); - } - } - } -}
\ No newline at end of file + m_cryptoBuf->Finalize(); + } + } + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp index d000c86baa..09cd9c0cf7 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp @@ -2,18 +2,18 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/utils/crypto/EncryptionMaterials.h> - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - //this is here to force the linker to behave correctly since this is an interface that will need to cross the dll - //boundary. - EncryptionMaterials::~EncryptionMaterials() - {} - } - } -}
\ No newline at end of file +#include <aws/core/utils/crypto/EncryptionMaterials.h> + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + //this is here to force the linker to behave correctly since this is an interface that will need to cross the dll + //boundary. + EncryptionMaterials::~EncryptionMaterials() + {} + } + } +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp index b9e098775c..fbe11626f1 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp @@ -2,67 +2,67 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/core/utils/crypto/KeyWrapAlgorithm.h> -#include <aws/core/utils/HashingUtils.h> -#include <aws/core/utils/EnumParseOverflowContainer.h> -#include <aws/core/Globals.h> - -using namespace Aws::Utils; - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - namespace KeyWrapAlgorithmMapper - { - static const int keyWrapAlgorithm_KMS_HASH = HashingUtils::HashString("kms"); +#include <aws/core/utils/crypto/KeyWrapAlgorithm.h> +#include <aws/core/utils/HashingUtils.h> +#include <aws/core/utils/EnumParseOverflowContainer.h> +#include <aws/core/Globals.h> + +using namespace Aws::Utils; + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + namespace KeyWrapAlgorithmMapper + { + static const int keyWrapAlgorithm_KMS_HASH = HashingUtils::HashString("kms"); static const int keyWrapAlgorithm_KMS_CONTEXT_HASH = HashingUtils::HashString("kms+context"); - static const int keyWrapAlgorithm_KeyWrap_HASH = HashingUtils::HashString("AESWrap"); + static const int keyWrapAlgorithm_KeyWrap_HASH = HashingUtils::HashString("AESWrap"); static const int keyWrapAlgorithm_AES_GCM_HASH = HashingUtils::HashString("AES/GCM"); - - KeyWrapAlgorithm GetKeyWrapAlgorithmForName(const Aws::String& name) - { - int hashcode = HashingUtils::HashString(name.c_str()); - if (hashcode == keyWrapAlgorithm_KMS_HASH) - { - return KeyWrapAlgorithm::KMS; - } + + KeyWrapAlgorithm GetKeyWrapAlgorithmForName(const Aws::String& name) + { + int hashcode = HashingUtils::HashString(name.c_str()); + if (hashcode == keyWrapAlgorithm_KMS_HASH) + { + return KeyWrapAlgorithm::KMS; + } else if (hashcode == keyWrapAlgorithm_KMS_CONTEXT_HASH) { return KeyWrapAlgorithm::KMS_CONTEXT; } - else if (hashcode == keyWrapAlgorithm_KeyWrap_HASH) - { - return KeyWrapAlgorithm::AES_KEY_WRAP; + else if (hashcode == keyWrapAlgorithm_KeyWrap_HASH) + { + return KeyWrapAlgorithm::AES_KEY_WRAP; } else if (hashcode == keyWrapAlgorithm_AES_GCM_HASH) { return KeyWrapAlgorithm::AES_GCM; - } - assert(0); - return KeyWrapAlgorithm::NONE; - } - - Aws::String GetNameForKeyWrapAlgorithm(KeyWrapAlgorithm enumValue) - { - switch (enumValue) - { - case KeyWrapAlgorithm::KMS: - return "kms"; + } + assert(0); + return KeyWrapAlgorithm::NONE; + } + + Aws::String GetNameForKeyWrapAlgorithm(KeyWrapAlgorithm enumValue) + { + switch (enumValue) + { + case KeyWrapAlgorithm::KMS: + return "kms"; case KeyWrapAlgorithm::KMS_CONTEXT: return "kms+context"; - case KeyWrapAlgorithm::AES_KEY_WRAP: - return "AESWrap"; + case KeyWrapAlgorithm::AES_KEY_WRAP: + return "AESWrap"; case KeyWrapAlgorithm::AES_GCM: return "AES/GCM"; - default: - assert(0); - } - return ""; - } - }//namespace KeyWrapAlgorithmMapper - }//namespace Crypto - }//namespace Utils + default: + assert(0); + } + return ""; + } + }//namespace KeyWrapAlgorithmMapper + }//namespace Crypto + }//namespace Utils }//namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp index bf14ace1ad..177947b743 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp @@ -2,30 +2,30 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/crypto/MD5.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/crypto/Factories.h> - -using namespace Aws::Utils::Crypto; - - -MD5::MD5() : - m_hashImpl(CreateMD5Implementation()) -{ -} - -MD5::~MD5() -{ -} - -HashResult MD5::Calculate(const Aws::String& str) -{ - return m_hashImpl->Calculate(str); -} - -HashResult MD5::Calculate(Aws::IStream& stream) -{ - return m_hashImpl->Calculate(stream); -}
\ No newline at end of file + + +#include <aws/core/utils/crypto/MD5.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/crypto/Factories.h> + +using namespace Aws::Utils::Crypto; + + +MD5::MD5() : + m_hashImpl(CreateMD5Implementation()) +{ +} + +MD5::~MD5() +{ +} + +HashResult MD5::Calculate(const Aws::String& str) +{ + return m_hashImpl->Calculate(str); +} + +HashResult MD5::Calculate(Aws::IStream& stream) +{ + return m_hashImpl->Calculate(stream); +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp index 178df00d37..47fbab0207 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp @@ -2,29 +2,29 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/crypto/Sha256.h> -#include <aws/core/utils/Outcome.h> -#include <aws/core/utils/crypto/Factories.h> - -using namespace Aws::Utils::Crypto; - -Sha256::Sha256() : - m_hashImpl(CreateSha256Implementation()) -{ -} - -Sha256::~Sha256() -{ -} - -HashResult Sha256::Calculate(const Aws::String& str) -{ - return m_hashImpl->Calculate(str); -} - -HashResult Sha256::Calculate(Aws::IStream& stream) -{ - return m_hashImpl->Calculate(stream); -}
\ No newline at end of file + + +#include <aws/core/utils/crypto/Sha256.h> +#include <aws/core/utils/Outcome.h> +#include <aws/core/utils/crypto/Factories.h> + +using namespace Aws::Utils::Crypto; + +Sha256::Sha256() : + m_hashImpl(CreateSha256Implementation()) +{ +} + +Sha256::~Sha256() +{ +} + +HashResult Sha256::Calculate(const Aws::String& str) +{ + return m_hashImpl->Calculate(str); +} + +HashResult Sha256::Calculate(Aws::IStream& stream) +{ + return m_hashImpl->Calculate(stream); +}
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp index ecc1f06529..6b16757f77 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp @@ -2,33 +2,33 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/crypto/Sha256HMAC.h> -#include <aws/core/utils/crypto/Factories.h> -#include <aws/core/utils/Outcome.h> - -namespace Aws -{ -namespace Utils -{ -namespace Crypto -{ - -Sha256HMAC::Sha256HMAC() : - m_hmacImpl(CreateSha256HMACImplementation()) -{ -} - -Sha256HMAC::~Sha256HMAC() -{ -} - -HashResult Sha256HMAC::Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret) -{ - return m_hmacImpl->Calculate(toSign, secret); -} - -} // namespace Crypto -} // namespace Utils -} // namespace Aws
\ No newline at end of file + + +#include <aws/core/utils/crypto/Sha256HMAC.h> +#include <aws/core/utils/crypto/Factories.h> +#include <aws/core/utils/Outcome.h> + +namespace Aws +{ +namespace Utils +{ +namespace Crypto +{ + +Sha256HMAC::Sha256HMAC() : + m_hmacImpl(CreateSha256HMACImplementation()) +{ +} + +Sha256HMAC::~Sha256HMAC() +{ +} + +HashResult Sha256HMAC::Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret) +{ + return m_hmacImpl->Calculate(toSign, secret); +} + +} // namespace Crypto +} // namespace Utils +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp index bff0382241..fcecdd1c40 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp @@ -2,51 +2,51 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/crypto/Factories.h> -#include <aws/core/utils/crypto/Hash.h> -#include <aws/core/utils/crypto/HMAC.h> - -#if ENABLE_BCRYPT_ENCRYPTION + + +#include <aws/core/utils/crypto/Factories.h> +#include <aws/core/utils/crypto/Hash.h> +#include <aws/core/utils/crypto/HMAC.h> + +#if ENABLE_BCRYPT_ENCRYPTION #error #include <aws/core/utils/crypto/bcrypt/CryptoImpl.h> -#elif ENABLE_OPENSSL_ENCRYPTION - #include <aws/core/utils/crypto/openssl/CryptoImpl.h> -#elif ENABLE_COMMONCRYPTO_ENCRYPTION +#elif ENABLE_OPENSSL_ENCRYPTION + #include <aws/core/utils/crypto/openssl/CryptoImpl.h> +#elif ENABLE_COMMONCRYPTO_ENCRYPTION #error #include <aws/core/utils/crypto/commoncrypto/CryptoImpl.h> - #include <aws/core/utils/logging/LogMacros.h> -#else - // if you don't have any encryption you still need to pull in the interface definitions - #include <aws/core/utils/crypto/Hash.h> - #include <aws/core/utils/crypto/HMAC.h> - #include <aws/core/utils/crypto/Cipher.h> - #include <aws/core/utils/crypto/SecureRandom.h> - #define NO_ENCRYPTION -#endif - -using namespace Aws::Utils; -using namespace Aws::Utils::Crypto; - -static const char *s_allocationTag = "CryptoFactory"; - + #include <aws/core/utils/logging/LogMacros.h> +#else + // if you don't have any encryption you still need to pull in the interface definitions + #include <aws/core/utils/crypto/Hash.h> + #include <aws/core/utils/crypto/HMAC.h> + #include <aws/core/utils/crypto/Cipher.h> + #include <aws/core/utils/crypto/SecureRandom.h> + #define NO_ENCRYPTION +#endif + +using namespace Aws::Utils; +using namespace Aws::Utils::Crypto; + +static const char *s_allocationTag = "CryptoFactory"; + static std::shared_ptr<HashFactory>& GetMD5Factory() { static std::shared_ptr<HashFactory> s_MD5Factory(nullptr); return s_MD5Factory; } - + static std::shared_ptr<HashFactory>& GetSha256Factory() { static std::shared_ptr<HashFactory> s_Sha256Factory(nullptr); return s_Sha256Factory; } - + static std::shared_ptr<HMACFactory>& GetSha256HMACFactory() { static std::shared_ptr<HMACFactory> s_Sha256HMACFactory(nullptr); return s_Sha256HMACFactory; } - + static std::shared_ptr<SymmetricCipherFactory>& GetAES_CBCFactory() { static std::shared_ptr<SymmetricCipherFactory> s_AES_CBCFactory(nullptr); @@ -83,323 +83,323 @@ static std::shared_ptr<SecureRandomBytes>& GetSecureRandom() return s_SecureRandom; } -static bool s_InitCleanupOpenSSLFlag(false); - -class DefaultMD5Factory : public HashFactory -{ -public: - std::shared_ptr<Hash> CreateImplementation() const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<MD5BcryptImpl>(s_allocationTag); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<MD5OpenSSLImpl>(s_allocationTag); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<MD5CommonCryptoImpl>(s_allocationTag); -#else - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -class DefaultSHA256Factory : public HashFactory -{ -public: - std::shared_ptr<Hash> CreateImplementation() const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<Sha256BcryptImpl>(s_allocationTag); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<Sha256OpenSSLImpl>(s_allocationTag); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<Sha256CommonCryptoImpl>(s_allocationTag); -#else - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -class DefaultSHA256HmacFactory : public HMACFactory -{ -public: - std::shared_ptr<Aws::Utils::Crypto::HMAC> CreateImplementation() const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<Sha256HMACBcryptImpl>(s_allocationTag); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<Sha256HMACOpenSSLImpl>(s_allocationTag); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<Sha256HMACCommonCryptoImpl>(s_allocationTag); -#else - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - - -class DefaultAES_CBCFactory : public SymmetricCipherFactory -{ -public: - std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key); -#else - AWS_UNREFERENCED_PARAM(key); - return nullptr; -#endif - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ +static bool s_InitCleanupOpenSSLFlag(false); + +class DefaultMD5Factory : public HashFactory +{ +public: + std::shared_ptr<Hash> CreateImplementation() const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<MD5BcryptImpl>(s_allocationTag); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<MD5OpenSSLImpl>(s_allocationTag); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<MD5CommonCryptoImpl>(s_allocationTag); +#else + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +class DefaultSHA256Factory : public HashFactory +{ +public: + std::shared_ptr<Hash> CreateImplementation() const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<Sha256BcryptImpl>(s_allocationTag); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<Sha256OpenSSLImpl>(s_allocationTag); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<Sha256CommonCryptoImpl>(s_allocationTag); +#else + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +class DefaultSHA256HmacFactory : public HMACFactory +{ +public: + std::shared_ptr<Aws::Utils::Crypto::HMAC> CreateImplementation() const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<Sha256HMACBcryptImpl>(s_allocationTag); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<Sha256HMACOpenSSLImpl>(s_allocationTag); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<Sha256HMACCommonCryptoImpl>(s_allocationTag); +#else + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + + +class DefaultAES_CBCFactory : public SymmetricCipherFactory +{ +public: + std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key); +#else + AWS_UNREFERENCED_PARAM(key); + return nullptr; +#endif + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer&, const CryptoBuffer&) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv); -#else - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - - return nullptr; -#endif - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv); +#else + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + + return nullptr; +#endif + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&&, CryptoBuffer&&) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv); -#else - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -class DefaultAES_CTRFactory : public SymmetricCipherFactory -{ -public: - std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key); -#else - AWS_UNREFERENCED_PARAM(key); - return nullptr; -#endif - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv); +#else + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +class DefaultAES_CTRFactory : public SymmetricCipherFactory +{ +public: + std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key); +#else + AWS_UNREFERENCED_PARAM(key); + return nullptr; +#endif + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer&, const CryptoBuffer&) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv); -#else - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - - return nullptr; -#endif - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv); +#else + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + + return nullptr; +#endif + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&&, CryptoBuffer&&) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv); -#else - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -class DefaultAES_GCMFactory : public SymmetricCipherFactory -{ -public: - std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv); +#else + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +class DefaultAES_GCMFactory : public SymmetricCipherFactory +{ +public: + std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key); #else - AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(key); - return nullptr; + return nullptr; #endif } @@ -411,464 +411,464 @@ public: return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key, aad); #elif ENABLE_COMMONCRYPTO_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key, aad); -#else - AWS_UNREFERENCED_PARAM(key); +#else + AWS_UNREFERENCED_PARAM(key); AWS_UNREFERENCED_PARAM(aad); - return nullptr; -#endif - } + return nullptr; +#endif + } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer& aad) const override - { -#if ENABLE_BCRYPT_ENCRYPTION + { +#if ENABLE_BCRYPT_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key, iv, tag, aad); -#elif ENABLE_OPENSSL_ENCRYPTION +#elif ENABLE_OPENSSL_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key, iv, tag, aad); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION +#elif ENABLE_COMMONCRYPTO_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key, iv, tag, aad); -#else - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - AWS_UNREFERENCED_PARAM(tag); +#else + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + AWS_UNREFERENCED_PARAM(tag); AWS_UNREFERENCED_PARAM(aad); - return nullptr; -#endif - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + return nullptr; +#endif + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&& aad) const override - { -#if ENABLE_BCRYPT_ENCRYPTION + { +#if ENABLE_BCRYPT_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad)); -#elif ENABLE_OPENSSL_ENCRYPTION +#elif ENABLE_OPENSSL_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad)); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION +#elif ENABLE_COMMONCRYPTO_ENCRYPTION return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad)); -#else - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - AWS_UNREFERENCED_PARAM(tag); +#else + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + AWS_UNREFERENCED_PARAM(tag); AWS_UNREFERENCED_PARAM(aad); - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -class DefaultAES_KeyWrapFactory : public SymmetricCipherFactory -{ -public: - std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<AES_KeyWrap_Cipher_BCrypt>(s_allocationTag, key); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<AES_KeyWrap_Cipher_OpenSSL>(s_allocationTag, key); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<AES_KeyWrap_Cipher_CommonCrypto>(s_allocationTag, key); -#else - AWS_UNREFERENCED_PARAM(key); - return nullptr; -#endif - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +class DefaultAES_KeyWrapFactory : public SymmetricCipherFactory +{ +public: + std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<AES_KeyWrap_Cipher_BCrypt>(s_allocationTag, key); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<AES_KeyWrap_Cipher_OpenSSL>(s_allocationTag, key); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<AES_KeyWrap_Cipher_CommonCrypto>(s_allocationTag, key); +#else + AWS_UNREFERENCED_PARAM(key); + return nullptr; +#endif + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer&) const override - { - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - AWS_UNREFERENCED_PARAM(tag); - return nullptr; - } - /** - * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. - */ + { + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + AWS_UNREFERENCED_PARAM(tag); + return nullptr; + } + /** + * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details. + */ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&&) const override - { - AWS_UNREFERENCED_PARAM(key); - AWS_UNREFERENCED_PARAM(iv); - AWS_UNREFERENCED_PARAM(tag); - return nullptr; - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if (s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if (s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -class DefaultSecureRandFactory : public SecureRandomFactory -{ - /** - * Factory method. Returns SecureRandom implementation. - */ - std::shared_ptr<SecureRandomBytes> CreateImplementation() const override - { -#if ENABLE_BCRYPT_ENCRYPTION - return Aws::MakeShared<SecureRandomBytes_BCrypt>(s_allocationTag); -#elif ENABLE_OPENSSL_ENCRYPTION - return Aws::MakeShared<SecureRandomBytes_OpenSSLImpl>(s_allocationTag); -#elif ENABLE_COMMONCRYPTO_ENCRYPTION - return Aws::MakeShared<SecureRandomBytes_CommonCrypto>(s_allocationTag); -#else - return nullptr; -#endif - } - - /** - * Opportunity to make any static initialization calls you need to make. - * Will only be called once. - */ - void InitStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); - } -#endif - } - - /** - * Opportunity to make any static cleanup calls you need to make. - * will only be called at the end of the application. - */ - void CleanupStaticState() override - { -#if ENABLE_OPENSSL_ENCRYPTION - if(s_InitCleanupOpenSSLFlag) - { - OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); - } -#endif - } -}; - -void Aws::Utils::Crypto::SetInitCleanupOpenSSLFlag(bool initCleanupFlag) -{ - s_InitCleanupOpenSSLFlag = initCleanupFlag; -} - -void Aws::Utils::Crypto::InitCrypto() -{ + { + AWS_UNREFERENCED_PARAM(key); + AWS_UNREFERENCED_PARAM(iv); + AWS_UNREFERENCED_PARAM(tag); + return nullptr; + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if (s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if (s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +class DefaultSecureRandFactory : public SecureRandomFactory +{ + /** + * Factory method. Returns SecureRandom implementation. + */ + std::shared_ptr<SecureRandomBytes> CreateImplementation() const override + { +#if ENABLE_BCRYPT_ENCRYPTION + return Aws::MakeShared<SecureRandomBytes_BCrypt>(s_allocationTag); +#elif ENABLE_OPENSSL_ENCRYPTION + return Aws::MakeShared<SecureRandomBytes_OpenSSLImpl>(s_allocationTag); +#elif ENABLE_COMMONCRYPTO_ENCRYPTION + return Aws::MakeShared<SecureRandomBytes_CommonCrypto>(s_allocationTag); +#else + return nullptr; +#endif + } + + /** + * Opportunity to make any static initialization calls you need to make. + * Will only be called once. + */ + void InitStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state); + } +#endif + } + + /** + * Opportunity to make any static cleanup calls you need to make. + * will only be called at the end of the application. + */ + void CleanupStaticState() override + { +#if ENABLE_OPENSSL_ENCRYPTION + if(s_InitCleanupOpenSSLFlag) + { + OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state); + } +#endif + } +}; + +void Aws::Utils::Crypto::SetInitCleanupOpenSSLFlag(bool initCleanupFlag) +{ + s_InitCleanupOpenSSLFlag = initCleanupFlag; +} + +void Aws::Utils::Crypto::InitCrypto() +{ if(GetMD5Factory()) - { + { GetMD5Factory()->InitStaticState(); - } - else - { + } + else + { GetMD5Factory() = Aws::MakeShared<DefaultMD5Factory>(s_allocationTag); GetMD5Factory()->InitStaticState(); - } - + } + if(GetSha256Factory()) - { + { GetSha256Factory()->InitStaticState(); - } - else - { + } + else + { GetSha256Factory() = Aws::MakeShared<DefaultSHA256Factory>(s_allocationTag); GetSha256Factory()->InitStaticState(); - } - + } + if(GetSha256HMACFactory()) - { + { GetSha256HMACFactory()->InitStaticState(); - } - else - { + } + else + { GetSha256HMACFactory() = Aws::MakeShared<DefaultSHA256HmacFactory>(s_allocationTag); GetSha256HMACFactory()->InitStaticState(); - } - + } + if(GetAES_CBCFactory()) - { + { GetAES_CBCFactory()->InitStaticState(); - } - else - { + } + else + { GetAES_CBCFactory() = Aws::MakeShared<DefaultAES_CBCFactory>(s_allocationTag); GetAES_CBCFactory()->InitStaticState(); - } - + } + if(GetAES_CTRFactory()) - { + { GetAES_CTRFactory()->InitStaticState(); - } - else - { + } + else + { GetAES_CTRFactory() = Aws::MakeShared<DefaultAES_CTRFactory>(s_allocationTag); GetAES_CTRFactory()->InitStaticState(); - } - + } + if(GetAES_GCMFactory()) - { + { GetAES_GCMFactory()->InitStaticState(); - } - else - { + } + else + { GetAES_GCMFactory() = Aws::MakeShared<DefaultAES_GCMFactory>(s_allocationTag); GetAES_GCMFactory()->InitStaticState(); - } - + } + if (!GetAES_KeyWrapFactory()) - { + { GetAES_KeyWrapFactory() = Aws::MakeShared<DefaultAES_KeyWrapFactory>(s_allocationTag); - } + } GetAES_KeyWrapFactory()->InitStaticState(); - + if(GetSecureRandomFactory()) - { + { GetSecureRandomFactory()->InitStaticState(); - } - else - { + } + else + { GetSecureRandomFactory() = Aws::MakeShared<DefaultSecureRandFactory>(s_allocationTag); GetSecureRandomFactory()->InitStaticState(); } GetSecureRandom() = GetSecureRandomFactory()->CreateImplementation(); -} - -void Aws::Utils::Crypto::CleanupCrypto() -{ +} + +void Aws::Utils::Crypto::CleanupCrypto() +{ if(GetMD5Factory()) - { + { GetMD5Factory()->CleanupStaticState(); GetMD5Factory() = nullptr; - } - + } + if(GetSha256Factory()) - { + { GetSha256Factory()->CleanupStaticState(); GetSha256Factory() = nullptr; - } - + } + if(GetSha256HMACFactory()) - { + { GetSha256HMACFactory()->CleanupStaticState(); GetSha256HMACFactory() = nullptr; - } - + } + if(GetAES_CBCFactory()) - { + { GetAES_CBCFactory()->CleanupStaticState(); GetAES_CBCFactory() = nullptr; - } - + } + if(GetAES_CTRFactory()) - { + { GetAES_CTRFactory()->CleanupStaticState(); GetAES_CTRFactory() = nullptr; - } - + } + if(GetAES_GCMFactory()) - { + { GetAES_GCMFactory()->CleanupStaticState(); GetAES_GCMFactory() = nullptr; - } - + } + if(GetAES_KeyWrapFactory()) - { + { GetAES_KeyWrapFactory()->CleanupStaticState(); GetAES_KeyWrapFactory() = nullptr; - } - + } + if(GetSecureRandomFactory()) - { + { GetSecureRandom() = nullptr; GetSecureRandomFactory()->CleanupStaticState(); GetSecureRandomFactory() = nullptr; } -} - -void Aws::Utils::Crypto::SetMD5Factory(const std::shared_ptr<HashFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetMD5Factory(const std::shared_ptr<HashFactory>& factory) +{ GetMD5Factory() = factory; -} - -void Aws::Utils::Crypto::SetSha256Factory(const std::shared_ptr<HashFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetSha256Factory(const std::shared_ptr<HashFactory>& factory) +{ GetSha256Factory() = factory; -} - -void Aws::Utils::Crypto::SetSha256HMACFactory(const std::shared_ptr<HMACFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetSha256HMACFactory(const std::shared_ptr<HMACFactory>& factory) +{ GetSha256HMACFactory() = factory; -} - -void Aws::Utils::Crypto::SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) +{ GetAES_CBCFactory() = factory; -} - -void Aws::Utils::Crypto::SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) +{ GetAES_CTRFactory() = factory; -} - -void Aws::Utils::Crypto::SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) +{ GetAES_GCMFactory() = factory; -} - -void Aws::Utils::Crypto::SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory>& factory) +{ GetAES_KeyWrapFactory() = factory; -} - -void Aws::Utils::Crypto::SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory>& factory) -{ +} + +void Aws::Utils::Crypto::SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory>& factory) +{ GetSecureRandomFactory() = factory; -} - -std::shared_ptr<Hash> Aws::Utils::Crypto::CreateMD5Implementation() -{ +} + +std::shared_ptr<Hash> Aws::Utils::Crypto::CreateMD5Implementation() +{ return GetMD5Factory()->CreateImplementation(); -} - -std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha256Implementation() -{ +} + +std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha256Implementation() +{ return GetSha256Factory()->CreateImplementation(); -} - -std::shared_ptr<Aws::Utils::Crypto::HMAC> Aws::Utils::Crypto::CreateSha256HMACImplementation() -{ +} + +std::shared_ptr<Aws::Utils::Crypto::HMAC> Aws::Utils::Crypto::CreateSha256HMACImplementation() +{ return GetSha256HMACFactory()->CreateImplementation(); -} - -#ifdef _WIN32 -#pragma warning( push ) -#pragma warning( disable : 4702 ) -#endif - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +#ifdef _WIN32 +#pragma warning( push ) +#pragma warning( disable : 4702 ) +#endif + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_CBCFactory()->CreateImplementation(key); -} - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key, const CryptoBuffer& iv) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key, const CryptoBuffer& iv) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_CBCFactory()->CreateImplementation(key, iv); -} - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(CryptoBuffer&& key, CryptoBuffer&& iv) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(CryptoBuffer&& key, CryptoBuffer&& iv) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_CBCFactory()->CreateImplementation(std::move(key), std::move(iv)); -} - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_CTRFactory()->CreateImplementation(key); -} - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key, const CryptoBuffer& iv) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key, const CryptoBuffer& iv) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_CTRFactory()->CreateImplementation(key, iv); -} - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(CryptoBuffer&& key, CryptoBuffer&& iv) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(CryptoBuffer&& key, CryptoBuffer&& iv) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_CTRFactory()->CreateImplementation(std::move(key), std::move(iv)); -} - -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +} + +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_GCMFactory()->CreateImplementation(key); -} - +} + std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer* aad) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_GCMFactory()->CreateImplementation(key, aad); -} - +} + std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer& aad) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_GCMFactory()->CreateImplementation(key, iv, tag, aad); -} - +} + std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&& aad) { #ifdef NO_SYMMETRIC_ENCRYPTION @@ -877,19 +877,19 @@ std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation return GetAES_GCMFactory()->CreateImplementation(std::move(key), std::move(iv), std::move(tag), std::move(aad)); } -std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_KeyWrapImplementation(const CryptoBuffer& key) -{ -#ifdef NO_SYMMETRIC_ENCRYPTION - return nullptr; -#endif +std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_KeyWrapImplementation(const CryptoBuffer& key) +{ +#ifdef NO_SYMMETRIC_ENCRYPTION + return nullptr; +#endif return GetAES_KeyWrapFactory()->CreateImplementation(key); -} - -#ifdef _WIN32 -#pragma warning(pop) -#endif - -std::shared_ptr<SecureRandomBytes> Aws::Utils::Crypto::CreateSecureRandomBytesImplementation() -{ +} + +#ifdef _WIN32 +#pragma warning(pop) +#endif + +std::shared_ptr<SecureRandomBytes> Aws::Utils::Crypto::CreateSecureRandomBytesImplementation() +{ return GetSecureRandom(); -} +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp index 911838864b..49a95e524b 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp @@ -2,13 +2,13 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <cstring> - -#include <aws/core/utils/memory/AWSMemory.h> -#include <aws/core/utils/crypto/openssl/CryptoImpl.h> -#include <aws/core/utils/Outcome.h> -#include <openssl/md5.h> + +#include <cstring> + +#include <aws/core/utils/memory/AWSMemory.h> +#include <aws/core/utils/crypto/openssl/CryptoImpl.h> +#include <aws/core/utils/Outcome.h> +#include <openssl/md5.h> #ifdef OPENSSL_IS_BORINGSSL #ifdef _MSC_VER @@ -18,119 +18,119 @@ AWS_SUPPRESS_WARNING_PUSH("-Wpedantic") #endif #endif -#include <openssl/sha.h> +#include <openssl/sha.h> #ifdef OPENSSL_IS_BORINGSSL AWS_SUPPRESS_WARNING_POP #endif -#include <openssl/err.h> -#include <aws/core/utils/logging/LogMacros.h> -#include <thread> - -using namespace Aws::Utils; -using namespace Aws::Utils::Crypto; - -namespace Aws -{ - namespace Utils - { - namespace Crypto - { - namespace OpenSSL - { -/** - * openssl with OPENSSL_VERSION_NUMBER < 0x10100003L made data type details unavailable +#include <openssl/err.h> +#include <aws/core/utils/logging/LogMacros.h> +#include <thread> + +using namespace Aws::Utils; +using namespace Aws::Utils::Crypto; + +namespace Aws +{ + namespace Utils + { + namespace Crypto + { + namespace OpenSSL + { +/** + * openssl with OPENSSL_VERSION_NUMBER < 0x10100003L made data type details unavailable * libressl use openssl with data type details available, but mandatorily set - * OPENSSL_VERSION_NUMBER = 0x20000000L, insane! - * https://github.com/aws/aws-sdk-cpp/pull/507/commits/2c99f1fe0c4b4683280caeb161538d4724d6a179 - */ -#if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L) -#undef OPENSSL_VERSION_NUMBER -#define OPENSSL_VERSION_NUMBER 0x1000107fL -#endif -#define OPENSSL_VERSION_LESS_1_1 (OPENSSL_VERSION_NUMBER < 0x10100003L) - -#if OPENSSL_VERSION_LESS_1_1 - static const char* OPENSSL_INTERNALS_TAG = "OpenSSLCallbackState"; - static std::mutex* locks(nullptr); -#endif - - GetTheLights getTheLights; - - void init_static_state() - { + * OPENSSL_VERSION_NUMBER = 0x20000000L, insane! + * https://github.com/aws/aws-sdk-cpp/pull/507/commits/2c99f1fe0c4b4683280caeb161538d4724d6a179 + */ +#if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L) +#undef OPENSSL_VERSION_NUMBER +#define OPENSSL_VERSION_NUMBER 0x1000107fL +#endif +#define OPENSSL_VERSION_LESS_1_1 (OPENSSL_VERSION_NUMBER < 0x10100003L) + +#if OPENSSL_VERSION_LESS_1_1 + static const char* OPENSSL_INTERNALS_TAG = "OpenSSLCallbackState"; + static std::mutex* locks(nullptr); +#endif + + GetTheLights getTheLights; + + void init_static_state() + { #if OPENSSL_VERSION_LESS_1_1 || defined(OPENSSL_IS_BORINGSSL) ERR_load_crypto_strings(); #else OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS /*options*/ ,NULL /* OpenSSL init settings*/ ); #endif #if !defined(OPENSSL_IS_BORINGSSL) - OPENSSL_add_all_algorithms_noconf(); -#endif -#if OPENSSL_VERSION_LESS_1_1 - if (!CRYPTO_get_locking_callback()) - { - locks = Aws::NewArray<std::mutex>(static_cast<size_t>(CRYPTO_num_locks()), - OPENSSL_INTERNALS_TAG); - CRYPTO_set_locking_callback(&locking_fn); - } - - if (!CRYPTO_get_id_callback()) - { - CRYPTO_set_id_callback(&id_fn); - } -#endif - RAND_poll(); - } - - void cleanup_static_state() - { -#if OPENSSL_VERSION_LESS_1_1 - if (CRYPTO_get_locking_callback() == &locking_fn) - { - CRYPTO_set_locking_callback(nullptr); - assert(locks); - Aws::DeleteArray(locks); - locks = nullptr; - } - - if (CRYPTO_get_id_callback() == &id_fn) - { - CRYPTO_set_id_callback(nullptr); - } + OPENSSL_add_all_algorithms_noconf(); #endif - } - -#if OPENSSL_VERSION_LESS_1_1 - void locking_fn(int mode, int n, const char*, int) - { - if (mode & CRYPTO_LOCK) - { - locks[n].lock(); - } - else - { - locks[n].unlock(); - } - } - - unsigned long id_fn() - { - return static_cast<unsigned long>(std::hash<std::thread::id>()(std::this_thread::get_id())); - } -#endif - } - +#if OPENSSL_VERSION_LESS_1_1 + if (!CRYPTO_get_locking_callback()) + { + locks = Aws::NewArray<std::mutex>(static_cast<size_t>(CRYPTO_num_locks()), + OPENSSL_INTERNALS_TAG); + CRYPTO_set_locking_callback(&locking_fn); + } + + if (!CRYPTO_get_id_callback()) + { + CRYPTO_set_id_callback(&id_fn); + } +#endif + RAND_poll(); + } + + void cleanup_static_state() + { +#if OPENSSL_VERSION_LESS_1_1 + if (CRYPTO_get_locking_callback() == &locking_fn) + { + CRYPTO_set_locking_callback(nullptr); + assert(locks); + Aws::DeleteArray(locks); + locks = nullptr; + } + + if (CRYPTO_get_id_callback() == &id_fn) + { + CRYPTO_set_id_callback(nullptr); + } +#endif + } + +#if OPENSSL_VERSION_LESS_1_1 + void locking_fn(int mode, int n, const char*, int) + { + if (mode & CRYPTO_LOCK) + { + locks[n].lock(); + } + else + { + locks[n].unlock(); + } + } + + unsigned long id_fn() + { + return static_cast<unsigned long>(std::hash<std::thread::id>()(std::this_thread::get_id())); + } +#endif + } + static const char* OPENSSL_LOG_TAG = "OpenSSLCipher"; - void SecureRandomBytes_OpenSSLImpl::GetBytes(unsigned char* buffer, size_t bufferSize) - { + void SecureRandomBytes_OpenSSLImpl::GetBytes(unsigned char* buffer, size_t bufferSize) + { if (!bufferSize) { return; } - + if (!buffer) { AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Secure Random Bytes generator can't generate: " << bufferSize << " bytes with nullptr buffer."); @@ -138,391 +138,391 @@ namespace Aws return; } - int success = RAND_bytes(buffer, static_cast<int>(bufferSize)); - if (success != 1) - { - m_failure = true; - } - } - + int success = RAND_bytes(buffer, static_cast<int>(bufferSize)); + if (success != 1) + { + m_failure = true; + } + } + class OpensslCtxRAIIGuard - { + { public: OpensslCtxRAIIGuard() - { - m_ctx = EVP_MD_CTX_create(); - assert(m_ctx != nullptr); - } - + { + m_ctx = EVP_MD_CTX_create(); + assert(m_ctx != nullptr); + } + ~OpensslCtxRAIIGuard() - { - EVP_MD_CTX_destroy(m_ctx); - m_ctx = nullptr; - } - + { + EVP_MD_CTX_destroy(m_ctx); + m_ctx = nullptr; + } + EVP_MD_CTX* getResource() - { - return m_ctx; - } - private: - EVP_MD_CTX *m_ctx; - }; - - HashResult MD5OpenSSLImpl::Calculate(const Aws::String& str) - { - OpensslCtxRAIIGuard guard; - auto ctx = guard.getResource(); + { + return m_ctx; + } + private: + EVP_MD_CTX *m_ctx; + }; + + HashResult MD5OpenSSLImpl::Calculate(const Aws::String& str) + { + OpensslCtxRAIIGuard guard; + auto ctx = guard.getResource(); #if !defined(OPENSSL_IS_BORINGSSL) - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); #endif - EVP_DigestInit_ex(ctx, EVP_md5(), nullptr); - EVP_DigestUpdate(ctx, str.c_str(), str.size()); - - ByteBuffer hash(EVP_MD_size(EVP_md5())); - EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); - - return HashResult(std::move(hash)); - } - - HashResult MD5OpenSSLImpl::Calculate(Aws::IStream& stream) - { - OpensslCtxRAIIGuard guard; - auto ctx = guard.getResource(); + EVP_DigestInit_ex(ctx, EVP_md5(), nullptr); + EVP_DigestUpdate(ctx, str.c_str(), str.size()); + + ByteBuffer hash(EVP_MD_size(EVP_md5())); + EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); + + return HashResult(std::move(hash)); + } + + HashResult MD5OpenSSLImpl::Calculate(Aws::IStream& stream) + { + OpensslCtxRAIIGuard guard; + auto ctx = guard.getResource(); #if !defined(OPENSSL_IS_BORINGSSL) - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); #endif - EVP_DigestInit_ex(ctx, EVP_md5(), nullptr); - - auto currentPos = stream.tellg(); - if (currentPos == -1) - { - currentPos = 0; - stream.clear(); - } - stream.seekg(0, stream.beg); - - char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; - while (stream.good()) - { - stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); - auto bytesRead = stream.gcount(); - - if (bytesRead > 0) - { - EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead)); - } - } - - stream.clear(); - stream.seekg(currentPos, stream.beg); - - ByteBuffer hash(EVP_MD_size(EVP_md5())); - EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); - - return HashResult(std::move(hash)); - } - - HashResult Sha256OpenSSLImpl::Calculate(const Aws::String& str) - { - OpensslCtxRAIIGuard guard; - auto ctx = guard.getResource(); - EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr); - EVP_DigestUpdate(ctx, str.c_str(), str.size()); - - ByteBuffer hash(EVP_MD_size(EVP_sha256())); - EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); - - return HashResult(std::move(hash)); - } - - HashResult Sha256OpenSSLImpl::Calculate(Aws::IStream& stream) - { - OpensslCtxRAIIGuard guard; - auto ctx = guard.getResource(); - - EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr); - - auto currentPos = stream.tellg(); - if (currentPos == -1) - { - currentPos = 0; - stream.clear(); - } - - stream.seekg(0, stream.beg); - - char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; - while (stream.good()) - { - stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); - auto bytesRead = stream.gcount(); - - if (bytesRead > 0) - { - EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead)); - } - } - - stream.clear(); - stream.seekg(currentPos, stream.beg); - - ByteBuffer hash(EVP_MD_size(EVP_sha256())); - EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); - - return HashResult(std::move(hash)); - } - - class HMACRAIIGuard { - public: - HMACRAIIGuard() { -#if OPENSSL_VERSION_LESS_1_1 - m_ctx = Aws::New<HMAC_CTX>("AllocSha256HAMCOpenSSLContext"); -#else - m_ctx = HMAC_CTX_new(); -#endif - assert(m_ctx != nullptr); - } - - ~HMACRAIIGuard() { -#if OPENSSL_VERSION_LESS_1_1 - Aws::Delete<HMAC_CTX>(m_ctx); -#else - HMAC_CTX_free(m_ctx); -#endif - m_ctx = nullptr; - } - - HMAC_CTX* getResource() { - return m_ctx; - } - private: - HMAC_CTX *m_ctx; - }; - - HashResult Sha256HMACOpenSSLImpl::Calculate(const ByteBuffer& toSign, const ByteBuffer& secret) - { - unsigned int length = SHA256_DIGEST_LENGTH; - ByteBuffer digest(length); - memset(digest.GetUnderlyingData(), 0, length); - - HMACRAIIGuard guard; - HMAC_CTX* m_ctx = guard.getResource(); - -#if OPENSSL_VERSION_LESS_1_1 - HMAC_CTX_init(m_ctx); -#endif - - HMAC_Init_ex(m_ctx, secret.GetUnderlyingData(), static_cast<int>(secret.GetLength()), EVP_sha256(), - NULL); - HMAC_Update(m_ctx, toSign.GetUnderlyingData(), toSign.GetLength()); - HMAC_Final(m_ctx, digest.GetUnderlyingData(), &length); - -#if OPENSSL_VERSION_LESS_1_1 - HMAC_CTX_cleanup(m_ctx); -#else - HMAC_CTX_reset(m_ctx); -#endif - return HashResult(std::move(digest)); - } - - void LogErrors(const char* logTag = OPENSSL_LOG_TAG) - { - unsigned long errorCode = ERR_get_error(); - char errStr[256]; - ERR_error_string_n(errorCode, errStr, 256); - - AWS_LOGSTREAM_ERROR(logTag, errStr); - } - - OpenSSLCipher::OpenSSLCipher(const CryptoBuffer& key, size_t blockSizeBytes, bool ctrMode) : - SymmetricCipher(key, blockSizeBytes, ctrMode), m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) - { - Init(); - } - - OpenSSLCipher::OpenSSLCipher(OpenSSLCipher&& toMove) : SymmetricCipher(std::move(toMove)), - m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) - { - Init(); - EVP_CIPHER_CTX_copy(m_encryptor_ctx, toMove.m_encryptor_ctx); - EVP_CIPHER_CTX_copy(m_decryptor_ctx, toMove.m_decryptor_ctx); - EVP_CIPHER_CTX_cleanup(toMove.m_encryptor_ctx); - EVP_CIPHER_CTX_cleanup(toMove.m_decryptor_ctx); - } - - OpenSSLCipher::OpenSSLCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag) : - SymmetricCipher(std::move(key), std::move(initializationVector), std::move(tag)), - m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) - { - Init(); - } - - OpenSSLCipher::OpenSSLCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, - const CryptoBuffer& tag) : - SymmetricCipher(key, initializationVector, tag), m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) - { - Init(); - } - - OpenSSLCipher::~OpenSSLCipher() - { - Cleanup(); - if (m_encryptor_ctx) - { - EVP_CIPHER_CTX_free(m_encryptor_ctx); - m_encryptor_ctx = nullptr; - } - if (m_decryptor_ctx) - { - EVP_CIPHER_CTX_free(m_decryptor_ctx); - m_decryptor_ctx = nullptr; - } - } - - void OpenSSLCipher::Init() - { + EVP_DigestInit_ex(ctx, EVP_md5(), nullptr); + + auto currentPos = stream.tellg(); + if (currentPos == -1) + { + currentPos = 0; + stream.clear(); + } + stream.seekg(0, stream.beg); + + char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; + while (stream.good()) + { + stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); + auto bytesRead = stream.gcount(); + + if (bytesRead > 0) + { + EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead)); + } + } + + stream.clear(); + stream.seekg(currentPos, stream.beg); + + ByteBuffer hash(EVP_MD_size(EVP_md5())); + EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); + + return HashResult(std::move(hash)); + } + + HashResult Sha256OpenSSLImpl::Calculate(const Aws::String& str) + { + OpensslCtxRAIIGuard guard; + auto ctx = guard.getResource(); + EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr); + EVP_DigestUpdate(ctx, str.c_str(), str.size()); + + ByteBuffer hash(EVP_MD_size(EVP_sha256())); + EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); + + return HashResult(std::move(hash)); + } + + HashResult Sha256OpenSSLImpl::Calculate(Aws::IStream& stream) + { + OpensslCtxRAIIGuard guard; + auto ctx = guard.getResource(); + + EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr); + + auto currentPos = stream.tellg(); + if (currentPos == -1) + { + currentPos = 0; + stream.clear(); + } + + stream.seekg(0, stream.beg); + + char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE]; + while (stream.good()) + { + stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE); + auto bytesRead = stream.gcount(); + + if (bytesRead > 0) + { + EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead)); + } + } + + stream.clear(); + stream.seekg(currentPos, stream.beg); + + ByteBuffer hash(EVP_MD_size(EVP_sha256())); + EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr); + + return HashResult(std::move(hash)); + } + + class HMACRAIIGuard { + public: + HMACRAIIGuard() { +#if OPENSSL_VERSION_LESS_1_1 + m_ctx = Aws::New<HMAC_CTX>("AllocSha256HAMCOpenSSLContext"); +#else + m_ctx = HMAC_CTX_new(); +#endif + assert(m_ctx != nullptr); + } + + ~HMACRAIIGuard() { +#if OPENSSL_VERSION_LESS_1_1 + Aws::Delete<HMAC_CTX>(m_ctx); +#else + HMAC_CTX_free(m_ctx); +#endif + m_ctx = nullptr; + } + + HMAC_CTX* getResource() { + return m_ctx; + } + private: + HMAC_CTX *m_ctx; + }; + + HashResult Sha256HMACOpenSSLImpl::Calculate(const ByteBuffer& toSign, const ByteBuffer& secret) + { + unsigned int length = SHA256_DIGEST_LENGTH; + ByteBuffer digest(length); + memset(digest.GetUnderlyingData(), 0, length); + + HMACRAIIGuard guard; + HMAC_CTX* m_ctx = guard.getResource(); + +#if OPENSSL_VERSION_LESS_1_1 + HMAC_CTX_init(m_ctx); +#endif + + HMAC_Init_ex(m_ctx, secret.GetUnderlyingData(), static_cast<int>(secret.GetLength()), EVP_sha256(), + NULL); + HMAC_Update(m_ctx, toSign.GetUnderlyingData(), toSign.GetLength()); + HMAC_Final(m_ctx, digest.GetUnderlyingData(), &length); + +#if OPENSSL_VERSION_LESS_1_1 + HMAC_CTX_cleanup(m_ctx); +#else + HMAC_CTX_reset(m_ctx); +#endif + return HashResult(std::move(digest)); + } + + void LogErrors(const char* logTag = OPENSSL_LOG_TAG) + { + unsigned long errorCode = ERR_get_error(); + char errStr[256]; + ERR_error_string_n(errorCode, errStr, 256); + + AWS_LOGSTREAM_ERROR(logTag, errStr); + } + + OpenSSLCipher::OpenSSLCipher(const CryptoBuffer& key, size_t blockSizeBytes, bool ctrMode) : + SymmetricCipher(key, blockSizeBytes, ctrMode), m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) + { + Init(); + } + + OpenSSLCipher::OpenSSLCipher(OpenSSLCipher&& toMove) : SymmetricCipher(std::move(toMove)), + m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) + { + Init(); + EVP_CIPHER_CTX_copy(m_encryptor_ctx, toMove.m_encryptor_ctx); + EVP_CIPHER_CTX_copy(m_decryptor_ctx, toMove.m_decryptor_ctx); + EVP_CIPHER_CTX_cleanup(toMove.m_encryptor_ctx); + EVP_CIPHER_CTX_cleanup(toMove.m_decryptor_ctx); + } + + OpenSSLCipher::OpenSSLCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag) : + SymmetricCipher(std::move(key), std::move(initializationVector), std::move(tag)), + m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) + { + Init(); + } + + OpenSSLCipher::OpenSSLCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector, + const CryptoBuffer& tag) : + SymmetricCipher(key, initializationVector, tag), m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr) + { + Init(); + } + + OpenSSLCipher::~OpenSSLCipher() + { + Cleanup(); + if (m_encryptor_ctx) + { + EVP_CIPHER_CTX_free(m_encryptor_ctx); + m_encryptor_ctx = nullptr; + } + if (m_decryptor_ctx) + { + EVP_CIPHER_CTX_free(m_decryptor_ctx); + m_decryptor_ctx = nullptr; + } + } + + void OpenSSLCipher::Init() + { if (m_failure) { return; } - if (!m_encryptor_ctx) - { - // EVP_CIPHER_CTX_init() will be called inside EVP_CIPHER_CTX_new(). - m_encryptor_ctx = EVP_CIPHER_CTX_new(); - assert(m_encryptor_ctx != nullptr); - } - else - { // _init is the same as _reset after openssl 1.1 - EVP_CIPHER_CTX_init(m_encryptor_ctx); - } - if (!m_decryptor_ctx) - { - // EVP_CIPHER_CTX_init() will be called inside EVP_CIPHER_CTX_new(). - m_decryptor_ctx = EVP_CIPHER_CTX_new(); - assert(m_decryptor_ctx != nullptr); - } - else - { // _init is the same as _reset after openssl 1.1 - EVP_CIPHER_CTX_init(m_decryptor_ctx); - } + if (!m_encryptor_ctx) + { + // EVP_CIPHER_CTX_init() will be called inside EVP_CIPHER_CTX_new(). + m_encryptor_ctx = EVP_CIPHER_CTX_new(); + assert(m_encryptor_ctx != nullptr); + } + else + { // _init is the same as _reset after openssl 1.1 + EVP_CIPHER_CTX_init(m_encryptor_ctx); + } + if (!m_decryptor_ctx) + { + // EVP_CIPHER_CTX_init() will be called inside EVP_CIPHER_CTX_new(). + m_decryptor_ctx = EVP_CIPHER_CTX_new(); + assert(m_decryptor_ctx != nullptr); + } + else + { // _init is the same as _reset after openssl 1.1 + EVP_CIPHER_CTX_init(m_decryptor_ctx); + } m_emptyPlaintext = false; - } - - CryptoBuffer OpenSSLCipher::EncryptBuffer(const CryptoBuffer& unEncryptedData) - { - if (m_failure) - { - AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for encryption. Aborting"); - return CryptoBuffer(); - } - - int lengthWritten = static_cast<int>(unEncryptedData.GetLength() + (GetBlockSizeBytes() - 1)); - CryptoBuffer encryptedText(static_cast<size_t>( lengthWritten + (GetBlockSizeBytes() - 1))); - - if (!EVP_EncryptUpdate(m_encryptor_ctx, encryptedText.GetUnderlyingData(), &lengthWritten, - unEncryptedData.GetUnderlyingData(), - static_cast<int>(unEncryptedData.GetLength()))) - { - m_failure = true; - LogErrors(); - return CryptoBuffer(); - } - - if (static_cast<size_t>(lengthWritten) < encryptedText.GetLength()) - { - return CryptoBuffer(encryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten)); - } - return encryptedText; - } - - CryptoBuffer OpenSSLCipher::FinalizeEncryption() - { - if (m_failure) - { + } + + CryptoBuffer OpenSSLCipher::EncryptBuffer(const CryptoBuffer& unEncryptedData) + { + if (m_failure) + { + AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for encryption. Aborting"); + return CryptoBuffer(); + } + + int lengthWritten = static_cast<int>(unEncryptedData.GetLength() + (GetBlockSizeBytes() - 1)); + CryptoBuffer encryptedText(static_cast<size_t>( lengthWritten + (GetBlockSizeBytes() - 1))); + + if (!EVP_EncryptUpdate(m_encryptor_ctx, encryptedText.GetUnderlyingData(), &lengthWritten, + unEncryptedData.GetUnderlyingData(), + static_cast<int>(unEncryptedData.GetLength()))) + { + m_failure = true; + LogErrors(); + return CryptoBuffer(); + } + + if (static_cast<size_t>(lengthWritten) < encryptedText.GetLength()) + { + return CryptoBuffer(encryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten)); + } + return encryptedText; + } + + CryptoBuffer OpenSSLCipher::FinalizeEncryption() + { + if (m_failure) + { AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for encryption finalization. Aborting"); - return CryptoBuffer(); - } - - CryptoBuffer finalBlock(GetBlockSizeBytes()); - int writtenSize = 0; - if (!EVP_EncryptFinal_ex(m_encryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize)) - { - m_failure = true; - LogErrors(); - return CryptoBuffer(); - } - return CryptoBuffer(finalBlock.GetUnderlyingData(), static_cast<size_t>(writtenSize)); - } - - CryptoBuffer OpenSSLCipher::DecryptBuffer(const CryptoBuffer& encryptedData) - { - if (m_failure) - { - AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for decryption. Aborting"); - return CryptoBuffer(); - } - - int lengthWritten = static_cast<int>(encryptedData.GetLength() + (GetBlockSizeBytes() - 1)); - CryptoBuffer decryptedText(static_cast<size_t>(lengthWritten)); - - if (!EVP_DecryptUpdate(m_decryptor_ctx, decryptedText.GetUnderlyingData(), &lengthWritten, - encryptedData.GetUnderlyingData(), - static_cast<int>(encryptedData.GetLength()))) - { - m_failure = true; - LogErrors(); - return CryptoBuffer(); - } - + return CryptoBuffer(); + } + + CryptoBuffer finalBlock(GetBlockSizeBytes()); + int writtenSize = 0; + if (!EVP_EncryptFinal_ex(m_encryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize)) + { + m_failure = true; + LogErrors(); + return CryptoBuffer(); + } + return CryptoBuffer(finalBlock.GetUnderlyingData(), static_cast<size_t>(writtenSize)); + } + + CryptoBuffer OpenSSLCipher::DecryptBuffer(const CryptoBuffer& encryptedData) + { + if (m_failure) + { + AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for decryption. Aborting"); + return CryptoBuffer(); + } + + int lengthWritten = static_cast<int>(encryptedData.GetLength() + (GetBlockSizeBytes() - 1)); + CryptoBuffer decryptedText(static_cast<size_t>(lengthWritten)); + + if (!EVP_DecryptUpdate(m_decryptor_ctx, decryptedText.GetUnderlyingData(), &lengthWritten, + encryptedData.GetUnderlyingData(), + static_cast<int>(encryptedData.GetLength()))) + { + m_failure = true; + LogErrors(); + return CryptoBuffer(); + } + if (lengthWritten == 0) { m_emptyPlaintext = true; } - if (static_cast<size_t>(lengthWritten) < decryptedText.GetLength()) - { - return CryptoBuffer(decryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten)); - } - return decryptedText; - } - - CryptoBuffer OpenSSLCipher::FinalizeDecryption() - { - if (m_failure) - { + if (static_cast<size_t>(lengthWritten) < decryptedText.GetLength()) + { + return CryptoBuffer(decryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten)); + } + return decryptedText; + } + + CryptoBuffer OpenSSLCipher::FinalizeDecryption() + { + if (m_failure) + { AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for decryption finalization. Aborting"); - return CryptoBuffer(); - } - - CryptoBuffer finalBlock(GetBlockSizeBytes()); - int writtenSize = static_cast<int>(finalBlock.GetLength()); + return CryptoBuffer(); + } + + CryptoBuffer finalBlock(GetBlockSizeBytes()); + int writtenSize = static_cast<int>(finalBlock.GetLength()); int ret = EVP_DecryptFinal_ex(m_decryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize); #if OPENSSL_VERSION_NUMBER > 0x1010104fL //1.1.1d if (ret <= 0) #else if (ret <= 0 && !m_emptyPlaintext) // see details why making exception for empty string at: https://github.com/aws/aws-sdk-cpp/issues/1413 #endif - { - m_failure = true; - LogErrors(); - return CryptoBuffer(); - } - return CryptoBuffer(finalBlock.GetUnderlyingData(), static_cast<size_t>(writtenSize)); - } - - void OpenSSLCipher::Reset() - { - Cleanup(); - Init(); - } - - void OpenSSLCipher::Cleanup() - { - m_failure = false; + { + m_failure = true; + LogErrors(); + return CryptoBuffer(); + } + return CryptoBuffer(finalBlock.GetUnderlyingData(), static_cast<size_t>(writtenSize)); + } + + void OpenSSLCipher::Reset() + { + Cleanup(); + Init(); + } + + void OpenSSLCipher::Cleanup() + { + m_failure = false; if (m_encryptor_ctx) EVP_CIPHER_CTX_cleanup(m_encryptor_ctx); if (m_decryptor_ctx) EVP_CIPHER_CTX_cleanup(m_decryptor_ctx); } - + bool OpenSSLCipher::CheckKeyAndIVLength(size_t expectedKeyLength, size_t expectedIVLength) { if (!m_failure && ((m_key.GetLength() != expectedKeyLength) || m_initializationVector.GetLength() != expectedIVLength)) @@ -531,156 +531,156 @@ namespace Aws m_failure = true; } return !m_failure; - } - - size_t AES_CBC_Cipher_OpenSSL::BlockSizeBytes = 16; - size_t AES_CBC_Cipher_OpenSSL::KeyLengthBits = 256; - static const char* CBC_LOG_TAG = "AES_CBC_Cipher_OpenSSL"; - - AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, BlockSizeBytes) - { - InitCipher(); - } - - AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector) : - OpenSSLCipher(std::move(key), std::move(initializationVector)) - { - InitCipher(); - } - - AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key, - const CryptoBuffer& initializationVector) : - OpenSSLCipher(key, initializationVector) - { - InitCipher(); - } - - void AES_CBC_Cipher_OpenSSL::InitCipher() - { + } + + size_t AES_CBC_Cipher_OpenSSL::BlockSizeBytes = 16; + size_t AES_CBC_Cipher_OpenSSL::KeyLengthBits = 256; + static const char* CBC_LOG_TAG = "AES_CBC_Cipher_OpenSSL"; + + AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, BlockSizeBytes) + { + InitCipher(); + } + + AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector) : + OpenSSLCipher(std::move(key), std::move(initializationVector)) + { + InitCipher(); + } + + AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key, + const CryptoBuffer& initializationVector) : + OpenSSLCipher(key, initializationVector) + { + InitCipher(); + } + + void AES_CBC_Cipher_OpenSSL::InitCipher() + { if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, BlockSizeBytes)) { return; } - if (!EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_cbc(), nullptr, m_key.GetUnderlyingData(), - m_initializationVector.GetUnderlyingData()) || - !EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_cbc(), nullptr, m_key.GetUnderlyingData(), - m_initializationVector.GetUnderlyingData())) - { - m_failure = true; - LogErrors(CBC_LOG_TAG); - } - } - - size_t AES_CBC_Cipher_OpenSSL::GetBlockSizeBytes() const - { - return BlockSizeBytes; - } - - size_t AES_CBC_Cipher_OpenSSL::GetKeyLengthBits() const - { - return KeyLengthBits; - } - + if (!EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_cbc(), nullptr, m_key.GetUnderlyingData(), + m_initializationVector.GetUnderlyingData()) || + !EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_cbc(), nullptr, m_key.GetUnderlyingData(), + m_initializationVector.GetUnderlyingData())) + { + m_failure = true; + LogErrors(CBC_LOG_TAG); + } + } + + size_t AES_CBC_Cipher_OpenSSL::GetBlockSizeBytes() const + { + return BlockSizeBytes; + } + + size_t AES_CBC_Cipher_OpenSSL::GetKeyLengthBits() const + { + return KeyLengthBits; + } + void AES_CBC_Cipher_OpenSSL::Reset() { OpenSSLCipher::Reset(); InitCipher(); } - size_t AES_CTR_Cipher_OpenSSL::BlockSizeBytes = 16; - size_t AES_CTR_Cipher_OpenSSL::KeyLengthBits = 256; - static const char* CTR_LOG_TAG = "AES_CTR_Cipher_OpenSSL"; - - AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, BlockSizeBytes, - true) - { - InitCipher(); - } - - AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector) : - OpenSSLCipher(std::move(key), std::move(initializationVector)) - { - InitCipher(); - } - - AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key, - const CryptoBuffer& initializationVector) : - OpenSSLCipher(key, initializationVector) - { - InitCipher(); - } - - void AES_CTR_Cipher_OpenSSL::InitCipher() - { + size_t AES_CTR_Cipher_OpenSSL::BlockSizeBytes = 16; + size_t AES_CTR_Cipher_OpenSSL::KeyLengthBits = 256; + static const char* CTR_LOG_TAG = "AES_CTR_Cipher_OpenSSL"; + + AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, BlockSizeBytes, + true) + { + InitCipher(); + } + + AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector) : + OpenSSLCipher(std::move(key), std::move(initializationVector)) + { + InitCipher(); + } + + AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key, + const CryptoBuffer& initializationVector) : + OpenSSLCipher(key, initializationVector) + { + InitCipher(); + } + + void AES_CTR_Cipher_OpenSSL::InitCipher() + { if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, BlockSizeBytes)) { return; } - if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_ctr(), nullptr, m_key.GetUnderlyingData(), - m_initializationVector.GetUnderlyingData()) - && EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) || - !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_ctr(), nullptr, m_key.GetUnderlyingData(), - m_initializationVector.GetUnderlyingData()) - && EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0))) - { - m_failure = true; - LogErrors(CTR_LOG_TAG); - } - } - - size_t AES_CTR_Cipher_OpenSSL::GetBlockSizeBytes() const - { - return BlockSizeBytes; - } - - size_t AES_CTR_Cipher_OpenSSL::GetKeyLengthBits() const - { - return KeyLengthBits; - } - + if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_ctr(), nullptr, m_key.GetUnderlyingData(), + m_initializationVector.GetUnderlyingData()) + && EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) || + !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_ctr(), nullptr, m_key.GetUnderlyingData(), + m_initializationVector.GetUnderlyingData()) + && EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0))) + { + m_failure = true; + LogErrors(CTR_LOG_TAG); + } + } + + size_t AES_CTR_Cipher_OpenSSL::GetBlockSizeBytes() const + { + return BlockSizeBytes; + } + + size_t AES_CTR_Cipher_OpenSSL::GetKeyLengthBits() const + { + return KeyLengthBits; + } + void AES_CTR_Cipher_OpenSSL::Reset() { OpenSSLCipher::Reset(); InitCipher(); } - size_t AES_GCM_Cipher_OpenSSL::BlockSizeBytes = 16; - size_t AES_GCM_Cipher_OpenSSL::KeyLengthBits = 256; - size_t AES_GCM_Cipher_OpenSSL::IVLengthBytes = 12; - size_t AES_GCM_Cipher_OpenSSL::TagLengthBytes = 16; - - static const char* GCM_LOG_TAG = "AES_GCM_Cipher_OpenSSL"; - + size_t AES_GCM_Cipher_OpenSSL::BlockSizeBytes = 16; + size_t AES_GCM_Cipher_OpenSSL::KeyLengthBits = 256; + size_t AES_GCM_Cipher_OpenSSL::IVLengthBytes = 12; + size_t AES_GCM_Cipher_OpenSSL::TagLengthBytes = 16; + + static const char* GCM_LOG_TAG = "AES_GCM_Cipher_OpenSSL"; + AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, IVLengthBytes) - { - InitCipher(); - } - + { + InitCipher(); + } + AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer* aad) : OpenSSLCipher(key, IVLengthBytes), m_aad(*aad) { InitCipher(); } - AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector, + AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag, CryptoBuffer&& aad) : OpenSSLCipher(std::move(key), std::move(initializationVector), std::move(tag)), m_aad(std::move(aad)) - { - InitCipher(); - } - + { + InitCipher(); + } + AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector, const CryptoBuffer& tag, const CryptoBuffer& aad) : OpenSSLCipher(key, initializationVector, tag), m_aad(std::move(aad)) - { - InitCipher(); - } - - CryptoBuffer AES_GCM_Cipher_OpenSSL::FinalizeEncryption() - { + { + InitCipher(); + } + + CryptoBuffer AES_GCM_Cipher_OpenSSL::FinalizeEncryption() + { if (m_failure) { AWS_LOGSTREAM_FATAL(GCM_LOG_TAG, "Cipher not properly initialized for encryption finalization. Aborting"); @@ -691,38 +691,38 @@ namespace Aws CryptoBuffer finalBlock(GetBlockSizeBytes()); EVP_EncryptFinal_ex(m_encryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize); - m_tag = CryptoBuffer(TagLengthBytes); + m_tag = CryptoBuffer(TagLengthBytes); if (!EVP_CIPHER_CTX_ctrl(m_encryptor_ctx, EVP_CTRL_GCM_GET_TAG, static_cast<int>(m_tag.GetLength()), - m_tag.GetUnderlyingData())) - { - m_failure = true; - LogErrors(GCM_LOG_TAG); - } - + m_tag.GetUnderlyingData())) + { + m_failure = true; + LogErrors(GCM_LOG_TAG); + } + return CryptoBuffer(); - } - - void AES_GCM_Cipher_OpenSSL::InitCipher() - { + } + + void AES_GCM_Cipher_OpenSSL::InitCipher() + { if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, IVLengthBytes)) { return; } - if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) && - EVP_EncryptInit_ex(m_encryptor_ctx, nullptr, nullptr, m_key.GetUnderlyingData(), - m_initializationVector.GetUnderlyingData()) && - EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) || - !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) && - EVP_DecryptInit_ex(m_decryptor_ctx, nullptr, nullptr, m_key.GetUnderlyingData(), - m_initializationVector.GetUnderlyingData()) && - EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0))) - { - m_failure = true; - LogErrors(GCM_LOG_TAG); - return; - } - + if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) && + EVP_EncryptInit_ex(m_encryptor_ctx, nullptr, nullptr, m_key.GetUnderlyingData(), + m_initializationVector.GetUnderlyingData()) && + EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) || + !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) && + EVP_DecryptInit_ex(m_decryptor_ctx, nullptr, nullptr, m_key.GetUnderlyingData(), + m_initializationVector.GetUnderlyingData()) && + EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0))) + { + m_failure = true; + LogErrors(GCM_LOG_TAG); + return; + } + if (m_aad.GetLength() > 0) { int outLen = 0; @@ -735,246 +735,246 @@ namespace Aws } } - //tag should always be set in GCM decrypt mode - if (m_tag.GetLength() > 0) - { - if (m_tag.GetLength() < TagLengthBytes) - { + //tag should always be set in GCM decrypt mode + if (m_tag.GetLength() > 0) + { + if (m_tag.GetLength() < TagLengthBytes) + { AWS_LOGSTREAM_ERROR(GCM_LOG_TAG, "Illegal attempt to decrypt an AES GCM payload without a valid tag set: tag length=" << m_tag.GetLength()); - m_failure = true; - return; - } - + m_failure = true; + return; + } + if (!EVP_CIPHER_CTX_ctrl(m_decryptor_ctx, EVP_CTRL_GCM_SET_TAG, static_cast<int>(m_tag.GetLength()), m_tag.GetUnderlyingData())) - { - m_failure = true; - LogErrors(GCM_LOG_TAG); - } - } - } - - size_t AES_GCM_Cipher_OpenSSL::GetBlockSizeBytes() const - { - return BlockSizeBytes; - } - - size_t AES_GCM_Cipher_OpenSSL::GetKeyLengthBits() const - { - return KeyLengthBits; - } - - size_t AES_GCM_Cipher_OpenSSL::GetTagLengthBytes() const - { - return TagLengthBytes; - } - + { + m_failure = true; + LogErrors(GCM_LOG_TAG); + } + } + } + + size_t AES_GCM_Cipher_OpenSSL::GetBlockSizeBytes() const + { + return BlockSizeBytes; + } + + size_t AES_GCM_Cipher_OpenSSL::GetKeyLengthBits() const + { + return KeyLengthBits; + } + + size_t AES_GCM_Cipher_OpenSSL::GetTagLengthBytes() const + { + return TagLengthBytes; + } + void AES_GCM_Cipher_OpenSSL::Reset() { OpenSSLCipher::Reset(); InitCipher(); } - size_t AES_KeyWrap_Cipher_OpenSSL::KeyLengthBits = 256; - size_t AES_KeyWrap_Cipher_OpenSSL::BlockSizeBytes = 8; - static const unsigned char INTEGRITY_VALUE = 0xA6; - static const size_t MIN_CEK_LENGTH_BYTES = 128 / 8; - - static const char* KEY_WRAP_TAG = "AES_KeyWrap_Cipher_OpenSSL"; - - AES_KeyWrap_Cipher_OpenSSL::AES_KeyWrap_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, 0) - { - InitCipher(); - } - - CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::EncryptBuffer(const CryptoBuffer& plainText) - { + size_t AES_KeyWrap_Cipher_OpenSSL::KeyLengthBits = 256; + size_t AES_KeyWrap_Cipher_OpenSSL::BlockSizeBytes = 8; + static const unsigned char INTEGRITY_VALUE = 0xA6; + static const size_t MIN_CEK_LENGTH_BYTES = 128 / 8; + + static const char* KEY_WRAP_TAG = "AES_KeyWrap_Cipher_OpenSSL"; + + AES_KeyWrap_Cipher_OpenSSL::AES_KeyWrap_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, 0) + { + InitCipher(); + } + + CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::EncryptBuffer(const CryptoBuffer& plainText) + { if (!m_failure) { m_workingKeyBuffer = CryptoBuffer({&m_workingKeyBuffer, (CryptoBuffer*) &plainText}); } - return CryptoBuffer(); - } - - CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::FinalizeEncryption() - { - if (m_failure) - { - AWS_LOGSTREAM_FATAL(KEY_WRAP_TAG, "Cipher not properly initialized for encryption finalization. Aborting"); - return CryptoBuffer(); - } - - if (m_workingKeyBuffer.GetLength() < MIN_CEK_LENGTH_BYTES) - { - AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Incorrect input length of " << m_workingKeyBuffer.GetLength()); - m_failure = true; - return CryptoBuffer(); - } - - //the following is an in place implementation of + return CryptoBuffer(); + } + + CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::FinalizeEncryption() + { + if (m_failure) + { + AWS_LOGSTREAM_FATAL(KEY_WRAP_TAG, "Cipher not properly initialized for encryption finalization. Aborting"); + return CryptoBuffer(); + } + + if (m_workingKeyBuffer.GetLength() < MIN_CEK_LENGTH_BYTES) + { + AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Incorrect input length of " << m_workingKeyBuffer.GetLength()); + m_failure = true; + return CryptoBuffer(); + } + + //the following is an in place implementation of //RFC 3394 using the alternate in-place implementation. - //we use one in-place buffer instead of the copy at the end. - //the one letter variable names are meant to directly reflect the variables in the RFC - CryptoBuffer cipherText(m_workingKeyBuffer.GetLength() + BlockSizeBytes); - - //put the integrity check register in the first 8 bytes of the final buffer. - memset(cipherText.GetUnderlyingData(), INTEGRITY_VALUE, BlockSizeBytes); - unsigned char* a = cipherText.GetUnderlyingData(); - - //put the register buffer after the integrity check register - memcpy(cipherText.GetUnderlyingData() + BlockSizeBytes, m_workingKeyBuffer.GetUnderlyingData(), - m_workingKeyBuffer.GetLength()); - unsigned char* r = cipherText.GetUnderlyingData() + BlockSizeBytes; - - int n = static_cast<int>(m_workingKeyBuffer.GetLength() / BlockSizeBytes); - - //temporary encryption buffer - CryptoBuffer b(BlockSizeBytes * 2); - int outLen = static_cast<int>(b.GetLength()); - - //concatenation buffer - CryptoBuffer tempInput(BlockSizeBytes * 2); - - for (int j = 0; j <= 5; ++j) - { - for (int i = 1; i <= n; ++i) - { - //concat A and R[i], A should be most significant and then R[i] should be least significant. - memcpy(tempInput.GetUnderlyingData(), a, BlockSizeBytes); - memcpy(tempInput.GetUnderlyingData() + BlockSizeBytes, r, BlockSizeBytes); - - //encrypt the concatenated A and R[I] and store it in B - if (!EVP_EncryptUpdate(m_encryptor_ctx, b.GetUnderlyingData(), &outLen, - tempInput.GetUnderlyingData(), static_cast<int>(tempInput.GetLength()))) - { - LogErrors(KEY_WRAP_TAG); - m_failure = true; - return CryptoBuffer(); - } - - unsigned char t = static_cast<unsigned char>((n * j) + i); - //put the 64 MSB ^ T into A - memcpy(a, b.GetUnderlyingData(), BlockSizeBytes); - a[7] ^= t; - //put the 64 LSB into R[i] - memcpy(r, b.GetUnderlyingData() + BlockSizeBytes, BlockSizeBytes); - //increment i -> R[i] - r += BlockSizeBytes; - } - //reset R - r = cipherText.GetUnderlyingData() + BlockSizeBytes; - } - - return cipherText; - } - - CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::DecryptBuffer(const CryptoBuffer& cipherText) - { + //we use one in-place buffer instead of the copy at the end. + //the one letter variable names are meant to directly reflect the variables in the RFC + CryptoBuffer cipherText(m_workingKeyBuffer.GetLength() + BlockSizeBytes); + + //put the integrity check register in the first 8 bytes of the final buffer. + memset(cipherText.GetUnderlyingData(), INTEGRITY_VALUE, BlockSizeBytes); + unsigned char* a = cipherText.GetUnderlyingData(); + + //put the register buffer after the integrity check register + memcpy(cipherText.GetUnderlyingData() + BlockSizeBytes, m_workingKeyBuffer.GetUnderlyingData(), + m_workingKeyBuffer.GetLength()); + unsigned char* r = cipherText.GetUnderlyingData() + BlockSizeBytes; + + int n = static_cast<int>(m_workingKeyBuffer.GetLength() / BlockSizeBytes); + + //temporary encryption buffer + CryptoBuffer b(BlockSizeBytes * 2); + int outLen = static_cast<int>(b.GetLength()); + + //concatenation buffer + CryptoBuffer tempInput(BlockSizeBytes * 2); + + for (int j = 0; j <= 5; ++j) + { + for (int i = 1; i <= n; ++i) + { + //concat A and R[i], A should be most significant and then R[i] should be least significant. + memcpy(tempInput.GetUnderlyingData(), a, BlockSizeBytes); + memcpy(tempInput.GetUnderlyingData() + BlockSizeBytes, r, BlockSizeBytes); + + //encrypt the concatenated A and R[I] and store it in B + if (!EVP_EncryptUpdate(m_encryptor_ctx, b.GetUnderlyingData(), &outLen, + tempInput.GetUnderlyingData(), static_cast<int>(tempInput.GetLength()))) + { + LogErrors(KEY_WRAP_TAG); + m_failure = true; + return CryptoBuffer(); + } + + unsigned char t = static_cast<unsigned char>((n * j) + i); + //put the 64 MSB ^ T into A + memcpy(a, b.GetUnderlyingData(), BlockSizeBytes); + a[7] ^= t; + //put the 64 LSB into R[i] + memcpy(r, b.GetUnderlyingData() + BlockSizeBytes, BlockSizeBytes); + //increment i -> R[i] + r += BlockSizeBytes; + } + //reset R + r = cipherText.GetUnderlyingData() + BlockSizeBytes; + } + + return cipherText; + } + + CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::DecryptBuffer(const CryptoBuffer& cipherText) + { if (!m_failure) { m_workingKeyBuffer = CryptoBuffer({&m_workingKeyBuffer, (CryptoBuffer*)&cipherText}); } - return CryptoBuffer(); - } - - CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::FinalizeDecryption() - { - if (m_failure) - { - AWS_LOGSTREAM_FATAL(KEY_WRAP_TAG, "Cipher not properly initialized for decryption finalization. Aborting"); - return CryptoBuffer(); - } - - if (m_workingKeyBuffer.GetLength() < MIN_CEK_LENGTH_BYTES + BlockSizeBytes) - { - AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Incorrect input length of " << m_workingKeyBuffer.GetLength()); - m_failure = true; - return CryptoBuffer(); - } - - //the following is an in place implementation of - //RFC 3394 using the alternate in-place implementation. - //we use one in-place buffer instead of the copy at the end. - //the one letter variable names are meant to directly reflect the variables in the RFC - CryptoBuffer plainText(m_workingKeyBuffer.GetLength() - BlockSizeBytes); - memcpy(plainText.GetUnderlyingData(), m_workingKeyBuffer.GetUnderlyingData() + BlockSizeBytes, plainText.GetLength()); - - //integrity register should be the first 8 bytes of the cipher text - unsigned char* a = m_workingKeyBuffer.GetUnderlyingData(); - - //in-place register is the plaintext. For decryption, start at the last array position (8 bytes before the end); - unsigned char* r = plainText.GetUnderlyingData() + plainText.GetLength() - BlockSizeBytes; - - int n = static_cast<int>(plainText.GetLength() / BlockSizeBytes); - - //temporary encryption buffer - CryptoBuffer b(BlockSizeBytes * 10); - int outLen = static_cast<int>(b.GetLength()); - - //concatenation buffer - CryptoBuffer tempInput(BlockSizeBytes * 2); - - for(int j = 5; j >= 0; --j) - { - for(int i = n; i >= 1; --i) - { - //concat - //A ^ t - memcpy(tempInput.GetUnderlyingData(), a, BlockSizeBytes); - unsigned char t = static_cast<unsigned char>((n * j) + i); - tempInput[7] ^= t; - //R[i] - memcpy(tempInput.GetUnderlyingData() + BlockSizeBytes, r, BlockSizeBytes); - - //Decrypt the concatenated buffer - if(!EVP_DecryptUpdate(m_decryptor_ctx, b.GetUnderlyingData(), &outLen, - tempInput.GetUnderlyingData(), static_cast<int>(tempInput.GetLength()))) - { - m_failure = true; - LogErrors(KEY_WRAP_TAG); - return CryptoBuffer(); - } - - //set A to MSB 64 bits of decrypted result - memcpy(a, b.GetUnderlyingData(), BlockSizeBytes); - //set R[i] to LSB 64 bits of decrypted result - memcpy(r, b.GetUnderlyingData() + BlockSizeBytes, BlockSizeBytes); - //decrement i -> R[i] - r -= BlockSizeBytes; - } - - r = plainText.GetUnderlyingData() + plainText.GetLength() - BlockSizeBytes; - } - - //here we perform the integrity check to make sure A == 0xA6A6A6A6A6A6A6A6 - for(size_t i = 0; i < BlockSizeBytes; ++i) - { - if(a[i] != INTEGRITY_VALUE) - { - m_failure = true; - AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Integrity check failed for key wrap decryption."); - return CryptoBuffer(); - } - } - - return plainText; - } - - void AES_KeyWrap_Cipher_OpenSSL::InitCipher() - { + return CryptoBuffer(); + } + + CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::FinalizeDecryption() + { + if (m_failure) + { + AWS_LOGSTREAM_FATAL(KEY_WRAP_TAG, "Cipher not properly initialized for decryption finalization. Aborting"); + return CryptoBuffer(); + } + + if (m_workingKeyBuffer.GetLength() < MIN_CEK_LENGTH_BYTES + BlockSizeBytes) + { + AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Incorrect input length of " << m_workingKeyBuffer.GetLength()); + m_failure = true; + return CryptoBuffer(); + } + + //the following is an in place implementation of + //RFC 3394 using the alternate in-place implementation. + //we use one in-place buffer instead of the copy at the end. + //the one letter variable names are meant to directly reflect the variables in the RFC + CryptoBuffer plainText(m_workingKeyBuffer.GetLength() - BlockSizeBytes); + memcpy(plainText.GetUnderlyingData(), m_workingKeyBuffer.GetUnderlyingData() + BlockSizeBytes, plainText.GetLength()); + + //integrity register should be the first 8 bytes of the cipher text + unsigned char* a = m_workingKeyBuffer.GetUnderlyingData(); + + //in-place register is the plaintext. For decryption, start at the last array position (8 bytes before the end); + unsigned char* r = plainText.GetUnderlyingData() + plainText.GetLength() - BlockSizeBytes; + + int n = static_cast<int>(plainText.GetLength() / BlockSizeBytes); + + //temporary encryption buffer + CryptoBuffer b(BlockSizeBytes * 10); + int outLen = static_cast<int>(b.GetLength()); + + //concatenation buffer + CryptoBuffer tempInput(BlockSizeBytes * 2); + + for(int j = 5; j >= 0; --j) + { + for(int i = n; i >= 1; --i) + { + //concat + //A ^ t + memcpy(tempInput.GetUnderlyingData(), a, BlockSizeBytes); + unsigned char t = static_cast<unsigned char>((n * j) + i); + tempInput[7] ^= t; + //R[i] + memcpy(tempInput.GetUnderlyingData() + BlockSizeBytes, r, BlockSizeBytes); + + //Decrypt the concatenated buffer + if(!EVP_DecryptUpdate(m_decryptor_ctx, b.GetUnderlyingData(), &outLen, + tempInput.GetUnderlyingData(), static_cast<int>(tempInput.GetLength()))) + { + m_failure = true; + LogErrors(KEY_WRAP_TAG); + return CryptoBuffer(); + } + + //set A to MSB 64 bits of decrypted result + memcpy(a, b.GetUnderlyingData(), BlockSizeBytes); + //set R[i] to LSB 64 bits of decrypted result + memcpy(r, b.GetUnderlyingData() + BlockSizeBytes, BlockSizeBytes); + //decrement i -> R[i] + r -= BlockSizeBytes; + } + + r = plainText.GetUnderlyingData() + plainText.GetLength() - BlockSizeBytes; + } + + //here we perform the integrity check to make sure A == 0xA6A6A6A6A6A6A6A6 + for(size_t i = 0; i < BlockSizeBytes; ++i) + { + if(a[i] != INTEGRITY_VALUE) + { + m_failure = true; + AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Integrity check failed for key wrap decryption."); + return CryptoBuffer(); + } + } + + return plainText; + } + + void AES_KeyWrap_Cipher_OpenSSL::InitCipher() + { if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, 0)) { return; } - if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_ecb(), nullptr, m_key.GetUnderlyingData(), nullptr) && - EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) || - !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_ecb(), nullptr, m_key.GetUnderlyingData(), nullptr) && - EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0))) - { - m_failure = true; - LogErrors(KEY_WRAP_TAG); - } - } + if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_ecb(), nullptr, m_key.GetUnderlyingData(), nullptr) && + EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) || + !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_ecb(), nullptr, m_key.GetUnderlyingData(), nullptr) && + EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0))) + { + m_failure = true; + LogErrors(KEY_WRAP_TAG); + } + } void AES_KeyWrap_Cipher_OpenSSL::Reset() { @@ -982,6 +982,6 @@ namespace Aws OpenSSLCipher::Reset(); InitCipher(); } - } - } -} + } + } +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp index 9b785d1995..cbf7d01678 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp @@ -2,190 +2,190 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/json/JsonSerializer.h> - -#include <iterator> -#include <algorithm> -#include <aws/core/utils/memory/stl/AWSStringStream.h> + +#include <aws/core/utils/json/JsonSerializer.h> + +#include <iterator> +#include <algorithm> +#include <aws/core/utils/memory/stl/AWSStringStream.h> #include <aws/core/utils/StringUtils.h> - -using namespace Aws::Utils; -using namespace Aws::Utils::Json; - -JsonValue::JsonValue() : m_wasParseSuccessful(true) -{ - m_value = nullptr; -} - -JsonValue::JsonValue(cJSON* value) : - m_value(cJSON_Duplicate(value, true /* recurse */)), - m_wasParseSuccessful(true) -{ -} - -JsonValue::JsonValue(const Aws::String& value) : m_wasParseSuccessful(true) -{ - const char* return_parse_end; - m_value = cJSON_ParseWithOpts(value.c_str(), &return_parse_end, 1/*require_null_terminated*/); - - if (!m_value || cJSON_IsInvalid(m_value)) - { - m_wasParseSuccessful = false; - m_errorMessage = "Failed to parse JSON at: "; - m_errorMessage += return_parse_end; - } -} - -JsonValue::JsonValue(Aws::IStream& istream) : m_wasParseSuccessful(true) -{ - Aws::StringStream memoryStream; - std::copy(std::istreambuf_iterator<char>(istream), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(memoryStream)); - const char* return_parse_end; - const auto input = memoryStream.str(); - m_value = cJSON_ParseWithOpts(input.c_str(), &return_parse_end, 1/*require_null_terminated*/); - - if (!m_value || cJSON_IsInvalid(m_value)) - { - m_wasParseSuccessful = false; - m_errorMessage = "Failed to parse JSON. Invalid input at: "; - m_errorMessage += return_parse_end; - } -} - -JsonValue::JsonValue(const JsonValue& value) : - m_value(cJSON_Duplicate(value.m_value, true/*recurse*/)), - m_wasParseSuccessful(value.m_wasParseSuccessful), - m_errorMessage(value.m_errorMessage) -{ -} - -JsonValue::JsonValue(JsonValue&& value) : - m_value(value.m_value), - m_wasParseSuccessful(value.m_wasParseSuccessful), - m_errorMessage(std::move(value.m_errorMessage)) -{ - value.m_value = nullptr; -} - -void JsonValue::Destroy() -{ - cJSON_Delete(m_value); -} - -JsonValue::~JsonValue() -{ - Destroy(); -} - -JsonValue& JsonValue::operator=(const JsonValue& other) -{ - if (this == &other) - { - return *this; - } - - Destroy(); - m_value = cJSON_Duplicate(other.m_value, true /*recurse*/); - m_wasParseSuccessful = other.m_wasParseSuccessful; - m_errorMessage = other.m_errorMessage; - return *this; -} - -JsonValue& JsonValue::operator=(JsonValue&& other) -{ - if (this == &other) - { - return *this; - } - - using std::swap; - swap(m_value, other.m_value); - swap(m_errorMessage, other.m_errorMessage); - m_wasParseSuccessful = other.m_wasParseSuccessful; - return *this; -} - -static void AddOrReplace(cJSON* root, const char* key, cJSON* value) -{ - const auto existing = cJSON_GetObjectItemCaseSensitive(root, key); - if (existing) - { - cJSON_ReplaceItemInObjectCaseSensitive(root, key, value); - } - else - { - cJSON_AddItemToObject(root, key, value); - } -} - -JsonValue& JsonValue::WithString(const char* key, const Aws::String& value) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - const auto val = cJSON_CreateString(value.c_str()); - AddOrReplace(m_value, key, val); - return *this; -} - -JsonValue& JsonValue::WithString(const Aws::String& key, const Aws::String& value) -{ - return WithString(key.c_str(), value); -} - -JsonValue& JsonValue::AsString(const Aws::String& value) -{ - Destroy(); - m_value = cJSON_CreateString(value.c_str()); - return *this; -} - -JsonValue& JsonValue::WithBool(const char* key, bool value) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - const auto val = cJSON_CreateBool(value); - AddOrReplace(m_value, key, val); - return *this; -} - -JsonValue& JsonValue::WithBool(const Aws::String& key, bool value) -{ - return WithBool(key.c_str(), value); -} - -JsonValue& JsonValue::AsBool(bool value) -{ - Destroy(); - m_value = cJSON_CreateBool(value); - return *this; -} - -JsonValue& JsonValue::WithInteger(const char* key, int value) -{ - return WithDouble(key, static_cast<double>(value)); -} - -JsonValue& JsonValue::WithInteger(const Aws::String& key, int value) -{ - return WithDouble(key.c_str(), static_cast<double>(value)); -} - -JsonValue& JsonValue::AsInteger(int value) -{ - Destroy(); - m_value = cJSON_CreateNumber(static_cast<double>(value)); - return *this; -} - -JsonValue& JsonValue::WithInt64(const char* key, long long value) -{ + +using namespace Aws::Utils; +using namespace Aws::Utils::Json; + +JsonValue::JsonValue() : m_wasParseSuccessful(true) +{ + m_value = nullptr; +} + +JsonValue::JsonValue(cJSON* value) : + m_value(cJSON_Duplicate(value, true /* recurse */)), + m_wasParseSuccessful(true) +{ +} + +JsonValue::JsonValue(const Aws::String& value) : m_wasParseSuccessful(true) +{ + const char* return_parse_end; + m_value = cJSON_ParseWithOpts(value.c_str(), &return_parse_end, 1/*require_null_terminated*/); + + if (!m_value || cJSON_IsInvalid(m_value)) + { + m_wasParseSuccessful = false; + m_errorMessage = "Failed to parse JSON at: "; + m_errorMessage += return_parse_end; + } +} + +JsonValue::JsonValue(Aws::IStream& istream) : m_wasParseSuccessful(true) +{ + Aws::StringStream memoryStream; + std::copy(std::istreambuf_iterator<char>(istream), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(memoryStream)); + const char* return_parse_end; + const auto input = memoryStream.str(); + m_value = cJSON_ParseWithOpts(input.c_str(), &return_parse_end, 1/*require_null_terminated*/); + + if (!m_value || cJSON_IsInvalid(m_value)) + { + m_wasParseSuccessful = false; + m_errorMessage = "Failed to parse JSON. Invalid input at: "; + m_errorMessage += return_parse_end; + } +} + +JsonValue::JsonValue(const JsonValue& value) : + m_value(cJSON_Duplicate(value.m_value, true/*recurse*/)), + m_wasParseSuccessful(value.m_wasParseSuccessful), + m_errorMessage(value.m_errorMessage) +{ +} + +JsonValue::JsonValue(JsonValue&& value) : + m_value(value.m_value), + m_wasParseSuccessful(value.m_wasParseSuccessful), + m_errorMessage(std::move(value.m_errorMessage)) +{ + value.m_value = nullptr; +} + +void JsonValue::Destroy() +{ + cJSON_Delete(m_value); +} + +JsonValue::~JsonValue() +{ + Destroy(); +} + +JsonValue& JsonValue::operator=(const JsonValue& other) +{ + if (this == &other) + { + return *this; + } + + Destroy(); + m_value = cJSON_Duplicate(other.m_value, true /*recurse*/); + m_wasParseSuccessful = other.m_wasParseSuccessful; + m_errorMessage = other.m_errorMessage; + return *this; +} + +JsonValue& JsonValue::operator=(JsonValue&& other) +{ + if (this == &other) + { + return *this; + } + + using std::swap; + swap(m_value, other.m_value); + swap(m_errorMessage, other.m_errorMessage); + m_wasParseSuccessful = other.m_wasParseSuccessful; + return *this; +} + +static void AddOrReplace(cJSON* root, const char* key, cJSON* value) +{ + const auto existing = cJSON_GetObjectItemCaseSensitive(root, key); + if (existing) + { + cJSON_ReplaceItemInObjectCaseSensitive(root, key, value); + } + else + { + cJSON_AddItemToObject(root, key, value); + } +} + +JsonValue& JsonValue::WithString(const char* key, const Aws::String& value) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + const auto val = cJSON_CreateString(value.c_str()); + AddOrReplace(m_value, key, val); + return *this; +} + +JsonValue& JsonValue::WithString(const Aws::String& key, const Aws::String& value) +{ + return WithString(key.c_str(), value); +} + +JsonValue& JsonValue::AsString(const Aws::String& value) +{ + Destroy(); + m_value = cJSON_CreateString(value.c_str()); + return *this; +} + +JsonValue& JsonValue::WithBool(const char* key, bool value) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + const auto val = cJSON_CreateBool(value); + AddOrReplace(m_value, key, val); + return *this; +} + +JsonValue& JsonValue::WithBool(const Aws::String& key, bool value) +{ + return WithBool(key.c_str(), value); +} + +JsonValue& JsonValue::AsBool(bool value) +{ + Destroy(); + m_value = cJSON_CreateBool(value); + return *this; +} + +JsonValue& JsonValue::WithInteger(const char* key, int value) +{ + return WithDouble(key, static_cast<double>(value)); +} + +JsonValue& JsonValue::WithInteger(const Aws::String& key, int value) +{ + return WithDouble(key.c_str(), static_cast<double>(value)); +} + +JsonValue& JsonValue::AsInteger(int value) +{ + Destroy(); + m_value = cJSON_CreateNumber(static_cast<double>(value)); + return *this; +} + +JsonValue& JsonValue::WithInt64(const char* key, long long value) +{ if (!m_value) { m_value = cJSON_CreateObject(); @@ -194,261 +194,261 @@ JsonValue& JsonValue::WithInt64(const char* key, long long value) const auto val = cJSON_CreateInt64(value); AddOrReplace(m_value, key, val); return *this; -} - -JsonValue& JsonValue::WithInt64(const Aws::String& key, long long value) -{ +} + +JsonValue& JsonValue::WithInt64(const Aws::String& key, long long value) +{ return WithInt64(key.c_str(), value); -} - -JsonValue& JsonValue::AsInt64(long long value) -{ +} + +JsonValue& JsonValue::AsInt64(long long value) +{ Destroy(); m_value = cJSON_CreateInt64(value); return *this; -} - -JsonValue& JsonValue::WithDouble(const char* key, double value) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - const auto val = cJSON_CreateNumber(value); - AddOrReplace(m_value, key, val); - return *this; -} - -JsonValue& JsonValue::WithDouble(const Aws::String& key, double value) -{ - return WithDouble(key.c_str(), value); -} - -JsonValue& JsonValue::AsDouble(double value) -{ - Destroy(); - m_value = cJSON_CreateNumber(value); - return *this; -} - -JsonValue& JsonValue::WithArray(const char* key, const Array<Aws::String>& array) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - auto arrayValue = cJSON_CreateArray(); - for (unsigned i = 0; i < array.GetLength(); ++i) - { - cJSON_AddItemToArray(arrayValue, cJSON_CreateString(array[i].c_str())); - } - - AddOrReplace(m_value, key, arrayValue); - return *this; -} - -JsonValue& JsonValue::WithArray(const Aws::String& key, const Array<Aws::String>& array) -{ - return WithArray(key.c_str(), array); -} - -JsonValue& JsonValue::WithArray(const Aws::String& key, const Array<JsonValue>& array) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - auto arrayValue = cJSON_CreateArray(); - for (unsigned i = 0; i < array.GetLength(); ++i) - { - cJSON_AddItemToArray(arrayValue, cJSON_Duplicate(array[i].m_value, true /*recurse*/)); - } - - AddOrReplace(m_value, key.c_str(), arrayValue); - return *this; -} - -JsonValue& JsonValue::WithArray(const Aws::String& key, Array<JsonValue>&& array) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - auto arrayValue = cJSON_CreateArray(); - for (unsigned i = 0; i < array.GetLength(); ++i) - { - cJSON_AddItemToArray(arrayValue, array[i].m_value); - array[i].m_value = nullptr; - } - - AddOrReplace(m_value, key.c_str(), arrayValue); - return *this; -} - -JsonValue& JsonValue::AsArray(const Array<JsonValue>& array) -{ - auto arrayValue = cJSON_CreateArray(); - for (unsigned i = 0; i < array.GetLength(); ++i) - { - cJSON_AddItemToArray(arrayValue, cJSON_Duplicate(array[i].m_value, true /*recurse*/)); - } - - Destroy(); - m_value = arrayValue; - return *this; -} - -JsonValue& JsonValue::AsArray(Array<JsonValue>&& array) -{ - auto arrayValue = cJSON_CreateArray(); - for (unsigned i = 0; i < array.GetLength(); ++i) - { - cJSON_AddItemToArray(arrayValue, array[i].m_value); - array[i].m_value = nullptr; - } - - Destroy(); - m_value = arrayValue; - return *this; -} - -JsonValue& JsonValue::WithObject(const char* key, const JsonValue& value) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - const auto copy = value.m_value == nullptr ? cJSON_CreateObject() : cJSON_Duplicate(value.m_value, true /*recurse*/); - AddOrReplace(m_value, key, copy); - return *this; -} - -JsonValue& JsonValue::WithObject(const Aws::String& key, const JsonValue& value) -{ - return WithObject(key.c_str(), value); -} - -JsonValue& JsonValue::WithObject(const char* key, JsonValue&& value) -{ - if (!m_value) - { - m_value = cJSON_CreateObject(); - } - - AddOrReplace(m_value, key, value.m_value == nullptr ? cJSON_CreateObject() : value.m_value); - value.m_value = nullptr; - return *this; -} - -JsonValue& JsonValue::WithObject(const Aws::String& key, JsonValue&& value) -{ - return WithObject(key.c_str(), std::move(value)); -} - -JsonValue& JsonValue::AsObject(const JsonValue& value) -{ - *this = value; - return *this; -} - -JsonValue& JsonValue::AsObject(JsonValue && value) -{ - *this = std::move(value); - return *this; -} - -bool JsonValue::operator==(const JsonValue& other) const -{ - return cJSON_Compare(m_value, other.m_value, true /*case-sensitive*/) != 0; -} - -bool JsonValue::operator!=(const JsonValue& other) const -{ - return !(*this == other); -} - -JsonView JsonValue::View() const -{ - return *this; -} - -JsonView::JsonView() : m_value(nullptr) -{ -} - -JsonView::JsonView(const JsonValue& val) : m_value(val.m_value) -{ -} - -JsonView::JsonView(cJSON* val) : m_value(val) -{ -} - -JsonView& JsonView::operator=(const JsonValue& v) -{ - m_value = v.m_value; - return *this; -} - -JsonView& JsonView::operator=(cJSON* val) -{ - m_value = val; - return *this; -} - -Aws::String JsonView::GetString(const Aws::String& key) const -{ - assert(m_value); - auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - auto str = cJSON_GetStringValue(item); - return str ? str : ""; -} - -Aws::String JsonView::AsString() const -{ - const char* str = cJSON_GetStringValue(m_value); - if (str == nullptr) - { - return {}; - } - return str; -} - -bool JsonView::GetBool(const Aws::String& key) const -{ - assert(m_value); - auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - assert(item); - return item->valueint != 0; -} - -bool JsonView::AsBool() const -{ - assert(cJSON_IsBool(m_value)); - return cJSON_IsTrue(m_value) != 0; -} - -int JsonView::GetInteger(const Aws::String& key) const -{ - assert(m_value); - auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - assert(item); - return item->valueint; -} - -int JsonView::AsInteger() const -{ - assert(cJSON_IsNumber(m_value)); // can be double or value larger than int_max, but at least not UB - return m_value->valueint; -} - -int64_t JsonView::GetInt64(const Aws::String& key) const -{ +} + +JsonValue& JsonValue::WithDouble(const char* key, double value) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + const auto val = cJSON_CreateNumber(value); + AddOrReplace(m_value, key, val); + return *this; +} + +JsonValue& JsonValue::WithDouble(const Aws::String& key, double value) +{ + return WithDouble(key.c_str(), value); +} + +JsonValue& JsonValue::AsDouble(double value) +{ + Destroy(); + m_value = cJSON_CreateNumber(value); + return *this; +} + +JsonValue& JsonValue::WithArray(const char* key, const Array<Aws::String>& array) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + auto arrayValue = cJSON_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AddItemToArray(arrayValue, cJSON_CreateString(array[i].c_str())); + } + + AddOrReplace(m_value, key, arrayValue); + return *this; +} + +JsonValue& JsonValue::WithArray(const Aws::String& key, const Array<Aws::String>& array) +{ + return WithArray(key.c_str(), array); +} + +JsonValue& JsonValue::WithArray(const Aws::String& key, const Array<JsonValue>& array) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + auto arrayValue = cJSON_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AddItemToArray(arrayValue, cJSON_Duplicate(array[i].m_value, true /*recurse*/)); + } + + AddOrReplace(m_value, key.c_str(), arrayValue); + return *this; +} + +JsonValue& JsonValue::WithArray(const Aws::String& key, Array<JsonValue>&& array) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + auto arrayValue = cJSON_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AddItemToArray(arrayValue, array[i].m_value); + array[i].m_value = nullptr; + } + + AddOrReplace(m_value, key.c_str(), arrayValue); + return *this; +} + +JsonValue& JsonValue::AsArray(const Array<JsonValue>& array) +{ + auto arrayValue = cJSON_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AddItemToArray(arrayValue, cJSON_Duplicate(array[i].m_value, true /*recurse*/)); + } + + Destroy(); + m_value = arrayValue; + return *this; +} + +JsonValue& JsonValue::AsArray(Array<JsonValue>&& array) +{ + auto arrayValue = cJSON_CreateArray(); + for (unsigned i = 0; i < array.GetLength(); ++i) + { + cJSON_AddItemToArray(arrayValue, array[i].m_value); + array[i].m_value = nullptr; + } + + Destroy(); + m_value = arrayValue; + return *this; +} + +JsonValue& JsonValue::WithObject(const char* key, const JsonValue& value) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + const auto copy = value.m_value == nullptr ? cJSON_CreateObject() : cJSON_Duplicate(value.m_value, true /*recurse*/); + AddOrReplace(m_value, key, copy); + return *this; +} + +JsonValue& JsonValue::WithObject(const Aws::String& key, const JsonValue& value) +{ + return WithObject(key.c_str(), value); +} + +JsonValue& JsonValue::WithObject(const char* key, JsonValue&& value) +{ + if (!m_value) + { + m_value = cJSON_CreateObject(); + } + + AddOrReplace(m_value, key, value.m_value == nullptr ? cJSON_CreateObject() : value.m_value); + value.m_value = nullptr; + return *this; +} + +JsonValue& JsonValue::WithObject(const Aws::String& key, JsonValue&& value) +{ + return WithObject(key.c_str(), std::move(value)); +} + +JsonValue& JsonValue::AsObject(const JsonValue& value) +{ + *this = value; + return *this; +} + +JsonValue& JsonValue::AsObject(JsonValue && value) +{ + *this = std::move(value); + return *this; +} + +bool JsonValue::operator==(const JsonValue& other) const +{ + return cJSON_Compare(m_value, other.m_value, true /*case-sensitive*/) != 0; +} + +bool JsonValue::operator!=(const JsonValue& other) const +{ + return !(*this == other); +} + +JsonView JsonValue::View() const +{ + return *this; +} + +JsonView::JsonView() : m_value(nullptr) +{ +} + +JsonView::JsonView(const JsonValue& val) : m_value(val.m_value) +{ +} + +JsonView::JsonView(cJSON* val) : m_value(val) +{ +} + +JsonView& JsonView::operator=(const JsonValue& v) +{ + m_value = v.m_value; + return *this; +} + +JsonView& JsonView::operator=(cJSON* val) +{ + m_value = val; + return *this; +} + +Aws::String JsonView::GetString(const Aws::String& key) const +{ + assert(m_value); + auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + auto str = cJSON_GetStringValue(item); + return str ? str : ""; +} + +Aws::String JsonView::AsString() const +{ + const char* str = cJSON_GetStringValue(m_value); + if (str == nullptr) + { + return {}; + } + return str; +} + +bool JsonView::GetBool(const Aws::String& key) const +{ + assert(m_value); + auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + assert(item); + return item->valueint != 0; +} + +bool JsonView::AsBool() const +{ + assert(cJSON_IsBool(m_value)); + return cJSON_IsTrue(m_value) != 0; +} + +int JsonView::GetInteger(const Aws::String& key) const +{ + assert(m_value); + auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + assert(item); + return item->valueint; +} + +int JsonView::AsInteger() const +{ + assert(cJSON_IsNumber(m_value)); // can be double or value larger than int_max, but at least not UB + return m_value->valueint; +} + +int64_t JsonView::GetInt64(const Aws::String& key) const +{ assert(m_value); auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); assert(item); @@ -460,11 +460,11 @@ int64_t JsonView::GetInt64(const Aws::String& key) const { return static_cast<int64_t>(item->valuedouble); } -} - -int64_t JsonView::AsInt64() const -{ - assert(cJSON_IsNumber(m_value)); +} + +int64_t JsonView::AsInt64() const +{ + assert(cJSON_IsNumber(m_value)); if (m_value->valuestring) { return Aws::Utils::StringUtils::ConvertToInt64(m_value->valuestring); @@ -473,193 +473,193 @@ int64_t JsonView::AsInt64() const { return static_cast<int64_t>(m_value->valuedouble); } -} - -double JsonView::GetDouble(const Aws::String& key) const -{ - assert(m_value); - auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - assert(item); - return item->valuedouble; -} - -double JsonView::AsDouble() const -{ - assert(cJSON_IsNumber(m_value)); - return m_value->valuedouble; -} - -JsonView JsonView::GetObject(const Aws::String& key) const -{ - assert(m_value); - auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - return item; -} - -JsonView JsonView::AsObject() const -{ +} + +double JsonView::GetDouble(const Aws::String& key) const +{ + assert(m_value); + auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + assert(item); + return item->valuedouble; +} + +double JsonView::AsDouble() const +{ + assert(cJSON_IsNumber(m_value)); + return m_value->valuedouble; +} + +JsonView JsonView::GetObject(const Aws::String& key) const +{ + assert(m_value); + auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + return item; +} + +JsonView JsonView::AsObject() const +{ assert(cJSON_IsObject(m_value) || cJSON_IsNull(m_value)); - return m_value; -} - -Array<JsonView> JsonView::GetArray(const Aws::String& key) const -{ - assert(m_value); - auto array = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - assert(cJSON_IsArray(array)); - Array<JsonView> returnArray(cJSON_GetArraySize(array)); - - auto element = array->child; - for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next) - { - returnArray[i] = element; - } - - return returnArray; -} - -Array<JsonView> JsonView::AsArray() const -{ - assert(cJSON_IsArray(m_value)); - Array<JsonView> returnArray(cJSON_GetArraySize(m_value)); - - auto element = m_value->child; - - for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next) - { - returnArray[i] = element; - } - - return returnArray; -} - -Aws::Map<Aws::String, JsonView> JsonView::GetAllObjects() const -{ - Aws::Map<Aws::String, JsonView> valueMap; - if (!m_value) - { - return valueMap; - } - - for (auto iter = m_value->child; iter; iter = iter->next) - { - valueMap.emplace(std::make_pair(Aws::String(iter->string), JsonView(iter))); - } - - return valueMap; -} - -bool JsonView::ValueExists(const Aws::String& key) const -{ - if (!cJSON_IsObject(m_value)) - { - return false; - } - - auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); - return !(item == nullptr || cJSON_IsNull(item)); -} - -bool JsonView::KeyExists(const Aws::String& key) const -{ - if (!cJSON_IsObject(m_value)) - { - return false; - } - - return cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()) != nullptr;; -} - -bool JsonView::IsObject() const -{ - return cJSON_IsObject(m_value) != 0; -} - -bool JsonView::IsBool() const -{ - return cJSON_IsBool(m_value) != 0; -} - -bool JsonView::IsString() const -{ - return cJSON_IsString(m_value) != 0; -} - -bool JsonView::IsIntegerType() const -{ - if (!cJSON_IsNumber(m_value)) - { - return false; - } - + return m_value; +} + +Array<JsonView> JsonView::GetArray(const Aws::String& key) const +{ + assert(m_value); + auto array = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + assert(cJSON_IsArray(array)); + Array<JsonView> returnArray(cJSON_GetArraySize(array)); + + auto element = array->child; + for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next) + { + returnArray[i] = element; + } + + return returnArray; +} + +Array<JsonView> JsonView::AsArray() const +{ + assert(cJSON_IsArray(m_value)); + Array<JsonView> returnArray(cJSON_GetArraySize(m_value)); + + auto element = m_value->child; + + for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next) + { + returnArray[i] = element; + } + + return returnArray; +} + +Aws::Map<Aws::String, JsonView> JsonView::GetAllObjects() const +{ + Aws::Map<Aws::String, JsonView> valueMap; + if (!m_value) + { + return valueMap; + } + + for (auto iter = m_value->child; iter; iter = iter->next) + { + valueMap.emplace(std::make_pair(Aws::String(iter->string), JsonView(iter))); + } + + return valueMap; +} + +bool JsonView::ValueExists(const Aws::String& key) const +{ + if (!cJSON_IsObject(m_value)) + { + return false; + } + + auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()); + return !(item == nullptr || cJSON_IsNull(item)); +} + +bool JsonView::KeyExists(const Aws::String& key) const +{ + if (!cJSON_IsObject(m_value)) + { + return false; + } + + return cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()) != nullptr;; +} + +bool JsonView::IsObject() const +{ + return cJSON_IsObject(m_value) != 0; +} + +bool JsonView::IsBool() const +{ + return cJSON_IsBool(m_value) != 0; +} + +bool JsonView::IsString() const +{ + return cJSON_IsString(m_value) != 0; +} + +bool JsonView::IsIntegerType() const +{ + if (!cJSON_IsNumber(m_value)) + { + return false; + } + if (m_value->valuestring) { Aws::String valueString = m_value->valuestring; return std::all_of(valueString.begin(), valueString.end(), [](unsigned char c){ return ::isdigit(c) || c == '+' || c == '-'; }); } - return m_value->valuedouble == static_cast<long long>(m_value->valuedouble); -} - -bool JsonView::IsFloatingPointType() const -{ - if (!cJSON_IsNumber(m_value)) - { - return false; - } - + return m_value->valuedouble == static_cast<long long>(m_value->valuedouble); +} + +bool JsonView::IsFloatingPointType() const +{ + if (!cJSON_IsNumber(m_value)) + { + return false; + } + if (m_value->valuestring) { Aws::String valueString = m_value->valuestring; return std::any_of(valueString.begin(), valueString.end(), [](unsigned char c){ return !::isdigit(c) && c != '+' && c != '-'; }); } - return m_value->valuedouble != static_cast<long long>(m_value->valuedouble); -} - -bool JsonView::IsListType() const -{ - return cJSON_IsArray(m_value) != 0; -} - -bool JsonView::IsNull() const -{ - return cJSON_IsNull(m_value) != 0; -} - -Aws::String JsonView::WriteCompact(bool treatAsObject) const -{ - if (!m_value) - { - if (treatAsObject) - { - return "{}"; - } + return m_value->valuedouble != static_cast<long long>(m_value->valuedouble); +} + +bool JsonView::IsListType() const +{ + return cJSON_IsArray(m_value) != 0; +} + +bool JsonView::IsNull() const +{ + return cJSON_IsNull(m_value) != 0; +} + +Aws::String JsonView::WriteCompact(bool treatAsObject) const +{ + if (!m_value) + { + if (treatAsObject) + { + return "{}"; + } return {}; - } - - auto temp = cJSON_PrintUnformatted(m_value); - Aws::String out(temp); - cJSON_free(temp); - return out; -} - -Aws::String JsonView::WriteReadable(bool treatAsObject) const -{ - if (!m_value) - { - if (treatAsObject) - { - return "{\n}\n"; - } + } + + auto temp = cJSON_PrintUnformatted(m_value); + Aws::String out(temp); + cJSON_free(temp); + return out; +} + +Aws::String JsonView::WriteReadable(bool treatAsObject) const +{ + if (!m_value) + { + if (treatAsObject) + { + return "{\n}\n"; + } return {}; - } - - auto temp = cJSON_Print(m_value); - Aws::String out(temp); - cJSON_free(temp); - return out; -} - -JsonValue JsonView::Materialize() const -{ - return m_value; -} + } + + auto temp = cJSON_Print(m_value); + Aws::String out(temp); + cJSON_free(temp); + return out; +} + +JsonValue JsonView::Materialize() const +{ + return m_value; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp index fc1b9fcc2e..82a49da4fb 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp @@ -2,50 +2,50 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/logging/AWSLogging.h> -#include <aws/core/utils/logging/LogSystemInterface.h> -#include <aws/core/utils/memory/stl/AWSStack.h> - -#include <memory> - -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; - -static std::shared_ptr<LogSystemInterface> AWSLogSystem(nullptr); -static std::shared_ptr<LogSystemInterface> OldLogger(nullptr); - -namespace Aws -{ -namespace Utils -{ -namespace Logging { - -void InitializeAWSLogging(const std::shared_ptr<LogSystemInterface> &logSystem) { - AWSLogSystem = logSystem; -} - -void ShutdownAWSLogging(void) { - InitializeAWSLogging(nullptr); -} - -LogSystemInterface *GetLogSystem() { - return AWSLogSystem.get(); -} - -void PushLogger(const std::shared_ptr<LogSystemInterface> &logSystem) -{ - OldLogger = AWSLogSystem; - AWSLogSystem = logSystem; -} - -void PopLogger() -{ - AWSLogSystem = OldLogger; - OldLogger = nullptr; -} - -} // namespace Logging -} // namespace Utils -} // namespace Aws
\ No newline at end of file + + +#include <aws/core/utils/logging/AWSLogging.h> +#include <aws/core/utils/logging/LogSystemInterface.h> +#include <aws/core/utils/memory/stl/AWSStack.h> + +#include <memory> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +static std::shared_ptr<LogSystemInterface> AWSLogSystem(nullptr); +static std::shared_ptr<LogSystemInterface> OldLogger(nullptr); + +namespace Aws +{ +namespace Utils +{ +namespace Logging { + +void InitializeAWSLogging(const std::shared_ptr<LogSystemInterface> &logSystem) { + AWSLogSystem = logSystem; +} + +void ShutdownAWSLogging(void) { + InitializeAWSLogging(nullptr); +} + +LogSystemInterface *GetLogSystem() { + return AWSLogSystem.get(); +} + +void PushLogger(const std::shared_ptr<LogSystemInterface> &logSystem) +{ + OldLogger = AWSLogSystem; + AWSLogSystem = logSystem; +} + +void PopLogger() +{ + AWSLogSystem = OldLogger; + OldLogger = nullptr; +} + +} // namespace Logging +} // namespace Utils +} // namespace Aws
\ No newline at end of file diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp index dec7cef82f..ac7cbba8c0 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp @@ -2,19 +2,19 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/logging/ConsoleLogSystem.h> - -#include <iostream> - -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; - -void ConsoleLogSystem::ProcessFormattedStatement(Aws::String&& statement) -{ - std::cout << statement; -} + + +#include <aws/core/utils/logging/ConsoleLogSystem.h> + +#include <iostream> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +void ConsoleLogSystem::ProcessFormattedStatement(Aws::String&& statement) +{ + std::cout << statement; +} void ConsoleLogSystem::Flush() { diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp index 7286bb6378..065dc9b037 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp @@ -2,114 +2,114 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/logging/DefaultLogSystem.h> - -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/memory/stl/AWSVector.h> - -#include <fstream> - -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; - -static const char* AllocationTag = "DefaultLogSystem"; -static const int BUFFERED_MSG_COUNT = 100; - + + +#include <aws/core/utils/logging/DefaultLogSystem.h> + +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/memory/stl/AWSVector.h> + +#include <fstream> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +static const char* AllocationTag = "DefaultLogSystem"; +static const int BUFFERED_MSG_COUNT = 100; + static std::shared_ptr<Aws::OFStream> MakeDefaultLogFile(const Aws::String& filenamePrefix) -{ - Aws::String newFileName = filenamePrefix + DateTime::CalculateGmtTimestampAsString("%Y-%m-%d-%H") + ".log"; - return Aws::MakeShared<Aws::OFStream>(AllocationTag, newFileName.c_str(), Aws::OFStream::out | Aws::OFStream::app); -} - -static void LogThread(DefaultLogSystem::LogSynchronizationData* syncData, const std::shared_ptr<Aws::OStream>& logFile, const Aws::String& filenamePrefix, bool rollLog) -{ - // localtime requires access to env. variables to get Timezone, which is not thread-safe - int32_t lastRolledHour = DateTime::Now().GetHour(false /*localtime*/); - std::shared_ptr<Aws::OStream> log = logFile; - - for(;;) - { - std::unique_lock<std::mutex> locker(syncData->m_logQueueMutex); +{ + Aws::String newFileName = filenamePrefix + DateTime::CalculateGmtTimestampAsString("%Y-%m-%d-%H") + ".log"; + return Aws::MakeShared<Aws::OFStream>(AllocationTag, newFileName.c_str(), Aws::OFStream::out | Aws::OFStream::app); +} + +static void LogThread(DefaultLogSystem::LogSynchronizationData* syncData, const std::shared_ptr<Aws::OStream>& logFile, const Aws::String& filenamePrefix, bool rollLog) +{ + // localtime requires access to env. variables to get Timezone, which is not thread-safe + int32_t lastRolledHour = DateTime::Now().GetHour(false /*localtime*/); + std::shared_ptr<Aws::OStream> log = logFile; + + for(;;) + { + std::unique_lock<std::mutex> locker(syncData->m_logQueueMutex); syncData->m_queueSignal.wait(locker, [&](){ return syncData->m_stopLogging == true || syncData->m_queuedLogMessages.size() > 0; } ); - - if (syncData->m_stopLogging && syncData->m_queuedLogMessages.size() == 0) - { - break; - } - - Aws::Vector<Aws::String> messages(std::move(syncData->m_queuedLogMessages)); - syncData->m_queuedLogMessages.reserve(BUFFERED_MSG_COUNT); - - locker.unlock(); - - if (messages.size() > 0) - { - if (rollLog) - { - // localtime requires access to env. variables to get Timezone, which is not thread-safe - int32_t currentHour = DateTime::Now().GetHour(false /*localtime*/); - if (currentHour != lastRolledHour) - { - log = MakeDefaultLogFile(filenamePrefix); - lastRolledHour = currentHour; - } - } - - for (const auto& msg : messages) - { - (*log) << msg; - } - - log->flush(); - } - } -} - -DefaultLogSystem::DefaultLogSystem(LogLevel logLevel, const std::shared_ptr<Aws::OStream>& logFile) : - Base(logLevel), - m_syncData(), - m_loggingThread() -{ - m_loggingThread = std::thread(LogThread, &m_syncData, logFile, "", false); -} - -DefaultLogSystem::DefaultLogSystem(LogLevel logLevel, const Aws::String& filenamePrefix) : - Base(logLevel), - m_syncData(), - m_loggingThread() -{ - m_loggingThread = std::thread(LogThread, &m_syncData, MakeDefaultLogFile(filenamePrefix), filenamePrefix, true); -} - -DefaultLogSystem::~DefaultLogSystem() -{ - { - std::lock_guard<std::mutex> locker(m_syncData.m_logQueueMutex); + + if (syncData->m_stopLogging && syncData->m_queuedLogMessages.size() == 0) + { + break; + } + + Aws::Vector<Aws::String> messages(std::move(syncData->m_queuedLogMessages)); + syncData->m_queuedLogMessages.reserve(BUFFERED_MSG_COUNT); + + locker.unlock(); + + if (messages.size() > 0) + { + if (rollLog) + { + // localtime requires access to env. variables to get Timezone, which is not thread-safe + int32_t currentHour = DateTime::Now().GetHour(false /*localtime*/); + if (currentHour != lastRolledHour) + { + log = MakeDefaultLogFile(filenamePrefix); + lastRolledHour = currentHour; + } + } + + for (const auto& msg : messages) + { + (*log) << msg; + } + + log->flush(); + } + } +} + +DefaultLogSystem::DefaultLogSystem(LogLevel logLevel, const std::shared_ptr<Aws::OStream>& logFile) : + Base(logLevel), + m_syncData(), + m_loggingThread() +{ + m_loggingThread = std::thread(LogThread, &m_syncData, logFile, "", false); +} + +DefaultLogSystem::DefaultLogSystem(LogLevel logLevel, const Aws::String& filenamePrefix) : + Base(logLevel), + m_syncData(), + m_loggingThread() +{ + m_loggingThread = std::thread(LogThread, &m_syncData, MakeDefaultLogFile(filenamePrefix), filenamePrefix, true); +} + +DefaultLogSystem::~DefaultLogSystem() +{ + { + std::lock_guard<std::mutex> locker(m_syncData.m_logQueueMutex); m_syncData.m_stopLogging = true; - } - - m_syncData.m_queueSignal.notify_one(); - - m_loggingThread.join(); -} - -void DefaultLogSystem::ProcessFormattedStatement(Aws::String&& statement) -{ - std::unique_lock<std::mutex> locker(m_syncData.m_logQueueMutex); - m_syncData.m_queuedLogMessages.emplace_back(std::move(statement)); - if(m_syncData.m_queuedLogMessages.size() >= BUFFERED_MSG_COUNT) - { - locker.unlock(); - m_syncData.m_queueSignal.notify_one(); - } - else - { - locker.unlock(); - } -} - + } + + m_syncData.m_queueSignal.notify_one(); + + m_loggingThread.join(); +} + +void DefaultLogSystem::ProcessFormattedStatement(Aws::String&& statement) +{ + std::unique_lock<std::mutex> locker(m_syncData.m_logQueueMutex); + m_syncData.m_queuedLogMessages.emplace_back(std::move(statement)); + if(m_syncData.m_queuedLogMessages.size() >= BUFFERED_MSG_COUNT) + { + locker.unlock(); + m_syncData.m_queueSignal.notify_one(); + } + else + { + locker.unlock(); + } +} + void DefaultLogSystem::Flush() { m_syncData.m_queueSignal.notify_one(); diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp index 41c4d7e09c..8cca6d89a8 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp @@ -2,98 +2,98 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - - -#include <aws/core/utils/logging/FormattedLogSystem.h> - -#include <aws/core/utils/DateTime.h> -#include <aws/core/utils/Array.h> - -#include <fstream> -#include <cstdarg> -#include <stdio.h> -#include <thread> - -using namespace Aws::Utils; -using namespace Aws::Utils::Logging; - -static Aws::String CreateLogPrefixLine(LogLevel logLevel, const char* tag) -{ - Aws::StringStream ss; - - switch(logLevel) - { - case LogLevel::Error: - ss << "[ERROR] "; - break; - - case LogLevel::Fatal: - ss << "[FATAL] "; - break; - - case LogLevel::Warn: - ss << "[WARN] "; - break; - - case LogLevel::Info: - ss << "[INFO] "; - break; - - case LogLevel::Debug: - ss << "[DEBUG] "; - break; - - case LogLevel::Trace: - ss << "[TRACE] "; - break; - - default: - ss << "[UNKOWN] "; - break; - } - + + +#include <aws/core/utils/logging/FormattedLogSystem.h> + +#include <aws/core/utils/DateTime.h> +#include <aws/core/utils/Array.h> + +#include <fstream> +#include <cstdarg> +#include <stdio.h> +#include <thread> + +using namespace Aws::Utils; +using namespace Aws::Utils::Logging; + +static Aws::String CreateLogPrefixLine(LogLevel logLevel, const char* tag) +{ + Aws::StringStream ss; + + switch(logLevel) + { + case LogLevel::Error: + ss << "[ERROR] "; + break; + + case LogLevel::Fatal: + ss << "[FATAL] "; + break; + + case LogLevel::Warn: + ss << "[WARN] "; + break; + + case LogLevel::Info: + ss << "[INFO] "; + break; + + case LogLevel::Debug: + ss << "[DEBUG] "; + break; + + case LogLevel::Trace: + ss << "[TRACE] "; + break; + + default: + ss << "[UNKOWN] "; + break; + } + ss << DateTime::Now().CalculateGmtTimeWithMsPrecision() << " " << tag << " [" << std::this_thread::get_id() << "] "; - - return ss.str(); -} - -FormattedLogSystem::FormattedLogSystem(LogLevel logLevel) : - m_logLevel(logLevel) -{ -} - -void FormattedLogSystem::Log(LogLevel logLevel, const char* tag, const char* formatStr, ...) -{ - Aws::StringStream ss; - ss << CreateLogPrefixLine(logLevel, tag); - - std::va_list args; - va_start(args, formatStr); - - va_list tmp_args; //unfortunately you cannot consume a va_list twice - va_copy(tmp_args, args); //so we have to copy it - #ifdef WIN32 - const int requiredLength = _vscprintf(formatStr, tmp_args) + 1; - #else - const int requiredLength = vsnprintf(nullptr, 0, formatStr, tmp_args) + 1; - #endif - va_end(tmp_args); - - Array<char> outputBuff(requiredLength); - #ifdef WIN32 - vsnprintf_s(outputBuff.GetUnderlyingData(), requiredLength, _TRUNCATE, formatStr, args); - #else - vsnprintf(outputBuff.GetUnderlyingData(), requiredLength, formatStr, args); - #endif // WIN32 - - ss << outputBuff.GetUnderlyingData() << std::endl; - - ProcessFormattedStatement(ss.str()); - - va_end(args); -} - -void FormattedLogSystem::LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &message_stream) -{ + + return ss.str(); +} + +FormattedLogSystem::FormattedLogSystem(LogLevel logLevel) : + m_logLevel(logLevel) +{ +} + +void FormattedLogSystem::Log(LogLevel logLevel, const char* tag, const char* formatStr, ...) +{ + Aws::StringStream ss; + ss << CreateLogPrefixLine(logLevel, tag); + + std::va_list args; + va_start(args, formatStr); + + va_list tmp_args; //unfortunately you cannot consume a va_list twice + va_copy(tmp_args, args); //so we have to copy it + #ifdef WIN32 + const int requiredLength = _vscprintf(formatStr, tmp_args) + 1; + #else + const int requiredLength = vsnprintf(nullptr, 0, formatStr, tmp_args) + 1; + #endif + va_end(tmp_args); + + Array<char> outputBuff(requiredLength); + #ifdef WIN32 + vsnprintf_s(outputBuff.GetUnderlyingData(), requiredLength, _TRUNCATE, formatStr, args); + #else + vsnprintf(outputBuff.GetUnderlyingData(), requiredLength, formatStr, args); + #endif // WIN32 + + ss << outputBuff.GetUnderlyingData() << std::endl; + + ProcessFormattedStatement(ss.str()); + + va_end(args); +} + +void FormattedLogSystem::LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &message_stream) +{ ProcessFormattedStatement(CreateLogPrefixLine(logLevel, tag) + message_stream.str() + "\n"); -} +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp index 9ff1bf3126..643985bd14 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp @@ -2,44 +2,44 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/logging/LogLevel.h> - -#include <aws/core/utils/memory/stl/AWSMap.h> -#include <aws/core/utils/memory/stl/AWSString.h> -#include <cassert> - -using namespace Aws::Utils::Logging; - -namespace Aws -{ -namespace Utils -{ -namespace Logging -{ - -Aws::String GetLogLevelName(LogLevel logLevel) + +#include <aws/core/utils/logging/LogLevel.h> + +#include <aws/core/utils/memory/stl/AWSMap.h> +#include <aws/core/utils/memory/stl/AWSString.h> +#include <cassert> + +using namespace Aws::Utils::Logging; + +namespace Aws { - switch (logLevel) - { - case LogLevel::Fatal: - return "FATAL"; - case LogLevel::Error: - return "ERROR"; - case LogLevel::Warn: - return "WARN"; - case LogLevel::Info: - return "INFO"; - case LogLevel::Debug: - return "DEBUG"; - case LogLevel::Trace: - return "TRACE"; - default: - assert(0); - return ""; - } -} - -} // namespace Logging -} // namespace Utils -} // namespace Aws +namespace Utils +{ +namespace Logging +{ + +Aws::String GetLogLevelName(LogLevel logLevel) +{ + switch (logLevel) + { + case LogLevel::Fatal: + return "FATAL"; + case LogLevel::Error: + return "ERROR"; + case LogLevel::Warn: + return "WARN"; + case LogLevel::Info: + return "INFO"; + case LogLevel::Debug: + return "DEBUG"; + case LogLevel::Trace: + return "TRACE"; + default: + assert(0); + return ""; + } +} + +} // namespace Logging +} // namespace Utils +} // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp index 96d339d385..361cdc95fc 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp @@ -2,102 +2,102 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/memory/AWSMemory.h> - -#include <aws/core/utils/memory/MemorySystemInterface.h> + +#include <aws/core/utils/memory/AWSMemory.h> + +#include <aws/core/utils/memory/MemorySystemInterface.h> #include <aws/common/common.h> - -#include <atomic> - -using namespace Aws::Utils; -using namespace Aws::Utils::Memory; - -#ifdef USE_AWS_MEMORY_MANAGEMENT - static MemorySystemInterface* AWSMemorySystem(nullptr); -#endif // USE_AWS_MEMORY_MANAGEMENT - -namespace Aws -{ -namespace Utils -{ -namespace Memory -{ - -void InitializeAWSMemorySystem(MemorySystemInterface& memorySystem) -{ - #ifdef USE_AWS_MEMORY_MANAGEMENT - if(AWSMemorySystem != nullptr) - { - AWSMemorySystem->End(); - } - - AWSMemorySystem = &memorySystem; - AWSMemorySystem->Begin(); - #else - AWS_UNREFERENCED_PARAM(memorySystem); - #endif // USE_AWS_MEMORY_MANAGEMENT -} - -void ShutdownAWSMemorySystem(void) -{ - #ifdef USE_AWS_MEMORY_MANAGEMENT - if(AWSMemorySystem != nullptr) - { - AWSMemorySystem->End(); - } - AWSMemorySystem = nullptr; - #endif // USE_AWS_MEMORY_MANAGEMENT -} - -MemorySystemInterface* GetMemorySystem() -{ - #ifdef USE_AWS_MEMORY_MANAGEMENT - return AWSMemorySystem; - #else - return nullptr; - #endif // USE_AWS_MEMORY_MANAGEMENT -} - -} // namespace Memory -} // namespace Utils - -void* Malloc(const char* allocationTag, size_t allocationSize) -{ - Aws::Utils::Memory::MemorySystemInterface* memorySystem = Aws::Utils::Memory::GetMemorySystem(); - - void* rawMemory = nullptr; - if(memorySystem != nullptr) - { - rawMemory = memorySystem->AllocateMemory(allocationSize, 1, allocationTag); - } - else - { - rawMemory = malloc(allocationSize); - } - - return rawMemory; -} - - -void Free(void* memoryPtr) -{ - if(memoryPtr == nullptr) - { - return; - } - - Aws::Utils::Memory::MemorySystemInterface* memorySystem = Aws::Utils::Memory::GetMemorySystem(); - if(memorySystem != nullptr) - { - memorySystem->FreeMemory(memoryPtr); - } - else - { - free(memoryPtr); - } -} - + +#include <atomic> + +using namespace Aws::Utils; +using namespace Aws::Utils::Memory; + +#ifdef USE_AWS_MEMORY_MANAGEMENT + static MemorySystemInterface* AWSMemorySystem(nullptr); +#endif // USE_AWS_MEMORY_MANAGEMENT + +namespace Aws +{ +namespace Utils +{ +namespace Memory +{ + +void InitializeAWSMemorySystem(MemorySystemInterface& memorySystem) +{ + #ifdef USE_AWS_MEMORY_MANAGEMENT + if(AWSMemorySystem != nullptr) + { + AWSMemorySystem->End(); + } + + AWSMemorySystem = &memorySystem; + AWSMemorySystem->Begin(); + #else + AWS_UNREFERENCED_PARAM(memorySystem); + #endif // USE_AWS_MEMORY_MANAGEMENT +} + +void ShutdownAWSMemorySystem(void) +{ + #ifdef USE_AWS_MEMORY_MANAGEMENT + if(AWSMemorySystem != nullptr) + { + AWSMemorySystem->End(); + } + AWSMemorySystem = nullptr; + #endif // USE_AWS_MEMORY_MANAGEMENT +} + +MemorySystemInterface* GetMemorySystem() +{ + #ifdef USE_AWS_MEMORY_MANAGEMENT + return AWSMemorySystem; + #else + return nullptr; + #endif // USE_AWS_MEMORY_MANAGEMENT +} + +} // namespace Memory +} // namespace Utils + +void* Malloc(const char* allocationTag, size_t allocationSize) +{ + Aws::Utils::Memory::MemorySystemInterface* memorySystem = Aws::Utils::Memory::GetMemorySystem(); + + void* rawMemory = nullptr; + if(memorySystem != nullptr) + { + rawMemory = memorySystem->AllocateMemory(allocationSize, 1, allocationTag); + } + else + { + rawMemory = malloc(allocationSize); + } + + return rawMemory; +} + + +void Free(void* memoryPtr) +{ + if(memoryPtr == nullptr) + { + return; + } + + Aws::Utils::Memory::MemorySystemInterface* memorySystem = Aws::Utils::Memory::GetMemorySystem(); + if(memorySystem != nullptr) + { + memorySystem->FreeMemory(memoryPtr); + } + else + { + free(memoryPtr); + } +} + static void* MemAcquire(aws_allocator* allocator, size_t size) { (void)allocator; // unused; @@ -129,6 +129,6 @@ aws_allocator* get_aws_allocator() return &wrapper; } -} // namespace Aws - - +} // namespace Aws + + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp index 4662749872..faee8777a8 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp @@ -2,65 +2,65 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/memory/stl/SimpleStringStream.h> - -namespace Aws -{ - -SimpleStringStream::SimpleStringStream() : - base(&m_streamBuffer), - m_streamBuffer() -{ -} - -SimpleStringStream::SimpleStringStream(const Aws::String& value) : - base(&m_streamBuffer), - m_streamBuffer(value) -{ -} - + +#include <aws/core/utils/memory/stl/SimpleStringStream.h> + +namespace Aws +{ + +SimpleStringStream::SimpleStringStream() : + base(&m_streamBuffer), + m_streamBuffer() +{ +} + +SimpleStringStream::SimpleStringStream(const Aws::String& value) : + base(&m_streamBuffer), + m_streamBuffer(value) +{ +} + void SimpleStringStream::str(const Aws::String& value) -{ - m_streamBuffer.str(value); -} - -// - -SimpleIStringStream::SimpleIStringStream() : - base(&m_streamBuffer), - m_streamBuffer() -{ -} - -SimpleIStringStream::SimpleIStringStream(const Aws::String& value) : - base(&m_streamBuffer), - m_streamBuffer(value) -{ -} - +{ + m_streamBuffer.str(value); +} + +// + +SimpleIStringStream::SimpleIStringStream() : + base(&m_streamBuffer), + m_streamBuffer() +{ +} + +SimpleIStringStream::SimpleIStringStream(const Aws::String& value) : + base(&m_streamBuffer), + m_streamBuffer(value) +{ +} + void SimpleIStringStream::str(const Aws::String& value) -{ - m_streamBuffer.str(value); -} - -// - -SimpleOStringStream::SimpleOStringStream() : - base(&m_streamBuffer), - m_streamBuffer() -{ -} - -SimpleOStringStream::SimpleOStringStream(const Aws::String& value) : - base(&m_streamBuffer), - m_streamBuffer(value) -{ -} - +{ + m_streamBuffer.str(value); +} + +// + +SimpleOStringStream::SimpleOStringStream() : + base(&m_streamBuffer), + m_streamBuffer() +{ +} + +SimpleOStringStream::SimpleOStringStream(const Aws::String& value) : + base(&m_streamBuffer), + m_streamBuffer(value) +{ +} + void SimpleOStringStream::str(const Aws::String& value) -{ - m_streamBuffer.str(value); -} - +{ + m_streamBuffer.str(value); +} + } // namespace Aws diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp index f656fc8613..a91903a0f3 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp @@ -1,75 +1,75 @@ - + /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/stream/PreallocatedStreamBuf.h> -#include <cassert> - -namespace Aws -{ - namespace Utils - { - namespace Stream - { + +#include <aws/core/utils/stream/PreallocatedStreamBuf.h> +#include <cassert> + +namespace Aws +{ + namespace Utils + { + namespace Stream + { PreallocatedStreamBuf::PreallocatedStreamBuf(unsigned char* buffer, uint64_t lengthToRead) : - m_underlyingBuffer(buffer), m_lengthToRead(lengthToRead) - { + m_underlyingBuffer(buffer), m_lengthToRead(lengthToRead) + { char* end = reinterpret_cast<char*>(m_underlyingBuffer + m_lengthToRead); char* begin = reinterpret_cast<char*>(m_underlyingBuffer); - setp(begin, end); - setg(begin, begin, end); - } - - PreallocatedStreamBuf::pos_type PreallocatedStreamBuf::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) - { - if (dir == std::ios_base::beg) - { - return seekpos(off, which); - } - else if (dir == std::ios_base::end) - { - return seekpos(m_lengthToRead - off, which); - } - else if (dir == std::ios_base::cur) - { - if(which == std::ios_base::in) - { + setp(begin, end); + setg(begin, begin, end); + } + + PreallocatedStreamBuf::pos_type PreallocatedStreamBuf::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) + { + if (dir == std::ios_base::beg) + { + return seekpos(off, which); + } + else if (dir == std::ios_base::end) + { + return seekpos(m_lengthToRead - off, which); + } + else if (dir == std::ios_base::cur) + { + if(which == std::ios_base::in) + { return seekpos((gptr() - reinterpret_cast<char*>(m_underlyingBuffer)) + off, which); - } - else - { + } + else + { return seekpos((pptr() - reinterpret_cast<char*>(m_underlyingBuffer)) + off, which); - } - } - - return off_type(-1); - } - - PreallocatedStreamBuf::pos_type PreallocatedStreamBuf::seekpos(pos_type pos, std::ios_base::openmode which) - { - assert(static_cast<size_t>(pos) <= m_lengthToRead); - if (static_cast<size_t>(pos) > m_lengthToRead) - { - return pos_type(off_type(-1)); - } - + } + } + + return off_type(-1); + } + + PreallocatedStreamBuf::pos_type PreallocatedStreamBuf::seekpos(pos_type pos, std::ios_base::openmode which) + { + assert(static_cast<size_t>(pos) <= m_lengthToRead); + if (static_cast<size_t>(pos) > m_lengthToRead) + { + return pos_type(off_type(-1)); + } + char* end = reinterpret_cast<char*>(m_underlyingBuffer + m_lengthToRead); char* begin = reinterpret_cast<char*>(m_underlyingBuffer); - - if (which == std::ios_base::in) - { + + if (which == std::ios_base::in) + { setg(begin, begin + static_cast<size_t>(pos), end); - } - - if (which == std::ios_base::out) - { - setp(begin + static_cast<size_t>(pos), end); - } - - return pos; - } - } - } + } + + if (which == std::ios_base::out) + { + setp(begin + static_cast<size_t>(pos), end); + } + + return pos; + } + } + } } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp index 6d1f90ed12..afba5ee828 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp @@ -2,90 +2,90 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/stream/ResponseStream.h> -#include <aws/core/utils/memory/stl/AWSStringStream.h> - -#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) -#include <aws/core/utils/stream/SimpleStreamBuf.h> -using DefaultStreamBufType = Aws::Utils::Stream::SimpleStreamBuf; -#else -using DefaultStreamBufType = Aws::StringBuf; -#endif - -using namespace Aws::Utils::Stream; - -ResponseStream::ResponseStream(void) : - m_underlyingStream(nullptr) -{ -} - -ResponseStream::ResponseStream(Aws::IOStream* underlyingStreamToManage) : - m_underlyingStream(underlyingStreamToManage) -{ -} - -ResponseStream::ResponseStream(const Aws::IOStreamFactory& factory) : - m_underlyingStream(factory()) -{ -} - -ResponseStream::ResponseStream(ResponseStream&& toMove) : m_underlyingStream(toMove.m_underlyingStream) -{ - toMove.m_underlyingStream = nullptr; -} - -ResponseStream& ResponseStream::operator=(ResponseStream&& toMove) -{ - if(m_underlyingStream == toMove.m_underlyingStream) - { - return *this; - } - - ReleaseStream(); - m_underlyingStream = toMove.m_underlyingStream; - toMove.m_underlyingStream = nullptr; - - return *this; -} - -ResponseStream::~ResponseStream() -{ - ReleaseStream(); -} - -void ResponseStream::ReleaseStream() -{ - if (m_underlyingStream) - { - m_underlyingStream->flush(); - Aws::Delete(m_underlyingStream); - } - - m_underlyingStream = nullptr; -} - -static const char *DEFAULT_STREAM_TAG = "DefaultUnderlyingStream"; - -DefaultUnderlyingStream::DefaultUnderlyingStream() : - Base( Aws::New< DefaultStreamBufType >( DEFAULT_STREAM_TAG ) ) -{} - -DefaultUnderlyingStream::DefaultUnderlyingStream(Aws::UniquePtr<std::streambuf> buf) : - Base(buf.release()) -{} - -DefaultUnderlyingStream::~DefaultUnderlyingStream() -{ - if( rdbuf() ) - { - Aws::Delete( rdbuf() ); - } -} - -static const char* RESPONSE_STREAM_FACTORY_TAG = "ResponseStreamFactory"; - -Aws::IOStream* Aws::Utils::Stream::DefaultResponseStreamFactoryMethod() -{ - return Aws::New<Aws::Utils::Stream::DefaultUnderlyingStream>(RESPONSE_STREAM_FACTORY_TAG); -} + +#include <aws/core/utils/stream/ResponseStream.h> +#include <aws/core/utils/memory/stl/AWSStringStream.h> + +#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__) +#include <aws/core/utils/stream/SimpleStreamBuf.h> +using DefaultStreamBufType = Aws::Utils::Stream::SimpleStreamBuf; +#else +using DefaultStreamBufType = Aws::StringBuf; +#endif + +using namespace Aws::Utils::Stream; + +ResponseStream::ResponseStream(void) : + m_underlyingStream(nullptr) +{ +} + +ResponseStream::ResponseStream(Aws::IOStream* underlyingStreamToManage) : + m_underlyingStream(underlyingStreamToManage) +{ +} + +ResponseStream::ResponseStream(const Aws::IOStreamFactory& factory) : + m_underlyingStream(factory()) +{ +} + +ResponseStream::ResponseStream(ResponseStream&& toMove) : m_underlyingStream(toMove.m_underlyingStream) +{ + toMove.m_underlyingStream = nullptr; +} + +ResponseStream& ResponseStream::operator=(ResponseStream&& toMove) +{ + if(m_underlyingStream == toMove.m_underlyingStream) + { + return *this; + } + + ReleaseStream(); + m_underlyingStream = toMove.m_underlyingStream; + toMove.m_underlyingStream = nullptr; + + return *this; +} + +ResponseStream::~ResponseStream() +{ + ReleaseStream(); +} + +void ResponseStream::ReleaseStream() +{ + if (m_underlyingStream) + { + m_underlyingStream->flush(); + Aws::Delete(m_underlyingStream); + } + + m_underlyingStream = nullptr; +} + +static const char *DEFAULT_STREAM_TAG = "DefaultUnderlyingStream"; + +DefaultUnderlyingStream::DefaultUnderlyingStream() : + Base( Aws::New< DefaultStreamBufType >( DEFAULT_STREAM_TAG ) ) +{} + +DefaultUnderlyingStream::DefaultUnderlyingStream(Aws::UniquePtr<std::streambuf> buf) : + Base(buf.release()) +{} + +DefaultUnderlyingStream::~DefaultUnderlyingStream() +{ + if( rdbuf() ) + { + Aws::Delete( rdbuf() ); + } +} + +static const char* RESPONSE_STREAM_FACTORY_TAG = "ResponseStreamFactory"; + +Aws::IOStream* Aws::Utils::Stream::DefaultResponseStreamFactoryMethod() +{ + return Aws::New<Aws::Utils::Stream::DefaultUnderlyingStream>(RESPONSE_STREAM_FACTORY_TAG); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp index 6e42994744..06ce057a36 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp @@ -1,239 +1,239 @@ - + /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/stream/SimpleStreamBuf.h> - -#include <algorithm> -#include <cassert> -#include <cstring> - -namespace Aws -{ -namespace Utils -{ -namespace Stream -{ - -static const uint32_t DEFAULT_BUFFER_SIZE = 100; -static const char* SIMPLE_STREAMBUF_ALLOCATION_TAG = "SimpleStreamBufTag"; - -SimpleStreamBuf::SimpleStreamBuf() : - m_buffer(nullptr), - m_bufferSize(0) -{ - m_buffer = Aws::NewArray<char>(DEFAULT_BUFFER_SIZE, SIMPLE_STREAMBUF_ALLOCATION_TAG); - m_bufferSize = DEFAULT_BUFFER_SIZE; - - char* begin = m_buffer; - char* end = begin + m_bufferSize; - - setp(begin, end); - setg(begin, begin, begin); -} - -SimpleStreamBuf::SimpleStreamBuf(const Aws::String& value) : - m_buffer(nullptr), - m_bufferSize(0) -{ - size_t baseSize = (std::max)(value.size(), static_cast<std::size_t>(DEFAULT_BUFFER_SIZE)); - - m_buffer = Aws::NewArray<char>(baseSize, SIMPLE_STREAMBUF_ALLOCATION_TAG); - m_bufferSize = baseSize; - - std::memcpy(m_buffer, value.c_str(), value.size()); - - char* begin = m_buffer; - char* end = begin + m_bufferSize; - - setp(begin + value.size(), end); - setg(begin, begin, begin); -} - -SimpleStreamBuf::~SimpleStreamBuf() -{ - if(m_buffer) - { - Aws::DeleteArray<char>(m_buffer); - m_buffer = nullptr; - } - - m_bufferSize = 0; -} - -std::streampos SimpleStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which) -{ - if (dir == std::ios_base::beg) - { - return seekpos(off, which); - } - else if (dir == std::ios_base::end) - { - return seekpos((pptr() - m_buffer) - off, which); - } - else if (dir == std::ios_base::cur) - { - if(which == std::ios_base::in) + +#include <aws/core/utils/stream/SimpleStreamBuf.h> + +#include <algorithm> +#include <cassert> +#include <cstring> + +namespace Aws +{ +namespace Utils +{ +namespace Stream +{ + +static const uint32_t DEFAULT_BUFFER_SIZE = 100; +static const char* SIMPLE_STREAMBUF_ALLOCATION_TAG = "SimpleStreamBufTag"; + +SimpleStreamBuf::SimpleStreamBuf() : + m_buffer(nullptr), + m_bufferSize(0) +{ + m_buffer = Aws::NewArray<char>(DEFAULT_BUFFER_SIZE, SIMPLE_STREAMBUF_ALLOCATION_TAG); + m_bufferSize = DEFAULT_BUFFER_SIZE; + + char* begin = m_buffer; + char* end = begin + m_bufferSize; + + setp(begin, end); + setg(begin, begin, begin); +} + +SimpleStreamBuf::SimpleStreamBuf(const Aws::String& value) : + m_buffer(nullptr), + m_bufferSize(0) +{ + size_t baseSize = (std::max)(value.size(), static_cast<std::size_t>(DEFAULT_BUFFER_SIZE)); + + m_buffer = Aws::NewArray<char>(baseSize, SIMPLE_STREAMBUF_ALLOCATION_TAG); + m_bufferSize = baseSize; + + std::memcpy(m_buffer, value.c_str(), value.size()); + + char* begin = m_buffer; + char* end = begin + m_bufferSize; + + setp(begin + value.size(), end); + setg(begin, begin, begin); +} + +SimpleStreamBuf::~SimpleStreamBuf() +{ + if(m_buffer) + { + Aws::DeleteArray<char>(m_buffer); + m_buffer = nullptr; + } + + m_bufferSize = 0; +} + +std::streampos SimpleStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which) +{ + if (dir == std::ios_base::beg) + { + return seekpos(off, which); + } + else if (dir == std::ios_base::end) + { + return seekpos((pptr() - m_buffer) - off, which); + } + else if (dir == std::ios_base::cur) + { + if(which == std::ios_base::in) + { + return seekpos((gptr() - m_buffer) + off, which); + } + else { - return seekpos((gptr() - m_buffer) + off, which); - } - else - { - return seekpos((pptr() - m_buffer) + off, which); - } - } - - return off_type(-1); -} - -std::streampos SimpleStreamBuf::seekpos(std::streampos pos, std::ios_base::openmode which) -{ - size_t maxSeek = pptr() - m_buffer; - assert(static_cast<size_t>(pos) <= maxSeek); - if (static_cast<size_t>(pos) > maxSeek) - { - return pos_type(off_type(-1)); - } - - if (which == std::ios_base::in) - { - setg(m_buffer, m_buffer + static_cast<size_t>(pos), pptr()); - } - - if (which == std::ios_base::out) - { - setp(m_buffer + static_cast<size_t>(pos), epptr()); - } - - return pos; -} - -bool SimpleStreamBuf::GrowBuffer() -{ - size_t currentSize = m_bufferSize; - size_t newSize = currentSize * 2; - - char* newBuffer = Aws::NewArray<char>(newSize, SIMPLE_STREAMBUF_ALLOCATION_TAG); - if(newBuffer == nullptr) - { - return false; - } - - if(currentSize > 0) - { - std::memcpy(newBuffer, m_buffer, currentSize); - } - - if(m_buffer) - { - Aws::DeleteArray<char>(m_buffer); - } - - m_buffer = newBuffer; - m_bufferSize = newSize; - - return true; -} - -int SimpleStreamBuf::overflow (int c) -{ - auto endOfFile = std::char_traits< char >::eof(); - if(c == endOfFile) - { - return endOfFile; - } - - char* old_begin = m_buffer; - - char *old_pptr = pptr(); - char *old_gptr = gptr(); - char *old_egptr = egptr(); - - size_t currentWritePosition = m_bufferSize; - - if(!GrowBuffer()) - { - return endOfFile; - } - - char* new_begin = m_buffer; - char* new_end = new_begin + m_bufferSize; - - setp(new_begin + (old_pptr - old_begin) + 1, new_end); - setg(new_begin, new_begin + (old_gptr - old_begin), new_begin + (old_egptr - old_begin)); - - auto val = std::char_traits< char >::to_char_type(c); - *(new_begin + currentWritePosition) = val; - - return c; -} - -std::streamsize SimpleStreamBuf::xsputn(const char* s, std::streamsize n) -{ - std::streamsize writeCount = 0; - while(writeCount < n) - { - char* current_pptr = pptr(); - char* current_epptr = epptr(); - - if (current_pptr < current_epptr) - { - std::size_t copySize = (std::min)(static_cast< std::size_t >(n - writeCount), - static_cast< std::size_t >(current_epptr - current_pptr)); - - std::memcpy(current_pptr, s + writeCount, copySize); - writeCount += copySize; - setp(current_pptr + copySize, current_epptr); - setg(m_buffer, gptr(), pptr()); - } - else if (overflow(std::char_traits< char >::to_int_type(*(s + writeCount))) != std::char_traits<char>::eof()) - { - writeCount++; - } - else - { - return writeCount; - } - } - - return writeCount; -} - + return seekpos((pptr() - m_buffer) + off, which); + } + } + + return off_type(-1); +} + +std::streampos SimpleStreamBuf::seekpos(std::streampos pos, std::ios_base::openmode which) +{ + size_t maxSeek = pptr() - m_buffer; + assert(static_cast<size_t>(pos) <= maxSeek); + if (static_cast<size_t>(pos) > maxSeek) + { + return pos_type(off_type(-1)); + } + + if (which == std::ios_base::in) + { + setg(m_buffer, m_buffer + static_cast<size_t>(pos), pptr()); + } + + if (which == std::ios_base::out) + { + setp(m_buffer + static_cast<size_t>(pos), epptr()); + } + + return pos; +} + +bool SimpleStreamBuf::GrowBuffer() +{ + size_t currentSize = m_bufferSize; + size_t newSize = currentSize * 2; + + char* newBuffer = Aws::NewArray<char>(newSize, SIMPLE_STREAMBUF_ALLOCATION_TAG); + if(newBuffer == nullptr) + { + return false; + } + + if(currentSize > 0) + { + std::memcpy(newBuffer, m_buffer, currentSize); + } + + if(m_buffer) + { + Aws::DeleteArray<char>(m_buffer); + } + + m_buffer = newBuffer; + m_bufferSize = newSize; + + return true; +} + +int SimpleStreamBuf::overflow (int c) +{ + auto endOfFile = std::char_traits< char >::eof(); + if(c == endOfFile) + { + return endOfFile; + } + + char* old_begin = m_buffer; + + char *old_pptr = pptr(); + char *old_gptr = gptr(); + char *old_egptr = egptr(); + + size_t currentWritePosition = m_bufferSize; + + if(!GrowBuffer()) + { + return endOfFile; + } + + char* new_begin = m_buffer; + char* new_end = new_begin + m_bufferSize; + + setp(new_begin + (old_pptr - old_begin) + 1, new_end); + setg(new_begin, new_begin + (old_gptr - old_begin), new_begin + (old_egptr - old_begin)); + + auto val = std::char_traits< char >::to_char_type(c); + *(new_begin + currentWritePosition) = val; + + return c; +} + +std::streamsize SimpleStreamBuf::xsputn(const char* s, std::streamsize n) +{ + std::streamsize writeCount = 0; + while(writeCount < n) + { + char* current_pptr = pptr(); + char* current_epptr = epptr(); + + if (current_pptr < current_epptr) + { + std::size_t copySize = (std::min)(static_cast< std::size_t >(n - writeCount), + static_cast< std::size_t >(current_epptr - current_pptr)); + + std::memcpy(current_pptr, s + writeCount, copySize); + writeCount += copySize; + setp(current_pptr + copySize, current_epptr); + setg(m_buffer, gptr(), pptr()); + } + else if (overflow(std::char_traits< char >::to_int_type(*(s + writeCount))) != std::char_traits<char>::eof()) + { + writeCount++; + } + else + { + return writeCount; + } + } + + return writeCount; +} + Aws::String SimpleStreamBuf::str() const -{ - return Aws::String(m_buffer, pptr()); -} - -int SimpleStreamBuf::underflow() -{ - if(egptr() != pptr()) - { - setg(m_buffer, gptr(), pptr()); - } - - if(gptr() != egptr()) - { - return std::char_traits< char >::to_int_type(*gptr()); - } - else - { - return std::char_traits< char >::eof(); - } -} - -void SimpleStreamBuf::str(const Aws::String& value) -{ - char* begin = m_buffer; - char* end = begin + m_bufferSize; - - setp(begin, end); - setg(begin, begin, begin); - - xsputn(value.c_str(), value.size()); -} - -} -} +{ + return Aws::String(m_buffer, pptr()); +} + +int SimpleStreamBuf::underflow() +{ + if(egptr() != pptr()) + { + setg(m_buffer, gptr(), pptr()); + } + + if(gptr() != egptr()) + { + return std::char_traits< char >::to_int_type(*gptr()); + } + else + { + return std::char_traits< char >::eof(); + } +} + +void SimpleStreamBuf::str(const Aws::String& value) +{ + char* begin = m_buffer; + char* end = begin + m_bufferSize; + + setp(begin, end); + setg(begin, begin, begin); + + xsputn(value.c_str(), value.size()); +} + +} +} } diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp index 4a3c4209c4..d63c66c884 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp @@ -2,154 +2,154 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/threading/Executor.h> -#include <aws/core/utils/threading/ThreadTask.h> -#include <thread> -#include <cassert> - -static const char* POOLED_CLASS_TAG = "PooledThreadExecutor"; - -using namespace Aws::Utils::Threading; - -bool DefaultExecutor::SubmitToThread(std::function<void()>&& fx) -{ - auto main = [fx, this] { - fx(); - Detach(std::this_thread::get_id()); - }; - - State expected; - do - { - expected = State::Free; - if(m_state.compare_exchange_strong(expected, State::Locked)) - { - std::thread t(main); - const auto id = t.get_id(); // copy the id before we std::move the thread - m_threads.emplace(id, std::move(t)); - m_state = State::Free; - return true; - } - } - while(expected != State::Shutdown); - return false; -} - -void DefaultExecutor::Detach(std::thread::id id) -{ - State expected; - do - { - expected = State::Free; - if(m_state.compare_exchange_strong(expected, State::Locked)) - { - auto it = m_threads.find(id); - assert(it != m_threads.end()); - it->second.detach(); - m_threads.erase(it); - m_state = State::Free; - return; - } + +#include <aws/core/utils/threading/Executor.h> +#include <aws/core/utils/threading/ThreadTask.h> +#include <thread> +#include <cassert> + +static const char* POOLED_CLASS_TAG = "PooledThreadExecutor"; + +using namespace Aws::Utils::Threading; + +bool DefaultExecutor::SubmitToThread(std::function<void()>&& fx) +{ + auto main = [fx, this] { + fx(); + Detach(std::this_thread::get_id()); + }; + + State expected; + do + { + expected = State::Free; + if(m_state.compare_exchange_strong(expected, State::Locked)) + { + std::thread t(main); + const auto id = t.get_id(); // copy the id before we std::move the thread + m_threads.emplace(id, std::move(t)); + m_state = State::Free; + return true; + } } - while(expected != State::Shutdown); -} - -DefaultExecutor::~DefaultExecutor() -{ - auto expected = State::Free; - while(!m_state.compare_exchange_strong(expected, State::Shutdown)) - { - //spin while currently detaching threads finish - assert(expected == State::Locked); + while(expected != State::Shutdown); + return false; +} + +void DefaultExecutor::Detach(std::thread::id id) +{ + State expected; + do + { expected = State::Free; - } - - auto it = m_threads.begin(); - while(!m_threads.empty()) - { - it->second.join(); - it = m_threads.erase(it); - } -} - -PooledThreadExecutor::PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy) : - m_sync(0, poolSize), m_poolSize(poolSize), m_overflowPolicy(overflowPolicy) -{ - for (size_t index = 0; index < m_poolSize; ++index) - { - m_threadTaskHandles.push_back(Aws::New<ThreadTask>(POOLED_CLASS_TAG, *this)); - } -} - -PooledThreadExecutor::~PooledThreadExecutor() -{ - for(auto threadTask : m_threadTaskHandles) - { - threadTask->StopProcessingWork(); - } - - m_sync.ReleaseAll(); - - for (auto threadTask : m_threadTaskHandles) - { - Aws::Delete(threadTask); - } - - while(m_tasks.size() > 0) - { - std::function<void()>* fn = m_tasks.front(); - m_tasks.pop(); - - if(fn) - { - Aws::Delete(fn); - } - } - -} - -bool PooledThreadExecutor::SubmitToThread(std::function<void()>&& fn) -{ - //avoid the need to do copies inside the lock. Instead lets do a pointer push. - std::function<void()>* fnCpy = Aws::New<std::function<void()>>(POOLED_CLASS_TAG, std::forward<std::function<void()>>(fn)); - - { - std::lock_guard<std::mutex> locker(m_queueLock); - - if (m_overflowPolicy == OverflowPolicy::REJECT_IMMEDIATELY && m_tasks.size() >= m_poolSize) - { - Aws::Delete(fnCpy); - return false; - } - - m_tasks.push(fnCpy); - } - - m_sync.Release(); - - return true; -} - -std::function<void()>* PooledThreadExecutor::PopTask() -{ - std::lock_guard<std::mutex> locker(m_queueLock); - - if (m_tasks.size() > 0) - { - std::function<void()>* fn = m_tasks.front(); - if (fn) - { - m_tasks.pop(); - return fn; - } - } - - return nullptr; -} - -bool PooledThreadExecutor::HasTasks() -{ - std::lock_guard<std::mutex> locker(m_queueLock); - return m_tasks.size() > 0; -} + if(m_state.compare_exchange_strong(expected, State::Locked)) + { + auto it = m_threads.find(id); + assert(it != m_threads.end()); + it->second.detach(); + m_threads.erase(it); + m_state = State::Free; + return; + } + } + while(expected != State::Shutdown); +} + +DefaultExecutor::~DefaultExecutor() +{ + auto expected = State::Free; + while(!m_state.compare_exchange_strong(expected, State::Shutdown)) + { + //spin while currently detaching threads finish + assert(expected == State::Locked); + expected = State::Free; + } + + auto it = m_threads.begin(); + while(!m_threads.empty()) + { + it->second.join(); + it = m_threads.erase(it); + } +} + +PooledThreadExecutor::PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy) : + m_sync(0, poolSize), m_poolSize(poolSize), m_overflowPolicy(overflowPolicy) +{ + for (size_t index = 0; index < m_poolSize; ++index) + { + m_threadTaskHandles.push_back(Aws::New<ThreadTask>(POOLED_CLASS_TAG, *this)); + } +} + +PooledThreadExecutor::~PooledThreadExecutor() +{ + for(auto threadTask : m_threadTaskHandles) + { + threadTask->StopProcessingWork(); + } + + m_sync.ReleaseAll(); + + for (auto threadTask : m_threadTaskHandles) + { + Aws::Delete(threadTask); + } + + while(m_tasks.size() > 0) + { + std::function<void()>* fn = m_tasks.front(); + m_tasks.pop(); + + if(fn) + { + Aws::Delete(fn); + } + } + +} + +bool PooledThreadExecutor::SubmitToThread(std::function<void()>&& fn) +{ + //avoid the need to do copies inside the lock. Instead lets do a pointer push. + std::function<void()>* fnCpy = Aws::New<std::function<void()>>(POOLED_CLASS_TAG, std::forward<std::function<void()>>(fn)); + + { + std::lock_guard<std::mutex> locker(m_queueLock); + + if (m_overflowPolicy == OverflowPolicy::REJECT_IMMEDIATELY && m_tasks.size() >= m_poolSize) + { + Aws::Delete(fnCpy); + return false; + } + + m_tasks.push(fnCpy); + } + + m_sync.Release(); + + return true; +} + +std::function<void()>* PooledThreadExecutor::PopTask() +{ + std::lock_guard<std::mutex> locker(m_queueLock); + + if (m_tasks.size() > 0) + { + std::function<void()>* fn = m_tasks.front(); + if (fn) + { + m_tasks.pop(); + return fn; + } + } + + return nullptr; +} + +bool PooledThreadExecutor::HasTasks() +{ + std::lock_guard<std::mutex> locker(m_queueLock); + return m_tasks.size() > 0; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp index ddb5860563..9daad445d8 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp @@ -1,64 +1,64 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/utils/threading/ReaderWriterLock.h> -#include <cstdint> -#include <limits> -#include <cassert> - -using namespace Aws::Utils::Threading; - + */ + +#include <aws/core/utils/threading/ReaderWriterLock.h> +#include <cstdint> +#include <limits> +#include <cassert> + +using namespace Aws::Utils::Threading; + static const int64_t MaxReaders = (std::numeric_limits<std::int32_t>::max)(); - -ReaderWriterLock::ReaderWriterLock() : - m_readers(0), - m_holdouts(0), - m_readerSem(0, static_cast<size_t>(MaxReaders)), - m_writerSem(0, 1) -{ -} - -void ReaderWriterLock::LockReader() -{ - if (++m_readers < 0) - { - m_readerSem.WaitOne(); - } -} - -void ReaderWriterLock::UnlockReader() -{ - if (--m_readers < 0 && --m_holdouts == 0) - { - m_writerSem.Release(); - } -} - -void ReaderWriterLock::LockWriter() -{ - m_writerLock.lock(); - if(const auto current = m_readers.fetch_sub(MaxReaders)) - { - assert(current > 0); - const auto holdouts = m_holdouts.fetch_add(current) + current; - assert(holdouts >= 0); - if(holdouts > 0) - { - m_writerSem.WaitOne(); - } - } -} - -void ReaderWriterLock::UnlockWriter() -{ - assert(m_holdouts == 0); - const auto current = m_readers.fetch_add(MaxReaders) + MaxReaders; - assert(current >= 0); - for(int64_t r = 0; r < current; r++) - { - m_readerSem.Release(); - } - m_writerLock.unlock(); -} + +ReaderWriterLock::ReaderWriterLock() : + m_readers(0), + m_holdouts(0), + m_readerSem(0, static_cast<size_t>(MaxReaders)), + m_writerSem(0, 1) +{ +} + +void ReaderWriterLock::LockReader() +{ + if (++m_readers < 0) + { + m_readerSem.WaitOne(); + } +} + +void ReaderWriterLock::UnlockReader() +{ + if (--m_readers < 0 && --m_holdouts == 0) + { + m_writerSem.Release(); + } +} + +void ReaderWriterLock::LockWriter() +{ + m_writerLock.lock(); + if(const auto current = m_readers.fetch_sub(MaxReaders)) + { + assert(current > 0); + const auto holdouts = m_holdouts.fetch_add(current) + current; + assert(holdouts >= 0); + if(holdouts > 0) + { + m_writerSem.WaitOne(); + } + } +} + +void ReaderWriterLock::UnlockWriter() +{ + assert(m_holdouts == 0); + const auto current = m_readers.fetch_add(MaxReaders) + MaxReaders; + assert(current >= 0); + for(int64_t r = 0; r < current; r++) + { + m_readerSem.Release(); + } + m_writerLock.unlock(); +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp index 86dabc9acf..dfc7d1a1f6 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp @@ -1,39 +1,39 @@ /** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/core/utils/threading/Semaphore.h> -#include <algorithm> - -using namespace Aws::Utils::Threading; - -Semaphore::Semaphore(size_t initialCount, size_t maxCount) - : m_count(initialCount), m_maxCount(maxCount) -{ -} - -void Semaphore::WaitOne() -{ - std::unique_lock<std::mutex> locker(m_mutex); - if(0 == m_count) - { - m_syncPoint.wait(locker, [this] { return m_count > 0; }); - } - --m_count; -} - -void Semaphore::Release() -{ - std::lock_guard<std::mutex> locker(m_mutex); - m_count = (std::min)(m_maxCount, m_count + 1); - m_syncPoint.notify_one(); -} - -void Semaphore::ReleaseAll() -{ - std::lock_guard<std::mutex> locker(m_mutex); - m_count = m_maxCount; - m_syncPoint.notify_all(); -} - + */ + +#include <aws/core/utils/threading/Semaphore.h> +#include <algorithm> + +using namespace Aws::Utils::Threading; + +Semaphore::Semaphore(size_t initialCount, size_t maxCount) + : m_count(initialCount), m_maxCount(maxCount) +{ +} + +void Semaphore::WaitOne() +{ + std::unique_lock<std::mutex> locker(m_mutex); + if(0 == m_count) + { + m_syncPoint.wait(locker, [this] { return m_count > 0; }); + } + --m_count; +} + +void Semaphore::Release() +{ + std::lock_guard<std::mutex> locker(m_mutex); + m_count = (std::min)(m_maxCount, m_count + 1); + m_syncPoint.notify_one(); +} + +void Semaphore::ReleaseAll() +{ + std::lock_guard<std::mutex> locker(m_mutex); + m_count = m_maxCount; + m_syncPoint.notify_all(); +} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp index a899fe045d..3f32ca2583 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp @@ -2,45 +2,45 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/threading/ThreadTask.h> -#include <aws/core/utils/threading/Executor.h> - -using namespace Aws::Utils; -using namespace Aws::Utils::Threading; - -ThreadTask::ThreadTask(PooledThreadExecutor& executor) : m_continue(true), m_executor(executor), m_thread(std::bind(&ThreadTask::MainTaskRunner, this)) -{ -} - -ThreadTask::~ThreadTask() -{ - StopProcessingWork(); - m_thread.join(); -} - -void ThreadTask::MainTaskRunner() -{ - while (m_continue) - { - while (m_continue && m_executor.HasTasks()) - { - auto fn = m_executor.PopTask(); - if(fn) - { - (*fn)(); - Aws::Delete(fn); - } - } - - if(m_continue) - { - m_executor.m_sync.WaitOne(); - } - } -} - -void ThreadTask::StopProcessingWork() -{ - m_continue = false; -} + +#include <aws/core/utils/threading/ThreadTask.h> +#include <aws/core/utils/threading/Executor.h> + +using namespace Aws::Utils; +using namespace Aws::Utils::Threading; + +ThreadTask::ThreadTask(PooledThreadExecutor& executor) : m_continue(true), m_executor(executor), m_thread(std::bind(&ThreadTask::MainTaskRunner, this)) +{ +} + +ThreadTask::~ThreadTask() +{ + StopProcessingWork(); + m_thread.join(); +} + +void ThreadTask::MainTaskRunner() +{ + while (m_continue) + { + while (m_continue && m_executor.HasTasks()) + { + auto fn = m_executor.PopTask(); + if(fn) + { + (*fn)(); + Aws::Delete(fn); + } + } + + if(m_continue) + { + m_executor.m_sync.WaitOne(); + } + } +} + +void ThreadTask::StopProcessingWork() +{ + m_continue = false; +} diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp index c06befaf9b..912ac7c3a3 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp @@ -2,165 +2,165 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ - -#include <aws/core/utils/xml/XmlSerializer.h> - -#include <aws/core/utils/StringUtils.h> -#include <aws/core/external/tinyxml2/tinyxml2.h> - -#include <utility> -#include <algorithm> -#include <iostream> - -using namespace Aws::Utils::Xml; -using namespace Aws::Utils; - -Aws::String Aws::Utils::Xml::DecodeEscapedXmlText(const Aws::String& textToDecode) -{ - Aws::String decodedString = textToDecode; - StringUtils::Replace(decodedString, """, "\""); - StringUtils::Replace(decodedString, "'", "'"); - StringUtils::Replace(decodedString, "<", "<"); - StringUtils::Replace(decodedString, ">", ">"); - StringUtils::Replace(decodedString, "&", "&"); - - return decodedString; -} - -XmlNode::XmlNode(const XmlNode& other) : m_node(other.m_node), m_doc(other.m_doc) -{ -} - -XmlNode& XmlNode::operator=(const XmlNode& other) -{ - if(this == &other) - { - return *this; - } - - m_node = other.m_node; - m_doc = other.m_doc; - - return *this; -} - -const Aws::String XmlNode::GetName() const -{ - return m_node->Value(); -} - -void XmlNode::SetName(const Aws::String& name) -{ - m_node->SetValue(name.c_str(), false); -} - -const Aws::String XmlNode::GetAttributeValue(const Aws::String& name) const -{ + +#include <aws/core/utils/xml/XmlSerializer.h> + +#include <aws/core/utils/StringUtils.h> +#include <aws/core/external/tinyxml2/tinyxml2.h> + +#include <utility> +#include <algorithm> +#include <iostream> + +using namespace Aws::Utils::Xml; +using namespace Aws::Utils; + +Aws::String Aws::Utils::Xml::DecodeEscapedXmlText(const Aws::String& textToDecode) +{ + Aws::String decodedString = textToDecode; + StringUtils::Replace(decodedString, """, "\""); + StringUtils::Replace(decodedString, "'", "'"); + StringUtils::Replace(decodedString, "<", "<"); + StringUtils::Replace(decodedString, ">", ">"); + StringUtils::Replace(decodedString, "&", "&"); + + return decodedString; +} + +XmlNode::XmlNode(const XmlNode& other) : m_node(other.m_node), m_doc(other.m_doc) +{ +} + +XmlNode& XmlNode::operator=(const XmlNode& other) +{ + if(this == &other) + { + return *this; + } + + m_node = other.m_node; + m_doc = other.m_doc; + + return *this; +} + +const Aws::String XmlNode::GetName() const +{ + return m_node->Value(); +} + +void XmlNode::SetName(const Aws::String& name) +{ + m_node->SetValue(name.c_str(), false); +} + +const Aws::String XmlNode::GetAttributeValue(const Aws::String& name) const +{ auto pointer = m_node->ToElement()->Attribute(name.c_str(), nullptr); return pointer ? pointer : ""; -} - -void XmlNode::SetAttributeValue(const Aws::String& name, const Aws::String& value) -{ - m_node->ToElement()->SetAttribute(name.c_str(), value.c_str()); -} - -bool XmlNode::HasNextNode() const -{ - return m_node->NextSibling() != nullptr; -} - -XmlNode XmlNode::NextNode() const -{ - return XmlNode(m_node->NextSiblingElement(), *m_doc); -} - -XmlNode XmlNode::NextNode(const char* name) const -{ - return XmlNode(m_node->NextSiblingElement(name), *m_doc); -} - -XmlNode XmlNode::NextNode(const Aws::String& name) const -{ - return NextNode(name.c_str()); -} - -XmlNode XmlNode::FirstChild() const -{ - return XmlNode(m_node->FirstChildElement(), *m_doc); -} - -XmlNode XmlNode::FirstChild(const char* name) const -{ - return XmlNode(m_node->FirstChildElement(name), *m_doc); -} - -XmlNode XmlNode::FirstChild(const Aws::String& name) const -{ - return FirstChild(name.c_str()); -} - -bool XmlNode::HasChildren() const -{ - return !m_node->NoChildren(); -} - -XmlNode XmlNode::Parent() const -{ - return XmlNode(m_node->Parent()->ToElement(), *m_doc); -} - -Aws::String XmlNode::GetText() const -{ - if (m_node != nullptr) - { - Aws::External::tinyxml2::XMLPrinter printer; - Aws::External::tinyxml2::XMLNode* node = m_node->FirstChild(); - while (node != nullptr) - { - node->Accept(&printer); - node = node->NextSibling(); - } - - return printer.CStr(); - } - +} + +void XmlNode::SetAttributeValue(const Aws::String& name, const Aws::String& value) +{ + m_node->ToElement()->SetAttribute(name.c_str(), value.c_str()); +} + +bool XmlNode::HasNextNode() const +{ + return m_node->NextSibling() != nullptr; +} + +XmlNode XmlNode::NextNode() const +{ + return XmlNode(m_node->NextSiblingElement(), *m_doc); +} + +XmlNode XmlNode::NextNode(const char* name) const +{ + return XmlNode(m_node->NextSiblingElement(name), *m_doc); +} + +XmlNode XmlNode::NextNode(const Aws::String& name) const +{ + return NextNode(name.c_str()); +} + +XmlNode XmlNode::FirstChild() const +{ + return XmlNode(m_node->FirstChildElement(), *m_doc); +} + +XmlNode XmlNode::FirstChild(const char* name) const +{ + return XmlNode(m_node->FirstChildElement(name), *m_doc); +} + +XmlNode XmlNode::FirstChild(const Aws::String& name) const +{ + return FirstChild(name.c_str()); +} + +bool XmlNode::HasChildren() const +{ + return !m_node->NoChildren(); +} + +XmlNode XmlNode::Parent() const +{ + return XmlNode(m_node->Parent()->ToElement(), *m_doc); +} + +Aws::String XmlNode::GetText() const +{ + if (m_node != nullptr) + { + Aws::External::tinyxml2::XMLPrinter printer; + Aws::External::tinyxml2::XMLNode* node = m_node->FirstChild(); + while (node != nullptr) + { + node->Accept(&printer); + node = node->NextSibling(); + } + + return printer.CStr(); + } + return {}; -} - -void XmlNode::SetText(const Aws::String& textValue) -{ - if (m_node != nullptr) - { - Aws::External::tinyxml2::XMLText* text = m_doc->m_doc->NewText(textValue.c_str()); - m_node->InsertEndChild(text); - } -} - -XmlNode XmlNode::CreateChildElement(const Aws::String& name) -{ - Aws::External::tinyxml2::XMLElement* element = m_doc->m_doc->NewElement(name.c_str()); - return XmlNode(m_node->InsertEndChild(element), *m_doc); -} - -XmlNode XmlNode::CreateSiblingElement(const Aws::String& name) -{ - Aws::External::tinyxml2::XMLElement* element = m_doc->m_doc->NewElement(name.c_str()); - return XmlNode(m_node->Parent()->InsertEndChild(element), *m_doc); -} - -bool XmlNode::IsNull() -{ - return m_node == nullptr; -} - -static const char* XML_SERIALIZER_ALLOCATION_TAG = "XmlDocument"; - -XmlDocument::XmlDocument() -{ +} + +void XmlNode::SetText(const Aws::String& textValue) +{ + if (m_node != nullptr) + { + Aws::External::tinyxml2::XMLText* text = m_doc->m_doc->NewText(textValue.c_str()); + m_node->InsertEndChild(text); + } +} + +XmlNode XmlNode::CreateChildElement(const Aws::String& name) +{ + Aws::External::tinyxml2::XMLElement* element = m_doc->m_doc->NewElement(name.c_str()); + return XmlNode(m_node->InsertEndChild(element), *m_doc); +} + +XmlNode XmlNode::CreateSiblingElement(const Aws::String& name) +{ + Aws::External::tinyxml2::XMLElement* element = m_doc->m_doc->NewElement(name.c_str()); + return XmlNode(m_node->Parent()->InsertEndChild(element), *m_doc); +} + +bool XmlNode::IsNull() +{ + return m_node == nullptr; +} + +static const char* XML_SERIALIZER_ALLOCATION_TAG = "XmlDocument"; + +XmlDocument::XmlDocument() +{ m_doc = nullptr; -} - +} + XmlDocument::XmlDocument(const XmlDocument& doc) { if (doc.m_doc == nullptr) @@ -175,10 +175,10 @@ XmlDocument::XmlDocument(const XmlDocument& doc) } XmlDocument::XmlDocument(XmlDocument&& doc) : m_doc{ doc.m_doc } // take the innards -{ - doc.m_doc = nullptr; // leave nothing behind -} - +{ + doc.m_doc = nullptr; // leave nothing behind +} + XmlDocument& XmlDocument::operator=(const XmlDocument& other) { if (this == &other) @@ -221,21 +221,21 @@ XmlDocument& XmlDocument::operator=(XmlDocument&& other) return *this; } -XmlDocument::~XmlDocument() -{ +XmlDocument::~XmlDocument() +{ if (m_doc) { Aws::Delete(m_doc); } -} - +} + void XmlDocument::InitDoc() { m_doc = Aws::New<Aws::External::tinyxml2::XMLDocument>(XML_SERIALIZER_ALLOCATION_TAG, true, Aws::External::tinyxml2::Whitespace::PRESERVE_WHITESPACE); } -XmlNode XmlDocument::GetRootElement() const -{ +XmlNode XmlDocument::GetRootElement() const +{ if (m_doc) { return XmlNode(m_doc->FirstChildElement(), *this); @@ -245,10 +245,10 @@ XmlNode XmlDocument::GetRootElement() const return XmlNode(nullptr, *this); } -} - -bool XmlDocument::WasParseSuccessful() const -{ +} + +bool XmlDocument::WasParseSuccessful() const +{ if (m_doc) { return !m_doc->Error(); @@ -258,45 +258,45 @@ bool XmlDocument::WasParseSuccessful() const return true; } -} - -Aws::String XmlDocument::GetErrorMessage() const -{ - return !WasParseSuccessful() ? m_doc->ErrorName() : ""; -} - -Aws::String XmlDocument::ConvertToString() const -{ +} + +Aws::String XmlDocument::GetErrorMessage() const +{ + return !WasParseSuccessful() ? m_doc->ErrorName() : ""; +} + +Aws::String XmlDocument::ConvertToString() const +{ if (!m_doc) return ""; - Aws::External::tinyxml2::XMLPrinter printer; - printer.PushHeader(false, true); - m_doc->Accept(&printer); - - return printer.CStr(); -} - -XmlDocument XmlDocument::CreateFromXmlStream(Aws::IOStream& xmlStream) -{ - Aws::String xmlString((Aws::IStreamBufIterator(xmlStream)), Aws::IStreamBufIterator()); - return CreateFromXmlString(xmlString); -} - -XmlDocument XmlDocument::CreateFromXmlString(const Aws::String& xmlText) -{ - XmlDocument xmlDocument; + Aws::External::tinyxml2::XMLPrinter printer; + printer.PushHeader(false, true); + m_doc->Accept(&printer); + + return printer.CStr(); +} + +XmlDocument XmlDocument::CreateFromXmlStream(Aws::IOStream& xmlStream) +{ + Aws::String xmlString((Aws::IStreamBufIterator(xmlStream)), Aws::IStreamBufIterator()); + return CreateFromXmlString(xmlString); +} + +XmlDocument XmlDocument::CreateFromXmlString(const Aws::String& xmlText) +{ + XmlDocument xmlDocument; xmlDocument.InitDoc(); - xmlDocument.m_doc->Parse(xmlText.c_str(), xmlText.size()); - return xmlDocument; -} - -XmlDocument XmlDocument::CreateWithRootNode(const Aws::String& rootNodeName) -{ - XmlDocument xmlDocument; + xmlDocument.m_doc->Parse(xmlText.c_str(), xmlText.size()); + return xmlDocument; +} + +XmlDocument XmlDocument::CreateWithRootNode(const Aws::String& rootNodeName) +{ + XmlDocument xmlDocument; xmlDocument.InitDoc(); - Aws::External::tinyxml2::XMLElement* rootNode = xmlDocument.m_doc->NewElement(rootNodeName.c_str()); - xmlDocument.m_doc->LinkEndChild(rootNode); - - return xmlDocument; -} - + Aws::External::tinyxml2::XMLElement* rootNode = xmlDocument.m_doc->NewElement(rootNodeName.c_str()); + xmlDocument.m_doc->LinkEndChild(rootNode); + + return xmlDocument; +} + diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make index d6b0823d45..425e101803 100644 --- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/ya.make @@ -1,7 +1,7 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + OWNER( orivej shindo @@ -16,114 +16,114 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/libs/curl - contrib/libs/openssl +PEERDIR( + contrib/libs/curl + contrib/libs/openssl contrib/restricted/aws/aws-c-common contrib/restricted/aws/aws-c-event-stream -) - +) + ADDINCL( GLOBAL contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/include ) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( -DAWS_CAL_USE_IMPORT_EXPORT -DAWS_CHECKSUMS_USE_IMPORT_EXPORT -DAWS_COMMON_USE_IMPORT_EXPORT -DAWS_EVENT_STREAM_USE_IMPORT_EXPORT -DAWS_IO_USE_IMPORT_EXPORT - -DAWS_SDK_VERSION_MAJOR=1 + -DAWS_SDK_VERSION_MAJOR=1 -DAWS_SDK_VERSION_MINOR=8 -DAWS_SDK_VERSION_PATCH=113 -DAWS_USE_EPOLL -DCURL_HAS_H2 -DCURL_HAS_TLS_PROXY - -DENABLE_CURL_CLIENT + -DENABLE_CURL_CLIENT -DENABLE_CURL_LOGGING - -DENABLE_OPENSSL_ENCRYPTION + -DENABLE_OPENSSL_ENCRYPTION -DHAS_PATHCONF -DHAS_UMASK -DS2N_ADX -DS2N_CPUID_AVAILABLE -DS2N_HAVE_EXECINFO -DS2N_SIKEP434R2_ASM -) - -SRCS( - source/AmazonSerializableWebServiceRequest.cpp - source/AmazonStreamingWebServiceRequest.cpp - source/AmazonWebServiceRequest.cpp - source/Aws.cpp - source/Globals.cpp +) + +SRCS( + source/AmazonSerializableWebServiceRequest.cpp + source/AmazonStreamingWebServiceRequest.cpp + source/AmazonWebServiceRequest.cpp + source/Aws.cpp + source/Globals.cpp source/Region.cpp - source/Version.cpp - source/auth/AWSAuthSigner.cpp - source/auth/AWSAuthSignerProvider.cpp - source/auth/AWSCredentialsProvider.cpp - source/auth/AWSCredentialsProviderChain.cpp + source/Version.cpp + source/auth/AWSAuthSigner.cpp + source/auth/AWSAuthSignerProvider.cpp + source/auth/AWSCredentialsProvider.cpp + source/auth/AWSCredentialsProviderChain.cpp source/auth/STSCredentialsProvider.cpp - source/client/AWSClient.cpp - source/client/AWSErrorMarshaller.cpp - source/client/AsyncCallerContext.cpp - source/client/ClientConfiguration.cpp - source/client/CoreErrors.cpp - source/client/DefaultRetryStrategy.cpp + source/client/AWSClient.cpp + source/client/AWSErrorMarshaller.cpp + source/client/AsyncCallerContext.cpp + source/client/ClientConfiguration.cpp + source/client/CoreErrors.cpp + source/client/DefaultRetryStrategy.cpp source/client/RetryStrategy.cpp source/client/SpecifiedRetryableErrorsRetryStrategy.cpp - source/config/AWSProfileConfigLoader.cpp - source/external/cjson/cJSON.cpp - source/external/tinyxml2/tinyxml2.cpp - source/http/HttpClient.cpp - source/http/HttpClientFactory.cpp - source/http/HttpRequest.cpp - source/http/HttpTypes.cpp - source/http/Scheme.cpp - source/http/URI.cpp - source/http/curl/CurlHandleContainer.cpp - source/http/curl/CurlHttpClient.cpp - source/http/standard/StandardHttpRequest.cpp - source/http/standard/StandardHttpResponse.cpp - source/internal/AWSHttpResourceClient.cpp - source/monitoring/DefaultMonitoring.cpp - source/monitoring/HttpClientMetrics.cpp - source/monitoring/MonitoringManager.cpp - source/net/linux-shared/Net.cpp - source/net/linux-shared/SimpleUDP.cpp - source/platform/linux-shared/Environment.cpp - source/platform/linux-shared/FileSystem.cpp - source/platform/linux-shared/OSVersionInfo.cpp - source/platform/linux-shared/Security.cpp - source/platform/linux-shared/Time.cpp + source/config/AWSProfileConfigLoader.cpp + source/external/cjson/cJSON.cpp + source/external/tinyxml2/tinyxml2.cpp + source/http/HttpClient.cpp + source/http/HttpClientFactory.cpp + source/http/HttpRequest.cpp + source/http/HttpTypes.cpp + source/http/Scheme.cpp + source/http/URI.cpp + source/http/curl/CurlHandleContainer.cpp + source/http/curl/CurlHttpClient.cpp + source/http/standard/StandardHttpRequest.cpp + source/http/standard/StandardHttpResponse.cpp + source/internal/AWSHttpResourceClient.cpp + source/monitoring/DefaultMonitoring.cpp + source/monitoring/HttpClientMetrics.cpp + source/monitoring/MonitoringManager.cpp + source/net/linux-shared/Net.cpp + source/net/linux-shared/SimpleUDP.cpp + source/platform/linux-shared/Environment.cpp + source/platform/linux-shared/FileSystem.cpp + source/platform/linux-shared/OSVersionInfo.cpp + source/platform/linux-shared/Security.cpp + source/platform/linux-shared/Time.cpp source/utils/ARN.cpp - source/utils/Array.cpp - source/utils/DNS.cpp - source/utils/DateTimeCommon.cpp - source/utils/Directory.cpp - source/utils/EnumParseOverflowContainer.cpp - source/utils/FileSystemUtils.cpp - source/utils/GetTheLights.cpp - source/utils/HashingUtils.cpp - source/utils/StringUtils.cpp - source/utils/TempFile.cpp - source/utils/UUID.cpp - source/utils/base64/Base64.cpp - source/utils/crypto/Cipher.cpp - source/utils/crypto/ContentCryptoMaterial.cpp - source/utils/crypto/ContentCryptoScheme.cpp - source/utils/crypto/CryptoBuf.cpp - source/utils/crypto/CryptoStream.cpp - source/utils/crypto/EncryptionMaterials.cpp - source/utils/crypto/KeyWrapAlgorithm.cpp - source/utils/crypto/MD5.cpp - source/utils/crypto/Sha256.cpp - source/utils/crypto/Sha256HMAC.cpp - source/utils/crypto/factory/Factories.cpp - source/utils/crypto/openssl/CryptoImpl.cpp + source/utils/Array.cpp + source/utils/DNS.cpp + source/utils/DateTimeCommon.cpp + source/utils/Directory.cpp + source/utils/EnumParseOverflowContainer.cpp + source/utils/FileSystemUtils.cpp + source/utils/GetTheLights.cpp + source/utils/HashingUtils.cpp + source/utils/StringUtils.cpp + source/utils/TempFile.cpp + source/utils/UUID.cpp + source/utils/base64/Base64.cpp + source/utils/crypto/Cipher.cpp + source/utils/crypto/ContentCryptoMaterial.cpp + source/utils/crypto/ContentCryptoScheme.cpp + source/utils/crypto/CryptoBuf.cpp + source/utils/crypto/CryptoStream.cpp + source/utils/crypto/EncryptionMaterials.cpp + source/utils/crypto/KeyWrapAlgorithm.cpp + source/utils/crypto/MD5.cpp + source/utils/crypto/Sha256.cpp + source/utils/crypto/Sha256HMAC.cpp + source/utils/crypto/factory/Factories.cpp + source/utils/crypto/openssl/CryptoImpl.cpp source/utils/event/EventDecoderStream.cpp source/utils/event/EventEncoderStream.cpp source/utils/event/EventHeader.cpp @@ -132,23 +132,23 @@ SRCS( source/utils/event/EventStreamDecoder.cpp source/utils/event/EventStreamEncoder.cpp source/utils/event/EventStreamErrors.cpp - source/utils/json/JsonSerializer.cpp - source/utils/logging/AWSLogging.cpp - source/utils/logging/ConsoleLogSystem.cpp - source/utils/logging/DefaultLogSystem.cpp - source/utils/logging/FormattedLogSystem.cpp - source/utils/logging/LogLevel.cpp - source/utils/memory/AWSMemory.cpp - source/utils/memory/stl/SimpleStringStream.cpp + source/utils/json/JsonSerializer.cpp + source/utils/logging/AWSLogging.cpp + source/utils/logging/ConsoleLogSystem.cpp + source/utils/logging/DefaultLogSystem.cpp + source/utils/logging/FormattedLogSystem.cpp + source/utils/logging/LogLevel.cpp + source/utils/memory/AWSMemory.cpp + source/utils/memory/stl/SimpleStringStream.cpp source/utils/stream/ConcurrentStreamBuf.cpp - source/utils/stream/PreallocatedStreamBuf.cpp - source/utils/stream/ResponseStream.cpp - source/utils/stream/SimpleStreamBuf.cpp - source/utils/threading/Executor.cpp - source/utils/threading/ReaderWriterLock.cpp - source/utils/threading/Semaphore.cpp - source/utils/threading/ThreadTask.cpp - source/utils/xml/XmlSerializer.cpp -) - -END() + source/utils/stream/PreallocatedStreamBuf.cpp + source/utils/stream/ResponseStream.cpp + source/utils/stream/SimpleStreamBuf.cpp + source/utils/threading/Executor.cpp + source/utils/threading/ReaderWriterLock.cpp + source/utils/threading/Semaphore.cpp + source/utils/threading/ThreadTask.cpp + source/utils/xml/XmlSerializer.cpp +) + +END() diff --git a/contrib/libs/aws-sdk-cpp/ya.make b/contrib/libs/aws-sdk-cpp/ya.make index d9fcb0818d..14637c11c4 100644 --- a/contrib/libs/aws-sdk-cpp/ya.make +++ b/contrib/libs/aws-sdk-cpp/ya.make @@ -1,17 +1,17 @@ # Generated by devtools/yamaker from nixpkgs 980c4c3c2f664ccc5002f7fd6e08059cf1f00e75. - + OWNER(orivej shindo g:cpp-contrib) - + VERSION(1.8.113) ORIGINAL_SOURCE(https://github.com/awslabs/aws-sdk-cpp/archive/1.8.113.tar.gz) -RECURSE( - aws-cpp-sdk-core +RECURSE( + aws-cpp-sdk-core aws-cpp-sdk-s3 aws-cpp-sdk-s3-integration-tests - aws-cpp-sdk-sqs + aws-cpp-sdk-sqs aws-cpp-sdk-kinesis aws-cpp-sdk-transfer testing-resources -) +) diff --git a/contrib/libs/ya.make b/contrib/libs/ya.make index 9c4640fdcf..a3bf8fbfe6 100644 --- a/contrib/libs/ya.make +++ b/contrib/libs/ya.make @@ -13,7 +13,7 @@ RECURSE( asmlib authparser avs-device-sdk - aws-sdk-cpp + aws-sdk-cpp backtrace base64 bdb @@ -427,7 +427,7 @@ IF (OS_LINUX OR OS_WINDOWS) lockless ) ENDIF() - + IF (OS_ANDROID) RECURSE( android_cpufeatures diff --git a/library/cpp/colorizer/ut/ya.make b/library/cpp/colorizer/ut/ya.make index 8a28c189af..e9ac941220 100644 --- a/library/cpp/colorizer/ut/ya.make +++ b/library/cpp/colorizer/ut/ya.make @@ -1,6 +1,6 @@ UNITTEST_FOR(library/cpp/colorizer) -OWNER(pg) +OWNER(pg) SRCS( colorizer_ut.cpp diff --git a/library/cpp/dbg_output/ut/ya.make b/library/cpp/dbg_output/ut/ya.make index 201601295d..108989de98 100644 --- a/library/cpp/dbg_output/ut/ya.make +++ b/library/cpp/dbg_output/ut/ya.make @@ -1,6 +1,6 @@ UNITTEST_FOR(library/cpp/dbg_output) -OWNER(pg) +OWNER(pg) SRCS( dbg_output_ut.cpp diff --git a/library/cpp/dbg_output/ya.make b/library/cpp/dbg_output/ya.make index 7d54108f93..6cc1d70ab1 100644 --- a/library/cpp/dbg_output/ya.make +++ b/library/cpp/dbg_output/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(pg) +OWNER(pg) PEERDIR( library/cpp/colorizer diff --git a/library/cpp/testing/unittest/ut/main.cpp b/library/cpp/testing/unittest/ut/main.cpp index e303e21e30..9541e8d089 100644 --- a/library/cpp/testing/unittest/ut/main.cpp +++ b/library/cpp/testing/unittest/ut/main.cpp @@ -6,7 +6,7 @@ #include <util/network/sock.h> #include <util/system/env.h> #include <util/system/fs.h> - + TEST(GTest, Test1) { UNIT_ASSERT_EQUAL(1, 1); } diff --git a/library/cpp/testing/unittest/ut/ya.make b/library/cpp/testing/unittest/ut/ya.make index 6d4c0959cc..5e3f4de559 100644 --- a/library/cpp/testing/unittest/ut/ya.make +++ b/library/cpp/testing/unittest/ut/ya.make @@ -1,10 +1,10 @@ UNITTEST_FOR(library/cpp/testing/unittest) - + OWNER(snowball) - -SRCS( - main.cpp + +SRCS( + main.cpp registar_ut.cpp -) - -END() +) + +END() diff --git a/library/python/filelock/__init__.py b/library/python/filelock/__init__.py index f81ff67f37..7325b1d398 100644 --- a/library/python/filelock/__init__.py +++ b/library/python/filelock/__init__.py @@ -30,7 +30,7 @@ class AbstractFileLock(object): def __enter__(self): self.acquire() return self - + def __exit__(self, type, value, traceback): self.release() diff --git a/library/python/pytest/yatest_tools.py b/library/python/pytest/yatest_tools.py index 6b8b896394..0a822f3c5d 100644 --- a/library/python/pytest/yatest_tools.py +++ b/library/python/pytest/yatest_tools.py @@ -10,24 +10,24 @@ import sys import yatest_lib.tools -class Subtest(object): +class Subtest(object): def __init__(self, name, test_name, status, comment, elapsed, result=None, test_type=None, logs=None, cwd=None, metrics=None): self._name = name self._test_name = test_name - self.status = status - self.elapsed = elapsed - self.comment = comment + self.status = status + self.elapsed = elapsed + self.comment = comment self.result = result self.test_type = test_type self.logs = logs or {} self.cwd = cwd self.metrics = metrics - + def __eq__(self, other): if not isinstance(other, Subtest): return False return self.name == other.name and self.test_name == other.test_name - + def __str__(self): return yatest_lib.tools.to_utf8(unicode(self)) @@ -83,7 +83,7 @@ class SubtestInfo(object): return str(self) -class Status(object): +class Status(object): GOOD, XFAIL, FAIL, XPASS, MISSING, CRASHED, TIMEOUT = range(7) SKIPPED = -100 NOT_LAUNCHED = -200 @@ -93,16 +93,16 @@ class Status(object): 'skipped': SKIPPED, 'flaky': FLAKY, 'not_launched': NOT_LAUNCHED, 'timeout': TIMEOUT, 'diff': CANON_DIFF} TO_STR = {GOOD: 'good', FAIL: 'fail', XFAIL: 'xfail', XPASS: 'xpass', MISSING: 'missing', CRASHED: 'crashed', SKIPPED: 'skipped', FLAKY: 'flaky', NOT_LAUNCHED: 'not_launched', TIMEOUT: 'timeout', CANON_DIFF: 'diff'} - - -class Test(object): + + +class Test(object): def __init__(self, name, path, status=None, comment=None, subtests=None): - self.name = name - self.path = path + self.name = name + self.path = path self.status = status self.comment = comment self.subtests = subtests or [] - + def __eq__(self, other): if not isinstance(other, Test): return False @@ -114,19 +114,19 @@ class Test(object): def __repr__(self): return str(self) - def add_subtest(self, subtest): - self.subtests.append(subtest) - - def setup_status(self, status, comment): - self.status = Status.BY_NAME[status or 'good'] - if len(self.subtests) != 0: - self.status = max(self.status, max(s.status for s in self.subtests)) - self.comment = comment - - def subtests_by_status(self, status): - return [x.status for x in self.subtests].count(status) - - + def add_subtest(self, subtest): + self.subtests.append(subtest) + + def setup_status(self, status, comment): + self.status = Status.BY_NAME[status or 'good'] + if len(self.subtests) != 0: + self.status = max(self.status, max(s.status for s in self.subtests)) + self.comment = comment + + def subtests_by_status(self, status): + return [x.status for x in self.subtests].count(status) + + class NoMd5FileException(Exception): pass diff --git a/library/python/testing/yatest_common/yatest/common/process.py b/library/python/testing/yatest_common/yatest/common/process.py index a8bcc21f51..62afaedb9d 100644 --- a/library/python/testing/yatest_common/yatest/common/process.py +++ b/library/python/testing/yatest_common/yatest/common/process.py @@ -24,22 +24,22 @@ from . import path from . import environment -MAX_OUT_LEN = 1000 * 1000 # 1 mb +MAX_OUT_LEN = 1000 * 1000 # 1 mb MAX_MESSAGE_LEN = 1500 SANITIZER_ERROR_PATTERN = br": ([A-Z][\w]+Sanitizer)" GLIBC_PATTERN = re.compile(r"\S+@GLIBC_([0-9.]+)") yatest_logger = logging.getLogger("ya.test") -def truncate(s, size): - if s is None: - return None - elif len(s) <= size: - return s - else: +def truncate(s, size): + if s is None: + return None + elif len(s) <= size: + return s + else: return (b'...' if isinstance(s, bytes) else '...') + s[-(size - 3):] - - + + def get_command_name(command): return os.path.basename(command.split()[0] if isinstance(command, six.string_types) else command[0]) @@ -623,7 +623,7 @@ def wait_for(check_function, timeout, fail_message="", sleep_time=1.0, on_check_ message = "{} second(s) wait timeout has expired".format(timeout) if fail_message: message += ": {}".format(fail_message) - raise TimeoutError(truncate(message, MAX_MESSAGE_LEN)) + raise TimeoutError(truncate(message, MAX_MESSAGE_LEN)) def _kill_process_tree(process_pid, target_pid_signal=None): diff --git a/tools/enum_parser/enum_parser/ya.make b/tools/enum_parser/enum_parser/ya.make index 82bac4e0f7..d8dc5a556c 100644 --- a/tools/enum_parser/enum_parser/ya.make +++ b/tools/enum_parser/enum_parser/ya.make @@ -10,7 +10,7 @@ ENDIF() IF (NOT PREBUILT) INCLUDE(${ARCADIA_ROOT}/tools/enum_parser/enum_parser/bin/ya.make) ENDIF() - + RECURSE( bin ) diff --git a/util/folder/path_ut.cpp b/util/folder/path_ut.cpp index e6a3451016..df67fc854f 100644 --- a/util/folder/path_ut.cpp +++ b/util/folder/path_ut.cpp @@ -1,7 +1,7 @@ #include "path.h" #include "pathsplit.h" -#include "dirut.h" -#include "tempdir.h" +#include "dirut.h" +#include "tempdir.h" #include <library/cpp/testing/unittest/registar.h> @@ -9,8 +9,8 @@ #include <util/system/platform.h> #include <util/system/yassert.h> #include <util/stream/output.h> -#include <util/stream/file.h> -#include <util/system/fs.h> +#include <util/stream/file.h> +#include <util/system/fs.h> #include <algorithm> @@ -424,108 +424,108 @@ Y_UNIT_TEST_SUITE(TFsPathTests) { TFsPath pathThree{"/a/b"}; UNIT_ASSERT_VALUES_EQUAL(ToString(pathThree), "/a/b"); } - -#ifdef _unix_ + +#ifdef _unix_ Y_UNIT_TEST(TestRemoveSymlinkToDir) { - TTempDir tempDir; - TFsPath tempDirPath(tempDir()); - + TTempDir tempDir; + TFsPath tempDirPath(tempDir()); + const TString originDir = tempDirPath.Child("origin"); - MakePathIfNotExist(originDir.c_str()); - + MakePathIfNotExist(originDir.c_str()); + const TString originFile = TFsPath(originDir).Child("data"); - { + { TFixedBufferFileOutput out(originFile); - out << "data111!!!"; - } - + out << "data111!!!"; + } + const TString link = tempDirPath.Child("origin_symlink"); - NFs::SymLink(originDir, link); - - TFsPath(link).ForceDelete(); - + NFs::SymLink(originDir, link); + + TFsPath(link).ForceDelete(); + UNIT_ASSERT(!NFs::Exists(link)); UNIT_ASSERT(NFs::Exists(originFile)); UNIT_ASSERT(NFs::Exists(originDir)); - } - + } + Y_UNIT_TEST(TestRemoveSymlinkToFile) { - TTempDir tempDir; - TFsPath tempDirPath(tempDir()); - + TTempDir tempDir; + TFsPath tempDirPath(tempDir()); + const TString originDir = tempDirPath.Child("origin"); - MakePathIfNotExist(originDir.c_str()); - + MakePathIfNotExist(originDir.c_str()); + const TString originFile = TFsPath(originDir).Child("data"); - { + { TFixedBufferFileOutput out(originFile); - out << "data111!!!"; - } - + out << "data111!!!"; + } + const TString link = tempDirPath.Child("origin_symlink"); - NFs::SymLink(originFile, link); - - TFsPath(link).ForceDelete(); - + NFs::SymLink(originFile, link); + + TFsPath(link).ForceDelete(); + UNIT_ASSERT(!NFs::Exists(link)); UNIT_ASSERT(NFs::Exists(originFile)); UNIT_ASSERT(NFs::Exists(originDir)); - } - + } + Y_UNIT_TEST(TestRemoveDirWithSymlinkToDir) { - TTempDir tempDir; - TFsPath tempDirPath(tempDir()); - + TTempDir tempDir; + TFsPath tempDirPath(tempDir()); + const TString symlinkedDir = tempDirPath.Child("to_remove"); - MakePathIfNotExist(symlinkedDir.c_str()); - + MakePathIfNotExist(symlinkedDir.c_str()); + const TString originDir = tempDirPath.Child("origin"); - MakePathIfNotExist(originDir.c_str()); - + MakePathIfNotExist(originDir.c_str()); + const TString originFile = TFsPath(originDir).Child("data"); - { + { TFixedBufferFileOutput out(originFile); - out << "data111!!!"; - } - + out << "data111!!!"; + } + const TString symlinkedFile = TFsPath(symlinkedDir).Child("origin_symlink"); - NFs::SymLink(originDir, symlinkedFile); - - TFsPath(symlinkedDir).ForceDelete(); - + NFs::SymLink(originDir, symlinkedFile); + + TFsPath(symlinkedDir).ForceDelete(); + UNIT_ASSERT(!NFs::Exists(symlinkedFile)); UNIT_ASSERT(!NFs::Exists(symlinkedDir)); UNIT_ASSERT(NFs::Exists(originFile)); UNIT_ASSERT(NFs::Exists(originDir)); - } - + } + Y_UNIT_TEST(TestRemoveDirWithSymlinkToFile) { - TTempDir tempDir; - TFsPath tempDirPath(tempDir()); - + TTempDir tempDir; + TFsPath tempDirPath(tempDir()); + const TString symlinkedDir = tempDirPath.Child("to_remove"); - MakePathIfNotExist(symlinkedDir.c_str()); - + MakePathIfNotExist(symlinkedDir.c_str()); + const TString originDir = tempDirPath.Child("origin"); - MakePathIfNotExist(originDir.c_str()); - + MakePathIfNotExist(originDir.c_str()); + const TString originFile = TFsPath(originDir).Child("data"); - { + { TFixedBufferFileOutput out(originFile); - out << "data111!!!"; - } - + out << "data111!!!"; + } + const TString symlinkedFile = TFsPath(symlinkedDir).Child("origin_symlink"); - NFs::SymLink(originFile, symlinkedFile); - - TFsPath(symlinkedDir).ForceDelete(); - + NFs::SymLink(originFile, symlinkedFile); + + TFsPath(symlinkedDir).ForceDelete(); + UNIT_ASSERT(!NFs::Exists(symlinkedFile)); UNIT_ASSERT(!NFs::Exists(symlinkedDir)); UNIT_ASSERT(NFs::Exists(originFile)); UNIT_ASSERT(NFs::Exists(originDir)); - } -#endif + } +#endif Y_UNIT_TEST(TestForceDeleteNonexisting) { TTempDir tempDir; diff --git a/util/system/file.cpp b/util/system/file.cpp index 4a261d020c..941a652d63 100644 --- a/util/system/file.cpp +++ b/util/system/file.cpp @@ -111,8 +111,8 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept { faMode &= ~FILE_WRITE_DATA; } - bool inheritHandle = !(oMode & CloseOnExec); - + bool inheritHandle = !(oMode & CloseOnExec); + ui32 shMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; ui32 attrMode = FILE_ATTRIBUTE_NORMAL; @@ -175,10 +175,10 @@ TFileHandle::TFileHandle(const TString& fName, EOpenMode oMode) noexcept { fcMode |= O_APPEND; } - if (oMode & CloseOnExec) { - fcMode |= O_CLOEXEC; - } - + if (oMode & CloseOnExec) { + fcMode |= O_CLOEXEC; + } + /* I don't now about this for unix... if (oMode & Temp) { } diff --git a/util/system/fs.cpp b/util/system/fs.cpp index d2611a8ccc..01ad2bb9b5 100644 --- a/util/system/fs.cpp +++ b/util/system/fs.cpp @@ -71,16 +71,16 @@ bool NFs::MakeDirectoryRecursive(const TString& path, EFilePermissions mode, boo return true; } else { //NOTE: recursion is finite due to existence of "." and "/" - if (!NFs::MakeDirectoryRecursive(TFsPath(path).Parent(), mode, false)) { - return false; - } - - bool isDirMade = NFs::MakeDirectory(path, mode); - if (!isDirMade && alwaysCreate) { + if (!NFs::MakeDirectoryRecursive(TFsPath(path).Parent(), mode, false)) { + return false; + } + + bool isDirMade = NFs::MakeDirectory(path, mode); + if (!isDirMade && alwaysCreate) { ythrow TIoException() << "failed to create " << path << " with cwd (" << NFs::CurrentWorkingDirectory() << ")"; } - - return TFileStat(path).IsDir(); + + return TFileStat(path).IsDir(); } } diff --git a/util/system/fs.h b/util/system/fs.h index 237daf2d2d..129d5ccd89 100644 --- a/util/system/fs.h +++ b/util/system/fs.h @@ -64,7 +64,7 @@ namespace NFs { /// /// @param[in] path Path to be created /// @param[in] mode Access permissions field; NOTE: ignored on win - /// @returns true if target path created or exists (and directory) + /// @returns true if target path created or exists (and directory) inline bool MakeDirectoryRecursive(const TString& path, EFilePermissions mode) { return MakeDirectoryRecursive(path, mode, false); } diff --git a/util/system/fs_ut.cpp b/util/system/fs_ut.cpp index de071ebf55..b96461a8a9 100644 --- a/util/system/fs_ut.cpp +++ b/util/system/fs_ut.cpp @@ -63,13 +63,13 @@ void TFsTest::TestCreateRemove() { Touch(file3); //UNIT_ASSERT(NFs::SymLink(file3.RealPath(), link)); - UNIT_ASSERT(NFs::MakeDirectoryRecursive(dir1 / "subdir1" / "subdir2" / "subdir3" / "subdir4", NFs::FP_COMMON_FILE, false)); - UNIT_ASSERT(NFs::MakeDirectoryRecursive(dir1 / "subdir1" / "subdir2", NFs::FP_COMMON_FILE, false)); - - // the target path is a file or "subdirectory" of a file - UNIT_ASSERT(!NFs::MakeDirectoryRecursive(file1 / "subdir1" / "subdir2", NFs::FP_COMMON_FILE, false)); - UNIT_ASSERT(!NFs::MakeDirectoryRecursive(file1, NFs::FP_COMMON_FILE, false)); - + UNIT_ASSERT(NFs::MakeDirectoryRecursive(dir1 / "subdir1" / "subdir2" / "subdir3" / "subdir4", NFs::FP_COMMON_FILE, false)); + UNIT_ASSERT(NFs::MakeDirectoryRecursive(dir1 / "subdir1" / "subdir2", NFs::FP_COMMON_FILE, false)); + + // the target path is a file or "subdirectory" of a file + UNIT_ASSERT(!NFs::MakeDirectoryRecursive(file1 / "subdir1" / "subdir2", NFs::FP_COMMON_FILE, false)); + UNIT_ASSERT(!NFs::MakeDirectoryRecursive(file1, NFs::FP_COMMON_FILE, false)); + TString longUtf8Name = ""; while (longUtf8Name.size() < 255) { longUtf8Name = longUtf8Name + "fф"; diff --git a/util/system/fs_win.cpp b/util/system/fs_win.cpp index a410ccac06..c76b25280e 100644 --- a/util/system/fs_win.cpp +++ b/util/system/fs_win.cpp @@ -215,7 +215,7 @@ namespace NFsPrivate { /* bool GetObjectId(const char* path, GUID* id) { TFileHandle h = CreateFileWithUtf8Name(path, 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, true); + OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, true); if (h.IsOpen()) { FILE_OBJECTID_BUFFER fob; DWORD resSize = 0; diff --git a/util/system/shellcommand.cpp b/util/system/shellcommand.cpp index b1989b5c8c..b712321c10 100644 --- a/util/system/shellcommand.cpp +++ b/util/system/shellcommand.cpp @@ -195,7 +195,7 @@ private: TList<TString> Arguments; TString WorkDir; TAtomic ExecutionStatus; // TShellCommand::ECommandStatus - TMaybe<int> ExitCode; + TMaybe<int> ExitCode; IInputStream* InputStream; IOutputStream* OutputStream; IOutputStream* ErrorStream; @@ -362,10 +362,10 @@ public: return static_cast<ECommandStatus>(AtomicGet(ExecutionStatus)); } - inline TMaybe<int> GetExitCode() const { - return ExitCode; - } - + inline TMaybe<int> GetExitCode() const { + return ExitCode; + } + inline TProcessId GetPid() const { #if defined(_win_) return GetProcessId(Pid); @@ -1062,9 +1062,9 @@ void TShellCommand::TImpl::Communicate(TProcessInfo* pi) { // Otherwise there is no way for input stream provider to discover // that process has exited and stream shouldn't wait for new data. bool cleanExit = false; - TMaybe<int> processExitCode; + TMaybe<int> processExitCode; #if defined(_unix_) - processExitCode = WEXITSTATUS(status); + processExitCode = WEXITSTATUS(status); if (WIFEXITED(status) && processExitCode == 0) { cleanExit = true; } else if (WIFSIGNALED(status)) { @@ -1078,11 +1078,11 @@ void TShellCommand::TImpl::Communicate(TProcessInfo* pi) { } if (exitCode == 0) cleanExit = true; - processExitCode = static_cast<int>(exitCode); + processExitCode = static_cast<int>(exitCode); DBG(Cerr << "exit code: " << exitCode << Endl); } #endif - pi->Parent->ExitCode = processExitCode; + pi->Parent->ExitCode = processExitCode; if (cleanExit) { AtomicSet(pi->Parent->ExecutionStatus, SHELL_FINISHED); } else { @@ -1155,10 +1155,10 @@ TShellCommand::ECommandStatus TShellCommand::GetStatus() const { return Impl->GetStatus(); } -TMaybe<int> TShellCommand::GetExitCode() const { - return Impl->GetExitCode(); -} - +TMaybe<int> TShellCommand::GetExitCode() const { + return Impl->GetExitCode(); +} + TProcessId TShellCommand::GetPid() const { return Impl->GetPid(); } diff --git a/util/system/shellcommand.h b/util/system/shellcommand.h index 8730627fe5..ba30735c41 100644 --- a/util/system/shellcommand.h +++ b/util/system/shellcommand.h @@ -5,7 +5,7 @@ #include <util/generic/list.h> #include <util/generic/hash.h> #include <util/generic/strbuf.h> -#include <util/generic/maybe.h> +#include <util/generic/maybe.h> #include <util/stream/input.h> #include <util/stream/output.h> #include "file.h" @@ -399,13 +399,13 @@ public: ECommandStatus GetStatus() const; /** - * @brief return exit code of finished process - * The value is unspecified in case of internal errors or if the process is running - * - * @return exit code - */ - TMaybe<int> GetExitCode() const; - + * @brief return exit code of finished process + * The value is unspecified in case of internal errors or if the process is running + * + * @return exit code + */ + TMaybe<int> GetExitCode() const; + /** * @brief get id of underlying process * @note depends on os: pid_t on UNIX, HANDLE on win diff --git a/util/system/shellcommand_ut.cpp b/util/system/shellcommand_ut.cpp index 9d849279d2..db5545ea88 100644 --- a/util/system/shellcommand_ut.cpp +++ b/util/system/shellcommand_ut.cpp @@ -79,7 +79,7 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { UNIT_ASSERT_VALUES_EQUAL(cmd.GetError(), ""); UNIT_ASSERT_VALUES_EQUAL(cmd.GetOutput(), "hello" NL); UNIT_ASSERT(TShellCommand::SHELL_FINISHED == cmd.GetStatus()); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); UNIT_ASSERT_VALUES_EQUAL(cmd.GetQuotedCommand(), "echo hello"); } @@ -108,7 +108,7 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { UNIT_ASSERT_VALUES_EQUAL(cmd.GetOutput(), "hello\n"); #endif UNIT_ASSERT(TShellCommand::SHELL_FINISHED == cmd.GetStatus()); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); } // running with no shell is not implemented for win // there should be no problem with it as long as SearchPath is on @@ -130,7 +130,7 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { cmd.Run(); UNIT_ASSERT(TShellCommand::SHELL_ERROR == cmd.GetStatus()); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 != cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 != cmd.GetExitCode()); } { options.SetUseShell(true); @@ -140,7 +140,7 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { cmd.Run(); UNIT_ASSERT(TShellCommand::SHELL_FINISHED == cmd.GetStatus()); UNIT_ASSERT_VALUES_EQUAL(cmd.GetError().size(), 0u); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); } } Y_UNIT_TEST(TestAsyncRun) { @@ -165,7 +165,7 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { #if !defined(_win_) UNIT_ASSERT(TShellCommand::SHELL_FINISHED == cmd.GetStatus()); UNIT_ASSERT_VALUES_EQUAL(cmd.GetOutput().size(), 0u); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); #endif } Y_UNIT_TEST(TestQuotes) { @@ -190,15 +190,15 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { cmd.Run().Wait(); UNIT_ASSERT(TShellCommand::SHELL_ERROR == cmd.GetStatus()); UNIT_ASSERT_VALUES_UNEQUAL(cmd.GetError().size(), 0u); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 != cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 != cmd.GetExitCode()); } Y_UNIT_TEST(TestExitCode) { - TShellCommand cmd("grep qwerty qwerty"); // some nonexistent file name - cmd.Run().Wait(); - UNIT_ASSERT(TShellCommand::SHELL_ERROR == cmd.GetStatus()); + TShellCommand cmd("grep qwerty qwerty"); // some nonexistent file name + cmd.Run().Wait(); + UNIT_ASSERT(TShellCommand::SHELL_ERROR == cmd.GetStatus()); UNIT_ASSERT_VALUES_UNEQUAL(cmd.GetError().size(), 0u); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 2 == cmd.GetExitCode()); - } + UNIT_ASSERT(cmd.GetExitCode().Defined() && 2 == cmd.GetExitCode()); + } // 'type con' and 'copy con con' want real console, not stdin, use sort Y_UNIT_TEST(TestInput) { TShellCommandOptions options; @@ -258,7 +258,7 @@ Y_UNIT_TEST_SUITE(TShellCommandTest) { UNIT_ASSERT_VALUES_EQUAL(cmd.GetError(), ""); UNIT_ASSERT(TShellCommand::SHELL_FINISHED == cmd.GetStatus()); UNIT_ASSERT_VALUES_EQUAL(read.Str(), "alpha" NL "omega" NL "zeta" NL); - UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); + UNIT_ASSERT(cmd.GetExitCode().Defined() && 0 == cmd.GetExitCode()); } Y_UNIT_TEST(TestStreamClose) { struct TStream: public IOutputStream { |